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 <map>
00069
00070 #ifdef CCXX_NAMESPACES
00071 namespace ost {
00072 #endif
00073
00074 #ifdef COMMON_STD_EXCEPTION
00075
00076 class CCXX_CLASS_EXPORT PersistException
00077 {
00078 public:
00079 PersistException(const std::string &what_arg) throw();
00080 virtual ~PersistException() throw();
00081 const std::string &getString() const;
00082 };
00083
00084 #else
00085
00086 class PersistException
00087 {
00088 public:
00089 CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const std::string& reason);
00090 CCXX_MEMBER_EXPORT(const std::string&) getString() const;
00091 CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00092 protected:
00093 std::string _what;
00094 };
00095
00096 #endif
00097
00098
00099 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00100
00109 class TypeManager
00110 {
00111 public:
00112
00117 class Registration
00118 {
00119 public:
00120 Registration(const char* name, NewBaseObjectFunction func)
00121 : myName(name) { TypeManager::add(name,func); }
00122 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00123 private:
00124 std::string myName;
00125 };
00126
00130 CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00131
00135 CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00136
00142 CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00143
00144 typedef std::map<std::string,NewBaseObjectFunction> StringFunctionMap;
00145 };
00146
00147
00148
00149
00150
00151
00152
00153 #define DECLARE_PERSISTENCE(ClassType) \
00154 public: \
00155 friend Engine& operator>>(Engine& ar, ClassType *&ob); \
00156 friend Engine& operator<<(Engine& ar, ClassType const *&ob); \
00157 friend BaseObject *createNew##ClassType(); \
00158 virtual const char* getPersistenceID() const; \
00159 static TypeManager::Registration registrationFor##ClassType;
00160
00161 #define IMPLEMENT_PERSISTENCE(ClassType,FullyQualifiedName) \
00162 BaseObject *createNew##ClassType() { return new ClassType; } \
00163 const char* ClassType::getPersistenceID()const {return FullyQualifiedName;} \
00164 Engine& operator>>(Engine& ar, ClassType *&ob) \
00165 { ar >> (BaseObject *&) ob; return ar; } \
00166 Engine& operator<<(Engine& ar, ClassType const *ob) \
00167 { ar << (BaseObject const *)ob; return ar; } \
00168 TypeManager::Registration \
00169 ClassType::registrationFor##ClassType(FullyQualifiedName, \
00170 CreateNew##ClassType);
00171
00172 class Engine;
00173
00188 class BaseObject
00189 {
00190 public:
00196 CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00197
00201 CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00202
00206 CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00207
00213 CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00214
00220 CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00221 };
00222
00223
00234 class Engine
00235 {
00236 public:
00241 class Exception : public PersistException
00242 {
00243 public:
00244 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const std::string &reason);
00245 };
00246
00250 enum EngineMode
00251 {
00252 modeRead,
00253 modeWrite
00254 };
00255
00261 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00262
00267 CCXX_MEMBER_EXPORT(virtual) ~Engine();
00268
00269
00270
00271 CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00272
00273
00274
00275 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00276 void write(int8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00277 void write(uint8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00278 void write(int16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00279 void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00280 void write(int32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00281 void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00282 void write(int64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00283 void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00284 void write(float i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00285 void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00286 #undef CCXX_ENGINEWRITE_REF
00287
00288 CCXX_MEMBER_EXPORT(void) write(const std::string& str) THROWS (Exception);
00289
00290 CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00291
00292
00293
00294 CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00295 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00296 void read(int8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00297 void read(uint8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00298 void read(int16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00299 void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00300 void read(int32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00301 void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00302 void read(int64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00303 void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00304 void read(float& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00305 void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00306 #undef CCXX_ENGINEREAD_REF
00307
00308 CCXX_MEMBER_EXPORT(void) read(std::string& str) THROWS (Exception);
00309
00310 CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00311
00312 private:
00316 std::iostream& myUnderlyingStream;
00317
00321 EngineMode myOperationalMode;
00322
00326 typedef std::vector<BaseObject*> ArchiveVector;
00327 typedef std::map<BaseObject const*, int32> ArchiveMap;
00328 typedef std::vector<std::string> ClassVector;
00329 typedef std::map<std::string, int32> ClassMap;
00330
00331 ArchiveVector myArchiveVector;
00332 ArchiveMap myArchiveMap;
00333 ClassVector myClassVector;
00334 ClassMap myClassMap;
00335
00336
00337 #ifndef NO_COMPRESSION
00338 z_stream myZStream;
00339 uint8* myCompressedDataBuffer;
00340 uint8* myUncompressedDataBuffer;
00341 uint8* myLastUncompressedDataRead;
00342 #endif
00343 };
00344
00345
00347 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception);
00349 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00350
00352 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00354 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception);
00355
00357 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00359 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception);
00360
00362 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00364 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception);
00365
00367 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00369 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception);
00370
00372 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00374 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception);
00375
00377 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00379 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception);
00380
00382 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00384 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception);
00385
00387 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00389 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception);
00390
00392 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00394 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob) THROWS (Engine::Exception);
00395
00397 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00399 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob) THROWS (Engine::Exception);
00400
00402 CCXX_EXPORT(Engine&) operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00404 CCXX_EXPORT(Engine&) operator <<( Engine& ar, std::string ob) THROWS (Engine::Exception);
00405
00407 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00409 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob) THROWS (Engine::Exception);
00410
00420 template<class T>
00421 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00422 {
00423 ar << (uint32)ob.size();
00424 for(uint i=0; i < ob.size(); ++i)
00425 ar << ob[i];
00426 return ar;
00427 }
00428
00434 template<class T>
00435 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00436 {
00437 ob.clear();
00438 uint32 siz;
00439 ar >> siz;
00440 ob.resize(siz);
00441 for(uint32 i=0; i < siz; ++i)
00442 ar >> ob[i];
00443 return ar;
00444 }
00445
00451 template<class Key, class Value>
00452 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00453 {
00454 ar << (uint32)ob.size();
00455 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00456 ar << it->first << it->second;
00457 return ar;
00458 }
00459
00465 template<class Key, class Value>
00466 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00467 {
00468 ob.clear();
00469 uint32 siz;
00470 ar >> siz;
00471 for(uint32 i=0; i < siz; ++i) {
00472 Key a;
00473 ar >> a;
00474 ar >> ob[a];
00475 }
00476 return ar;
00477 }
00478
00479 #ifdef CCXX_NAMESPACES
00480 };
00481 #endif
00482
00483 #endif
00484