GNU CommonC++
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free software 00019 // library without restriction. Specifically, if other files instantiate 00020 // templates or use macros or inline functions from this file, or you compile 00021 // this file and link it with other files to produce an executable, this 00022 // file does not by itself cause the resulting executable to be covered by 00023 // the GNU General Public License. This exception does not however 00024 // invalidate any other reasons why the executable file might be covered by 00025 // the GNU General Public License. 00026 // 00027 // This exception applies only to the code released under the name GNU 00028 // Common C++. If you copy code from other releases into a copy of GNU 00029 // Common C++, as the General Public License permits, the exception does 00030 // not apply to the code that you add in this way. To avoid misleading 00031 // anyone as to the status of such modified files, you must delete 00032 // this exception notice from them. 00033 // 00034 // If you write modifications of your own for GNU Common C++, it is your choice 00035 // whether to permit this exception to apply to your modifications. 00036 // If you do not wish that, delete this exception notice. 00037 // 00038 00044 #ifndef CCXX_PERSIST_H_ 00045 #define CCXX_PERSIST_H_ 00046 00047 #ifndef CCXX_CONFIG_H_ 00048 #include <cc++/config.h> 00049 #endif 00050 00051 #ifndef CCXX_EXCEPTIONS_H_ 00052 #include <cc++/exception.h> 00053 #endif 00054 00055 #ifndef CCXX_MISSING_H_ 00056 #include <cc++/missing.h> 00057 #endif 00058 00059 #ifndef CCXX_STRING_H_ 00060 #include <cc++/string.h> 00061 #endif 00062 00063 #ifdef HAVE_ZLIB_H 00064 #ifndef NO_COMPRESSION 00065 #include <zlib.h> 00066 #endif 00067 #else 00068 #define NO_COMPRESSION 00069 #endif 00070 00071 #include <iostream> 00072 #include <string> 00073 #include <vector> 00074 #include <deque> 00075 #include <map> 00076 00077 #ifdef CCXX_NAMESPACES 00078 namespace ost { 00079 #define NS_PREFIX ost:: 00080 #else 00081 #define NS_PREFIX 00082 #endif 00083 00084 #ifdef CCXX_EXCEPTIONS 00085 #ifdef COMMON_STD_EXCEPTION 00086 00087 class __EXPORT PersistException : public Exception 00088 { 00089 public: 00090 PersistException(const String &what) : Exception(what) {}; 00091 }; 00092 00093 #else 00094 00095 class __EXPORT PersistException 00096 { 00097 public: 00098 PersistException(const String& reason); 00099 inline const String& getString() const 00100 {return Exception::getString();}; 00101 00102 virtual ~PersistException() {} throw(); 00103 protected: 00104 String _what; 00105 }; 00106 00107 #endif 00108 #endif 00109 00110 // This typedef allows us to declare NewBaseObjectFunction now 00111 typedef class BaseObject* (*NewBaseObjectFunction) (void); 00112 00121 class __EXPORT TypeManager 00122 { 00123 public: 00124 00129 class Registration 00130 { 00131 public: 00132 Registration(const char* name, NewBaseObjectFunction func); 00133 virtual ~Registration(); 00134 private: 00135 String myName; 00136 }; 00137 00141 static void add(const char* name, NewBaseObjectFunction construction); 00142 00146 static void remove(const char* name); 00147 00153 static BaseObject* createInstanceOf(const char* name); 00154 00155 typedef std::map<String,NewBaseObjectFunction> StringFunctionMap; 00156 }; 00157 00158 00159 /* 00160 * The following defines are used to declare and define the relevant code 00161 * to allow a class to use the Persistence::Engine code. 00162 */ 00163 00164 #define DECLARE_PERSISTENCE(ClassType) \ 00165 public: \ 00166 friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \ 00167 friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \ 00168 friend NS_PREFIX BaseObject *createNew##ClassType(); \ 00169 virtual const char* getPersistenceID() const; \ 00170 static NS_PREFIX TypeManager::Registration registrationFor##ClassType; 00171 00172 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \ 00173 NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \ 00174 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \ 00175 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \ 00176 { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \ 00177 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob) \ 00178 { ar >> (NS_PREFIX BaseObject *&) ob; return ar; } \ 00179 NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob) \ 00180 { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \ 00181 NS_PREFIX TypeManager::Registration \ 00182 ClassType::registrationFor##ClassType(FullyQualifiedName, \ 00183 createNew##ClassType); 00184 00185 class Engine; 00186 00206 class __EXPORT BaseObject 00207 { 00208 public: 00214 BaseObject(); 00215 00219 virtual ~BaseObject(); 00220 00224 virtual const char* getPersistenceID() const; 00225 00231 virtual bool write(Engine& archive) const; 00232 00238 virtual bool read(Engine& archive); 00239 }; 00240 00241 00252 class __EXPORT Engine 00253 { 00254 public: 00258 enum EngineMode { 00259 modeRead, 00260 modeWrite 00261 }; 00262 00269 Engine(std::iostream& stream, EngineMode mode, bool compress=true) THROWS (PersistException); 00270 00275 void sync(); 00276 00280 bool more(); 00281 00282 virtual ~Engine(); 00283 00284 00285 // Write operations 00286 00290 void write(const BaseObject &object) THROWS (PersistException) 00291 { write(&object); }; 00292 00296 void write(const BaseObject *object) THROWS (PersistException); 00297 00298 // writes supported primitive types 00299 // shortcut, to make the following more readable 00300 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref)) 00301 void write(int8 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00302 void write(uint8 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00303 void write(int16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00304 void write(uint16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00305 void write(int32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00306 void write(uint32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00307 #ifdef HAVE_64_BITS 00308 void write(int64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00309 void write(uint64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00310 #endif 00311 void write(float i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00312 void write(double i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00313 #undef CCXX_ENGINEWRITE_REF 00314 00315 void write(const String& str) THROWS (PersistException); 00316 void write(const std::string& str) THROWS (PersistException); 00317 00318 // Every write operation boils down to one or more of these 00319 void writeBinary(const uint8* data, const uint32 size) THROWS (PersistException); 00320 00321 00322 // Read Operations 00323 00327 void read(BaseObject &object) THROWS (PersistException); 00328 00332 void read(BaseObject *&object) THROWS (PersistException); 00333 00334 // reads supported primitive types 00335 // shortcut, to make the following more readable 00336 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref)) 00337 void read(int8& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00338 void read(uint8& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00339 void read(int16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00340 void read(uint16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00341 void read(int32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00342 void read(uint32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00343 #ifdef HAVE_64_BITS 00344 void read(int64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00345 void read(uint64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00346 #endif 00347 void read(float& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00348 void read(double& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00349 #undef CCXX_ENGINEREAD_REF 00350 00351 void read(String& str) THROWS (PersistException); 00352 void read(std::string& str) THROWS (PersistException); 00353 00354 // Every read operation boild down to one or more of these 00355 void readBinary(uint8* data, uint32 size) THROWS (PersistException); 00356 00357 private: 00362 void readObject(BaseObject* object) THROWS (PersistException); 00363 00367 const String readClass() THROWS (PersistException); 00368 00369 00373 std::iostream& myUnderlyingStream; 00374 00378 EngineMode myOperationalMode; 00379 00383 typedef std::vector<BaseObject*> ArchiveVector; 00384 typedef std::map<BaseObject const*, int32> ArchiveMap; 00385 typedef std::vector<String> ClassVector; 00386 typedef std::map<String, int32> ClassMap; 00387 00388 ArchiveVector myArchiveVector; 00389 ArchiveMap myArchiveMap; 00390 ClassVector myClassVector; 00391 ClassMap myClassMap; 00392 00393 // Compression support 00394 bool use_compression; // valid onlry if NO_COMPRESSION is false 00395 #ifndef NO_COMPRESSION 00396 z_stream myZStream; 00397 uint8* myCompressedDataBuffer; 00398 uint8* myUncompressedDataBuffer; 00399 uint8* myLastUncompressedDataRead; 00400 #endif 00401 }; 00402 00403 // Standard >> and << stream operators for BaseObject 00405 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob) THROWS (PersistException); 00407 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob) THROWS (PersistException); 00409 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (PersistException); 00411 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (PersistException); 00412 00414 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (PersistException); 00416 __EXPORT Engine& operator <<( Engine& ar, int8 ob) THROWS (PersistException); 00417 00419 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (PersistException); 00421 __EXPORT Engine& operator <<( Engine& ar, uint8 ob) THROWS (PersistException); 00422 00424 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (PersistException); 00426 __EXPORT Engine& operator <<( Engine& ar, int16 ob) THROWS (PersistException); 00427 00429 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (PersistException); 00431 __EXPORT Engine& operator <<( Engine& ar, uint16 ob) THROWS (PersistException); 00432 00434 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (PersistException); 00436 __EXPORT Engine& operator <<( Engine& ar, int32 ob) THROWS (PersistException); 00437 00439 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (PersistException); 00441 __EXPORT Engine& operator <<( Engine& ar, uint32 ob) THROWS (PersistException); 00442 00443 #ifdef HAVE_64_BITS 00444 00445 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (PersistException); 00447 __EXPORT Engine& operator <<( Engine& ar, int64 ob) THROWS (PersistException); 00448 00450 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (PersistException); 00452 __EXPORT Engine& operator <<( Engine& ar, uint64 ob) THROWS (PersistException); 00453 #endif 00454 00456 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (PersistException); 00458 __EXPORT Engine& operator <<( Engine& ar, float ob) THROWS (PersistException); 00459 00461 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (PersistException); 00463 __EXPORT Engine& operator <<( Engine& ar, double ob) THROWS (PersistException); 00464 00466 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (PersistException); 00468 __EXPORT Engine& operator <<( Engine& ar, String ob) THROWS (PersistException); 00469 00471 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (PersistException); 00473 __EXPORT Engine& operator <<( Engine& ar, std::string ob) THROWS (PersistException); 00474 00476 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (PersistException); 00478 __EXPORT Engine& operator <<( Engine& ar, bool ob) THROWS (PersistException); 00479 00489 template<class T> 00490 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (PersistException) 00491 { 00492 ar << (uint32)ob.size(); 00493 for(unsigned int i=0; i < ob.size(); ++i) 00494 ar << ob[i]; 00495 return ar; 00496 } 00497 00503 template<class T> 00504 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (PersistException) 00505 { 00506 ob.clear(); 00507 uint32 siz; 00508 ar >> siz; 00509 ob.resize(siz); 00510 for(uint32 i=0; i < siz; ++i) 00511 ar >> ob[i]; 00512 return ar; 00513 } 00514 00520 template<class T> 00521 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (PersistException) 00522 { 00523 ar << (uint32)ob.size(); 00524 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it) 00525 ar << *it; 00526 return ar; 00527 } 00528 00534 template<class T> 00535 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (PersistException) 00536 { 00537 ob.clear(); 00538 uint32 siz; 00539 ar >> siz; 00540 //ob.resize(siz); 00541 for(uint32 i=0; i < siz; ++i) { 00542 T node; 00543 ar >> node; 00544 ob.push_back(node); 00545 //ar >> ob[i]; 00546 } 00547 return ar; 00548 } 00549 00555 template<class Key, class Value> 00556 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (PersistException) 00557 { 00558 ar << (uint32)ob.size(); 00559 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it) 00560 ar << it->first << it->second; 00561 return ar; 00562 } 00563 00569 template<class Key, class Value> 00570 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (PersistException) 00571 { 00572 ob.clear(); 00573 uint32 siz; 00574 ar >> siz; 00575 for(uint32 i=0; i < siz; ++i) { 00576 Key a; 00577 ar >> a; 00578 ar >> ob[a]; 00579 } 00580 return ar; 00581 } 00582 00587 template<class x, class y> 00588 Engine& operator <<( Engine& ar, std::pair<x,y> &ob) THROWS (PersistException) 00589 { 00590 ar << ob.first << ob.second; 00591 return ar; 00592 } 00593 00598 template<class x, class y> 00599 Engine& operator >>(Engine& ar, std::pair<x, y> &ob) THROWS (PersistException) 00600 { 00601 ar >> ob.first >> ob.second; 00602 return ar; 00603 } 00604 00605 #ifdef CCXX_NAMESPACES 00606 } 00607 #endif 00608 00609 #endif 00610