• Main Page
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

ucommon/persist.h

Go to the documentation of this file.
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

Generated on Fri Oct 1 2010 for UCommon by  doxygen 1.7.1