Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

persist.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2002 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 to the GNU General Public License, permission is 00018 // granted for additional uses of the text contained in its release 00019 // of Common C++. 00020 // 00021 // The exception is that, if you link the Common C++ library with other 00022 // files to produce an executable, this does not by itself cause the 00023 // resulting executable to be covered by the GNU General Public License. 00024 // Your use of that executable is in no way restricted on account of 00025 // linking the Common C++ library code into it. 00026 // 00027 // This exception does not however invalidate any other reasons why 00028 // the executable file might be covered by the GNU General Public License. 00029 // 00030 // This exception applies only to the code released under the 00031 // name Common C++. If you copy code from other releases into a copy of 00032 // Common C++, as the General Public License permits, the exception does 00033 // not apply to the code that you add in this way. To avoid misleading 00034 // anyone as to the status of such modified files, you must delete 00035 // this exception notice from them. 00036 // 00037 // If you write modifications of your own for Common C++, it is your choice 00038 // whether to permit this exception to apply to your modifications. 00039 // If you do not wish that, delete this exception notice. 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_EXCEPTIONS_H_ 00054 #include <cc++/exception.h> 00055 #endif 00056 00057 #ifndef CCXX_MISSING_H_ 00058 #include <cc++/missing.h> 00059 #endif 00060 00061 #ifndef CCXX_STRING_H_ 00062 #include <cc++/string.h> 00063 #endif 00064 00065 #ifdef HAVE_ZLIB_H 00066 #ifndef NO_COMPRESSION 00067 #include <zlib.h> 00068 #endif 00069 #else 00070 #define NO_COMPRESSION 00071 #endif 00072 00073 #include <iostream> 00074 #include <string> 00075 #include <vector> 00076 #include <deque> 00077 #include <map> 00078 00079 #ifdef CCXX_NAMESPACES 00080 namespace ost { 00081 #define NS_PREFIX ost:: 00082 #else 00083 #define NS_PREFIX 00084 #endif 00085 00086 #ifdef CCXX_EXCEPTIONS 00087 #ifdef COMMON_STD_EXCEPTION 00088 00089 class __EXPORT PersistException : public Exception 00090 { 00091 public: 00092 PersistException(const String &what) : Exception(what) {}; 00093 }; 00094 00095 #else 00096 00097 class __EXPORT PersistException 00098 { 00099 public: 00100 PersistException(const String& reason); 00101 inline const String& getString() const 00102 {return Exception::getString();}; 00103 00104 virtual ~PersistException() {} throw(); 00105 protected: 00106 String _what; 00107 }; 00108 00109 #endif 00110 #endif 00111 00112 // This typedef allows us to declare NewBaseObjectFunction now 00113 typedef class BaseObject* (*NewBaseObjectFunction) (void); 00114 00123 class __EXPORT TypeManager 00124 { 00125 public: 00126 00131 class Registration 00132 { 00133 public: 00134 Registration(const char* name, NewBaseObjectFunction func) 00135 : myName(name) { TypeManager::add(name,func); } 00136 virtual ~Registration() { TypeManager::remove(myName.c_str()); } 00137 private: 00138 String myName; 00139 }; 00140 00144 static void add(const char* name, NewBaseObjectFunction construction); 00145 00149 static void remove(const char* name); 00150 00156 static BaseObject* createInstanceOf(const char* name); 00157 00158 typedef std::map<String,NewBaseObjectFunction> StringFunctionMap; 00159 }; 00160 00161 00162 /* 00163 * The following defines are used to declare and define the relevant code 00164 * to allow a class to use the Persistence::Engine code. 00165 */ 00166 00167 #define DECLARE_PERSISTENCE(ClassType) \ 00168 public: \ 00169 friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \ 00170 friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \ 00171 friend NS_PREFIX BaseObject *createNew##ClassType(); \ 00172 virtual const char* getPersistenceID() const; \ 00173 static NS_PREFIX TypeManager::Registration registrationFor##ClassType; 00174 00175 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \ 00176 NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \ 00177 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \ 00178 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \ 00179 { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \ 00180 NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob) \ 00181 { ar >> (NS_PREFIX BaseObject *&) ob; return ar; } \ 00182 NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob) \ 00183 { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \ 00184 NS_PREFIX TypeManager::Registration \ 00185 ClassType::registrationFor##ClassType(FullyQualifiedName, \ 00186 createNew##ClassType); 00187 00188 class Engine; 00189 00209 class __EXPORT BaseObject 00210 { 00211 public: 00217 BaseObject(); 00218 00222 virtual ~BaseObject(); 00223 00227 virtual const char* getPersistenceID() const; 00228 00234 virtual bool write(Engine& archive) const; 00235 00241 virtual bool read(Engine& archive); 00242 }; 00243 00244 00256 class __EXPORT Engine 00257 { 00258 public: 00263 #ifdef CCXX_EXCEPTIONS 00264 class Exception : public PersistException 00265 { 00266 public: 00267 Exception(const String &reason); 00268 }; 00269 #endif 00270 00274 enum EngineMode 00275 { 00276 modeRead, 00277 modeWrite 00278 }; 00279 00285 Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException); 00286 00291 void sync(); 00292 00293 virtual ~Engine(); 00294 00295 00296 // Write operations 00297 00301 void write(const BaseObject &object) THROWS (Exception) 00302 { write(&object); }; 00303 00307 void write(const BaseObject *object) THROWS (Exception); 00308 00309 // writes supported primitive types 00310 // shortcut, to make the following more readable 00311 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref)) 00312 void write(int8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00313 void write(uint8 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00314 void write(int16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00315 void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00316 void write(int32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00317 void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00318 #ifdef HAVE_64_BITS 00319 void write(int64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00320 void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00321 #endif 00322 void write(float i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00323 void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); } 00324 #undef CCXX_ENGINEWRITE_REF 00325 00326 void write(const String& str) THROWS (Exception); 00327 void write(const std::string& str) THROWS (Exception); 00328 00329 // Every write operation boils down to one or more of these 00330 void writeBinary(const uint8* data, const uint32 size) THROWS (Exception); 00331 00332 00333 // Read Operations 00334 00338 void read(BaseObject &object) THROWS (Exception); 00339 00343 void read(BaseObject *&object) THROWS (Exception); 00344 00345 // reads supported primitive types 00346 // shortcut, to make the following more readable 00347 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref)) 00348 void read(int8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00349 void read(uint8& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00350 void read(int16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00351 void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00352 void read(int32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00353 void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00354 #ifdef HAVE_64_BITS 00355 void read(int64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00356 void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00357 #endif 00358 void read(float& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00359 void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); } 00360 #undef CCXX_ENGINEREAD_REF 00361 00362 void read(String& str) THROWS (Exception); 00363 void read(std::string& str) THROWS (Exception); 00364 00365 // Every read operation boild down to one or more of these 00366 void readBinary(uint8* data, uint32 size) THROWS (Exception); 00367 00368 private: 00373 void readObject(BaseObject* object); 00374 00378 const String readClass(); 00379 00380 00384 std::iostream& myUnderlyingStream; 00385 00389 EngineMode myOperationalMode; 00390 00394 typedef std::vector<BaseObject*> ArchiveVector; 00395 typedef std::map<BaseObject const*, int32> ArchiveMap; 00396 typedef std::vector<String> ClassVector; 00397 typedef std::map<String, int32> ClassMap; 00398 00399 ArchiveVector myArchiveVector; 00400 ArchiveMap myArchiveMap; 00401 ClassVector myClassVector; 00402 ClassMap myClassMap; 00403 00404 // Compression support 00405 #ifndef NO_COMPRESSION 00406 z_stream myZStream; 00407 uint8* myCompressedDataBuffer; 00408 uint8* myUncompressedDataBuffer; 00409 uint8* myLastUncompressedDataRead; 00410 #endif 00411 }; 00412 00413 // Standard >> and << stream operators for BaseObject 00415 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob) THROWS (Engine::Exception); 00417 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob) THROWS (Engine::Exception); 00419 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception); 00421 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception); 00422 00424 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception); 00426 __EXPORT Engine& operator <<( Engine& ar, int8 ob) THROWS (Engine::Exception); 00427 00429 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception); 00431 __EXPORT Engine& operator <<( Engine& ar, uint8 ob) THROWS (Engine::Exception); 00432 00434 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception); 00436 __EXPORT Engine& operator <<( Engine& ar, int16 ob) THROWS (Engine::Exception); 00437 00439 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception); 00441 __EXPORT Engine& operator <<( Engine& ar, uint16 ob) THROWS (Engine::Exception); 00442 00444 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception); 00446 __EXPORT Engine& operator <<( Engine& ar, int32 ob) THROWS (Engine::Exception); 00447 00449 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception); 00451 __EXPORT Engine& operator <<( Engine& ar, uint32 ob) THROWS (Engine::Exception); 00452 00453 #ifdef HAVE_64_BITS 00454 00455 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception); 00457 __EXPORT Engine& operator <<( Engine& ar, int64 ob) THROWS (Engine::Exception); 00458 00460 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception); 00462 __EXPORT Engine& operator <<( Engine& ar, uint64 ob) THROWS (Engine::Exception); 00463 #endif 00464 00466 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (Engine::Exception); 00468 __EXPORT Engine& operator <<( Engine& ar, float ob) THROWS (Engine::Exception); 00469 00471 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (Engine::Exception); 00473 __EXPORT Engine& operator <<( Engine& ar, double ob) THROWS (Engine::Exception); 00474 00476 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (Engine::Exception); 00478 __EXPORT Engine& operator <<( Engine& ar, String ob) THROWS (Engine::Exception); 00479 00481 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception); 00483 __EXPORT Engine& operator <<( Engine& ar, std::string ob) THROWS (Engine::Exception); 00484 00486 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception); 00488 __EXPORT Engine& operator <<( Engine& ar, bool ob) THROWS (Engine::Exception); 00489 00499 template<class T> 00500 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception) 00501 { 00502 ar << (uint32)ob.size(); 00503 for(unsigned int i=0; i < ob.size(); ++i) 00504 ar << ob[i]; 00505 return ar; 00506 } 00507 00513 template<class T> 00514 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception) 00515 { 00516 ob.clear(); 00517 uint32 siz; 00518 ar >> siz; 00519 ob.resize(siz); 00520 for(uint32 i=0; i < siz; ++i) 00521 ar >> ob[i]; 00522 return ar; 00523 } 00524 00530 template<class T> 00531 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception) 00532 { 00533 ar << (uint32)ob.size(); 00534 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it) 00535 ar << *it; 00536 return ar; 00537 } 00538 00544 template<class T> 00545 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception) 00546 { 00547 ob.clear(); 00548 uint32 siz; 00549 ar >> siz; 00550 //ob.resize(siz); 00551 for(uint32 i=0; i < siz; ++i) 00552 { 00553 T node; 00554 ar >> node; 00555 ob.push_back(node); 00556 //ar >> ob[i]; 00557 } 00558 return ar; 00559 } 00560 00566 template<class Key, class Value> 00567 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception) 00568 { 00569 ar << (uint32)ob.size(); 00570 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it) 00571 ar << it->first << it->second; 00572 return ar; 00573 } 00574 00580 template<class Key, class Value> 00581 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception) 00582 { 00583 ob.clear(); 00584 uint32 siz; 00585 ar >> siz; 00586 for(uint32 i=0; i < siz; ++i) { 00587 Key a; 00588 ar >> a; 00589 ar >> ob[a]; 00590 } 00591 return ar; 00592 } 00593 00594 #ifdef CCXX_NAMESPACES 00595 } 00596 #endif 00597 00598 #endif 00599

Generated on Fri Jan 21 13:36:02 2005 for GNU CommonC++ by doxygen 1.3.8