diff options
author | Mike Buland <eichlan@xagasoft.com> | 2022-04-21 10:32:35 -0700 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2022-04-21 10:32:35 -0700 |
commit | 23d88aa2812c361d30abefeeb296548698409bf5 (patch) | |
tree | 1fae38f0fccdff7bf8bc8f868bb5533cbe607af9 | |
parent | fd56cdd21a7c9c944ad189cf91ff24d3c2b0f975 (diff) | |
download | libbu++-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.cpp | 41 | ||||
-rw-r--r-- | src/stable/archivebinary.h | 72 | ||||
-rw-r--r-- | src/tests/archivetags.cpp | 6 |
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 | ||
14 | Bu::ArchiveBinary::ArchiveBinary( Stream &rStream, bool bLoading ) : | 14 | Bu::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 | ||
239 | uint32_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 | |||
247 | void 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 | |||
261 | void 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 | |||
277 | void Bu::ArchiveBinary::setProperty( const Bu::Blob &rKey, const Bu::Variant &rValue ) | 238 | void 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 | ||
33 | Bu::Archive &operator>>( Bu::Archive &ar, SubThing &st ) | 33 | Bu::Archive &operator>>( Bu::Archive &ar, SubThing &st ) |