GNU CommonC++
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // 00003 // This program is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00016 // 00017 // As a special exception, you may use this file as part of a free software 00018 // library without restriction. Specifically, if other files instantiate 00019 // templates or use macros or inline functions from this file, or you compile 00020 // this file and link it with other files to produce an executable, this 00021 // file does not by itself cause the resulting executable to be covered by 00022 // the GNU General Public License. This exception does not however 00023 // invalidate any other reasons why the executable file might be covered by 00024 // the GNU General Public License. 00025 // 00026 // This exception applies only to the code released under the name GNU 00027 // Common C++. If you copy code from other releases into a copy of GNU 00028 // Common C++, as the General Public License permits, the exception does 00029 // not apply to the code that you add in this way. To avoid misleading 00030 // anyone as to the status of such modified files, you must delete 00031 // this exception notice from them. 00032 // 00033 // If you write modifications of your own for GNU Common C++, it is your choice 00034 // whether to permit this exception to apply to your modifications. 00035 // If you do not wish that, delete this exception notice. 00036 // 00037 00043 #ifndef CCXX_PERSIST_H_ 00044 #define CCXX_PERSIST_H_ 00045 00046 #ifndef CCXX_CONFIG_H_ 00047 #include <cc++/config.h> 00048 #endif 00049 00050 #ifndef CCXX_EXCEPTIONS_H_ 00051 #include <cc++/exception.h> 00052 #endif 00053 00054 #ifndef CCXX_MISSING_H_ 00055 #include <cc++/missing.h> 00056 #endif 00057 00058 #ifndef CCXX_STRING_H_ 00059 #include <cc++/string.h> 00060 #endif 00061 00062 #ifdef HAVE_ZLIB_H 00063 #ifndef NO_COMPRESSION 00064 #include <zlib.h> 00065 #endif 00066 #else 00067 #define NO_COMPRESSION 00068 #endif 00069 00070 #include <iostream> 00071 #include <string> 00072 #include <vector> 00073 #include <deque> 00074 #include <map> 00075 00076 #ifdef CCXX_NAMESPACES 00077 namespace ost { 00078 #define NS_PREFIX ost:: 00079 #else 00080 #define NS_PREFIX 00081 #endif 00082 00083 #ifdef CCXX_EXCEPTIONS 00084 #ifdef COMMON_STD_EXCEPTION 00085 00086 class __EXPORT PersistException : public Exception 00087 { 00088 public: 00089 PersistException(const String &what) : Exception(what) {}; 00090 }; 00091 00092 #else 00093 00094 class __EXPORT PersistException 00095 { 00096 public: 00097 PersistException(const String& reason); 00098 inline const String& getString() const 00099 {return Exception::getString();}; 00100 00101 virtual ~PersistException() {} throw(); 00102 protected: 00103 String _what; 00104 }; 00105 00106 #endif 00107 #endif 00108 00109 // This typedef allows us to declare NewBaseObjectFunction now 00110 typedef class BaseObject* (*NewBaseObjectFunction) (void); 00111 00120 class __EXPORT TypeManager 00121 { 00122 public: 00123 00128 class Registration 00129 { 00130 public: 00131 Registration(const char* name, NewBaseObjectFunction func); 00132 virtual ~Registration(); 00133 private: 00134 String myName; 00135 }; 00136 00140 static void add(const char* name, NewBaseObjectFunction construction); 00141 00145 static void remove(const char* name); 00146 00152 static BaseObject* createInstanceOf(const char* name); 00153 00154 typedef std::map<String,NewBaseObjectFunction> StringFunctionMap; 00155 }; 00156 00157 00158 /* 00159 * The following defines are used to declare and define the relevant code 00160 * to allow a class to use the Persistence::Engine code. 00161 */ 00162 00163 #define DECLARE_PERSISTENCE(ClassType) \ 00164 public: \ 00165 friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \ 00166 friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \ 00167 friend NS_PREFIX BaseObject *createNew##ClassType(); \ 00168 virtual const char* getPersistenceID() const; \ 00169 static NS_PREFIX TypeManager::Registration registrationFor##ClassType; 00170 00171 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \ 00172 NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \ 00173 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \ 00174 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \ 00175 { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \ 00176 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob) \ 00177 { ar >> (NS_PREFIX BaseObject *&) ob; return ar; } \ 00178 NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob) \ 00179 { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \ 00180 NS_PREFIX TypeManager::Registration \ 00181 ClassType::registrationFor##ClassType(FullyQualifiedName, \ 00182 createNew##ClassType); 00183 00184 class Engine; 00185 00205 class __EXPORT BaseObject 00206 { 00207 public: 00213 BaseObject(); 00214 00218 virtual ~BaseObject(); 00219 00223 virtual const char* getPersistenceID() const; 00224 00230 virtual bool write(Engine& archive) const; 00231 00237 virtual bool read(Engine& archive); 00238 }; 00239 00240 00251 class __EXPORT Engine 00252 { 00253 public: 00257 enum EngineMode { 00258 modeRead, 00259 modeWrite 00260 }; 00261 00267 Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException); 00268 00273 void sync(); 00274 00275 virtual ~Engine(); 00276 00277 00278 // Write operations 00279 00283 void write(const BaseObject &object) THROWS (PersistException) 00284 { write(&object); }; 00285 00289 void write(const BaseObject *object) THROWS (PersistException); 00290 00291 // writes supported primitive types 00292 // shortcut, to make the following more readable 00293 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref)) 00294 void write(int8 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00295 void write(uint8 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00296 void write(int16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00297 void write(uint16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00298 void write(int32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00299 void write(uint32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00300 #ifdef HAVE_64_BITS 00301 void write(int64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00302 void write(uint64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00303 #endif 00304 void write(float i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00305 void write(double i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); } 00306 #undef CCXX_ENGINEWRITE_REF 00307 00308 void write(const String& str) THROWS (PersistException); 00309 void write(const std::string& str) THROWS (PersistException); 00310 00311 // Every write operation boils down to one or more of these 00312 void writeBinary(const uint8* data, const uint32 size) THROWS (PersistException); 00313 00314 00315 // Read Operations 00316 00320 void read(BaseObject &object) THROWS (PersistException); 00321 00325 void read(BaseObject *&object) THROWS (PersistException); 00326 00327 // reads supported primitive types 00328 // shortcut, to make the following more readable 00329 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref)) 00330 void read(int8& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00331 void read(uint8& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00332 void read(int16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00333 void read(uint16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00334 void read(int32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00335 void read(uint32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00336 #ifdef HAVE_64_BITS 00337 void read(int64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00338 void read(uint64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00339 #endif 00340 void read(float& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00341 void read(double& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); } 00342 #undef CCXX_ENGINEREAD_REF 00343 00344 void read(String& str) THROWS (PersistException); 00345 void read(std::string& str) THROWS (PersistException); 00346 00347 // Every read operation boild down to one or more of these 00348 void readBinary(uint8* data, uint32 size) THROWS (PersistException); 00349 00350 private: 00355 void readObject(BaseObject* object) THROWS (PersistException); 00356 00360 const String readClass() THROWS (PersistException); 00361 00362 00366 std::iostream& myUnderlyingStream; 00367 00371 EngineMode myOperationalMode; 00372 00376 typedef std::vector<BaseObject*> ArchiveVector; 00377 typedef std::map<BaseObject const*, int32> ArchiveMap; 00378 typedef std::vector<String> ClassVector; 00379 typedef std::map<String, int32> ClassMap; 00380 00381 ArchiveVector myArchiveVector; 00382 ArchiveMap myArchiveMap; 00383 ClassVector myClassVector; 00384 ClassMap myClassMap; 00385 00386 // Compression support 00387 #ifndef NO_COMPRESSION 00388 z_stream myZStream; 00389 uint8* myCompressedDataBuffer; 00390 uint8* myUncompressedDataBuffer; 00391 uint8* myLastUncompressedDataRead; 00392 #endif 00393 }; 00394 00395 // Standard >> and << stream operators for BaseObject 00397 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob) THROWS (PersistException); 00399 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob) THROWS (PersistException); 00401 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (PersistException); 00403 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (PersistException); 00404 00406 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (PersistException); 00408 __EXPORT Engine& operator <<( Engine& ar, int8 ob) THROWS (PersistException); 00409 00411 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (PersistException); 00413 __EXPORT Engine& operator <<( Engine& ar, uint8 ob) THROWS (PersistException); 00414 00416 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (PersistException); 00418 __EXPORT Engine& operator <<( Engine& ar, int16 ob) THROWS (PersistException); 00419 00421 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (PersistException); 00423 __EXPORT Engine& operator <<( Engine& ar, uint16 ob) THROWS (PersistException); 00424 00426 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (PersistException); 00428 __EXPORT Engine& operator <<( Engine& ar, int32 ob) THROWS (PersistException); 00429 00431 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (PersistException); 00433 __EXPORT Engine& operator <<( Engine& ar, uint32 ob) THROWS (PersistException); 00434 00435 #ifdef HAVE_64_BITS 00436 00437 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (PersistException); 00439 __EXPORT Engine& operator <<( Engine& ar, int64 ob) THROWS (PersistException); 00440 00442 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (PersistException); 00444 __EXPORT Engine& operator <<( Engine& ar, uint64 ob) THROWS (PersistException); 00445 #endif 00446 00448 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (PersistException); 00450 __EXPORT Engine& operator <<( Engine& ar, float ob) THROWS (PersistException); 00451 00453 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (PersistException); 00455 __EXPORT Engine& operator <<( Engine& ar, double ob) THROWS (PersistException); 00456 00458 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (PersistException); 00460 __EXPORT Engine& operator <<( Engine& ar, String ob) THROWS (PersistException); 00461 00463 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (PersistException); 00465 __EXPORT Engine& operator <<( Engine& ar, std::string ob) THROWS (PersistException); 00466 00468 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (PersistException); 00470 __EXPORT Engine& operator <<( Engine& ar, bool ob) THROWS (PersistException); 00471 00481 template<class T> 00482 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (PersistException) 00483 { 00484 ar << (uint32)ob.size(); 00485 for(unsigned int i=0; i < ob.size(); ++i) 00486 ar << ob[i]; 00487 return ar; 00488 } 00489 00495 template<class T> 00496 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (PersistException) 00497 { 00498 ob.clear(); 00499 uint32 siz; 00500 ar >> siz; 00501 ob.resize(siz); 00502 for(uint32 i=0; i < siz; ++i) 00503 ar >> ob[i]; 00504 return ar; 00505 } 00506 00512 template<class T> 00513 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (PersistException) 00514 { 00515 ar << (uint32)ob.size(); 00516 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it) 00517 ar << *it; 00518 return ar; 00519 } 00520 00526 template<class T> 00527 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (PersistException) 00528 { 00529 ob.clear(); 00530 uint32 siz; 00531 ar >> siz; 00532 //ob.resize(siz); 00533 for(uint32 i=0; i < siz; ++i) { 00534 T node; 00535 ar >> node; 00536 ob.push_back(node); 00537 //ar >> ob[i]; 00538 } 00539 return ar; 00540 } 00541 00547 template<class Key, class Value> 00548 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (PersistException) 00549 { 00550 ar << (uint32)ob.size(); 00551 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it) 00552 ar << it->first << it->second; 00553 return ar; 00554 } 00555 00561 template<class Key, class Value> 00562 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (PersistException) 00563 { 00564 ob.clear(); 00565 uint32 siz; 00566 ar >> siz; 00567 for(uint32 i=0; i < siz; ++i) { 00568 Key a; 00569 ar >> a; 00570 ar >> ob[a]; 00571 } 00572 return ar; 00573 } 00574 00579 template<class x, class y> 00580 Engine& operator <<( Engine& ar, std::pair<x,y> &ob) THROWS (PersistException) 00581 { 00582 ar << ob.first << ob.second; 00583 return ar; 00584 } 00585 00590 template<class x, class y> 00591 Engine& operator >>(Engine& ar, std::pair<x, y> &ob) THROWS (PersistException) 00592 { 00593 ar >> ob.first >> ob.second; 00594 return ar; 00595 } 00596 00597 #ifdef CCXX_NAMESPACES 00598 } 00599 #endif 00600 00601 #endif 00602