Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   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_STRCHAR_H__
00049 #include <cc++/persist.h>
00050 #endif
00051 
00052 #ifdef HAVE_ZLIB_H
00053 #ifndef NO_COMPRESSION
00054 #include <zlib.h>
00055 #endif
00056 #else
00057 #define NO_COMPRESSION
00058 #endif
00059 
00060 #include <iostream>
00061 #include <string>
00062 #include <vector>
00063 #include <map>
00064 
00065 #ifdef __NAMESPACES__
00066 namespace ost {
00067 #endif
00068 
00069 class PersistException
00070 {
00071 public:
00072         CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const std::string& reason);
00073         CCXX_MEMBER_EXPORT(const std::string&) GetMessage() const;
00074         CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00075 protected:
00076         std::string myMessage;
00077 };
00078 
00079 // This typedef allows us to declare NewBaseObjectFunction now
00080 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00081 
00090 class TypeManager
00091 {
00092 public:
00093         
00098         class Registration
00099         {
00100         public:
00101                 Registration(const char* name, NewBaseObjectFunction func)
00102                         : myName(name) { TypeManager::Add(name,func); }
00103                 virtual ~Registration() { TypeManager::Remove(myName.c_str()); }
00104         private:
00105                 std::string myName;
00106         };
00107         
00111         CCXX_MEMBER_EXPORT(static void) Add(const char* name, NewBaseObjectFunction construction);
00112         
00116         CCXX_MEMBER_EXPORT(static void) Remove(const char* name);
00117         
00123         CCXX_EXPORT(static BaseObject*) CreateInstanceOf(const char* name);
00124         
00125         typedef std::map<std::string,NewBaseObjectFunction> StringFunctionMap;
00126 };
00127 
00128 
00129 /*
00130  * The following defines are used to declare and define the relevant code
00131  * to allow a class to use the Persistence::Engine code.
00132  */
00133 
00134 #define DECLARE_PERSISTENCE(ClassType)                                  \
00135   public:                                                               \
00136     friend Engine& operator>>(Engine& ar, ClassType *&ob);              \
00137     friend Engine& operator<<(Engine& ar, ClassType const *&ob);        \
00138     friend BaseObject *CreateNew##ClassType();                          \
00139     virtual const char* GetPersistenceID() const;                       \
00140     static TypeManager::Registration RegistrationFor##ClassType;
00141 
00142 #define IMPLEMENT_PERSISTENCE(ClassType,FullyQualifiedName)                   \
00143   BaseObject *CreateNew##ClassType() { return new ClassType; }                \
00144   const char* ClassType::GetPersistenceID()const {return FullyQualifiedName;} \
00145   Engine& operator>>(Engine& ar, ClassType *&ob)                              \
00146     { ar >> (BaseObject *&) ob; return ar; }                                  \
00147   Engine& operator<<(Engine& ar, ClassType const *ob)                         \
00148     { ar << (BaseObject const *)ob; return ar; }                              \
00149   TypeManager::Registration                                                   \
00150         ClassType::RegistrationFor##ClassType(FullyQualifiedName,             \
00151                                               CreateNew##ClassType);
00152 
00153 class Engine;
00154 
00169 class BaseObject
00170 {
00171 public:
00177         CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00178         
00182         CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00183         
00187         CCXX_MEMBER_EXPORT(virtual const char*) GetPersistenceID() const;
00188         
00194         CCXX_MEMBER_EXPORT(virtual bool) Write(Engine& archive) const;
00195 
00201         CCXX_MEMBER_EXPORT(virtual bool) Read(Engine& archive);
00202 };
00203 
00204 
00215 class Engine
00216 {
00217 public:
00222         class Exception : public PersistException
00223         {
00224         public:
00225                 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const std::string &reason) : PersistException(reason) {}
00226         };
00227         
00231         enum EngineMode
00232         {
00233                 modeRead,
00234                 modeWrite
00235         };
00236         
00242         CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00243         
00248         CCXX_MEMBER_EXPORT(virtual) ~Engine();
00249 
00250 
00251         // Write operations
00252         CCXX_MEMBER_EXPORT(void) Write(const BaseObject *object) THROWS (Exception);
00253         /*
00254          * shortcut, to make the following more readable
00255          */
00256 #define _ENGINEWRITE_REF(valref) WriteBinary((const uint8*)&valref,sizeof(valref))
00257         void Write(int8 i)   THROWS (Exception) { _ENGINEWRITE_REF(i); }
00258         void Write(uint8 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00259         void Write(int16 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00260         void Write(uint16 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00261         void Write(int32 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00262         void Write(uint32 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00263         void Write(int64 i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00264         void Write(uint64 i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00265         void Write(float i)  THROWS (Exception) { _ENGINEWRITE_REF(i); }
00266         void Write(double i) THROWS (Exception) { _ENGINEWRITE_REF(i); }
00267 #undef _ENGINEWRITE_REF
00268 
00269         CCXX_MEMBER_EXPORT(void) Write(const std::string& str) THROWS (Exception);
00270         // Every write operation boils down to one or more of theses
00271         CCXX_MEMBER_EXPORT(void) WriteBinary(const uint8* data, const uint32 size) THROWS (Exception);
00272         
00273         // Read Operations
00274         
00275         CCXX_MEMBER_EXPORT(void) Read(BaseObject *&object) THROWS (Exception);
00276 #define _ENGINEREAD_REF(valref) ReadBinary((uint8*)&valref,sizeof(valref))
00277         void Read(int8& i)   THROWS (Exception) { _ENGINEREAD_REF(i); }
00278         void Read(uint8& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00279         void Read(int16& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00280         void Read(uint16& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00281         void Read(int32& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00282         void Read(uint32& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00283         void Read(int64& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00284         void Read(uint64& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00285         void Read(float& i)  THROWS (Exception) { _ENGINEREAD_REF(i); }
00286         void Read(double& i) THROWS (Exception) { _ENGINEREAD_REF(i); }
00287 #undef _ENGINEREAD_REF
00288 
00289         CCXX_MEMBER_EXPORT(void) Read(std::string& str) THROWS (Exception);
00290         // Every read operation boild down to one or more of these
00291         CCXX_MEMBER_EXPORT(void) ReadBinary(uint8* data, uint32 size) THROWS (Exception);
00292 
00293 private:
00297         std::iostream& myUnderlyingStream;
00298         
00302         EngineMode myOperationalMode;
00303 
00307         typedef std::vector<BaseObject*>           ArchiveVector;
00308         typedef std::map<BaseObject const*, int32> ArchiveMap;
00309         typedef std::vector<std::string>                ClassVector;
00310         typedef std::map<std::string, int32>            ClassMap;
00311         
00312         ArchiveVector myArchiveVector;
00313         ArchiveMap myArchiveMap;
00314         ClassVector myClassVector;
00315         ClassMap myClassMap;
00316 
00317         // Compression support
00318 #ifndef NO_COMPRESSION
00319         z_stream myZStream;
00320         uint8* myCompressedDataBuffer;
00321         uint8* myUncompressedDataBuffer;
00322         uint8* myLastUncompressedDataRead;
00323 #endif
00324 };
00325 
00326 // Standard >> and << stream operators for BaseObject
00327 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00328 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00329 
00330 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00331 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00332 
00333 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00334 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00335 
00336 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00337 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00338 
00339 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00340 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00341 
00342 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00343 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00344 
00345 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00346 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00347 
00348 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00349 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00350 
00351 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00352 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00353 
00354 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00355 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00356 
00357 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00358 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00359 
00360 CCXX_EXPORT(Engine&) operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00361 CCXX_EXPORT(Engine&) operator <<( Engine& ar, std::string ob)  THROWS (Engine::Exception);
00362 
00363 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00364 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00365 
00374 template<class T>
00375 Engine& operator <<( Engine& ar, std::vector<T> const& ob) THROWS (Engine::Exception)
00376 {
00377         ar << (uint32)ob.size();
00378         for(uint i=0; i < ob.size(); ++i)
00379                 ar << ob[i];
00380         return ar;
00381 }
00382 
00387 template<class T>
00388 Engine& operator >>( Engine& ar, std::vector<T>& ob) THROWS (Engine::Exception)
00389 {
00390         ob.clear();
00391         uint32 siz;
00392         ar >> siz;
00393         ob.resize(siz);
00394         for(uint32 i=0; i < siz; ++i)
00395                 ar >> ob[i];
00396         return ar;
00397 }
00398 
00403 template<class Key, class Value>
00404 Engine& operator <<( Engine& ar, std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00405 {
00406         ar << (uint32)ob.size();
00407         for(std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00408                 ar << it->first << it->second;
00409         return ar;
00410 }
00411 
00416 template<class Key, class Value>
00417 Engine& operator >>( Engine& ar, std::map<Key,Value>& ob) THROWS (Engine::Exception)
00418 {
00419         ob.clear();
00420         uint32 siz;
00421         ar >> siz;
00422         for(uint32 i=0; i < siz; ++i) {
00423                 Key a;
00424                 ar >> a;
00425                 ar >> ob[a];
00426         }
00427         return ar;
00428 }
00429 
00430 #ifdef  __NAMESPACES__
00431 };
00432 #endif
00433 
00434 #endif
00435 

Generated at Tue Nov 20 12:34:33 2001 for CommonC++ by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001