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
00041 #ifndef __CCXX_PERSIST_H__
00042 #define __CCXX_PERSIST_H__
00043
00044 #ifndef __CCXX_CONFIG_H__
00045 #include <cc++/config.h>
00046 #endif
00047
00048 #ifndef __CCXX_MACROS_H__
00049 #include <cc++/macros.h>
00050 #else
00051 #ifdef __CCXX_NAMESPACE_H__
00052 #include <cc++/macros.h>
00053 #endif
00054 #endif
00055
00056 #ifdef HAVE_ZLIB_H
00057 #include <zlib.h>
00058 #else
00059 #define NO_COMPRESSION
00060 #endif
00061
00062 #include <iostream.h>
00063 #include <string>
00064 #include <vector>
00065 #include <map>
00066
00067 #ifdef __WIN32__
00068 class __EXPORT PersistException;
00069 class __EXPORT Engine;
00070 class __EXPORT TypeManager;
00071 class __EXPORT BaseObject;
00072 #endif
00073
00074 class PersistException
00075 {
00076 public:
00077 PersistException(string const& reason);
00078 string const& GetMessage() const;
00079 virtual ~PersistException();
00080 protected:
00081 string myMessage;
00082 };
00083
00084 class Engine;
00085
00086
00087 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00088
00097 class TypeManager
00098 {
00099 public:
00100
00105 class Registration
00106 {
00107 public:
00108 Registration(const char* name, NewBaseObjectFunction func)
00109 : myName(name) { TypeManager::Add(name,func); }
00110 ~Registration() { TypeManager::Remove(myName.c_str()); }
00111 private:
00112 string myName;
00113 };
00114
00118 static void Add(const char* name, NewBaseObjectFunction construction);
00119
00123 static void Remove(const char* name);
00124
00130 static BaseObject* CreateInstanceOf(const char* name);
00131
00132 typedef map<string,NewBaseObjectFunction> StringFunctionMap;
00133 };
00134
00135
00136 00137 00138 00139
00140
00141 #define DECLARE_PERSISTENCE(ClassType) \
00142 public: \
00143 friend Engine& operator>>(Engine& ar, ClassType *&ob); \
00144 friend Engine& operator<<(Engine& ar, ClassType const *&ob); \
00145 friend BaseObject *CreateNew##ClassType(); \
00146 virtual const char* GetPersistenceID() const; \
00147 static TypeManager::Registration RegistrationFor##ClassType;
00148
00149 #define IMPLEMENT_PERSISTENCE(ClassType,FullyQualifiedName) \
00150 BaseObject *CreateNew##ClassType() { return new ClassType; } \
00151 const char* ClassType::GetPersistenceID()const {return FullyQualifiedName;} \
00152 Engine& operator>>(Engine& ar, ClassType *&ob) \
00153 { ar >> (BaseObject *&) ob; return ar; } \
00154 Engine& operator<<(Engine& ar, ClassType const *ob) \
00155 { ar << (BaseObject const *)ob; return ar; } \
00156 TypeManager::Registration \
00157 ClassType::RegistrationFor##ClassType(FullyQualifiedName, \
00158 CreateNew##ClassType);
00159
00174 class BaseObject
00175 {
00176 public:
00180 virtual const char* GetPersistenceID() const;
00181
00187 BaseObject();
00188
00192 virtual ~BaseObject();
00193
00199 virtual bool Write(Engine& archive) const;
00200
00206 virtual bool Read(Engine& archive);
00207 };
00208
00209
00220 class Engine
00221 {
00222 public:
00227 class Exception : public PersistException
00228 {
00229 public:
00230 Exception(const string &reason) : PersistException(reason) {}
00231 };
00232
00236 enum EngineMode
00237 {
00238 modeRead,
00239 modeWrite
00240 };
00241
00247 Engine(iostream& stream, EngineMode mode) THROWS (PersistException);
00248
00253 ~Engine();
00254
00255
00256
00257 void Write(const BaseObject *object) THROWS (Exception);
00258 00259 00260
00261 #define _ENGINEWRITE_REF(valref) WriteBinary((const uint8*)&valref,sizeof(valref))
00262 void Write(int8 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00263 void Write(uint8 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00264 void Write(int16 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00265 void Write(uint16 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00266 void Write(int32 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00267 void Write(uint32 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00268 void Write(int64 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00269 void Write(uint64 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00270 void Write(float i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00271 void Write(double i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00272 #undef _ENGINEWRITE_REF
00273
00274 void Write(const string& str) THROWS (Exception);
00275
00276 void WriteBinary(const uint8* data, const uint32 size) THROWS (Exception);
00277
00278
00279
00280 void Read(BaseObject *&object) THROWS (Exception);
00281 #define _ENGINEREAD_REF(valref) ReadBinary((uint8*)&valref,sizeof(valref))
00282 void Read(int8& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00283 void Read(uint8& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00284 void Read(int16& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00285 void Read(uint16& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00286 void Read(int32& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00287 void Read(uint32& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00288 void Read(int64& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00289 void Read(uint64& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00290 void Read(float& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00291 void Read(double& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00292 #undef _ENGINEREAD_REF
00293
00294 void Read(string& str) THROWS (Exception);
00295
00296 void ReadBinary(uint8* data, uint32 size) THROWS (Exception);
00297
00298 private:
00302 iostream& myUnderlyingStream;
00303
00307 EngineMode myOperationalMode;
00308
00312 typedef vector<BaseObject*> ArchiveVector;
00313 typedef map<BaseObject const*, int32> ArchiveMap;
00314 typedef vector<string> ClassVector;
00315 typedef map<string, int32> ClassMap;
00316
00317 ArchiveVector myArchiveVector;
00318 ArchiveMap myArchiveMap;
00319 ClassVector myClassVector;
00320 ClassMap myClassMap;
00321
00322
00323 #ifndef NO_COMPRESSION
00324 z_stream myZStream;
00325 uint8* myCompressedDataBuffer;
00326 uint8* myUncompressedDataBuffer;
00327 uint8* myLastUncompressedDataRead;
00328 #endif
00329 };
00330
00331
00332 Engine& operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception);
00333 Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00334
00335 Engine& operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00336 Engine& operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception);
00337
00338 Engine& operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00339 Engine& operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception);
00340
00341 Engine& operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00342 Engine& operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception);
00343
00344 Engine& operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00345 Engine& operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception);
00346
00347 Engine& operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00348 Engine& operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception);
00349
00350 Engine& operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00351 Engine& operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception);
00352
00353 Engine& operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00354 Engine& operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception);
00355
00356 Engine& operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00357 Engine& operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception);
00358
00359 Engine& operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00360 Engine& operator <<( Engine& ar, float ob) THROWS (Engine::Exception);
00361
00362 Engine& operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00363 Engine& operator <<( Engine& ar, double ob) THROWS (Engine::Exception);
00364
00365 Engine& operator >>( Engine& ar, string& ob) THROWS (Engine::Exception);
00366 Engine& operator <<( Engine& ar, string ob) THROWS (Engine::Exception);
00367
00368 Engine& operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00369 Engine& operator <<( Engine& ar, bool ob) THROWS (Engine::Exception);
00370
00379 template<class T>
00380 Engine& operator <<( Engine& ar, vector<T> const& ob) THROWS (Engine::Exception)
00381 {
00382 ar << ob.size();
00383 for(int i=0; i < ob.size(); ++i)
00384 ar << ob[i];
00385 return ar;
00386 }
00387
00392 template<class T>
00393 Engine& operator >>( Engine& ar, vector<T>& ob) THROWS (Engine::Exception)
00394 {
00395 ob.clear();
00396 uint32 siz;
00397 ar >> siz;
00398 ob.resize(siz);
00399 for(int i=0; i < siz; ++i)
00400 ar >> ob[i];
00401 return ar;
00402 }
00403
00408 template<class Key, class Value>
00409 Engine& operator <<( Engine& ar, map<Key,Value> const & ob) THROWS (Engine::Exception)
00410 {
00411 ar << ob.size();
00412 for(map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00413 ar << it->first << it->second;
00414 return ar;
00415 }
00416
00421 template<class Key, class Value>
00422 Engine& operator >>( Engine& ar, map<Key,Value>& ob) THROWS (Engine::Exception)
00423 {
00424 ob.clear();
00425 uint32 siz;
00426 ar >> siz;
00427 for(int i=0; i < siz; ++i) {
00428 Key a;
00429 ar >> a;
00430 ar >> ob[a];
00431 }
00432 return ar;
00433 }
00434
00435 #ifdef __CCXX_NAMESPACE_H__
00436 #undef __CCXX_NAMESPACE_H__
00437 #include <cc++/namespace.h>
00438 #endif
00439
00440 #endif
00441