summaryrefslogtreecommitdiff
path: root/src/stable/archive.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/archive.h')
-rw-r--r--src/stable/archive.h138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/stable/archive.h b/src/stable/archive.h
new file mode 100644
index 0000000..61474a4
--- /dev/null
+++ b/src/stable/archive.h
@@ -0,0 +1,138 @@
1/*
2 * Copyright (C) 2007-2011 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_ARCHIVE_H
9#define BU_ARCHIVE_H
10
11#include <stdint.h>
12#include "bu/archivebase.h"
13#include "bu/hash.h"
14#include "bu/util.h"
15#include "bu/variant.h"
16
17namespace Bu
18{
19 class Archival;
20 class Stream;
21
22 /**
23 * Provides a framework for serialization of objects and primitives. The
24 * archive will handle any basic primitive, a few special types, like char *
25 * strings, as well as STL classes and anything that inherits from the
26 * Archival class. Each Archive operates on a Stream, so you can send the
27 * data using an Archive almost anywhere.
28 *
29 * In order to use an Archive to store something to a file, try something
30 * like:
31 *@code
32 * File sOut("output", "wb"); // This is a stream subclass
33 * Archive ar( sOut, Archive::save );
34 * ar << myClass;
35 @endcode
36 * In this example myClass is any class that inherits from Archival. When
37 * the storage operator is called, the Archival::archive() function in the
38 * myClass object is called with a reference to the Archive. This can be
39 * handled in one of two ways:
40 *@code
41 * void MyClass::archive( Archive &ar )
42 * {
43 * ar && sName && nAge && sJob;
44 * }
45 @endcode
46 * Here we don't worry about weather we're loading or saving by using the
47 * smart && operator. This allows us to write very consistent, very simple
48 * archive functions that really do a lot of work. If we wanted to do
49 * something different in the case of loading or saving we would do:
50 *@code
51 * void MyClass::archive( Archive &ar )
52 * {
53 * if( ar.isLoading() )
54 * {
55 * ar >> sName >> nAge >> sJob;
56 * } else
57 * {
58 * ar << sName << nAge << sJob;
59 * }
60 * }
61 @endcode
62 * Archive currently does not provide facility to make fully portable
63 * archives. For example, it will not convert between endianness for you,
64 * nor will it take into account differences between primitive sizes on
65 * different platforms. This, at the moment, is up to the user to ensure.
66 * One way of dealing with the latter problem is to make sure and use
67 * explicit primitive types from the stdint.h header, i.e. int32_t.
68 */
69 class Archive : public ArchiveBase
70 {
71 private:
72 bool bLoading;
73 public:
74 bool isLoading();
75
76 enum
77 {
78 load = true,
79 save = false
80 };
81
82 Archive( Stream &rStream, bool bLoading );
83 virtual ~Archive();
84 virtual void close();
85
86 virtual void write( const void *pData, size_t iSize );
87 virtual void read( void *pData, size_t iSize );
88
89 /**
90 * For storage, get an ID for the pointer to the object you're going to
91 * write.
92 */
93 uint32_t getID( const void *ptr );
94
95 /**
96 * For loading. Assosiates an empty pointer with an id. When you wind
97 * up loading an id reference to a pointer for an object that may or
98 * may not have loaded yet, call this with the id, if it has been loaded
99 * already, you'll immediately get a pointer, if not, it will write one
100 * for you when the time comes.
101 */
102 void assocPtrID( void **ptr, uint32_t id );
103
104 /**
105 * For loading. Call this when you load an object that other things may
106 * have pointers to. It will assosiate every pointer that's been
107 * registered with assocPtrID to the pointer passed in, and id passed
108 * in. It will also set things up so future calls to assocPtrID will
109 * automatically succeed immediately.
110 */
111 void readID( const void *ptr, uint32_t id );
112
113 template<typename t>
114 void setProp( const Bu::String &sId, const t &val )
115 {
116 if( !hProps.has( sId ) )
117 {
118 hProps.insert( sId, Variant() );
119 }
120 hProps.get( sId ) = val;
121 }
122
123 template<typename t>
124 t getProp( const Bu::String &sId )
125 {
126 return hProps.get( sId );
127 }
128
129 private:
130 Stream &rStream;
131 uint32_t nNextID;
132 Hash<uint32_t,uint32_t> hPtrID;
133 Hash<uint32_t,List<void **> > hPtrDest;
134 Hash<Bu::String, Variant> hProps;
135 };
136}
137
138#endif