aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2022-04-21 10:32:35 -0700
committerMike Buland <eichlan@xagasoft.com>2022-04-21 10:32:35 -0700
commit23d88aa2812c361d30abefeeb296548698409bf5 (patch)
tree1fae38f0fccdff7bf8bc8f868bb5533cbe607af9
parentfd56cdd21a7c9c944ad189cf91ff24d3c2b0f975 (diff)
downloadlibbu++-23d88aa2812c361d30abefeeb296548698409bf5.tar.gz
libbu++-23d88aa2812c361d30abefeeb296548698409bf5.tar.bz2
libbu++-23d88aa2812c361d30abefeeb296548698409bf5.tar.xz
libbu++-23d88aa2812c361d30abefeeb296548698409bf5.zip
More progress, mostly planning and playing.
I'm trying to find the right design usage patterns for using the archive system with tagging and lists and dictionaries. Also, are there other structures that I'm missing?
-rw-r--r--src/stable/archivebinary.cpp41
-rw-r--r--src/stable/archivebinary.h72
-rw-r--r--src/tests/archivetags.cpp6
3 files changed, 4 insertions, 115 deletions
diff --git a/src/stable/archivebinary.cpp b/src/stable/archivebinary.cpp
index 04e80d2..f46bd28 100644
--- a/src/stable/archivebinary.cpp
+++ b/src/stable/archivebinary.cpp
@@ -13,8 +13,7 @@
13 13
14Bu::ArchiveBinary::ArchiveBinary( Stream &rStream, bool bLoading ) : 14Bu::ArchiveBinary::ArchiveBinary( Stream &rStream, bool bLoading ) :
15 bLoading( bLoading ), 15 bLoading( bLoading ),
16 rStream( rStream ), 16 rStream( rStream )
17 nNextID( 1 )
18{ 17{
19} 18}
20 19
@@ -236,44 +235,6 @@ bool Bu::ArchiveBinary::isLoading()
236 return bLoading; 235 return bLoading;
237} 236}
238 237
239uint32_t Bu::ArchiveBinary::getID( const void *ptr )
240{
241 if( hPtrID.has( (ptrdiff_t)ptr ) )
242 return hPtrID.get( (ptrdiff_t)ptr );
243 hPtrID.insert( (ptrdiff_t)ptr, nNextID );
244 return nNextID++;
245}
246
247void Bu::ArchiveBinary::assocPtrID( void **ptr, uint32_t id )
248{
249 if( hPtrID.has( id ) )
250 {
251 *ptr = (void *)hPtrID.get( id );
252 return;
253 }
254
255 if( !hPtrDest.has( id ) )
256 hPtrDest.insert( id, List<void **>() );
257
258 hPtrDest[id].getValue().append( ptr );
259}
260
261void Bu::ArchiveBinary::readID( const void *ptr, uint32_t id )
262{
263 hPtrID.insert( id, (ptrdiff_t)ptr );
264
265 if( hPtrDest.has( id ) )
266 {
267 Bu::List<void **> &l = hPtrDest.get( id );
268 for( Bu::List<void **>::iterator i = l.begin(); i != l.end(); i++ )
269 {
270 *(*i) = (void *)ptr;
271 }
272
273 hPtrDest.erase( id );
274 }
275}
276
277void Bu::ArchiveBinary::setProperty( const Bu::Blob &rKey, const Bu::Variant &rValue ) 238void Bu::ArchiveBinary::setProperty( const Bu::Blob &rKey, const Bu::Variant &rValue )
278{ 239{
279 hProps.insert( rKey, rValue ); 240 hProps.insert( rKey, rValue );
diff --git a/src/stable/archivebinary.h b/src/stable/archivebinary.h
index d28e5e7..d917249 100644
--- a/src/stable/archivebinary.h
+++ b/src/stable/archivebinary.h
@@ -20,51 +20,6 @@ namespace Bu
20 class Stream; 20 class Stream;
21 21
22 /** 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 ArchiveBinary operates on a Stream, so you can send the
27 * data using an ArchiveBinary almost anywhere.
28 *
29 * In order to use an ArchiveBinary to store something to a file, try something
30 * like:
31 *@code
32 * File sOut("output", "wb"); // This is a stream subclass
33 * ArchiveBinary ar( sOut, ArchiveBinary::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 ArchiveBinary. This can be
39 * handled in one of two ways:
40 *@code
41 * void MyClass::archive( ArchiveBinary &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( ArchiveBinary &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 * ArchiveBinary 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 */ 23 */
69 class ArchiveBinary : public Archive 24 class ArchiveBinary : public Archive
70 { 25 {
@@ -116,39 +71,12 @@ namespace Bu
116 virtual void read( Bu::Blob &rData ); 71 virtual void read( Bu::Blob &rData );
117 virtual void read( Bu::Text &rData ); 72 virtual void read( Bu::Text &rData );
118 73
119 /**
120 * For storage, get an ID for the pointer to the object you're going to
121 * write.
122 */
123 uint32_t getID( const void *ptr );
124
125 /**
126 * For loading. Assosiates an empty pointer with an id. When you wind
127 * up loading an id reference to a pointer for an object that may or
128 * may not have loaded yet, call this with the id, if it has been loaded
129 * already, you'll immediately get a pointer, if not, it will write one
130 * for you when the time comes.
131 */
132 void assocPtrID( void **ptr, uint32_t id );
133
134 /**
135 * For loading. Call this when you load an object that other things may
136 * have pointers to. It will assosiate every pointer that's been
137 * registered with assocPtrID to the pointer passed in, and id passed
138 * in. It will also set things up so future calls to assocPtrID will
139 * automatically succeed immediately.
140 */
141 void readID( const void *ptr, uint32_t id );
142
143 virtual void setProperty( const Bu::Blob &rKey, 74 virtual void setProperty( const Bu::Blob &rKey,
144 const Bu::Variant &rValue ); 75 const Bu::Variant &rValue );
145 virtual Bu::Variant getProperty( const Bu::Blob &rKey ) const; 76 virtual Bu::Variant getProperty( const Bu::Blob &rKey ) const;
146 77
147 private: 78 private:
148 Stream &rStream; 79 Stream &rStream;
149 uint32_t nNextID;
150 Hash<uint32_t,ptrdiff_t> hPtrID;
151 Hash<uint32_t,List<void **> > hPtrDest;
152 Hash<Bu::Blob, Variant> hProps; 80 Hash<Bu::Blob, Variant> hProps;
153 }; 81 };
154} 82}
diff --git a/src/tests/archivetags.cpp b/src/tests/archivetags.cpp
index f0587fd..5c8e0fa 100644
--- a/src/tests/archivetags.cpp
+++ b/src/tests/archivetags.cpp
@@ -25,9 +25,9 @@ Bu::Archive &operator<<( Bu::Archive &ar, const SubThing &st )
25{ 25{
26 Bu::Archive::Dictionary ds( ar ); 26 Bu::Archive::Dictionary ds( ar );
27 27
28 return ar 28 ar.tag("data") << st.bData
29 << ar.tag("data") << st.bData 29 ar.tag("name") << st.tName;
30 << ar.tag("name") << st.tName; 30 return ar;
31} 31}
32 32
33Bu::Archive &operator>>( Bu::Archive &ar, SubThing &st ) 33Bu::Archive &operator>>( Bu::Archive &ar, SubThing &st )