UCommon
|
00001 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00017 00023 #if defined(OLD_STDCPP) || defined(NEW_STDCPP) 00024 #if !defined(_MSC_VER) || _MSC_VER >= 1400 00025 #ifndef _UCOMMON_PERSIST_H_ 00026 #define _UCOMMON_PERSIST_H_ 00027 00028 #ifndef _UCOMMON_PLATFORM_H_ 00029 #include <ucommon/platform.h> 00030 #endif 00031 00032 #include <iostream> 00033 #include <string> 00034 #include <vector> 00035 #include <deque> 00036 #include <map> 00037 00038 NAMESPACE_UCOMMON 00039 #define NS_PREFIX ucc:: 00040 00041 // This typedef allows us to declare NewPersistObjectFunction now 00042 typedef class PersistObject* (*NewPersistObjectFunction) (void); 00043 00044 class __EXPORT PersistException 00045 { 00046 public: 00047 PersistException(const std::string& reason); 00048 const std::string& getString() const; 00049 00050 virtual ~PersistException() throw(); 00051 00052 protected: 00053 std::string _what; 00054 }; 00055 00064 class __EXPORT TypeManager 00065 { 00066 public: 00071 class registration 00072 { 00073 public: 00074 registration(const char* name, NewPersistObjectFunction func); 00075 virtual ~registration(); 00076 private: 00077 std::string myName; 00078 }; 00079 00083 static void add(const char* name, NewPersistObjectFunction construction); 00084 00088 static void remove(const char* name); 00089 00095 static PersistObject* createInstanceOf(const char* name); 00096 00097 typedef std::map<std::string,NewPersistObjectFunction> StringFunctionMap; 00098 }; 00099 00100 /* 00101 * The following defines are used to declare and define the relevant code 00102 * to allow a class to use the Persistence::Engine code. 00103 */ 00104 00105 #define DECLARE_PERSISTENCE(ClassType) \ 00106 public: \ 00107 friend NS_PREFIX PersistEngine& operator>>( NS_PREFIX PersistEngine& ar, ClassType *&ob); \ 00108 friend NS_PREFIX PersistEngine& operator<<( NS_PREFIX PersistEngine& ar, ClassType const &ob); \ 00109 friend NS_PREFIX PersistObject *createNew##ClassType(); \ 00110 virtual const char* getPersistenceID() const; \ 00111 static NS_PREFIX TypeManager::Registration registrationFor##ClassType; 00112 00113 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \ 00114 NS_PREFIX PersistObject *createNew##ClassType() { return new ClassType; } \ 00115 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \ 00116 NS_PREFIX PersistEngine& operator>>(NS_PREFIX PersistEngine& ar, ClassType &ob) \ 00117 { ar >> (NS_PREFIX PersistObject &) ob; return ar; } \ 00118 NS_PREFIX PersistEngine& operator>>(NS_PREFIX PersistEngine& ar, ClassType *&ob) \ 00119 { ar >> (NS_PREFIX PersistObject *&) ob; return ar; } \ 00120 NS_PREFIX PersistEngine& operator<<(NS_PREFIX PersistEngine& ar, ClassType const &ob) \ 00121 { ar << (NS_PREFIX PersistObject const *)&ob; return ar; } \ 00122 NS_PREFIX TypeManager::Registration \ 00123 ClassType::registrationFor##ClassType(FullyQualifiedName, \ 00124 createNew##ClassType); 00125 00126 class PersistEngine; 00127 00147 class __EXPORT PersistObject 00148 { 00149 public: 00155 PersistObject(); 00156 00160 virtual ~PersistObject(); 00161 00165 virtual const char* getPersistenceID() const; 00166 00172 virtual bool write(PersistEngine& archive) const; 00173 00179 virtual bool read(PersistEngine& archive); 00180 }; 00181 00190 class __EXPORT PersistEngine 00191 { 00192 public: 00196 enum EngineMode { 00197 modeRead, 00198 modeWrite 00199 }; 00200 00206 PersistEngine(std::iostream& stream, EngineMode mode) throw(PersistException); 00207 00208 virtual ~PersistEngine(); 00209 00210 // Write operations 00211 00215 inline void write(const PersistObject &object) throw(PersistException) 00216 {write(&object); }; 00217 00221 void write(const PersistObject *object) throw(PersistException); 00222 00223 // writes supported primitive types 00224 // shortcut, to make the following more readable 00225 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8_t*)&valref,sizeof(valref)) 00226 inline void write(int8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00227 inline void write(uint8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00228 inline void write(int16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00229 inline void write(uint16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00230 inline void write(int32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00231 inline void write(uint32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00232 inline void write(float i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00233 inline void write(double i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00234 inline void write(bool i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00235 #undef CCXX_ENGINEWRITE_REF 00236 00237 void write(const std::string& str) throw(PersistException); 00238 00239 // Every write operation boils down to one or more of these 00240 void writeBinary(const uint8_t* data, const uint32_t size) throw(PersistException); 00241 00242 // Read Operations 00243 00247 void read(PersistObject &object) throw(PersistException); 00248 00252 void read(PersistObject *&object) throw(PersistException); 00253 00254 // reads supported primitive types 00255 // shortcut, to make the following more readable 00256 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8_t*)&valref,sizeof(valref)) 00257 inline void read(int8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00258 inline void read(uint8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00259 inline void read(int16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00260 inline void read(uint16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00261 inline void read(int32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00262 inline void read(uint32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00263 inline void read(float& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00264 inline void read(double& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00265 inline void read(bool &i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00266 #undef CCXX_ENGINEREAD_REF 00267 00268 void read(std::string& str) throw(PersistException); 00269 00270 // Every read operation boiled down to one or more of these 00271 void readBinary(uint8_t* data, uint32_t size) throw(PersistException); 00272 00273 private: 00278 void readObject(PersistObject* object) throw(PersistException); 00279 00283 const std::string readClass() throw(PersistException); 00284 00285 00289 std::iostream& myUnderlyingStream; 00290 00294 EngineMode myOperationalMode; 00295 00299 typedef std::vector<PersistObject*> ArchiveVector; 00300 typedef std::map<PersistObject const*, int32_t> ArchiveMap; 00301 typedef std::vector<std::string> ClassVector; 00302 typedef std::map<std::string, int32_t> ClassMap; 00303 00304 ArchiveVector myArchiveVector; 00305 ArchiveMap myArchiveMap; 00306 ClassVector myClassVector; 00307 ClassMap myClassMap; 00308 }; 00309 00310 #define CCXX_RE(ar,ob) ar.read(ob); return ar 00311 #define CCXX_WE(ar,ob) ar.write(ob); return ar 00312 00313 // Standard >> and << stream operators for PersistObject 00315 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject &ob) throw(PersistException) {CCXX_RE(ar,ob);} 00317 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject *&ob) throw(PersistException) {CCXX_RE(ar,ob);} 00319 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const &ob) throw(PersistException) {CCXX_WE(ar,ob);} 00321 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const *ob) throw(PersistException) {CCXX_WE(ar,ob);} 00322 00324 inline PersistEngine& operator >>( PersistEngine& ar, int8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00326 inline PersistEngine& operator <<( PersistEngine& ar, int8_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00327 00329 inline PersistEngine& operator >>( PersistEngine& ar, uint8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00331 inline PersistEngine& operator <<( PersistEngine& ar, uint8_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00332 00334 inline PersistEngine& operator >>( PersistEngine& ar, int16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00336 inline PersistEngine& operator <<( PersistEngine& ar, int16_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00337 00339 inline PersistEngine& operator >>( PersistEngine& ar, uint16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00341 inline PersistEngine& operator <<( PersistEngine& ar, uint16_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00342 00344 inline PersistEngine& operator >>( PersistEngine& ar, int32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00346 inline PersistEngine& operator <<( PersistEngine& ar, int32_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00347 00349 inline PersistEngine& operator >>( PersistEngine& ar, uint32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00351 inline PersistEngine& operator <<( PersistEngine& ar, uint32_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00352 00354 inline PersistEngine& operator >>( PersistEngine& ar, float& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00356 inline PersistEngine& operator <<( PersistEngine& ar, float ob) throw(PersistException) {CCXX_WE(ar,ob);} 00357 00359 inline PersistEngine& operator >>( PersistEngine& ar, double& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00361 inline PersistEngine& operator <<( PersistEngine& ar, double ob) throw(PersistException) {CCXX_WE(ar,ob);} 00362 00364 inline PersistEngine& operator >>( PersistEngine& ar, std::string& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00366 inline PersistEngine& operator <<( PersistEngine& ar, std::string ob) throw(PersistException) {CCXX_WE(ar,ob);} 00367 00369 inline PersistEngine& operator >>( PersistEngine& ar, bool& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00371 inline PersistEngine& operator <<( PersistEngine& ar, bool ob) throw(PersistException) {CCXX_WE(ar,ob);} 00372 00373 #undef CCXX_RE 00374 #undef CCXX_WE 00375 00385 template<class T> 00386 PersistEngine& operator <<( PersistEngine& ar, typename std::vector<T> const& ob) throw(PersistException) 00387 { 00388 ar << (uint32_t)ob.size(); 00389 for(unsigned int i=0; i < ob.size(); ++i) 00390 ar << ob[i]; 00391 return ar; 00392 } 00393 00399 template<class T> 00400 PersistEngine& operator >>( PersistEngine& ar, typename std::vector<T>& ob) throw(PersistException) 00401 { 00402 ob.clear(); 00403 uint32_t siz; 00404 ar >> siz; 00405 ob.resize(siz); 00406 for(uint32_t i=0; i < siz; ++i) 00407 ar >> ob[i]; 00408 return ar; 00409 } 00410 00416 template<class T> 00417 PersistEngine& operator <<( PersistEngine& ar, typename std::deque<T> const& ob) throw(PersistException) 00418 { 00419 ar << (uint32_t)ob.size(); 00420 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it) 00421 ar << *it; 00422 return ar; 00423 } 00424 00430 template<class T> 00431 PersistEngine& operator >>( PersistEngine& ar, typename std::deque<T>& ob) throw(PersistException) 00432 { 00433 ob.clear(); 00434 uint32_t siz; 00435 ar >> siz; 00436 //ob.resize(siz); 00437 for(uint32_t i=0; i < siz; ++i) { 00438 T node; 00439 ar >> node; 00440 ob.push_back(node); 00441 //ar >> ob[i]; 00442 } 00443 return ar; 00444 } 00445 00451 template<class Key, class Value> 00452 PersistEngine& operator <<( PersistEngine& ar, typename std::map<Key,Value> const & ob) throw(PersistException) 00453 { 00454 ar << (uint32_t)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 PersistEngine& operator >>( PersistEngine& ar, typename std::map<Key,Value>& ob) throw(PersistException) 00467 { 00468 ob.clear(); 00469 uint32_t siz; 00470 ar >> siz; 00471 for(uint32_t i=0; i < siz; ++i) { 00472 Key a; 00473 ar >> a; 00474 ar >> ob[a]; 00475 } 00476 return ar; 00477 } 00478 00483 template<class x, class y> 00484 PersistEngine& operator <<( PersistEngine& ar, std::pair<x,y> &ob) throw(PersistException) 00485 { 00486 ar << ob.first << ob.second; 00487 return ar; 00488 } 00489 00494 template<class x, class y> 00495 PersistEngine& operator >>(PersistEngine& ar, std::pair<x, y> &ob) throw(PersistException) 00496 { 00497 ar >> ob.first >> ob.second; 00498 return ar; 00499 } 00500 00501 END_NAMESPACE 00502 00503 #endif 00504 #endif 00505 #endif