persistence/persistent_contexts.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#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