ucommon
|
00001 // Copyright (C) 2006-2014 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 00040 // This typedef allows us to declare NewPersistObjectFunction now 00041 typedef class PersistObject* (*NewPersistObjectFunction) (void); 00042 00043 class __EXPORT PersistException 00044 { 00045 public: 00046 PersistException(const std::string& reason); 00047 const std::string& getString() const; 00048 00049 virtual ~PersistException() throw(); 00050 00051 protected: 00052 std::string _what; 00053 }; 00054 00063 class __EXPORT TypeManager 00064 { 00065 public: 00070 class registration 00071 { 00072 public: 00073 registration(const char* name, NewPersistObjectFunction func); 00074 virtual ~registration(); 00075 private: 00076 std::string myName; 00077 }; 00078 00082 static void add(const char* name, NewPersistObjectFunction construction); 00083 00087 static void remove(const char* name); 00088 00094 static PersistObject* createInstanceOf(const char* name); 00095 00096 typedef std::map<std::string,NewPersistObjectFunction> StringFunctionMap; 00097 }; 00098 00099 /* 00100 * The following defines are used to declare and define the relevant code 00101 * to allow a class to use the Persistence::Engine code. 00102 */ 00103 00104 #define DECLARE_PERSISTENCE(ClassType) \ 00105 public: \ 00106 friend ucommon::PersistEngine& operator>>( ucommon::PersistEngine& ar, ClassType *&ob); \ 00107 friend ucommon::PersistEngine& operator<<( ucommon::PersistEngine& ar, ClassType const &ob); \ 00108 friend ucommon::PersistObject *createNew##ClassType(); \ 00109 virtual const char* getPersistenceID() const; \ 00110 static ucommon::TypeManager::Registration registrationFor##ClassType; 00111 00112 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \ 00113 ucommon::PersistObject *createNew##ClassType() { return new ClassType; } \ 00114 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \ 00115 ucommon::PersistEngine& operator>>(ucommon::PersistEngine& ar, ClassType &ob) \ 00116 { ar >> (ucommon::PersistObject &) ob; return ar; } \ 00117 ucommon::PersistEngine& operator>>(ucommon::PersistEngine& ar, ClassType *&ob) \ 00118 { ar >> (ucommon::PersistObject *&) ob; return ar; } \ 00119 ucommon::PersistEngine& operator<<(ucommon::PersistEngine& ar, ClassType const &ob) \ 00120 { ar << (ucommon::PersistObject const *)&ob; return ar; } \ 00121 ucommon::TypeManager::Registration \ 00122 ClassType::registrationFor##ClassType(FullyQualifiedName, \ 00123 createNew##ClassType); 00124 00125 class PersistEngine; 00126 00146 class __EXPORT PersistObject 00147 { 00148 public: 00154 PersistObject(); 00155 00159 virtual ~PersistObject(); 00160 00164 virtual const char* getPersistenceID() const; 00165 00171 virtual bool write(PersistEngine& archive) const; 00172 00178 virtual bool read(PersistEngine& archive); 00179 }; 00180 00189 class __EXPORT PersistEngine 00190 { 00191 public: 00195 enum EngineMode { 00196 modeRead, 00197 modeWrite 00198 }; 00199 00205 PersistEngine(std::iostream& stream, EngineMode mode) throw(PersistException); 00206 00207 virtual ~PersistEngine(); 00208 00209 // Write operations 00210 00214 inline void write(const PersistObject &object) throw(PersistException) 00215 {write(&object);} 00216 00220 void write(const PersistObject *object) throw(PersistException); 00221 00222 // writes supported primitive types 00223 // shortcut, to make the following more readable 00224 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8_t*)&valref,sizeof(valref)) 00225 inline void write(int8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00226 inline void write(uint8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00227 inline void write(int16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00228 inline void write(uint16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00229 inline void write(int32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00230 inline void write(uint32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00231 inline void write(float i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00232 inline void write(double i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00233 inline void write(bool i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); } 00234 #undef CCXX_ENGINEWRITE_REF 00235 00236 void write(const std::string& str) throw(PersistException); 00237 00238 // Every write operation boils down to one or more of these 00239 void writeBinary(const uint8_t* data, const uint32_t size) throw(PersistException); 00240 00241 // Read Operations 00242 00246 void read(PersistObject &object) throw(PersistException); 00247 00251 void read(PersistObject *&object) throw(PersistException); 00252 00253 // reads supported primitive types 00254 // shortcut, to make the following more readable 00255 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8_t*)&valref,sizeof(valref)) 00256 inline void read(int8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00257 inline void read(uint8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00258 inline void read(int16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00259 inline void read(uint16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00260 inline void read(int32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00261 inline void read(uint32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00262 inline void read(float& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00263 inline void read(double& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00264 inline void read(bool &i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); } 00265 #undef CCXX_ENGINEREAD_REF 00266 00267 void read(std::string& str) throw(PersistException); 00268 00269 // Every read operation boiled down to one or more of these 00270 void readBinary(uint8_t* data, uint32_t size) throw(PersistException); 00271 00272 private: 00277 void readObject(PersistObject* object) throw(PersistException); 00278 00282 const std::string readClass() throw(PersistException); 00283 00284 00288 std::iostream& myUnderlyingStream; 00289 00293 EngineMode myOperationalMode; 00294 00298 typedef std::vector<PersistObject*> ArchiveVector; 00299 typedef std::map<PersistObject const*, int32_t> ArchiveMap; 00300 typedef std::vector<std::string> ClassVector; 00301 typedef std::map<std::string, int32_t> ClassMap; 00302 00303 ArchiveVector myArchiveVector; 00304 ArchiveMap myArchiveMap; 00305 ClassVector myClassVector; 00306 ClassMap myClassMap; 00307 }; 00308 00309 #define CCXX_RE(ar,ob) ar.read(ob); return ar 00310 #define CCXX_WE(ar,ob) ar.write(ob); return ar 00311 00312 // Standard >> and << stream operators for PersistObject 00314 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject &ob) throw(PersistException) {CCXX_RE(ar,ob);} 00316 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject *&ob) throw(PersistException) {CCXX_RE(ar,ob);} 00318 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const &ob) throw(PersistException) {CCXX_WE(ar,ob);} 00320 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const *ob) throw(PersistException) {CCXX_WE(ar,ob);} 00321 00323 inline PersistEngine& operator >>( PersistEngine& ar, int8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00325 inline PersistEngine& operator <<( PersistEngine& ar, int8_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00326 00328 inline PersistEngine& operator >>( PersistEngine& ar, uint8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00330 inline PersistEngine& operator <<( PersistEngine& ar, uint8_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00331 00333 inline PersistEngine& operator >>( PersistEngine& ar, int16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00335 inline PersistEngine& operator <<( PersistEngine& ar, int16_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00336 00338 inline PersistEngine& operator >>( PersistEngine& ar, uint16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00340 inline PersistEngine& operator <<( PersistEngine& ar, uint16_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00341 00343 inline PersistEngine& operator >>( PersistEngine& ar, int32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00345 inline PersistEngine& operator <<( PersistEngine& ar, int32_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00346 00348 inline PersistEngine& operator >>( PersistEngine& ar, uint32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00350 inline PersistEngine& operator <<( PersistEngine& ar, uint32_t ob) throw(PersistException) {CCXX_WE(ar,ob);} 00351 00353 inline PersistEngine& operator >>( PersistEngine& ar, float& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00355 inline PersistEngine& operator <<( PersistEngine& ar, float ob) throw(PersistException) {CCXX_WE(ar,ob);} 00356 00358 inline PersistEngine& operator >>( PersistEngine& ar, double& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00360 inline PersistEngine& operator <<( PersistEngine& ar, double ob) throw(PersistException) {CCXX_WE(ar,ob);} 00361 00363 inline PersistEngine& operator >>( PersistEngine& ar, std::string& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00365 inline PersistEngine& operator <<( PersistEngine& ar, std::string ob) throw(PersistException) {CCXX_WE(ar,ob);} 00366 00368 inline PersistEngine& operator >>( PersistEngine& ar, bool& ob) throw(PersistException) {CCXX_RE(ar,ob);} 00370 inline PersistEngine& operator <<( PersistEngine& ar, bool ob) throw(PersistException) {CCXX_WE(ar,ob);} 00371 00372 #undef CCXX_RE 00373 #undef CCXX_WE 00374 00384 template<class T> 00385 PersistEngine& operator <<( PersistEngine& ar, typename std::vector<T> const& ob) throw(PersistException) 00386 { 00387 ar << (uint32_t)ob.size(); 00388 for(unsigned int i=0; i < ob.size(); ++i) 00389 ar << ob[i]; 00390 return ar; 00391 } 00392 00398 template<class T> 00399 PersistEngine& operator >>( PersistEngine& ar, typename std::vector<T>& ob) throw(PersistException) 00400 { 00401 ob.clear(); 00402 uint32_t siz; 00403 ar >> siz; 00404 ob.resize(siz); 00405 for(uint32_t i=0; i < siz; ++i) 00406 ar >> ob[i]; 00407 return ar; 00408 } 00409 00415 template<class T> 00416 PersistEngine& operator <<( PersistEngine& ar, typename std::deque<T> const& ob) throw(PersistException) 00417 { 00418 ar << (uint32_t)ob.size(); 00419 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it) 00420 ar << *it; 00421 return ar; 00422 } 00423 00429 template<class T> 00430 PersistEngine& operator >>( PersistEngine& ar, typename std::deque<T>& ob) throw(PersistException) 00431 { 00432 ob.clear(); 00433 uint32_t siz; 00434 ar >> siz; 00435 //ob.resize(siz); 00436 for(uint32_t i=0; i < siz; ++i) { 00437 T node; 00438 ar >> node; 00439 ob.push_back(node); 00440 //ar >> ob[i]; 00441 } 00442 return ar; 00443 } 00444 00450 template<class Key, class Value> 00451 PersistEngine& operator <<( PersistEngine& ar, typename std::map<Key,Value> const & ob) throw(PersistException) 00452 { 00453 ar << (uint32_t)ob.size(); 00454 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it) 00455 ar << it->first << it->second; 00456 return ar; 00457 } 00458 00464 template<class Key, class Value> 00465 PersistEngine& operator >>( PersistEngine& ar, typename std::map<Key,Value>& ob) throw(PersistException) 00466 { 00467 ob.clear(); 00468 uint32_t siz; 00469 ar >> siz; 00470 for(uint32_t i=0; i < siz; ++i) { 00471 Key a; 00472 ar >> a; 00473 ar >> ob[a]; 00474 } 00475 return ar; 00476 } 00477 00482 template<class x, class y> 00483 PersistEngine& operator <<( PersistEngine& ar, std::pair<x,y> &ob) throw(PersistException) 00484 { 00485 ar << ob.first << ob.second; 00486 return ar; 00487 } 00488 00493 template<class x, class y> 00494 PersistEngine& operator >>(PersistEngine& ar, std::pair<x, y> &ob) throw(PersistException) 00495 { 00496 ar >> ob.first >> ob.second; 00497 return ar; 00498 } 00499 00500 } // namespace ucommon 00501 00502 #endif 00503 #endif 00504 #endif