persist.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 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, you may use this file as part of a free software
00018 // library without restriction.  Specifically, if other files instantiate
00019 // templates or use macros or inline functions from this file, or you compile
00020 // this file and link it with other files to produce an executable, this
00021 // file does not by itself cause the resulting executable to be covered by
00022 // the GNU General Public License.  This exception does not however
00023 // invalidate any other reasons why the executable file might be covered by
00024 // the GNU General Public License.
00025 //
00026 // This exception applies only to the code released under the name GNU
00027 // Common C++.  If you copy code from other releases into a copy of GNU
00028 // Common C++, as the General Public License permits, the exception does
00029 // not apply to the code that you add in this way.  To avoid misleading
00030 // anyone as to the status of such modified files, you must delete
00031 // this exception notice from them.
00032 //
00033 // If you write modifications of your own for GNU Common C++, it is your choice
00034 // whether to permit this exception to apply to your modifications.
00035 // If you do not wish that, delete this exception notice.
00036 //
00037 
00043 #ifndef CCXX_PERSIST_H_
00044 #define CCXX_PERSIST_H_
00045 
00046 #ifndef CCXX_CONFIG_H_
00047 #include <cc++/config.h>
00048 #endif
00049 
00050 #ifndef CCXX_EXCEPTIONS_H_
00051 #include <cc++/exception.h>
00052 #endif
00053 
00054 #ifndef CCXX_MISSING_H_
00055 #include <cc++/missing.h>
00056 #endif
00057 
00058 #ifndef CCXX_STRING_H_
00059 #include <cc++/string.h>
00060 #endif
00061 
00062 #ifdef HAVE_ZLIB_H
00063 #ifndef NO_COMPRESSION
00064 #include <zlib.h>
00065 #endif
00066 #else
00067 #define NO_COMPRESSION
00068 #endif
00069 
00070 #include <iostream>
00071 #include <string>
00072 #include <vector>
00073 #include <deque>
00074 #include <map>
00075 
00076 #ifdef CCXX_NAMESPACES
00077 namespace ost {
00078 #define NS_PREFIX ost::
00079 #else
00080 #define NS_PREFIX
00081 #endif
00082 
00083 #ifdef  CCXX_EXCEPTIONS
00084 #ifdef  COMMON_STD_EXCEPTION
00085 
00086 class __EXPORT PersistException : public Exception
00087 {
00088 public:
00089         PersistException(const String &what) : Exception(what) {};
00090 };
00091 
00092 #else
00093 
00094 class __EXPORT PersistException
00095 {
00096 public:
00097         PersistException(const String& reason);
00098         inline const String& getString() const
00099                 {return Exception::getString();};
00100 
00101         virtual ~PersistException() {} throw();
00102 protected:
00103         String _what;
00104 };
00105 
00106 #endif
00107 #endif
00108 
00109 // This typedef allows us to declare NewBaseObjectFunction now
00110 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00111 
00120 class __EXPORT TypeManager
00121 {
00122 public:
00123 
00128         class Registration 
00129         {
00130         public:
00131                 Registration(const char* name, NewBaseObjectFunction func);
00132                 virtual ~Registration();
00133         private:
00134                 String myName;
00135         };
00136 
00140         static void add(const char* name, NewBaseObjectFunction construction);
00141 
00145         static void remove(const char* name);
00146 
00152         static BaseObject* createInstanceOf(const char* name);
00153 
00154         typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00155 };
00156 
00157 
00158 /*
00159  * The following defines are used to declare and define the relevant code
00160  * to allow a class to use the Persistence::Engine code.
00161  */
00162 
00163 #define DECLARE_PERSISTENCE(ClassType)                                  \
00164   public:                                                               \
00165         friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob);             \
00166         friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob);        \
00167         friend NS_PREFIX BaseObject *createNew##ClassType();                            \
00168         virtual const char* getPersistenceID() const;                   \
00169         static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00170 
00171 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName)                  \
00172   NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; }                      \
00173   const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00174   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob)                           \
00175         { ar >> (NS_PREFIX BaseObject &) ob; return ar; }                                     \
00176   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob)                          \
00177         { ar >> (NS_PREFIX BaseObject *&) ob; return ar; }                                    \
00178   NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob)                             \
00179         { ar << (NS_PREFIX BaseObject const *)&ob; return ar; }                       \
00180   NS_PREFIX TypeManager::Registration                                                 \
00181         ClassType::registrationFor##ClassType(FullyQualifiedName,             \
00182                                               createNew##ClassType);
00183 
00184 class Engine;
00185 
00205 class __EXPORT BaseObject
00206 {
00207 public:
00213          BaseObject();
00214 
00218          virtual ~BaseObject();
00219 
00223          virtual const char* getPersistenceID() const;
00224 
00230          virtual bool write(Engine& archive) const;
00231 
00237          virtual bool read(Engine& archive);
00238 };
00239 
00240 
00251 class __EXPORT Engine
00252 {
00253 public:
00257         enum EngineMode {
00258                 modeRead,
00259                 modeWrite
00260         };
00261 
00267         Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00268 
00273   void sync();
00274 
00275         virtual ~Engine();
00276 
00277 
00278         // Write operations
00279 
00283         void write(const BaseObject &object) THROWS (PersistException)
00284         { write(&object); };
00285 
00289         void write(const BaseObject *object) THROWS (PersistException);
00290 
00291         // writes supported primitive types
00292   // shortcut, to make the following more readable
00293 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00294         void write(int8 i)   THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00295         void write(uint8 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00296         void write(int16 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00297         void write(uint16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00298         void write(int32 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00299         void write(uint32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00300 #ifdef  HAVE_64_BITS
00301         void write(int64 i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00302         void write(uint64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00303 #endif
00304         void write(float i)  THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00305         void write(double i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
00306 #undef CCXX_ENGINEWRITE_REF
00307 
00308         void write(const String& str) THROWS (PersistException);
00309         void write(const std::string& str) THROWS (PersistException);
00310 
00311         // Every write operation boils down to one or more of these
00312         void writeBinary(const uint8* data, const uint32 size) THROWS (PersistException);
00313 
00314 
00315         // Read Operations
00316 
00320         void read(BaseObject &object) THROWS (PersistException);
00321 
00325         void read(BaseObject *&object) THROWS (PersistException);
00326 
00327         // reads supported primitive types
00328   // shortcut, to make the following more readable
00329 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00330         void read(int8& i)   THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00331         void read(uint8& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00332         void read(int16& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00333         void read(uint16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00334         void read(int32& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00335         void read(uint32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00336 #ifdef  HAVE_64_BITS
00337         void read(int64& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00338         void read(uint64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00339 #endif
00340         void read(float& i)  THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00341         void read(double& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
00342 #undef CCXX_ENGINEREAD_REF
00343 
00344         void read(String& str) THROWS (PersistException);
00345         void read(std::string& str) THROWS (PersistException);
00346 
00347         // Every read operation boild down to one or more of these
00348         void readBinary(uint8* data, uint32 size) THROWS (PersistException);
00349 
00350 private:
00355         void readObject(BaseObject* object) THROWS (PersistException);
00356 
00360         const String readClass() THROWS (PersistException);
00361 
00362 
00366         std::iostream& myUnderlyingStream;
00367 
00371         EngineMode myOperationalMode;
00372 
00376         typedef std::vector<BaseObject*>           ArchiveVector;
00377         typedef std::map<BaseObject const*, int32> ArchiveMap;
00378         typedef std::vector<String>                ClassVector;
00379         typedef std::map<String, int32>            ClassMap;
00380 
00381         ArchiveVector myArchiveVector;
00382         ArchiveMap myArchiveMap;
00383         ClassVector myClassVector;
00384         ClassMap myClassMap;
00385 
00386         // Compression support
00387 #ifndef NO_COMPRESSION
00388         z_stream myZStream;
00389         uint8* myCompressedDataBuffer;
00390         uint8* myUncompressedDataBuffer;
00391         uint8* myLastUncompressedDataRead;
00392 #endif
00393 };
00394 
00395 // Standard >> and << stream operators for BaseObject
00397 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob)      THROWS (PersistException);
00399 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob)      THROWS (PersistException);
00401 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (PersistException);
00403 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (PersistException);
00404 
00406 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (PersistException);
00408 __EXPORT Engine& operator <<( Engine& ar, int8 ob)  THROWS (PersistException);
00409 
00411 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (PersistException);
00413 __EXPORT Engine& operator <<( Engine& ar, uint8 ob)  THROWS (PersistException);
00414 
00416 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (PersistException);
00418 __EXPORT Engine& operator <<( Engine& ar, int16 ob)  THROWS (PersistException);
00419 
00421 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (PersistException);
00423 __EXPORT Engine& operator <<( Engine& ar, uint16 ob)  THROWS (PersistException);
00424 
00426 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (PersistException);
00428 __EXPORT Engine& operator <<( Engine& ar, int32 ob)  THROWS (PersistException);
00429 
00431 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (PersistException);
00433 __EXPORT Engine& operator <<( Engine& ar, uint32 ob)  THROWS (PersistException);
00434 
00435 #ifdef  HAVE_64_BITS
00436 
00437 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (PersistException);
00439 __EXPORT Engine& operator <<( Engine& ar, int64 ob)  THROWS (PersistException);
00440 
00442 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (PersistException);
00444 __EXPORT Engine& operator <<( Engine& ar, uint64 ob)  THROWS (PersistException);
00445 #endif
00446 
00448 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (PersistException);
00450 __EXPORT Engine& operator <<( Engine& ar, float ob)  THROWS (PersistException);
00451 
00453 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (PersistException);
00455 __EXPORT Engine& operator <<( Engine& ar, double ob)  THROWS (PersistException);
00456 
00458 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (PersistException);
00460 __EXPORT Engine& operator <<( Engine& ar, String ob)  THROWS (PersistException);
00461 
00463 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (PersistException);
00465 __EXPORT Engine& operator <<( Engine& ar, std::string ob)  THROWS (PersistException);
00466 
00468 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (PersistException);
00470 __EXPORT Engine& operator <<( Engine& ar, bool ob)  THROWS (PersistException);
00471 
00481 template<class T>
00482 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (PersistException)
00483 {
00484         ar << (uint32)ob.size();
00485         for(unsigned int i=0; i < ob.size(); ++i)
00486                 ar << ob[i];
00487         return ar;
00488 }
00489 
00495 template<class T>
00496 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (PersistException)
00497 {
00498         ob.clear();
00499         uint32 siz;
00500         ar >> siz;
00501         ob.resize(siz);
00502         for(uint32 i=0; i < siz; ++i)
00503                 ar >> ob[i];
00504         return ar;
00505 }
00506 
00512 template<class T>
00513 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (PersistException)
00514 {
00515         ar << (uint32)ob.size();
00516   for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00517                 ar << *it;
00518         return ar;
00519 }
00520 
00526 template<class T>
00527 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (PersistException)
00528 {
00529         ob.clear();
00530         uint32 siz;
00531         ar >> siz;
00532         //ob.resize(siz);
00533         for(uint32 i=0; i < siz; ++i) {
00534         T node;
00535         ar >> node;
00536         ob.push_back(node);
00537                 //ar >> ob[i];
00538   }
00539         return ar;
00540 }
00541 
00547 template<class Key, class Value>
00548 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (PersistException)
00549 {
00550         ar << (uint32)ob.size();
00551         for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00552                 ar << it->first << it->second;
00553         return ar;
00554 }
00555 
00561 template<class Key, class Value>
00562 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (PersistException)
00563 {
00564         ob.clear();
00565         uint32 siz;
00566         ar >> siz;
00567         for(uint32 i=0; i < siz; ++i) {
00568                 Key a;
00569                 ar >> a;
00570                 ar >> ob[a];
00571         }
00572         return ar;
00573 }
00574 
00579 template<class x, class y>
00580 Engine& operator <<( Engine& ar, std::pair<x,y> &ob) THROWS (PersistException)
00581 {
00582         ar << ob.first << ob.second;
00583         return ar;
00584 }
00585 
00590 template<class x, class y>
00591 Engine& operator >>(Engine& ar, std::pair<x, y> &ob) THROWS (PersistException)
00592 {
00593         ar >> ob.first >> ob.second;
00594         return ar;
00595 }
00596 
00597 #ifdef  CCXX_NAMESPACES
00598 }
00599 #endif
00600 
00601 #endif
00602 

Generated on Wed Feb 6 07:07:20 2008 for GNU CommonC++ by  doxygen 1.5.1