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 interface approach
10 // format: magic [ key data ]
12 ////////////////////////////////////////////////////////////////////////////////
13 #include "persistent_int.hpp"
18 ////////////////////////////////////////////////////////////////////////////////
21 void dump_interface(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)
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
43 catch (const persistent_illegal_type& except)
45 // convert this to a simpler dump failed exception
46 throw persistent_dump_failed(except.what());
50 ////////////////////////////////////////////////////////////////////////////////
53 void restore_interface(restore_context& context, T*& data)
54 throw(persistent_restore_failed)
58 // first delete any previous object pointed to since the restore creates the object of the right subclass
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);
72 // seen before, so simply map it to the existing address
73 data = (T*)address.second;
77 // now restore the magic key that denotes the particular subclass
79 restore_unsigned(context, key);
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);
90 catch (const persistent_illegal_type& exception)
92 // convert this to a simpler dump failed exception
93 throw persistent_restore_failed(exception.what());
97 ////////////////////////////////////////////////////////////////////////////////
99 } // end namespace stlplus