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 COMMON_STD_EXCEPTION
00079
00080 class __EXPORT PersistException : public Exception
00081 {
00082 public:
00083 PersistException(String what) : Exception(what) {};
00084 };
00085
00086 #else
00087
00088 class PersistException
00089 {
00090 public:
00091 CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const String& reason);
00092 CCXX_MEMBER_EXPORT(const String&) getString() const;
00093 CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00094 protected:
00095 String _what;
00096 };
00097
00098 #endif
00099
00100
00101 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00102
00111 class TypeManager
00112 {
00113 public:
00114
00119 class Registration
00120 {
00121 public:
00122 Registration(const char* name, NewBaseObjectFunction func)
00123 : myName(name) { TypeManager::add(name,func); }
00124 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00125 private:
00126 String myName;
00127 };
00128
00132 CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00133
00137 CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00138
00144 CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00145
00146 typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00147 };
00148
00149
00150
00151
00152
00153
00154
00155 #define DECLARE_PERSISTENCE(ClassType) \
00156 public: \
00157 friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \
00158 friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \
00159 friend NS_PREFIX BaseObject *createNew##ClassType(); \
00160 virtual const char* getPersistenceID() const; \
00161 static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00162
00163 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
00164 NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \
00165 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00166 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \
00167 { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \
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 const &ob) \
00171 { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \
00172 NS_PREFIX TypeManager::Registration \
00173 ClassType::registrationFor##ClassType(FullyQualifiedName, \
00174 createNew##ClassType);
00175
00176 class Engine;
00177
00197 class BaseObject
00198 {
00199 public:
00205 CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00206
00210 CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00211
00215 CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00216
00222 CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00223
00229 CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00230 };
00231
00232
00244 class Engine
00245 {
00246 public:
00251 class Exception : public PersistException
00252 {
00253 public:
00254 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const String &reason);
00255 };
00256
00260 enum EngineMode
00261 {
00262 modeRead,
00263 modeWrite
00264 };
00265
00271 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00272
00277 CCXX_MEMBER_EXPORT(virtual) ~Engine();
00278
00279
00280
00281
00285 CCXX_MEMBER_EXPORT(void) write(const BaseObject &object) THROWS (Exception)
00286 { write(&object); };
00287
00291 CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00292
00293
00294
00295 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00296 void write(int8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00297 void write(uint8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00298 void write(int16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00299 void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00300 void write(int32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00301 void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00302 #ifdef HAVE_64_BITS
00303 void write(int64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00304 void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00305 #endif
00306 void write(float i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00307 void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00308 #undef CCXX_ENGINEWRITE_REF
00309 CCXX_MEMBER_EXPORT(void) write(const String& str) THROWS (Exception);
00310
00311
00312 CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00313
00314
00315
00316
00320 CCXX_MEMBER_EXPORT(void) read(BaseObject &object) THROWS (Exception);
00321
00325 CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00326
00327
00328
00329 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00330 void read(int8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00331 void read(uint8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00332 void read(int16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00333 void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00334 void read(int32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00335 void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00336 #ifdef HAVE_64_BITS
00337 void read(int64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00338 void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00339 #endif
00340 void read(float& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00341 void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00342 #undef CCXX_ENGINEREAD_REF
00343
00344 CCXX_MEMBER_EXPORT(void) read(String& str) THROWS (Exception);
00345
00346
00347 CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00348
00349 private:
00354 void readObject(BaseObject* object);
00355
00359 const String readClass();
00360
00361
00365 std::iostream& myUnderlyingStream;
00366
00370 EngineMode myOperationalMode;
00371
00375 typedef std::vector<BaseObject*> ArchiveVector;
00376 typedef std::map<BaseObject const*, int32> ArchiveMap;
00377 typedef std::vector<String> ClassVector;
00378 typedef std::map<String, int32> ClassMap;
00379
00380 ArchiveVector myArchiveVector;
00381 ArchiveMap myArchiveMap;
00382 ClassVector myClassVector;
00383 ClassMap myClassMap;
00384
00385
00386 #ifndef NO_COMPRESSION
00387 z_stream myZStream;
00388 uint8* myCompressedDataBuffer;
00389 uint8* myUncompressedDataBuffer;
00390 uint8* myLastUncompressedDataRead;
00391 #endif
00392 };
00393
00394
00396 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject &ob) THROWS (Engine::Exception);
00398 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception);
00400 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00402 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00403
00405 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00407 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception);
00408
00410 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00412 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception);
00413
00415 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00417 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception);
00418
00420 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00422 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception);
00423
00425 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00427 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception);
00428
00430 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00432 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception);
00433
00434 #ifdef HAVE_64_BITS
00435
00436 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00438 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception);
00439
00441 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00443 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception);
00444 #endif
00445
00447 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00449 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob) THROWS (Engine::Exception);
00450
00452 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00454 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob) THROWS (Engine::Exception);
00455
00457 CCXX_EXPORT(Engine&) operator >>( Engine& ar, String& ob) THROWS (Engine::Exception);
00459 CCXX_EXPORT(Engine&) operator <<( Engine& ar, String ob) THROWS (Engine::Exception);
00460
00462 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00464 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob) THROWS (Engine::Exception);
00465
00475 template<class T>
00476 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00477 {
00478 ar << (uint32)ob.size();
00479 for(uint i=0; i < ob.size(); ++i)
00480 ar << ob[i];
00481 return ar;
00482 }
00483
00489 template<class T>
00490 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00491 {
00492 ob.clear();
00493 uint32 siz;
00494 ar >> siz;
00495 ob.resize(siz);
00496 for(uint32 i=0; i < siz; ++i)
00497 ar >> ob[i];
00498 return ar;
00499 }
00500
00506 template<class T>
00507 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00508 {
00509 ar << (uint32)ob.size();
00510 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00511 ar << *it;
00512 return ar;
00513 }
00514
00520 template<class T>
00521 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception)
00522 {
00523 ob.clear();
00524 uint32 siz;
00525 ar >> siz;
00526
00527 for(uint32 i=0; i < siz; ++i)
00528 {
00529 T node;
00530 ar >> node;
00531 ob.push_back(node);
00532
00533 }
00534 return ar;
00535 }
00536
00542 template<class Key, class Value>
00543 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00544 {
00545 ar << (uint32)ob.size();
00546 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00547 ar << it->first << it->second;
00548 return ar;
00549 }
00550
00556 template<class Key, class Value>
00557 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00558 {
00559 ob.clear();
00560 uint32 siz;
00561 ar >> siz;
00562 for(uint32 i=0; i < siz; ++i) {
00563 Key a;
00564 ar >> a;
00565 ar >> ob[a];
00566 }
00567 return ar;
00568 }
00569
00570 #ifdef CCXX_NAMESPACES
00571 };
00572 #endif
00573
00574 #endif
00575