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

persist.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
00002 // Copyright (C) 2006-2008 David Sugar, Tycho Softworks.
00003 //
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 2 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free software
00019 // library without restriction.  Specifically, if other files instantiate
00020 // templates or use macros or inline functions from this file, or you compile
00021 // this file and link it with other files to produce an executable, this
00022 // file does not by itself cause the resulting executable to be covered by
00023 // the GNU General Public License.  This exception does not however
00024 // invalidate any other reasons why the executable file might be covered by
00025 // the GNU General Public License.
00026 //
00027 // This exception applies only to the code released under the name GNU
00028 // Common C++.  If you copy code from other releases into a copy of GNU
00029 // Common C++, as the General Public License permits, the exception does
00030 // not apply to the code that you add in this way.  To avoid misleading
00031 // anyone as to the status of such modified files, you must delete
00032 // this exception notice from them.
00033 //
00034 // If you write modifications of your own for GNU Common C++, it is your choice
00035 // whether to permit this exception to apply to your modifications.
00036 // If you do not wish that, delete this exception notice.
00037 //
00038 
00044 #ifndef CCXX_PERSIST_H_
00045 #define CCXX_PERSIST_H_
00046 
00047 #ifndef CCXX_CONFIG_H_
00048 #include <cc++/config.h>
00049 #endif
00050 
00051 #ifndef CCXX_EXCEPTIONS_H_
00052 #include <cc++/exception.h>
00053 #endif
00054 
00055 #ifndef CCXX_MISSING_H_
00056 #include <cc++/missing.h>
00057 #endif
00058 
00059 #ifndef CCXX_STRING_H_
00060 #include <cc++/string.h>
00061 #endif
00062 
00063 #ifdef HAVE_ZLIB_H
00064 #ifndef NO_COMPRESSION
00065 #include <zlib.h>
00066 #endif
00067 #else
00068 #define NO_COMPRESSION
00069 #endif
00070 
00071 #include <iostream>
00072 #include <string>
00073 #include <vector>
00074 #include <deque>
00075 #include <map>
00076 
00077 #ifdef CCXX_NAMESPACES
00078 namespace ost {
00079 #define NS_PREFIX ost::
00080 #else
00081 #define NS_PREFIX
00082 #endif
00083 
00084 #ifdef  CCXX_EXCEPTIONS
00085 #ifdef  COMMON_STD_EXCEPTION
00086 
00087 class __EXPORT PersistException : public Exception
00088 {
00089 public:
00090         PersistException(const String &what) : Exception(what) {};
00091 };
00092 
00093 #else
00094 
00095 class __EXPORT PersistException
00096 {
00097 public:
00098         PersistException(const String& reason);
00099         inline const String& getString() const
00100                 {return Exception::getString();};
00101 
00102         virtual ~PersistException() {} throw();
00103 protected:
00104         String _what;
00105 };
00106 
00107 #endif
00108 #endif
00109 
00110 // This typedef allows us to declare NewBaseObjectFunction now
00111 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00112 
00121 class __EXPORT TypeManager
00122 {
00123 public:
00124 
00129         class Registration 
00130         {
00131         public:
00132                 Registration(const char* name, NewBaseObjectFunction func);
00133                 virtual ~Registration();
00134         private:
00135                 String myName;
00136         };
00137 
00141         static void add(const char* name, NewBaseObjectFunction construction);
00142 
00146         static void remove(const char* name);
00147 
00153         static BaseObject* createInstanceOf(const char* name);
00154 
00155         typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00156 };
00157 
00158 
00159 /*
00160  * The following defines are used to declare and define the relevant code
00161  * to allow a class to use the Persistence::Engine code.
00162  */
00163 
00164 #define DECLARE_PERSISTENCE(ClassType)                                  \
00165   public:                                                               \
00166         friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob);             \
00167         friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob);        \
00168         friend NS_PREFIX BaseObject *createNew##ClassType();                            \
00169         virtual const char* getPersistenceID() const;                   \
00170         static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00171 
00172 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName)                  \
00173   NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; }                      \
00174   const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00175   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob)                           \
00176         { ar >> (NS_PREFIX BaseObject &) ob; return ar; }                                     \
00177   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob)                          \
00178         { ar >> (NS_PREFIX BaseObject *&) ob; return ar; }                                    \
00179   NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob)                             \
00180         { ar << (NS_PREFIX BaseObject const *)&ob; return ar; }                       \
00181   NS_PREFIX TypeManager::Registration                                                 \
00182         ClassType::registrationFor##ClassType(FullyQualifiedName,             \
00183                                               createNew##ClassType);
00184 
00185 class Engine;
00186 
00206 class __EXPORT BaseObject
00207 {
00208 public:
00214          BaseObject();
00215 
00219          virtual ~BaseObject();
00220 
00224          virtual const char* getPersistenceID() const;
00225 
00231          virtual bool write(Engine& archive) const;
00232 
00238          virtual bool read(Engine& archive);
00239 };
00240 
00241 
00252 class __EXPORT Engine
00253 {
00254 public:
00258         enum EngineMode {
00259                 modeRead,
00260                 modeWrite
00261         };
00262 
00269         Engine(std::iostream& stream, EngineMode mode, bool compress=true) THROWS (PersistException);
00270 
00275         void sync();
00276         
00280         bool more();
00281 
00282         virtual ~Engine();
00283 
00284 
00285         // Write operations
00286 
00290         void write(const BaseObject &object) THROWS (PersistException)
00291         { write(&object); };
00292 
00296         void write(const BaseObject *object) THROWS (PersistException);
00297 
00298         // writes supported primitive types
00299         // shortcut, to make the following more readable
00300 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00301         void write(int8 i)   THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00302         void write(uint8 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00303         void write(int16 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00304         void write(uint16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00305         void write(int32 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00306         void write(uint32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00307 #ifdef  HAVE_64_BITS
00308         void write(int64 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00309         void write(uint64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00310 #endif
00311         void write(float i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00312         void write(double i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00313 #undef CCXX_ENGINEWRITE_REF
00314 
00315         void write(const String& str) THROWS (PersistException);
00316         void write(const std::string& str) THROWS (PersistException);
00317 
00318         // Every write operation boils down to one or more of these
00319         void writeBinary(const uint8* data, const uint32 size) THROWS (PersistException);
00320 
00321 
00322         // Read Operations
00323 
00327         void read(BaseObject &object) THROWS (PersistException);
00328 
00332         void read(BaseObject *&object) THROWS (PersistException);
00333 
00334         // reads supported primitive types
00335   // shortcut, to make the following more readable
00336 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00337         void read(int8& i)   THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00338         void read(uint8& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00339         void read(int16& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00340         void read(uint16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00341         void read(int32& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00342         void read(uint32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00343 #ifdef  HAVE_64_BITS
00344         void read(int64& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00345         void read(uint64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00346 #endif
00347         void read(float& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00348         void read(double& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00349 #undef CCXX_ENGINEREAD_REF
00350 
00351         void read(String& str) THROWS (PersistException);
00352         void read(std::string& str) THROWS (PersistException);
00353 
00354         // Every read operation boild down to one or more of these
00355         void readBinary(uint8* data, uint32 size) THROWS (PersistException);
00356 
00357 private:
00362         void readObject(BaseObject* object) THROWS (PersistException);
00363 
00367         const String readClass() THROWS (PersistException);
00368 
00369 
00373         std::iostream& myUnderlyingStream;
00374 
00378         EngineMode myOperationalMode;
00379 
00383         typedef std::vector<BaseObject*>           ArchiveVector;
00384         typedef std::map<BaseObject const*, int32> ArchiveMap;
00385         typedef std::vector<String>                ClassVector;
00386         typedef std::map<String, int32>            ClassMap;
00387 
00388         ArchiveVector myArchiveVector;
00389         ArchiveMap myArchiveMap;
00390         ClassVector myClassVector;
00391         ClassMap myClassMap;
00392 
00393         // Compression support
00394         bool use_compression; // valid onlry if NO_COMPRESSION is false
00395 #ifndef NO_COMPRESSION
00396         z_stream myZStream;
00397         uint8* myCompressedDataBuffer;
00398         uint8* myUncompressedDataBuffer;
00399         uint8* myLastUncompressedDataRead;
00400 #endif
00401 };
00402 
00403 // Standard >> and << stream operators for BaseObject
00405 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob)      THROWS (PersistException);
00407 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob)      THROWS (PersistException);
00409 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (PersistException);
00411 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (PersistException);
00412 
00414 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (PersistException);
00416 __EXPORT Engine& operator <<( Engine& ar, int8 ob)  THROWS (PersistException);
00417 
00419 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (PersistException);
00421 __EXPORT Engine& operator <<( Engine& ar, uint8 ob)  THROWS (PersistException);
00422 
00424 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (PersistException);
00426 __EXPORT Engine& operator <<( Engine& ar, int16 ob)  THROWS (PersistException);
00427 
00429 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (PersistException);
00431 __EXPORT Engine& operator <<( Engine& ar, uint16 ob)  THROWS (PersistException);
00432 
00434 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (PersistException);
00436 __EXPORT Engine& operator <<( Engine& ar, int32 ob)  THROWS (PersistException);
00437 
00439 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (PersistException);
00441 __EXPORT Engine& operator <<( Engine& ar, uint32 ob)  THROWS (PersistException);
00442 
00443 #ifdef  HAVE_64_BITS
00444 
00445 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (PersistException);
00447 __EXPORT Engine& operator <<( Engine& ar, int64 ob)  THROWS (PersistException);
00448 
00450 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (PersistException);
00452 __EXPORT Engine& operator <<( Engine& ar, uint64 ob)  THROWS (PersistException);
00453 #endif
00454 
00456 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (PersistException);
00458 __EXPORT Engine& operator <<( Engine& ar, float ob)  THROWS (PersistException);
00459 
00461 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (PersistException);
00463 __EXPORT Engine& operator <<( Engine& ar, double ob)  THROWS (PersistException);
00464 
00466 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (PersistException);
00468 __EXPORT Engine& operator <<( Engine& ar, String ob)  THROWS (PersistException);
00469 
00471 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (PersistException);
00473 __EXPORT Engine& operator <<( Engine& ar, std::string ob)  THROWS (PersistException);
00474 
00476 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (PersistException);
00478 __EXPORT Engine& operator <<( Engine& ar, bool ob)  THROWS (PersistException);
00479 
00489 template<class T>
00490 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (PersistException)
00491 {
00492         ar << (uint32)ob.size();
00493         for(unsigned int i=0; i < ob.size(); ++i)
00494                 ar << ob[i];
00495         return ar;
00496 }
00497 
00503 template<class T>
00504 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (PersistException)
00505 {
00506         ob.clear();
00507         uint32 siz;
00508         ar >> siz;
00509         ob.resize(siz);
00510         for(uint32 i=0; i < siz; ++i)
00511                 ar >> ob[i];
00512         return ar;
00513 }
00514 
00520 template<class T>
00521 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (PersistException)
00522 {
00523         ar << (uint32)ob.size();
00524   for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00525                 ar << *it;
00526         return ar;
00527 }
00528 
00534 template<class T>
00535 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (PersistException)
00536 {
00537         ob.clear();
00538         uint32 siz;
00539         ar >> siz;
00540         //ob.resize(siz);
00541         for(uint32 i=0; i < siz; ++i) {
00542         T node;
00543         ar >> node;
00544         ob.push_back(node);
00545                 //ar >> ob[i];
00546   }
00547         return ar;
00548 }
00549 
00555 template<class Key, class Value>
00556 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (PersistException)
00557 {
00558         ar << (uint32)ob.size();
00559         for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00560                 ar << it->first << it->second;
00561         return ar;
00562 }
00563 
00569 template<class Key, class Value>
00570 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (PersistException)
00571 {
00572         ob.clear();
00573         uint32 siz;
00574         ar >> siz;
00575         for(uint32 i=0; i < siz; ++i) {
00576                 Key a;
00577                 ar >> a;
00578                 ar >> ob[a];
00579         }
00580         return ar;
00581 }
00582 
00587 template<class x, class y>
00588 Engine& operator <<( Engine& ar, std::pair<x,y> &ob) THROWS (PersistException)
00589 {
00590         ar << ob.first << ob.second;
00591         return ar;
00592 }
00593 
00598 template<class x, class y>
00599 Engine& operator >>(Engine& ar, std::pair<x, y> &ob) THROWS (PersistException)
00600 {
00601         ar >> ob.first >> ob.second;
00602         return ar;
00603 }
00604 
00605 #ifdef  CCXX_NAMESPACES
00606 }
00607 #endif
00608 
00609 #endif
00610 

Generated on Sun Mar 21 21:43:15 2010 for GNU CommonC++ by doxygen 1.3.5