00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00046 #ifndef CCXX_PERSIST_H_
00047 #define CCXX_PERSIST_H_
00048
00049 #ifndef CCXX_MISSING_H_
00050 #include <cc++/missing.h>
00051 #endif
00052
00053 #ifndef CCXX_STRING_H_
00054 #include <cc++/string.h>
00055 #endif
00056
00057 #ifdef HAVE_ZLIB_H
00058 #ifndef NO_COMPRESSION
00059 #include <zlib.h>
00060 #endif
00061 #else
00062 #define NO_COMPRESSION
00063 #endif
00064
00065 #include <iostream>
00066 #include <string>
00067 #include <vector>
00068 #include <deque>
00069 #include <map>
00070
00071 #ifdef CCXX_NAMESPACES
00072 namespace ost {
00073 #define NS_PREFIX ost::
00074 #else
00075 #define NS_PREFIX
00076 #endif
00077
00078 #ifdef CCXX_EXCEPTIONS
00079 #ifdef COMMON_STD_EXCEPTION
00080
00081 class __EXPORT PersistException : public Exception
00082 {
00083 public:
00084 PersistException(String what) : Exception(what) {};
00085 };
00086
00087 #else
00088
00089 class PersistException
00090 {
00091 public:
00092 CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const String& reason);
00093 CCXX_MEMBER_EXPORT(const String&) getString() const;
00094 CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00095 protected:
00096 String _what;
00097 };
00098
00099 #endif
00100 #endif
00101
00102
00103 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00104
00113 class TypeManager
00114 {
00115 public:
00116
00121 class Registration
00122 {
00123 public:
00124 Registration(const char* name, NewBaseObjectFunction func)
00125 : myName(name) { TypeManager::add(name,func); }
00126 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00127 private:
00128 String myName;
00129 };
00130
00134 CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00135
00139 CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00140
00146 CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00147
00148 typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00149 };
00150
00151
00152
00153
00154
00155
00156
00157 #define DECLARE_PERSISTENCE(ClassType) \
00158 public: \
00159 friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \
00160 friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \
00161 friend NS_PREFIX BaseObject *createNew##ClassType(); \
00162 virtual const char* getPersistenceID() const; \
00163 static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00164
00165 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
00166 NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \
00167 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00168 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \
00169 { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \
00170 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob) \
00171 { ar >> (NS_PREFIX BaseObject *&) ob; return ar; } \
00172 NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob) \
00173 { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \
00174 NS_PREFIX TypeManager::Registration \
00175 ClassType::registrationFor##ClassType(FullyQualifiedName, \
00176 createNew##ClassType);
00177
00178 class Engine;
00179
00199 class BaseObject
00200 {
00201 public:
00207 CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00208
00212 CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00213
00217 CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00218
00224 CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00225
00231 CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00232 };
00233
00234
00246 class Engine
00247 {
00248 public:
00253 #ifdef CCXX_EXCEPTIONS
00254 class Exception : public PersistException
00255 {
00256 public:
00257 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const String &reason);
00258 };
00259 #endif
00260
00264 enum EngineMode
00265 {
00266 modeRead,
00267 modeWrite
00268 };
00269
00275 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00276
00281 CCXX_MEMBER_EXPORT(virtual) ~Engine();
00282
00283
00284
00285
00289 CCXX_MEMBER_EXPORT(void) write(const BaseObject &object) THROWS (Exception)
00290 { write(&object); };
00291
00295 CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00296
00297
00298
00299 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00300 void write(int8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00301 void write(uint8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00302 void write(int16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00303 void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00304 void write(int32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00305 void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00306 #ifdef HAVE_64_BITS
00307 void write(int64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00308 void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00309 #endif
00310 void write(float i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00311 void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00312 #undef CCXX_ENGINEWRITE_REF
00313 CCXX_MEMBER_EXPORT(void) write(const String& str) THROWS (Exception);
00314
00315
00316 CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00317
00318
00319
00320
00324 CCXX_MEMBER_EXPORT(void) read(BaseObject &object) THROWS (Exception);
00325
00329 CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00330
00331
00332
00333 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00334 void read(int8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00335 void read(uint8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00336 void read(int16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00337 void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00338 void read(int32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00339 void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00340 #ifdef HAVE_64_BITS
00341 void read(int64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00342 void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00343 #endif
00344 void read(float& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00345 void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00346 #undef CCXX_ENGINEREAD_REF
00347
00348 CCXX_MEMBER_EXPORT(void) read(String& str) THROWS (Exception);
00349
00350
00351 CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00352
00353 private:
00358 void readObject(BaseObject* object);
00359
00363 const String readClass();
00364
00365
00369 std::iostream& myUnderlyingStream;
00370
00374 EngineMode myOperationalMode;
00375
00379 typedef std::vector<BaseObject*> ArchiveVector;
00380 typedef std::map<BaseObject const*, int32> ArchiveMap;
00381 typedef std::vector<String> ClassVector;
00382 typedef std::map<String, int32> ClassMap;
00383
00384 ArchiveVector myArchiveVector;
00385 ArchiveMap myArchiveMap;
00386 ClassVector myClassVector;
00387 ClassMap myClassMap;
00388
00389
00390 #ifndef NO_COMPRESSION
00391 z_stream myZStream;
00392 uint8* myCompressedDataBuffer;
00393 uint8* myUncompressedDataBuffer;
00394 uint8* myLastUncompressedDataRead;
00395 #endif
00396 };
00397
00398
00400 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject &ob) THROWS (Engine::Exception);
00402 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception);
00404 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00406 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00407
00409 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00411 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception);
00412
00414 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00416 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception);
00417
00419 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00421 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception);
00422
00424 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00426 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception);
00427
00429 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00431 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception);
00432
00434 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00436 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception);
00437
00438 #ifdef HAVE_64_BITS
00439
00440 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00442 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception);
00443
00445 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00447 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception);
00448 #endif
00449
00451 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00453 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob) THROWS (Engine::Exception);
00454
00456 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00458 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob) THROWS (Engine::Exception);
00459
00461 CCXX_EXPORT(Engine&) operator >>( Engine& ar, String& ob) THROWS (Engine::Exception);
00463 CCXX_EXPORT(Engine&) operator <<( Engine& ar, String ob) THROWS (Engine::Exception);
00464
00466 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00468 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob) THROWS (Engine::Exception);
00469
00479 template<class T>
00480 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00481 {
00482 ar << (uint32)ob.size();
00483 for(uint i=0; i < ob.size(); ++i)
00484 ar << ob[i];
00485 return ar;
00486 }
00487
00493 template<class T>
00494 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00495 {
00496 ob.clear();
00497 uint32 siz;
00498 ar >> siz;
00499 ob.resize(siz);
00500 for(uint32 i=0; i < siz; ++i)
00501 ar >> ob[i];
00502 return ar;
00503 }
00504
00510 template<class T>
00511 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00512 {
00513 ar << (uint32)ob.size();
00514 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00515 ar << *it;
00516 return ar;
00517 }
00518
00524 template<class T>
00525 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception)
00526 {
00527 ob.clear();
00528 uint32 siz;
00529 ar >> siz;
00530
00531 for(uint32 i=0; i < siz; ++i)
00532 {
00533 T node;
00534 ar >> node;
00535 ob.push_back(node);
00536
00537 }
00538 return ar;
00539 }
00540
00546 template<class Key, class Value>
00547 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00548 {
00549 ar << (uint32)ob.size();
00550 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00551 ar << it->first << it->second;
00552 return ar;
00553 }
00554
00560 template<class Key, class Value>
00561 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00562 {
00563 ob.clear();
00564 uint32 siz;
00565 ar >> siz;
00566 for(uint32 i=0; i < siz; ++i) {
00567 Key a;
00568 ar >> a;
00569 ar >> ob[a];
00570 }
00571 return ar;
00572 }
00573
00574 #ifdef CCXX_NAMESPACES
00575 };
00576 #endif
00577
00578 #endif
00579