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_CONFIG_H_
00050 #include <cc++/config.h>
00051 #endif
00052
00053 #ifndef CCXX_EXCEPTIONS_H_
00054 #include <cc++/exception.h>
00055 #endif
00056
00057 #ifndef CCXX_MISSING_H_
00058 #include <cc++/missing.h>
00059 #endif
00060
00061 #ifndef CCXX_STRING_H_
00062 #include <cc++/string.h>
00063 #endif
00064
00065 #ifdef HAVE_ZLIB_H
00066 #ifndef NO_COMPRESSION
00067 #include <zlib.h>
00068 #endif
00069 #else
00070 #define NO_COMPRESSION
00071 #endif
00072
00073 #include <iostream>
00074 #include <string>
00075 #include <vector>
00076 #include <deque>
00077 #include <map>
00078
00079 #ifdef CCXX_NAMESPACES
00080 namespace ost {
00081 #define NS_PREFIX ost::
00082 #else
00083 #define NS_PREFIX
00084 #endif
00085
00086 #ifdef CCXX_EXCEPTIONS
00087 #ifdef COMMON_STD_EXCEPTION
00088
00089 class __EXPORT PersistException : public Exception
00090 {
00091 public:
00092 PersistException(const String &what) : Exception(what) {};
00093 };
00094
00095 #else
00096
00097 class __EXPORT PersistException
00098 {
00099 public:
00100 PersistException(const String& reason);
00101 inline const String& getString() const
00102 {return Exception::getString();};
00103
00104 virtual ~PersistException() {} throw();
00105 protected:
00106 String _what;
00107 };
00108
00109 #endif
00110 #endif
00111
00112
00113 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00114
00123 class __EXPORT TypeManager
00124 {
00125 public:
00126
00131 class Registration
00132 {
00133 public:
00134 Registration(const char* name, NewBaseObjectFunction func)
00135 : myName(name) { TypeManager::add(name,func); }
00136 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00137 private:
00138 String myName;
00139 };
00140
00144 static void add(const char* name, NewBaseObjectFunction construction);
00145
00149 static void remove(const char* name);
00150
00156 static BaseObject* createInstanceOf(const char* name);
00157
00158 typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00159 };
00160
00161
00162
00163
00164
00165
00166
00167 #define DECLARE_PERSISTENCE(ClassType) \
00168 public: \
00169 friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \
00170 friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \
00171 friend NS_PREFIX BaseObject *createNew##ClassType(); \
00172 virtual const char* getPersistenceID() const; \
00173 static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00174
00175 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
00176 NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \
00177 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00178 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \
00179 { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \
00180 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob) \
00181 { ar >> (NS_PREFIX BaseObject *&) ob; return ar; } \
00182 NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob) \
00183 { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \
00184 NS_PREFIX TypeManager::Registration \
00185 ClassType::registrationFor##ClassType(FullyQualifiedName, \
00186 createNew##ClassType);
00187
00188 class Engine;
00189
00209 class __EXPORT BaseObject
00210 {
00211 public:
00217 BaseObject();
00218
00222 virtual ~BaseObject();
00223
00227 virtual const char* getPersistenceID() const;
00228
00234 virtual bool write(Engine& archive) const;
00235
00241 virtual bool read(Engine& archive);
00242 };
00243
00244
00256 class __EXPORT Engine
00257 {
00258 public:
00263 #ifdef CCXX_EXCEPTIONS
00264 class Exception : public PersistException
00265 {
00266 public:
00267 Exception(const String &reason);
00268 };
00269 #endif
00270
00274 enum EngineMode
00275 {
00276 modeRead,
00277 modeWrite
00278 };
00279
00285 Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00286
00291 void sync();
00292
00293 virtual ~Engine();
00294
00295
00296
00297
00301 void write(const BaseObject &object) THROWS (Exception)
00302 { write(&object); };
00303
00307 void write(const BaseObject *object) THROWS (Exception);
00308
00309
00310
00311 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00312 void write(int8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00313 void write(uint8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00314 void write(int16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00315 void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00316 void write(int32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00317 void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00318 #ifdef HAVE_64_BITS
00319 void write(int64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00320 void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00321 #endif
00322 void write(float i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00323 void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00324 #undef CCXX_ENGINEWRITE_REF
00325
00326 void write(const String& str) THROWS (Exception);
00327 void write(const std::string& str) THROWS (Exception);
00328
00329
00330 void writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00331
00332
00333
00334
00338 void read(BaseObject &object) THROWS (Exception);
00339
00343 void read(BaseObject *&object) THROWS (Exception);
00344
00345
00346
00347 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00348 void read(int8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00349 void read(uint8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00350 void read(int16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00351 void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00352 void read(int32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00353 void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00354 #ifdef HAVE_64_BITS
00355 void read(int64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00356 void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00357 #endif
00358 void read(float& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00359 void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00360 #undef CCXX_ENGINEREAD_REF
00361
00362 void read(String& str) THROWS (Exception);
00363 void read(std::string& str) THROWS (Exception);
00364
00365
00366 void readBinary(uint8* data, uint32 size) THROWS (Exception);
00367
00368 private:
00373 void readObject(BaseObject* object);
00374
00378 const String readClass();
00379
00380
00384 std::iostream& myUnderlyingStream;
00385
00389 EngineMode myOperationalMode;
00390
00394 typedef std::vector<BaseObject*> ArchiveVector;
00395 typedef std::map<BaseObject const*, int32> ArchiveMap;
00396 typedef std::vector<String> ClassVector;
00397 typedef std::map<String, int32> ClassMap;
00398
00399 ArchiveVector myArchiveVector;
00400 ArchiveMap myArchiveMap;
00401 ClassVector myClassVector;
00402 ClassMap myClassMap;
00403
00404
00405 #ifndef NO_COMPRESSION
00406 z_stream myZStream;
00407 uint8* myCompressedDataBuffer;
00408 uint8* myUncompressedDataBuffer;
00409 uint8* myLastUncompressedDataRead;
00410 #endif
00411 };
00412
00413
00415 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob) THROWS (Engine::Exception);
00417 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception);
00419 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00421 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00422
00424 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00426 __EXPORT Engine& operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception);
00427
00429 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00431 __EXPORT Engine& operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception);
00432
00434 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00436 __EXPORT Engine& operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception);
00437
00439 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00441 __EXPORT Engine& operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception);
00442
00444 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00446 __EXPORT Engine& operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception);
00447
00449 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00451 __EXPORT Engine& operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception);
00452
00453 #ifdef HAVE_64_BITS
00454
00455 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00457 __EXPORT Engine& operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception);
00458
00460 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00462 __EXPORT Engine& operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception);
00463 #endif
00464
00466 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00468 __EXPORT Engine& operator <<( Engine& ar, float ob) THROWS (Engine::Exception);
00469
00471 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00473 __EXPORT Engine& operator <<( Engine& ar, double ob) THROWS (Engine::Exception);
00474
00476 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (Engine::Exception);
00478 __EXPORT Engine& operator <<( Engine& ar, String ob) THROWS (Engine::Exception);
00479
00481 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00483 __EXPORT Engine& operator <<( Engine& ar, std::string ob) THROWS (Engine::Exception);
00484
00486 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00488 __EXPORT Engine& operator <<( Engine& ar, bool ob) THROWS (Engine::Exception);
00489
00499 template<class T>
00500 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00501 {
00502 ar << (uint32)ob.size();
00503 for(unsigned int i=0; i < ob.size(); ++i)
00504 ar << ob[i];
00505 return ar;
00506 }
00507
00513 template<class T>
00514 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00515 {
00516 ob.clear();
00517 uint32 siz;
00518 ar >> siz;
00519 ob.resize(siz);
00520 for(uint32 i=0; i < siz; ++i)
00521 ar >> ob[i];
00522 return ar;
00523 }
00524
00530 template<class T>
00531 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00532 {
00533 ar << (uint32)ob.size();
00534 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00535 ar << *it;
00536 return ar;
00537 }
00538
00544 template<class T>
00545 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception)
00546 {
00547 ob.clear();
00548 uint32 siz;
00549 ar >> siz;
00550
00551 for(uint32 i=0; i < siz; ++i)
00552 {
00553 T node;
00554 ar >> node;
00555 ob.push_back(node);
00556
00557 }
00558 return ar;
00559 }
00560
00566 template<class Key, class Value>
00567 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00568 {
00569 ar << (uint32)ob.size();
00570 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00571 ar << it->first << it->second;
00572 return ar;
00573 }
00574
00580 template<class Key, class Value>
00581 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00582 {
00583 ob.clear();
00584 uint32 siz;
00585 ar >> siz;
00586 for(uint32 i=0; i < siz; ++i) {
00587 Key a;
00588 ar >> a;
00589 ar >> ob[a];
00590 }
00591 return ar;
00592 }
00593
00594 #ifdef CCXX_NAMESPACES
00595 }
00596 #endif
00597
00598 #endif
00599