persistence/persistent_contexts.hpp
#ifndef STLPLUS_PERSISTENT_CONTEXTS
#define STLPLUS_PERSISTENT_CONTEXTS
////////////////////////////////////////////////////////////////////////////////
// Author: Andy Rushton
// Copyright: (c) Southampton University 1999-2004
// (c) Andy Rushton 2004 onwards
// License: BSD License, see ../docs/license.html
// Core context classes used to control the persistent dump/restore operations
////////////////////////////////////////////////////////////////////////////////
#include "persistence_fixes.hpp"
#include "persistent.hpp"
#include <iostream>
#include <map>
#include <typeinfo>
////////////////////////////////////////////////////////////////////////////////
namespace stlplus
{
////////////////////////////////////////////////////////////////////////////////
// Internals
class dump_context_body;
class restore_context_body;
////////////////////////////////////////////////////////////////////////////////
// The format version number currently supported
////////////////////////////////////////////////////////////////////////////////
extern unsigned char PersistentVersion;
////////////////////////////////////////////////////////////////////////////////
// dump_context controls the formatting of a persistent dump
////////////////////////////////////////////////////////////////////////////////
class dump_context
{
friend class persistent;
public:
//////////////////////////////////////////////////////////////////////////////
// device must be in binary mode
// exceptions: persistent_dump_failed
dump_context(std::ostream& device, unsigned char version = PersistentVersion) ;
~dump_context(void);
// low level output used to dump a byte
// exceptions: persistent_dump_failed
void put(unsigned char data) ;
// access the device, for example to check the error status
const std::ostream& device(void) const;
// recover the version number of the dumped output
unsigned char version(void) const;
// test whether the current platform uses little-endian or big-endian addressing of bytes
// this is used in dump/restore of integers and is exported so that other routines can use it
bool little_endian(void) const;
// Assist functions for Pointers
// the return pair value is a flag saying whether this is a new pointer and the magic key to dump to file
std::pair<bool,unsigned> pointer_map(const void* const pointer);
// the return pair value is a flag saying whether this is a new object and the magic key to dump to file
std::pair<bool,unsigned> object_map(const void* const pointer);
// Assist functions for Polymorphous classes (i.e. subclasses) using callback approach
typedef void (*dump_callback)(dump_context&,const void*);
unsigned register_callback(const std::type_info& info, dump_callback);
bool is_callback(const std::type_info& info) const;
typedef std::pair<unsigned,dump_callback> callback_data;
// exceptions: persistent_illegal_type
callback_data lookup_callback(const std::type_info&) const ;
// Assist functions for Polymorphous classes (i.e. subclasses) using interface approach
unsigned register_interface(const std::type_info& info);
bool is_interface(const std::type_info& info) const;
// exceptions: persistent_illegal_type
unsigned lookup_interface(const std::type_info&) const ;
// Register all Polymorphous classes using either approach by calling an installer callback
typedef void (*installer)(dump_context&);
void register_all(installer);
private:
friend class dump_context_body;
dump_context_body* m_body;
// disallow copying by making assignment and copy constructor private
dump_context(const dump_context&);
dump_context& operator=(const dump_context&);
};
////////////////////////////////////////////////////////////////////////////////
// restore_context controls the reading of the persistent data during a restore
class restore_context
{
friend class persistent;
public:
//////////////////////////////////////////////////////////////////////////////
// device must be in binary mode
// exceptions: persistent_restore_failed
restore_context(std::istream& device) ;
~restore_context(void);
// low level input used to restore a byte
// exceptions: persistent_restore_failed
int get(void) ;
// access the device, for example to check the error status
const std::istream& device(void) const;
// access the version number of the input being restored
unsigned char version(void) const;
// test whether the current platform uses little-endian or big-endian addressing of bytes
// this is used in dump/restore of integers
bool little_endian(void) const;
// Assist functions for Pointers
std::pair<bool,void*> pointer_map(unsigned magic);
void pointer_add(unsigned magic, void* new_pointer);
std::pair<bool,void*> object_map(unsigned magic);
void object_add(unsigned magic, void* new_pointer);
// Assist functions for Polymorphous classes using the callback approach
typedef void* (*create_callback)(void);
typedef void (*restore_callback)(restore_context&,void*);
unsigned register_callback(create_callback,restore_callback);
bool is_callback(unsigned) const;
typedef std::pair<create_callback, restore_callback> callback_data;
// exceptions: persistent_illegal_type
callback_data lookup_callback(unsigned) const ;
// Assist functions for Polymorphous classes using the interface approach
unsigned register_interface(persistent*);
bool is_interface(unsigned) const;
// exceptions: persistent_illegal_type
persistent* lookup_interface(unsigned) const ;
// Register all Polymorphous classes using either approach by calling an installer callback
typedef void (*installer)(restore_context&);
void register_all(installer);
private:
friend class restore_context_body;
restore_context_body* m_body;
typedef std::pair<unsigned,persistent*> interface_data;
// disallow copying by making assignment and copy constructor private
restore_context(const restore_context&);
restore_context& operator=(const restore_context&);
};
////////////////////////////////////////////////////////////////////////////////
} // end namespace stlplus
////////////////////////////////////////////////////////////////////////////////
#endif