1 ////////////////////////////////////////////////////////////////////////////////
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
8 // Polymorphous classes using the callback approach
10 // format: magic [ key data ]
12 ////////////////////////////////////////////////////////////////////////////////
13 #include "persistent_int.hpp"
18 ////////////////////////////////////////////////////////////////////////////////
21 void dump_callback(dump_context& context, const T* const data)
22 throw(persistent_dump_failed)
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)
33 // callback method - get the callback data and perform the dump
34 // this will throw persistent_illegal_type if not recognised, thus the try block
35 dump_context::callback_data callback = context.lookup_callback(typeid(*data));
36 // dump the magic key for the type
37 dump_unsigned(context, callback.first);
38 // now call the callback that dumps the subclass
39 callback.second(context,data);
42 catch (const persistent_illegal_type& except)
44 // convert this to a simpler dump failed exception
45 throw persistent_dump_failed(except.what());
49 ////////////////////////////////////////////////////////////////////////////////
52 void restore_callback(restore_context& context, T*& data)
53 throw(persistent_restore_failed)
57 // first delete any previous object pointed to since the restore creates the object of the right subclass
65 restore_unsigned(context,magic);
66 // now lookup the magic key to see if this pointer has already been restored
67 // null pointers are always flagged as already restored
68 std::pair<bool,void*> address = context.pointer_map(magic);
71 // seen before, so simply map it to the existing address
72 data = (T*)address.second;
76 // now restore the magic key that denotes the particular subclass
78 restore_unsigned(context, key);
80 // call the create callback to create an object of the right type
81 // then call the restore callback to get the contents
82 // this will throw persistent_illegal_type if not recognised - this is caught below
83 restore_context::callback_data callbacks = context.lookup_callback(key);
84 data = (T*)callbacks.first();
85 // add this pointer to the set of already seen objects
86 // note that the address is mapped before it is dumped so that self-referential structures dump correctly
87 context.pointer_add(magic,data);
88 callbacks.second(context,data);
91 catch (const persistent_illegal_type& exception)
93 // convert this to a simpler dump failed exception
94 throw persistent_restore_failed(exception.what());
98 ////////////////////////////////////////////////////////////////////////////////
100 } // end namespace stlplus