Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

persist.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2002 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 to the GNU General Public License, permission is 
00018 // granted for additional uses of the text contained in its release 
00019 // of Common C++.
00020 // 
00021 // The exception is that, if you link the Common C++ library with other
00022 // files to produce an executable, this does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public License.
00024 // Your use of that executable is in no way restricted on account of
00025 // linking the Common C++ library code into it.
00026 //
00027 // This exception does not however invalidate any other reasons why
00028 // the executable file might be covered by the GNU General Public License.
00029 // 
00030 // This exception applies only to the code released under the 
00031 // name Common C++.  If you copy code from other releases into a copy of
00032 // Common C++, as the General Public License permits, the exception does
00033 // not apply to the code that you add in this way.  To avoid misleading
00034 // anyone as to the status of such modified files, you must delete
00035 // this exception notice from them.
00036 // 
00037 // If you write modifications of your own for Common C++, it is your choice
00038 // whether to permit this exception to apply to your modifications.
00039 // If you do not wish that, delete this exception notice.
00040 
00046 #ifndef CCXX_PERSIST_H_
00047 #define CCXX_PERSIST_H_
00048 
00049 #ifndef CCXX_CONFIG_H_
00050 #include <cc++/config.h>
00051 #endif
00052 
00053 #ifndef CCXX_EXCEPTIONS_H_
00054 #include <cc++/exception.h>
00055 #endif
00056 
00057 #ifndef CCXX_MISSING_H_
00058 #include <cc++/missing.h>
00059 #endif
00060 
00061 #ifndef CCXX_STRING_H_
00062 #include <cc++/string.h>
00063 #endif
00064 
00065 #ifdef HAVE_ZLIB_H
00066 #ifndef NO_COMPRESSION
00067 #include <zlib.h>
00068 #endif
00069 #else
00070 #define NO_COMPRESSION
00071 #endif
00072 
00073 #include <iostream>
00074 #include <string>
00075 #include <vector>
00076 #include <deque>
00077 #include <map>
00078 
00079 #ifdef CCXX_NAMESPACES
00080 namespace ost {
00081 #define NS_PREFIX ost::
00082 #else
00083 #define NS_PREFIX
00084 #endif
00085 
00086 #ifdef  CCXX_EXCEPTIONS
00087 #ifdef  COMMON_STD_EXCEPTION
00088 
00089 class __EXPORT PersistException : public Exception
00090 {
00091 public:
00092         PersistException(const String &what) : Exception(what) {};
00093 };
00094 
00095 #else
00096 
00097 class __EXPORT PersistException
00098 {
00099 public:
00100         PersistException(const String& reason);
00101         inline const String& getString() const
00102                 {return Exception::getString();};
00103 
00104         virtual ~PersistException() {} throw();
00105 protected:
00106         String _what;
00107 };
00108 
00109 #endif
00110 #endif
00111 
00112 // This typedef allows us to declare NewBaseObjectFunction now
00113 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00114 
00123 class __EXPORT TypeManager
00124 {
00125 public:
00126         
00131         class Registration
00132         {
00133         public:
00134                 Registration(const char* name, NewBaseObjectFunction func)
00135                         : myName(name) { TypeManager::add(name,func); }
00136                 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00137         private:
00138                 String myName;
00139         };
00140         
00144         static void add(const char* name, NewBaseObjectFunction construction);
00145         
00149         static void remove(const char* name);
00150         
00156         static BaseObject* createInstanceOf(const char* name);
00157         
00158         typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00159 };
00160 
00161 
00162 /*
00163  * The following defines are used to declare and define the relevant code
00164  * to allow a class to use the Persistence::Engine code.
00165  */
00166 
00167 #define DECLARE_PERSISTENCE(ClassType)                                  \
00168   public:                                                               \
00169     friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob);         \
00170     friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob);    \
00171     friend NS_PREFIX BaseObject *createNew##ClassType();                                \
00172     virtual const char* getPersistenceID() const;                       \
00173     static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00174 
00175 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName)                  \
00176   NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; }                      \
00177   const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00178   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob)                           \
00179     { ar >> (NS_PREFIX BaseObject &) ob; return ar; }                                 \
00180   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob)                          \
00181     { ar >> (NS_PREFIX BaseObject *&) ob; return ar; }                                \
00182   NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob)                             \
00183     { ar << (NS_PREFIX BaseObject const *)&ob; return ar; }                           \
00184   NS_PREFIX TypeManager::Registration                                                 \
00185         ClassType::registrationFor##ClassType(FullyQualifiedName,             \
00186                                               createNew##ClassType);
00187 
00188 class Engine;
00189 
00209 class __EXPORT BaseObject
00210 {
00211 public:
00217          BaseObject();
00218         
00222          virtual ~BaseObject();
00223         
00227          virtual const char* getPersistenceID() const;
00228         
00234          virtual bool write(Engine& archive) const;
00235 
00241          virtual bool read(Engine& archive);
00242 };
00243 
00244 
00256 class __EXPORT Engine
00257 {
00258 public:
00263 #ifdef  CCXX_EXCEPTIONS
00264         class Exception : public PersistException
00265         {
00266         public:
00267                 Exception(const String &reason);
00268         };
00269 #endif
00270         
00274         enum EngineMode
00275         {
00276                 modeRead,
00277                 modeWrite
00278         };
00279         
00285         Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00286         
00291   void sync();
00292   
00293         virtual ~Engine();
00294 
00295 
00296         // Write operations
00297 
00301         void write(const BaseObject &object) THROWS (Exception)
00302         { write(&object); };
00303 
00307         void write(const BaseObject *object) THROWS (Exception);
00308 
00309         // writes supported primitive types
00310   // shortcut, to make the following more readable
00311 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00312         void write(int8 i)   THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00313         void write(uint8 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00314         void write(int16 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00315         void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00316         void write(int32 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00317         void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00318 #ifdef  HAVE_64_BITS
00319         void write(int64 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00320         void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00321 #endif
00322         void write(float i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00323         void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00324 #undef CCXX_ENGINEWRITE_REF
00325 
00326         void write(const String& str) THROWS (Exception);
00327         void write(const std::string& str) THROWS (Exception);
00328 
00329         // Every write operation boils down to one or more of these
00330         void writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00331 
00332 
00333         // Read Operations
00334 
00338         void read(BaseObject &object) THROWS (Exception);
00339 
00343         void read(BaseObject *&object) THROWS (Exception);
00344 
00345         // reads supported primitive types
00346   // shortcut, to make the following more readable
00347 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00348         void read(int8& i)   THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00349         void read(uint8& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00350         void read(int16& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00351         void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00352         void read(int32& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00353         void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00354 #ifdef  HAVE_64_BITS
00355         void read(int64& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00356         void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00357 #endif
00358         void read(float& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00359         void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00360 #undef CCXX_ENGINEREAD_REF
00361 
00362         void read(String& str) THROWS (Exception);
00363         void read(std::string& str) THROWS (Exception);
00364 
00365         // Every read operation boild down to one or more of these
00366         void readBinary(uint8* data, uint32 size) THROWS (Exception);
00367 
00368 private:
00373   void readObject(BaseObject* object);
00374 
00378   const String readClass();
00379 
00380 
00384         std::iostream& myUnderlyingStream;
00385         
00389         EngineMode myOperationalMode;
00390 
00394         typedef std::vector<BaseObject*>           ArchiveVector;
00395         typedef std::map<BaseObject const*, int32> ArchiveMap;
00396         typedef std::vector<String>                ClassVector;
00397         typedef std::map<String, int32>            ClassMap;
00398         
00399         ArchiveVector myArchiveVector;
00400         ArchiveMap myArchiveMap;
00401         ClassVector myClassVector;
00402         ClassMap myClassMap;
00403 
00404         // Compression support
00405 #ifndef NO_COMPRESSION
00406         z_stream myZStream;
00407         uint8* myCompressedDataBuffer;
00408         uint8* myUncompressedDataBuffer;
00409         uint8* myLastUncompressedDataRead;
00410 #endif
00411 };
00412 
00413 // Standard >> and << stream operators for BaseObject
00415 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob)      THROWS (Engine::Exception);
00417 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00419 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00421 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00422 
00424 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00426 __EXPORT Engine& operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00427 
00429 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00431 __EXPORT Engine& operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00432 
00434 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00436 __EXPORT Engine& operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00437 
00439 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00441 __EXPORT Engine& operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00442 
00444 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00446 __EXPORT Engine& operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00447 
00449 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00451 __EXPORT Engine& operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00452 
00453 #ifdef  HAVE_64_BITS
00454 
00455 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00457 __EXPORT Engine& operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00458 
00460 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00462 __EXPORT Engine& operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00463 #endif
00464 
00466 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00468 __EXPORT Engine& operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00469 
00471 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00473 __EXPORT Engine& operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00474 
00476 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (Engine::Exception);
00478 __EXPORT Engine& operator <<( Engine& ar, String ob)  THROWS (Engine::Exception);
00479 
00481 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00483 __EXPORT Engine& operator <<( Engine& ar, std::string ob)  THROWS (Engine::Exception);
00484 
00486 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00488 __EXPORT Engine& operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00489 
00499 template<class T>
00500 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00501 {
00502         ar << (uint32)ob.size();
00503         for(unsigned int i=0; i < ob.size(); ++i)
00504                 ar << ob[i];
00505         return ar;
00506 }
00507 
00513 template<class T>
00514 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00515 {
00516         ob.clear();
00517         uint32 siz;
00518         ar >> siz;
00519         ob.resize(siz);
00520         for(uint32 i=0; i < siz; ++i)
00521                 ar >> ob[i];
00522         return ar;
00523 }
00524 
00530 template<class T>
00531 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00532 {
00533         ar << (uint32)ob.size();
00534   for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00535                 ar << *it;
00536         return ar;
00537 }
00538 
00544 template<class T>
00545 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception)
00546 {
00547         ob.clear();
00548         uint32 siz;
00549         ar >> siz;
00550         //ob.resize(siz);
00551         for(uint32 i=0; i < siz; ++i)
00552   {
00553     T node;
00554     ar >> node;
00555     ob.push_back(node);
00556                 //ar >> ob[i];
00557   }
00558         return ar;
00559 }
00560 
00566 template<class Key, class Value>
00567 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00568 {
00569         ar << (uint32)ob.size();
00570         for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00571                 ar << it->first << it->second;
00572         return ar;
00573 }
00574 
00580 template<class Key, class Value>
00581 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00582 {
00583         ob.clear();
00584         uint32 siz;
00585         ar >> siz;
00586         for(uint32 i=0; i < siz; ++i) {
00587                 Key a;
00588                 ar >> a;
00589                 ar >> ob[a];
00590         }
00591         return ar;
00592 }
00593 
00594 #ifdef  CCXX_NAMESPACES
00595 }
00596 #endif
00597 
00598 #endif
00599 

Generated on Tue Jan 18 14:32:37 2005 for GNU CommonC++ by  doxygen 1.3.9.1