Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound 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_STRCHAR_H_
00054 #include <cc++/persist.h>
00055 #endif
00056 
00057 #ifdef HAVE_ZLIB_H
00058 #ifndef NO_COMPRESSION
00059 #include <zlib.h>
00060 #endif
00061 #else
00062 #define NO_COMPRESSION
00063 #endif
00064 
00065 #include <iostream>
00066 #include <string>
00067 #include <vector>
00068 #include <deque>
00069 #include <map>
00070 
00071 #ifdef CCXX_NAMESPACES
00072 namespace ost {
00073 #endif
00074 
00075 #ifdef  COMMON_STD_EXCEPTION
00076 
00077 class CCXX_CLASS_EXPORT PersistException
00078 {
00079 public:
00080         PersistException(const std::string &what_arg) throw();
00081         virtual ~PersistException() throw();
00082         const std::string &getString() const;
00083 };
00084 
00085 #else
00086 
00087 class PersistException
00088 {
00089 public:
00090         CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const std::string& reason);
00091         CCXX_MEMBER_EXPORT(const std::string&) getString() const;
00092         CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00093 protected:
00094         std::string _what;
00095 };
00096 
00097 #endif
00098 
00099 // This typedef allows us to declare NewBaseObjectFunction now
00100 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00101 
00110 class TypeManager
00111 {
00112 public:
00113         
00118         class Registration
00119         {
00120         public:
00121                 Registration(const char* name, NewBaseObjectFunction func)
00122                         : myName(name) { TypeManager::add(name,func); }
00123                 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00124         private:
00125                 std::string myName;
00126         };
00127         
00131         CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00132         
00136         CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00137         
00143         CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00144         
00145         typedef std::map<std::string,NewBaseObjectFunction> StringFunctionMap;
00146 };
00147 
00148 
00149 /*
00150  * The following defines are used to declare and define the relevant code
00151  * to allow a class to use the Persistence::Engine code.
00152  */
00153 
00154 #define DECLARE_PERSISTENCE(ClassType)                                  \
00155   public:                                                               \
00156     friend Engine& operator>>(Engine& ar, ClassType *&ob);              \
00157     friend Engine& operator<<(Engine& ar, ClassType const &ob); \
00158     friend BaseObject *createNew##ClassType();                          \
00159     virtual const char* getPersistenceID() const;                       \
00160     static TypeManager::Registration registrationFor##ClassType;
00161 
00162 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName)                  \
00163   BaseObject *createNew##ClassType() { return new ClassType; }                \
00164   const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00165   Engine& operator>>(Engine& ar, ClassType &ob)                       \
00166     { ar >> (BaseObject &) ob; return ar; }                                   \
00167   Engine& operator>>(Engine& ar, ClassType *&ob)                              \
00168     { ar >> (BaseObject *&) ob; return ar; }                                  \
00169   Engine& operator<<(Engine& ar, ClassType const &ob)                         \
00170     { ar << (BaseObject const *)&ob; return ar; }                             \
00171   TypeManager::Registration                                                   \
00172         ClassType::registrationFor##ClassType(FullyQualifiedName,             \
00173                                               createNew##ClassType);
00174 
00175 class Engine;
00176 
00196 class BaseObject
00197 {
00198 public:
00204         CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00205         
00209         CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00210         
00214         CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00215         
00221         CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00222 
00228         CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00229 };
00230 
00231 
00243 class Engine
00244 {
00245 public:
00250         class Exception : public PersistException
00251         {
00252         public:
00253                 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const std::string &reason);
00254         };
00255         
00259         enum EngineMode
00260         {
00261                 modeRead,
00262                 modeWrite
00263         };
00264         
00270         CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00271         
00276         CCXX_MEMBER_EXPORT(virtual) ~Engine();
00277 
00278 
00279         // Write operations
00280 
00284         CCXX_MEMBER_EXPORT(void) write(const BaseObject &object) THROWS (Exception)
00285   { write(&object); };
00286 
00290         CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00291 
00292         // writes supported primitive types
00293   // shortcut, to make the following more readable
00294 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00295         void write(int8 i)   THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00296         void write(uint8 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00297         void write(int16 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00298         void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00299         void write(int32 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00300         void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00301         void write(int64 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00302         void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00303         void write(float i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00304         void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00305 #undef CCXX_ENGINEWRITE_REF
00306         CCXX_MEMBER_EXPORT(void) write(const std::string& str) THROWS (Exception);
00307 
00308         // Every write operation boils down to one or more of these
00309         CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00310 
00311 
00312         // Read Operations
00313 
00317         CCXX_MEMBER_EXPORT(void) read(BaseObject &object) THROWS (Exception);
00318 
00322         CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00323 
00324         // reads supported primitive types
00325   // shortcut, to make the following more readable
00326 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00327         void read(int8& i)   THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00328         void read(uint8& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00329         void read(int16& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00330         void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00331         void read(int32& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00332         void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00333         void read(int64& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00334         void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00335         void read(float& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00336         void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00337 #undef CCXX_ENGINEREAD_REF
00338 
00339         CCXX_MEMBER_EXPORT(void) read(std::string& str) THROWS (Exception);
00340 
00341         // Every read operation boild down to one or more of these
00342         CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00343 
00344 private:
00349   void readObject(BaseObject* object);
00350 
00354   const std::string readClass();
00355 
00356 
00360         std::iostream& myUnderlyingStream;
00361         
00365         EngineMode myOperationalMode;
00366 
00370         typedef std::vector<BaseObject*>           ArchiveVector;
00371         typedef std::map<BaseObject const*, int32> ArchiveMap;
00372         typedef std::vector<std::string>                ClassVector;
00373         typedef std::map<std::string, int32>            ClassMap;
00374         
00375         ArchiveVector myArchiveVector;
00376         ArchiveMap myArchiveMap;
00377         ClassVector myClassVector;
00378         ClassMap myClassMap;
00379 
00380         // Compression support
00381 #ifndef NO_COMPRESSION
00382         z_stream myZStream;
00383         uint8* myCompressedDataBuffer;
00384         uint8* myUncompressedDataBuffer;
00385         uint8* myLastUncompressedDataRead;
00386 #endif
00387 };
00388 
00389 // Standard >> and << stream operators for BaseObject
00391 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject &ob)      THROWS (Engine::Exception);
00393 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00395 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00397 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00398 
00400 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00402 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00403 
00405 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00407 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00408 
00410 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00412 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00413 
00415 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00417 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00418 
00420 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00422 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00423 
00425 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00427 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00428 
00430 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00432 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00433 
00435 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00437 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00438 
00440 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00442 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00443 
00445 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00447 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00448 
00450 CCXX_EXPORT(Engine&) operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00452 CCXX_EXPORT(Engine&) operator <<( Engine& ar, std::string ob)  THROWS (Engine::Exception);
00453 
00455 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00457 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00458 
00468 template<class T>
00469 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00470 {
00471         ar << (uint32)ob.size();
00472         for(uint i=0; i < ob.size(); ++i)
00473                 ar << ob[i];
00474         return ar;
00475 }
00476 
00482 template<class T>
00483 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00484 {
00485         ob.clear();
00486         uint32 siz;
00487         ar >> siz;
00488         ob.resize(siz);
00489         for(uint32 i=0; i < siz; ++i)
00490                 ar >> ob[i];
00491         return ar;
00492 }
00493 
00499 template<class T>
00500 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00501 {
00502         ar << (uint32)ob.size();
00503   for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00504                 ar << *it;
00505         return ar;
00506 }
00507 
00513 template<class T>
00514 Engine& operator >>( Engine& ar, typename std::deque<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   {
00522     T node;
00523     ar >> node;
00524     ob.push_back(node);
00525                 //ar >> ob[i];
00526   }
00527         return ar;
00528 }
00529 
00535 template<class Key, class Value>
00536 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00537 {
00538         ar << (uint32)ob.size();
00539         for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00540                 ar << it->first << it->second;
00541         return ar;
00542 }
00543 
00549 template<class Key, class Value>
00550 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00551 {
00552         ob.clear();
00553         uint32 siz;
00554         ar >> siz;
00555         for(uint32 i=0; i < siz; ++i) {
00556                 Key a;
00557                 ar >> a;
00558                 ar >> ob[a];
00559         }
00560         return ar;
00561 }
00562 
00563 #ifdef  CCXX_NAMESPACES
00564 };
00565 #endif
00566 
00567 #endif
00568 

Generated on Thu Sep 25 13:14:31 2003 for GNU CommonC++ by doxygen 1.3.3