]> Dogcows Code - chaz/yoink/blob - src/stlplus/persistence/persistent_interface.tpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / persistence / persistent_interface.tpp
1 ////////////////////////////////////////////////////////////////////////////////
2
3 // Author: Andy Rushton
4 // Copyright: (c) Southampton University 1999-2004
5 // (c) Andy Rushton 2004-2009
6 // License: BSD License, see ../docs/license.html
7
8 // Polymorphous classes using the interface approach
9
10 // format: magic [ key data ]
11
12 ////////////////////////////////////////////////////////////////////////////////
13 #include "persistent_int.hpp"
14
15 namespace stlplus
16 {
17
18 ////////////////////////////////////////////////////////////////////////////////
19
20 template<typename T>
21 void dump_interface(dump_context& context, const T* const data)
22 throw(persistent_dump_failed)
23 {
24 try
25 {
26 // register the address and get the magic key for it
27 std::pair<bool,unsigned> mapping = context.pointer_map(data);
28 dump_unsigned(context,mapping.second);
29 // if the address is null, then that is all that we need to do
30 // however, if it is non-null and this is the first sight of the address, dump the contents
31 if (data && !mapping.first)
32 {
33 // interface method
34 // the lookup just finds the magic key and the type has a dump method
35 // this will throw persistent_illegal_type if the type is not registered
36 unsigned key = context.lookup_interface(typeid(*data));
37 // dump the magic key for the type
38 dump_unsigned(context, key);
39 // now call the dump method defined by the interface
40 data->dump(context);
41 }
42 }
43 catch (const persistent_illegal_type& except)
44 {
45 // convert this to a simpler dump failed exception
46 throw persistent_dump_failed(except.what());
47 }
48 }
49
50 ////////////////////////////////////////////////////////////////////////////////
51
52 template<typename T>
53 void restore_interface(restore_context& context, T*& data)
54 throw(persistent_restore_failed)
55 {
56 try
57 {
58 // first delete any previous object pointed to since the restore creates the object of the right subclass
59 if (data)
60 {
61 delete data;
62 data = 0;
63 }
64 // get the magic key
65 unsigned magic = 0;
66 restore_unsigned(context,magic);
67 // now lookup the magic key to see if this pointer has already been restored
68 // null pointers are always flagged as already restored
69 std::pair<bool,void*> address = context.pointer_map(magic);
70 if (address.first)
71 {
72 // seen before, so simply map it to the existing address
73 data = (T*)address.second;
74 }
75 else
76 {
77 // now restore the magic key that denotes the particular subclass
78 unsigned key = 0;
79 restore_unsigned(context, key);
80 // interface approach
81 // first clone the sample object stored in the map - lookup_interface can throw persistent_illegal_type
82 data = (T*)(context.lookup_interface(key)->clone());
83 // add this pointer to the set of already seen objects
84 // do this before restoring the object so that self-referential structures restore correctly
85 context.pointer_add(magic,data);
86 // now restore the contents using the object's method
87 data->restore(context);
88 }
89 }
90 catch (const persistent_illegal_type& exception)
91 {
92 // convert this to a simpler dump failed exception
93 throw persistent_restore_failed(exception.what());
94 }
95 }
96
97 ////////////////////////////////////////////////////////////////////////////////
98
99 } // end namespace stlplus
This page took 0.033916 seconds and 4 git commands to generate.