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-2001 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 #ifndef NO_COMPRESSION
00058 #include <zlib.h>
00059 #endif
00060 #else
00061 #define NO_COMPRESSION
00062 #endif
00063 
00064 #include <iostream>
00065 #include <string>
00066 #include <vector>
00067 #include <map>
00068 
00069 #if defined(__WIN32__)
00070 class __EXPORT PersistException;
00071 class __EXPORT Engine;
00072 class __EXPORT TypeManager;
00073 class __EXPORT BaseObject;
00074 #endif
00075 
00076 class PersistException
00077 {
00078 public:
00079         __MEMBER_EXPORT PersistException(const std::string& reason);
00080         __MEMBER_EXPORT const std::string& GetMessage() const;
00081         __MEMBER_EXPORT virtual ~PersistException();
00082 protected:
00083         std::string myMessage;
00084 };
00085 
00086 // This typedef allows us to declare NewBaseObjectFunction now
00087 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00088 
00097 class TypeManager
00098 {
00099 public:
00100         
00105         class Registration
00106         {
00107         public:
00108                 Registration(const char* name, NewBaseObjectFunction func)
00109                         : myName(name) { TypeManager::Add(name,func); }
00110                 ~Registration() { TypeManager::Remove(myName.c_str()); }
00111         private:
00112                 std::string myName;
00113         };
00114         
00118         __MEMBER_EXPORT static void Add(const char* name, NewBaseObjectFunction construction);
00119         
00123         __MEMBER_EXPORT static void Remove(const char* name);
00124         
00130         static BaseObject* CreateInstanceOf(const char* name);
00131         
00132         typedef std::map<std::string,NewBaseObjectFunction> StringFunctionMap;
00133 };
00134 
00135 
00136 /*
00137  * The following defines are used to declare and define the relevant code
00138  * to allow a class to use the Persistence::Engine code.
00139  */
00140 
00141 #define DECLARE_PERSISTENCE(ClassType)                                  \
00142   public:                                                               \
00143     friend Engine& operator>>(Engine& ar, ClassType *&ob);              \
00144     friend Engine& operator<<(Engine& ar, ClassType const *&ob);        \
00145     friend BaseObject *CreateNew##ClassType();                          \
00146     virtual const char* GetPersistenceID() const;                       \
00147     static TypeManager::Registration RegistrationFor##ClassType;
00148 
00149 #define IMPLEMENT_PERSISTENCE(ClassType,FullyQualifiedName)                   \
00150   BaseObject *CreateNew##ClassType() { return new ClassType; }                \
00151   const char* ClassType::GetPersistenceID()const {return FullyQualifiedName;} \
00152   Engine& operator>>(Engine& ar, ClassType *&ob)                              \
00153     { ar >> (BaseObject *&) ob; return ar; }                                  \
00154   Engine& operator<<(Engine& ar, ClassType const *ob)                         \
00155     { ar << (BaseObject const *)ob; return ar; }                              \
00156   TypeManager::Registration                                                   \
00157         ClassType::RegistrationFor##ClassType(FullyQualifiedName,             \
00158                                               CreateNew##ClassType);
00159 
00160 class Engine;
00161 
00176 class __EXPORT BaseObject
00177 {
00178 public:
00184         BaseObject();
00185         
00189         virtual ~BaseObject();
00190         
00194         virtual const char* GetPersistenceID() const;
00195         
00201         virtual bool Write(Engine& archive) const;
00202 
00208         virtual bool Read(Engine& archive);
00209 };
00210 
00211 
00222 class Engine
00223 {
00224 public:
00229         class Exception : public PersistException
00230         {
00231         public:
00232                 Exception(const std::string &reason) : PersistException(reason) {}
00233         };
00234         
00238         enum EngineMode
00239         {
00240                 modeRead,
00241                 modeWrite
00242         };
00243         
00249         __MEMBER_EXPORT Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00250         
00255         __MEMBER_EXPORT ~Engine();
00256 
00257 
00258         // Write operations
00259         void Write(const BaseObject *object) THROWS (Exception);
00260         /*
00261          * shortcut, to make the following more readable
00262          */
00263 #define _ENGINEWRITE_REF(valref) WriteBinary((const uint8*)&valref,sizeof(valref))
00264         void Write(int8 i)   THROWS (Exception) { _ENGINEWRITE_REF(i); }
00265         void Write(uint8 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00266         void Write(int16 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00267         void Write(uint16 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00268         void Write(int32 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00269         void Write(uint32 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00270         void Write(int64 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00271         void Write(uint64 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00272         void Write(float i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00273         void Write(double i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00274 #undef _ENGINEWRITE_REF
00275 
00276         void Write(const std::string& str) THROWS (Exception);
00277         // Every write operation boils down to one or more of theses
00278         void WriteBinary(const uint8* data, const uint32 size) THROWS (Exception);
00279         
00280         // Read Operations
00281         
00282         void Read(BaseObject *&object) THROWS (Exception);
00283 #define _ENGINEREAD_REF(valref) ReadBinary((uint8*)&valref,sizeof(valref))
00284         void Read(int8& i)   THROWS (Exception) { _ENGINEREAD_REF(i); }
00285         void Read(uint8& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00286         void Read(int16& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00287         void Read(uint16& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00288         void Read(int32& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00289         void Read(uint32& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00290         void Read(int64& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00291         void Read(uint64& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00292         void Read(float& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00293         void Read(double& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00294 #undef _ENGINEREAD_REF
00295 
00296         void Read(std::string& str) THROWS (Exception);
00297         // Every read operation boild down to one or more of these
00298         void ReadBinary(uint8* data, uint32 size) THROWS (Exception);
00299 
00300 private:
00304         std::iostream& myUnderlyingStream;
00305         
00309         EngineMode myOperationalMode;
00310 
00314         typedef std::vector<BaseObject*>           ArchiveVector;
00315         typedef std::map<BaseObject const*, int32> ArchiveMap;
00316         typedef std::vector<std::string>                ClassVector;
00317         typedef std::map<std::string, int32>            ClassMap;
00318         
00319         ArchiveVector myArchiveVector;
00320         ArchiveMap myArchiveMap;
00321         ClassVector myClassVector;
00322         ClassMap myClassMap;
00323 
00324         // Compression support
00325 #ifndef NO_COMPRESSION
00326         z_stream myZStream;
00327         uint8* myCompressedDataBuffer;
00328         uint8* myUncompressedDataBuffer;
00329         uint8* myLastUncompressedDataRead;
00330 #endif
00331 };
00332 
00333 // Standard >> and << stream operators for BaseObject
00334 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00335 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00336 
00337 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00338 __EXPORT Engine& operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00339 
00340 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00341 __EXPORT Engine& operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00342 
00343 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00344 __EXPORT Engine& operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00345 
00346 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00347 __EXPORT Engine& operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00348 
00349 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00350 __EXPORT Engine& operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00351 
00352 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00353 __EXPORT Engine& operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00354 
00355 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00356 __EXPORT Engine& operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00357 
00358 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00359 __EXPORT Engine& operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00360 
00361 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00362 __EXPORT Engine& operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00363 
00364 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00365 __EXPORT Engine& operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00366 
00367 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00368 __EXPORT Engine& operator <<( Engine& ar, std::string ob)  THROWS (Engine::Exception);
00369 
00370 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00371 __EXPORT Engine& operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00372 
00381 template<class T>
00382 Engine& operator <<( Engine& ar, std::vector<T> const& ob) THROWS (Engine::Exception)
00383 {
00384         ar << (uint32)ob.size();
00385         for(uint i=0; i < ob.size(); ++i)
00386                 ar << ob[i];
00387         return ar;
00388 }
00389 
00394 template<class T>
00395 Engine& operator >>( Engine& ar, std::vector<T>& ob) THROWS (Engine::Exception)
00396 {
00397         ob.clear();
00398         uint32 siz;
00399         ar >> siz;
00400         ob.resize(siz);
00401         for(uint32 i=0; i < siz; ++i)
00402                 ar >> ob[i];
00403         return ar;
00404 }
00405 
00410 template<class Key, class Value>
00411 Engine& operator <<( Engine& ar, std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00412 {
00413         ar << (uint32)ob.size();
00414         for(std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00415                 ar << it->first << it->second;
00416         return ar;
00417 }
00418 
00423 template<class Key, class Value>
00424 Engine& operator >>( Engine& ar, std::map<Key,Value>& ob) THROWS (Engine::Exception)
00425 {
00426         ob.clear();
00427         uint32 siz;
00428         ar >> siz;
00429         for(uint32 i=0; i < siz; ++i) {
00430                 Key a;
00431                 ar >> a;
00432                 ar >> ob[a];
00433         }
00434         return ar;
00435 }
00436 
00437 #ifdef  __CCXX_NAMESPACE_H__
00438 #undef  __CCXX_NAMESPACE_H__
00439 #include <cc++/namespace.h>
00440 #endif
00441 
00442 #endif
00443 

Generated at Thu Oct 4 15:32:58 2001 for CommonC++ by doxygen1.2.5 written by Dimitri van Heesch, © 1997-2001