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 <map>
00069 
00070 #ifdef CCXX_NAMESPACES
00071 namespace ost {
00072 #endif
00073 
00074 #ifdef  COMMON_STD_EXCEPTION
00075 
00076 class CCXX_CLASS_EXPORT PersistException
00077 {
00078 public:
00079         PersistException(const std::string &what_arg) throw();
00080         virtual ~PersistException() throw();
00081         const std::string &getString() const;
00082 };
00083 
00084 #else
00085 
00086 class PersistException
00087 {
00088 public:
00089         CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const std::string& reason);
00090         CCXX_MEMBER_EXPORT(const std::string&) getString() const;
00091         CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00092 protected:
00093         std::string _what;
00094 };
00095 
00096 #endif
00097 
00098 // This typedef allows us to declare NewBaseObjectFunction now
00099 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00100 
00109 class TypeManager
00110 {
00111 public:
00112         
00117         class Registration
00118         {
00119         public:
00120                 Registration(const char* name, NewBaseObjectFunction func)
00121                         : myName(name) { TypeManager::add(name,func); }
00122                 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00123         private:
00124                 std::string myName;
00125         };
00126         
00130         CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00131         
00135         CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00136         
00142         CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00143         
00144         typedef std::map<std::string,NewBaseObjectFunction> StringFunctionMap;
00145 };
00146 
00147 
00148 /*
00149  * The following defines are used to declare and define the relevant code
00150  * to allow a class to use the Persistence::Engine code.
00151  */
00152 
00153 #define DECLARE_PERSISTENCE(ClassType)                                  \
00154   public:                                                               \
00155     friend Engine& operator>>(Engine& ar, ClassType *&ob);              \
00156     friend Engine& operator<<(Engine& ar, ClassType const *&ob);        \
00157     friend BaseObject *createNew##ClassType();                          \
00158     virtual const char* getPersistenceID() const;                       \
00159     static TypeManager::Registration registrationFor##ClassType;
00160 
00161 #define IMPLEMENT_PERSISTENCE(ClassType,FullyQualifiedName)                   \
00162   BaseObject *createNew##ClassType() { return new ClassType; }                \
00163   const char* ClassType::getPersistenceID()const {return FullyQualifiedName;} \
00164   Engine& operator>>(Engine& ar, ClassType *&ob)                              \
00165     { ar >> (BaseObject *&) ob; return ar; }                                  \
00166   Engine& operator<<(Engine& ar, ClassType const *ob)                         \
00167     { ar << (BaseObject const *)ob; return ar; }                              \
00168   TypeManager::Registration                                                   \
00169         ClassType::registrationFor##ClassType(FullyQualifiedName,             \
00170                                               CreateNew##ClassType);
00171 
00172 class Engine;
00173 
00188 class BaseObject
00189 {
00190 public:
00196         CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00197         
00201         CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00202         
00206         CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00207         
00213         CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00214 
00220         CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00221 };
00222 
00223 
00234 class Engine
00235 {
00236 public:
00241         class Exception : public PersistException
00242         {
00243         public:
00244                 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const std::string &reason);
00245         };
00246         
00250         enum EngineMode
00251         {
00252                 modeRead,
00253                 modeWrite
00254         };
00255         
00261         CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00262         
00267         CCXX_MEMBER_EXPORT(virtual) ~Engine();
00268 
00269 
00270         // Write operations
00271         CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00272         /*
00273          * shortcut, to make the following more readable
00274          */
00275 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00276         void write(int8 i)   THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00277         void write(uint8 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00278         void write(int16 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00279         void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00280         void write(int32 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00281         void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00282         void write(int64 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00283         void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00284         void write(float i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00285         void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00286 #undef CCXX_ENGINEWRITE_REF
00287 
00288         CCXX_MEMBER_EXPORT(void) write(const std::string& str) THROWS (Exception);
00289         // Every write operation boils down to one or more of theses
00290         CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00291         
00292         // Read Operations
00293         
00294         CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00295 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00296         void read(int8& i)   THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00297         void read(uint8& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00298         void read(int16& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00299         void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00300         void read(int32& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00301         void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00302         void read(int64& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00303         void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00304         void read(float& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00305         void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00306 #undef CCXX_ENGINEREAD_REF
00307 
00308         CCXX_MEMBER_EXPORT(void) read(std::string& str) THROWS (Exception);
00309         // Every read operation boild down to one or more of these
00310         CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00311 
00312 private:
00316         std::iostream& myUnderlyingStream;
00317         
00321         EngineMode myOperationalMode;
00322 
00326         typedef std::vector<BaseObject*>           ArchiveVector;
00327         typedef std::map<BaseObject const*, int32> ArchiveMap;
00328         typedef std::vector<std::string>                ClassVector;
00329         typedef std::map<std::string, int32>            ClassMap;
00330         
00331         ArchiveVector myArchiveVector;
00332         ArchiveMap myArchiveMap;
00333         ClassVector myClassVector;
00334         ClassMap myClassMap;
00335 
00336         // Compression support
00337 #ifndef NO_COMPRESSION
00338         z_stream myZStream;
00339         uint8* myCompressedDataBuffer;
00340         uint8* myUncompressedDataBuffer;
00341         uint8* myLastUncompressedDataRead;
00342 #endif
00343 };
00344 
00345 // Standard >> and << stream operators for BaseObject
00347 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00349 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00350 
00352 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00354 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00355 
00357 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00359 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00360 
00362 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00364 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00365 
00367 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00369 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00370 
00372 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00374 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00375 
00377 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00379 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00380 
00382 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00384 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00385 
00387 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00389 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00390 
00392 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00394 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00395 
00397 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00399 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00400 
00402 CCXX_EXPORT(Engine&) operator >>( Engine& ar, std::string& ob) THROWS (Engine::Exception);
00404 CCXX_EXPORT(Engine&) operator <<( Engine& ar, std::string ob)  THROWS (Engine::Exception);
00405 
00407 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00409 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00410 
00420 template<class T>
00421 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00422 {
00423         ar << (uint32)ob.size();
00424         for(uint i=0; i < ob.size(); ++i)
00425                 ar << ob[i];
00426         return ar;
00427 }
00428 
00434 template<class T>
00435 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00436 {
00437         ob.clear();
00438         uint32 siz;
00439         ar >> siz;
00440         ob.resize(siz);
00441         for(uint32 i=0; i < siz; ++i)
00442                 ar >> ob[i];
00443         return ar;
00444 }
00445 
00451 template<class Key, class Value>
00452 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00453 {
00454         ar << (uint32)ob.size();
00455         for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00456                 ar << it->first << it->second;
00457         return ar;
00458 }
00459 
00465 template<class Key, class Value>
00466 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00467 {
00468         ob.clear();
00469         uint32 siz;
00470         ar >> siz;
00471         for(uint32 i=0; i < siz; ++i) {
00472                 Key a;
00473                 ar >> a;
00474                 ar >> ob[a];
00475         }
00476         return ar;
00477 }
00478 
00479 #ifdef  CCXX_NAMESPACES
00480 };
00481 #endif
00482 
00483 #endif
00484 

Generated on Thu Nov 21 12:28:31 2002 for GNU CommonC++ by doxygen1.2.18