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_STRCHAR_H_
00054 #include <cc++/persist.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 #endif
00074
00075 #ifdef COMMON_STD_EXCEPTION
00076
00077 class CCXX_CLASS_EXPORT PersistException
00078 {
00079 public:
00080 PersistException(const std::string &what_arg) throw();
00081 virtual ~PersistException() throw();
00082 const std::string &getString() const;
00083 };
00084
00085 #else
00086
00087 class PersistException
00088 {
00089 public:
00090 CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const std::string& reason);
00091 CCXX_MEMBER_EXPORT(const std::string&) getString() const;
00092 CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00093 protected:
00094 std::string _what;
00095 };
00096
00097 #endif
00098
00099
00100 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00101
00110 class TypeManager
00111 {
00112 public:
00113
00118 class Registration
00119 {
00120 public:
00121 Registration(const char* name, NewBaseObjectFunction func)
00122 : myName(name) { TypeManager::add(name,func); }
00123 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00124 private:
00125 std::string myName;
00126 };
00127
00131 CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00132
00136 CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00137
00143 CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00144
00145 typedef std::map<std::string,NewBaseObjectFunction> StringFunctionMap;
00146 };
00147
00148
00149
00150
00151
00152
00153
00154 #define DECLARE_PERSISTENCE(ClassType) \
00155 public: \
00156 friend Engine& operator>>(Engine& ar, ClassType *&ob); \
00157 friend Engine& operator<<(Engine& ar, ClassType const &ob); \
00158 friend BaseObject *createNew##ClassType(); \
00159 virtual const char* getPersistenceID() const; \
00160 static TypeManager::Registration registrationFor##ClassType;
00161
00162 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
00163 BaseObject *createNew##ClassType() { return new ClassType; } \
00164 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00165 Engine& operator>>(Engine& ar, ClassType &ob) \
00166 { ar >> (BaseObject &) ob; return ar; } \
00167 Engine& operator>>(Engine& ar, ClassType *&ob) \
00168 { ar >> (BaseObject *&) ob; return ar; } \
00169 Engine& operator<<(Engine& ar, ClassType const &ob) \
00170 { ar << (BaseObject const *)&ob; return ar; } \
00171 TypeManager::Registration \
00172 ClassType::registrationFor##ClassType(FullyQualifiedName, \
00173 createNew##ClassType);
00174
00175 class Engine;
00176
00196 class BaseObject
00197 {
00198 public:
00204 CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00205
00209 CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00210
00214 CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00215
00221 CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00222
00228 CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00229 };
00230
00231
00243 class Engine
00244 {
00245 public:
00250 class Exception : public PersistException
00251 {
00252 public:
00253 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const std::string &reason);
00254 };
00255
00259 enum EngineMode
00260 {
00261 modeRead,
00262 modeWrite
00263 };
00264
00270 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00271
00276 CCXX_MEMBER_EXPORT(virtual) ~Engine();
00277
00278
00279
00280
00284 CCXX_MEMBER_EXPORT(void) write(const BaseObject &object) THROWS (Exception)
00285 { write(&object); };
00286
00290 CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00291
00292
00293
00294 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00295 void write(int8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00296 void write(uint8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00297 void write(int16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00298 void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00299 void write(int32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00300 void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00301 void write(int64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00302 void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00303 void write(float i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00304 void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00305 #undef CCXX_ENGINEWRITE_REF
00306 CCXX_MEMBER_EXPORT(void) write(const std::string& str) THROWS (Exception);
00307
00308
00309 CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00310
00311
00312
00313
00317 CCXX_MEMBER_EXPORT(void) read(BaseObject &object) THROWS (Exception);
00318
00322 CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00323
00324
00325
00326 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00327 void read(int8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00328 void read(uint8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00329 void read(int16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00330 void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00331 void read(int32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00332 void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00333 void read(int64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00334 void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00335 void read(float& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00336 void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00337 #undef CCXX_ENGINEREAD_REF
00338
00339 CCXX_MEMBER_EXPORT(void) read(std::string& str) THROWS (Exception);
00340
00341
00342 CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00343
00344 private:
00349 void readObject(BaseObject* object);
00350
00354 const std::string readClass();
00355
00356
00360 std::iostream& myUnderlyingStream;
00361
00365 EngineMode myOperationalMode;
00366
00370 typedef std::vector<BaseObject*> ArchiveVector;
00371 typedef std::map<BaseObject const*, int32> ArchiveMap;
00372 typedef std::vector<std::string> ClassVector;
00373 typedef std::map<std::string, int32> ClassMap;
00374
00375 ArchiveVector myArchiveVector;
00376 ArchiveMap myArchiveMap;
00377 ClassVector myClassVector;
00378 ClassMap myClassMap;
00379
00380
00381 #ifndef NO_COMPRESSION
00382 z_stream myZStream;
00383 uint8* myCompressedDataBuffer;
00384 uint8* myUncompressedDataBuffer;
00385 uint8* myLastUncompressedDataRead;
00386 #endif
00387 };
00388
00389
00391 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject &ob) THROWS (Engine::Exception);
00393 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception);
00395 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00397 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00398
00400 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00402 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception);
00403
00405 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00407 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception);
00408
00410 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00412 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception);
00413
00415 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00417 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception);
00418
00420 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00422 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception);
00423
00425 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00427 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception);
00428
00430 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00432 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception);
00433
00435 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00437 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception);
00438
00440 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00442 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob) THROWS (Engine::Exception);
00443
00445 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00447 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob) THROWS (Engine::Exception);
00448
00450 CCXX_EXPORT(Engine&) operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00452 CCXX_EXPORT(Engine&) operator <<( Engine& ar, std::string ob) THROWS (Engine::Exception);
00453
00455 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00457 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob) THROWS (Engine::Exception);
00458
00468 template<class T>
00469 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00470 {
00471 ar << (uint32)ob.size();
00472 for(uint i=0; i < ob.size(); ++i)
00473 ar << ob[i];
00474 return ar;
00475 }
00476
00482 template<class T>
00483 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00484 {
00485 ob.clear();
00486 uint32 siz;
00487 ar >> siz;
00488 ob.resize(siz);
00489 for(uint32 i=0; i < siz; ++i)
00490 ar >> ob[i];
00491 return ar;
00492 }
00493
00499 template<class T>
00500 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00501 {
00502 ar << (uint32)ob.size();
00503 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00504 ar << *it;
00505 return ar;
00506 }
00507
00513 template<class T>
00514 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception)
00515 {
00516 ob.clear();
00517 uint32 siz;
00518 ar >> siz;
00519
00520 for(uint32 i=0; i < siz; ++i)
00521 {
00522 T node;
00523 ar >> node;
00524 ob.push_back(node);
00525
00526 }
00527 return ar;
00528 }
00529
00535 template<class Key, class Value>
00536 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00537 {
00538 ar << (uint32)ob.size();
00539 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00540 ar << it->first << it->second;
00541 return ar;
00542 }
00543
00549 template<class Key, class Value>
00550 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00551 {
00552 ob.clear();
00553 uint32 siz;
00554 ar >> siz;
00555 for(uint32 i=0; i < siz; ++i) {
00556 Key a;
00557 ar >> a;
00558 ar >> ob[a];
00559 }
00560 return ar;
00561 }
00562
00563 #ifdef CCXX_NAMESPACES
00564 };
00565 #endif
00566
00567 #endif
00568