Google

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

persist.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 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 
00041 #ifndef __CCXX_PERSIST_H__
00042 #define __CCXX_PERSIST_H__
00043 
00044 #ifndef __CCXX_CONFIG_H__
00045 #include <cc++/config.h>
00046 #endif
00047 
00048 #ifndef __CCXX_MACROS_H__
00049 #include <cc++/macros.h>
00050 #else
00051 #ifdef  __CCXX_NAMESPACE_H__
00052 #include <cc++/macros.h>
00053 #endif
00054 #endif
00055 
00056 #ifdef  HAVE_ZLIB_H
00057 #include <zlib.h>
00058 #else
00059 #define NO_COMPRESSION
00060 #endif
00061 
00062 #include <iostream.h>
00063 #include <string>
00064 #include <vector>
00065 #include <map>
00066 
00067 #ifdef  __WIN32__
00068 class __EXPORT PersistException;
00069 class __EXPORT Engine;
00070 class __EXPORT TypeManager;
00071 class __EXPORT BaseObject;
00072 #endif
00073 
00074 using std::string;
00075 using std::map;
00076 using std::vector;
00077 
00078 class PersistException
00079 {
00080 public:
00081         PersistException(const string& reason);
00082         const string& GetMessage() const;
00083         virtual ~PersistException();
00084 protected:
00085         string myMessage;
00086 };
00087 
00088 class Engine;
00089 
00090 // This typedef allows us to declare NewBaseObjectFunction now
00091 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00092 
00101 class TypeManager
00102 {
00103 public:
00104         
00109         class Registration
00110         {
00111         public:
00112                 Registration(const char* name, NewBaseObjectFunction func)
00113                         : myName(name) { TypeManager::Add(name,func); }
00114                 ~Registration() { TypeManager::Remove(myName.c_str()); }
00115         private:
00116                 string myName;
00117         };
00118         
00122         static void Add(const char* name, NewBaseObjectFunction construction);
00123         
00127         static void Remove(const char* name);
00128         
00134         static BaseObject* CreateInstanceOf(const char* name);
00135         
00136         typedef map<string,NewBaseObjectFunction> StringFunctionMap;
00137 };
00138 
00139 
00140 /*
00141  * The following defines are used to declare and define the relevant code
00142  * to allow a class to use the Persistence::Engine code.
00143  */
00144 
00145 #define DECLARE_PERSISTENCE(ClassType)                                  \
00146   public:                                                               \
00147     friend Engine& operator>>(Engine& ar, ClassType *&ob);              \
00148     friend Engine& operator<<(Engine& ar, ClassType const *&ob);        \
00149     friend BaseObject *CreateNew##ClassType();                          \
00150     virtual const char* GetPersistenceID() const;                       \
00151     static TypeManager::Registration RegistrationFor##ClassType;
00152 
00153 #define IMPLEMENT_PERSISTENCE(ClassType,FullyQualifiedName)                   \
00154   BaseObject *CreateNew##ClassType() { return new ClassType; }                \
00155   const char* ClassType::GetPersistenceID()const {return FullyQualifiedName;} \
00156   Engine& operator>>(Engine& ar, ClassType *&ob)                              \
00157     { ar >> (BaseObject *&) ob; return ar; }                                  \
00158   Engine& operator<<(Engine& ar, ClassType const *ob)                         \
00159     { ar << (BaseObject const *)ob; return ar; }                              \
00160   TypeManager::Registration                                                   \
00161         ClassType::RegistrationFor##ClassType(FullyQualifiedName,             \
00162                                               CreateNew##ClassType);
00163 
00178 class BaseObject
00179 {
00180 public:
00184         virtual const char* GetPersistenceID() const;
00185         
00191         BaseObject();
00192         
00196         virtual ~BaseObject();
00197         
00203         virtual bool Write(Engine& archive) const;
00204 
00210         virtual bool Read(Engine& archive);
00211 };
00212 
00213 
00224 class Engine
00225 {
00226 public:
00231         class Exception : public PersistException
00232         {
00233         public:
00234                 Exception(const string &reason) : PersistException(reason) {}
00235         };
00236         
00240         enum EngineMode
00241         {
00242                 modeRead,
00243                 modeWrite
00244         };
00245         
00251         Engine(iostream& stream, EngineMode mode) THROWS (PersistException);
00252         
00257         ~Engine();
00258 
00259 
00260         // Write operations
00261         void Write(const BaseObject *object) THROWS (Exception);
00262         /*
00263          * shortcut, to make the following more readable
00264          */
00265 #define _ENGINEWRITE_REF(valref) WriteBinary((const uint8*)&valref,sizeof(valref))
00266         void Write(int8 i)   THROWS (Exception) { _ENGINEWRITE_REF(i); }
00267         void Write(uint8 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00268         void Write(int16 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00269         void Write(uint16 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00270         void Write(int32 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00271         void Write(uint32 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00272         void Write(int64 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00273         void Write(uint64 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00274         void Write(float i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00275         void Write(double i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00276 #undef _ENGINEWRITE_REF
00277 
00278         void Write(const string& str) THROWS (Exception);
00279         // Every write operation boils down to one or more of theses
00280         void WriteBinary(const uint8* data, const uint32 size) THROWS (Exception);
00281         
00282         // Read Operations
00283         
00284         void Read(BaseObject *&object) THROWS (Exception);
00285 #define _ENGINEREAD_REF(valref) ReadBinary((uint8*)&valref,sizeof(valref))
00286         void Read(int8& i)   THROWS (Exception) { _ENGINEREAD_REF(i); }
00287         void Read(uint8& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00288         void Read(int16& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00289         void Read(uint16& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00290         void Read(int32& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00291         void Read(uint32& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00292         void Read(int64& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00293         void Read(uint64& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00294         void Read(float& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00295         void Read(double& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00296 #undef _ENGINEREAD_REF
00297 
00298         void Read(string& str) THROWS (Exception);
00299         // Every read operation boild down to one or more of these
00300         void ReadBinary(uint8* data, uint32 size) THROWS (Exception);
00301 
00302 private:
00306         iostream& myUnderlyingStream;
00307         
00311         EngineMode myOperationalMode;
00312 
00316         typedef vector<BaseObject*>           ArchiveVector;
00317         typedef map<BaseObject const*, int32> ArchiveMap;
00318         typedef vector<string>                ClassVector;
00319         typedef map<string, int32>            ClassMap;
00320         
00321         ArchiveVector myArchiveVector;
00322         ArchiveMap myArchiveMap;
00323         ClassVector myClassVector;
00324         ClassMap myClassMap;
00325 
00326         // Compression support
00327 #ifndef NO_COMPRESSION
00328         z_stream myZStream;
00329         uint8* myCompressedDataBuffer;
00330         uint8* myUncompressedDataBuffer;
00331         uint8* myLastUncompressedDataRead;
00332 #endif
00333 };
00334 
00335 // Standard >> and << stream operators for BaseObject
00336 Engine& operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00337 Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00338 
00339 Engine& operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00340 Engine& operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00341 
00342 Engine& operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00343 Engine& operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00344 
00345 Engine& operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00346 Engine& operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00347 
00348 Engine& operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00349 Engine& operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00350 
00351 Engine& operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00352 Engine& operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00353 
00354 Engine& operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00355 Engine& operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00356 
00357 Engine& operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00358 Engine& operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00359 
00360 Engine& operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00361 Engine& operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00362 
00363 Engine& operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00364 Engine& operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00365 
00366 Engine& operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00367 Engine& operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00368 
00369 Engine& operator >>( Engine& ar, string& ob) THROWS (Engine::Exception);
00370 Engine& operator <<( Engine& ar, string ob)  THROWS (Engine::Exception);
00371 
00372 Engine& operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00373 Engine& operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00374 
00383 template<class T>
00384 Engine& operator <<( Engine& ar, vector<T> const& ob) THROWS (Engine::Exception)
00385 {
00386         ar << ob.size();
00387         for(int i=0; i < ob.size(); ++i)
00388                 ar << ob[i];
00389         return ar;
00390 }
00391 
00396 template<class T>
00397 Engine& operator >>( Engine& ar, vector<T>& ob) THROWS (Engine::Exception)
00398 {
00399         ob.clear();
00400         uint32 siz;
00401         ar >> siz;
00402         ob.resize(siz);
00403         for(uint32 i=0; i < siz; ++i)
00404                 ar >> ob[i];
00405         return ar;
00406 }
00407 
00412 template<class Key, class Value>
00413 Engine& operator <<( Engine& ar, map<Key,Value> const & ob) THROWS (Engine::Exception)
00414 {
00415         ar << ob.size();
00416         for(map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00417                 ar << it->first << it->second;
00418         return ar;
00419 }
00420 
00425 template<class Key, class Value>
00426 Engine& operator >>( Engine& ar, map<Key,Value>& ob) THROWS (Engine::Exception)
00427 {
00428         ob.clear();
00429         uint32 siz;
00430         ar >> siz;
00431         for(uint32 i=0; i < siz; ++i) {
00432                 Key a;
00433                 ar >> a;
00434                 ar >> ob[a];
00435         }
00436         return ar;
00437 }
00438 
00439 #ifdef  __CCXX_NAMESPACE_H__
00440 #undef  __CCXX_NAMESPACE_H__
00441 #include <cc++/namespace.h>
00442 #endif
00443 
00444 #endif
00445 

Generated at Fri Mar 23 10:47:54 2001 for CommonC++ by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000