Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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_MISSING_H_
00050 #include <cc++/missing.h>
00051 #endif
00052 
00053 #ifndef CCXX_STRING_H_
00054 #include <cc++/string.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 #define NS_PREFIX ost::
00074 #else
00075 #define NS_PREFIX
00076 #endif
00077 
00078 #ifdef  CCXX_EXCEPTIONS
00079 #ifdef  COMMON_STD_EXCEPTION
00080 
00081 class __EXPORT PersistException : public Exception
00082 {
00083 public:
00084         PersistException(String what) : Exception(what) {};
00085 };
00086 
00087 #else
00088 
00089 class PersistException
00090 {
00091 public:
00092         CCXX_MEMBER_EXPORT(CCXX_EMPTY) PersistException(const String& reason);
00093         CCXX_MEMBER_EXPORT(const String&) getString() const;
00094         CCXX_MEMBER_EXPORT(virtual) ~PersistException();
00095 protected:
00096         String _what;
00097 };
00098 
00099 #endif
00100 #endif
00101 
00102 // This typedef allows us to declare NewBaseObjectFunction now
00103 typedef class BaseObject* (*NewBaseObjectFunction) (void);
00104 
00113 class TypeManager
00114 {
00115 public:
00116         
00121         class Registration
00122         {
00123         public:
00124                 Registration(const char* name, NewBaseObjectFunction func)
00125                         : myName(name) { TypeManager::add(name,func); }
00126                 virtual ~Registration() { TypeManager::remove(myName.c_str()); }
00127         private:
00128                 String myName;
00129         };
00130         
00134         CCXX_MEMBER_EXPORT(static void) add(const char* name, NewBaseObjectFunction construction);
00135         
00139         CCXX_MEMBER_EXPORT(static void) remove(const char* name);
00140         
00146         CCXX_EXPORT(static BaseObject*) createInstanceOf(const char* name);
00147         
00148         typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
00149 };
00150 
00151 
00152 /*
00153  * The following defines are used to declare and define the relevant code
00154  * to allow a class to use the Persistence::Engine code.
00155  */
00156 
00157 #define DECLARE_PERSISTENCE(ClassType)                                  \
00158   public:                                                               \
00159     friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob);         \
00160     friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob);    \
00161     friend NS_PREFIX BaseObject *createNew##ClassType();                                \
00162     virtual const char* getPersistenceID() const;                       \
00163     static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
00164 
00165 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName)                  \
00166   NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; }                      \
00167   const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
00168   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob)                           \
00169     { ar >> (NS_PREFIX BaseObject &) ob; return ar; }                                 \
00170   NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob)                          \
00171     { ar >> (NS_PREFIX BaseObject *&) ob; return ar; }                                \
00172   NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob)                             \
00173     { ar << (NS_PREFIX BaseObject const *)&ob; return ar; }                           \
00174   NS_PREFIX TypeManager::Registration                                                 \
00175         ClassType::registrationFor##ClassType(FullyQualifiedName,             \
00176                                               createNew##ClassType);
00177 
00178 class Engine;
00179 
00199 class BaseObject
00200 {
00201 public:
00207         CCXX_MEMBER_EXPORT(CCXX_EMPTY) BaseObject();
00208         
00212         CCXX_MEMBER_EXPORT(virtual) ~BaseObject();
00213         
00217         CCXX_MEMBER_EXPORT(virtual const char*) getPersistenceID() const;
00218         
00224         CCXX_MEMBER_EXPORT(virtual bool) write(Engine& archive) const;
00225 
00231         CCXX_MEMBER_EXPORT(virtual bool) read(Engine& archive);
00232 };
00233 
00234 
00246 class Engine
00247 {
00248 public:
00253 #ifdef  CCXX_EXCEPTIONS
00254         class Exception : public PersistException
00255         {
00256         public:
00257                 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Exception(const String &reason);
00258         };
00259 #endif
00260         
00264         enum EngineMode
00265         {
00266                 modeRead,
00267                 modeWrite
00268         };
00269         
00275         CCXX_MEMBER_EXPORT(CCXX_EMPTY) Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
00276         
00281         CCXX_MEMBER_EXPORT(virtual) ~Engine();
00282 
00283 
00284         // Write operations
00285 
00289         CCXX_MEMBER_EXPORT(void) write(const BaseObject &object) THROWS (Exception)
00290   { write(&object); };
00291 
00295         CCXX_MEMBER_EXPORT(void) write(const BaseObject *object) THROWS (Exception);
00296 
00297         // writes supported primitive types
00298   // shortcut, to make the following more readable
00299 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
00300         void write(int8 i)   THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00301         void write(uint8 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00302         void write(int16 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00303         void write(uint16 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00304         void write(int32 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00305         void write(uint32 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00306 #ifdef  HAVE_64_BITS
00307         void write(int64 i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00308         void write(uint64 i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00309 #endif
00310         void write(float i)  THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00311         void write(double i) THROWS (Exception) { CCXX_ENGINEWRITE_REF(i); }
00312 #undef CCXX_ENGINEWRITE_REF
00313         CCXX_MEMBER_EXPORT(void) write(const String& str) THROWS (Exception);
00314 
00315         // Every write operation boils down to one or more of these
00316         CCXX_MEMBER_EXPORT(void) writeBinary(const uint8* data, const uint32 size) THROWS (Exception);
00317 
00318 
00319         // Read Operations
00320 
00324         CCXX_MEMBER_EXPORT(void) read(BaseObject &object) THROWS (Exception);
00325 
00329         CCXX_MEMBER_EXPORT(void) read(BaseObject *&object) THROWS (Exception);
00330 
00331         // reads supported primitive types
00332   // shortcut, to make the following more readable
00333 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
00334         void read(int8& i)   THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00335         void read(uint8& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00336         void read(int16& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00337         void read(uint16& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00338         void read(int32& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00339         void read(uint32& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00340 #ifdef  HAVE_64_BITS
00341         void read(int64& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00342         void read(uint64& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00343 #endif
00344         void read(float& i)  THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00345         void read(double& i) THROWS (Exception) { CCXX_ENGINEREAD_REF(i); }
00346 #undef CCXX_ENGINEREAD_REF
00347 
00348         CCXX_MEMBER_EXPORT(void) read(String& str) THROWS (Exception);
00349 
00350         // Every read operation boild down to one or more of these
00351         CCXX_MEMBER_EXPORT(void) readBinary(uint8* data, uint32 size) THROWS (Exception);
00352 
00353 private:
00358   void readObject(BaseObject* object);
00359 
00363   const String readClass();
00364 
00365 
00369         std::iostream& myUnderlyingStream;
00370         
00374         EngineMode myOperationalMode;
00375 
00379         typedef std::vector<BaseObject*>           ArchiveVector;
00380         typedef std::map<BaseObject const*, int32> ArchiveMap;
00381         typedef std::vector<String>                ClassVector;
00382         typedef std::map<String, int32>            ClassMap;
00383         
00384         ArchiveVector myArchiveVector;
00385         ArchiveMap myArchiveMap;
00386         ClassVector myClassVector;
00387         ClassMap myClassMap;
00388 
00389         // Compression support
00390 #ifndef NO_COMPRESSION
00391         z_stream myZStream;
00392         uint8* myCompressedDataBuffer;
00393         uint8* myUncompressedDataBuffer;
00394         uint8* myLastUncompressedDataRead;
00395 #endif
00396 };
00397 
00398 // Standard >> and << stream operators for BaseObject
00400 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject &ob)      THROWS (Engine::Exception);
00402 CCXX_EXPORT(Engine&) operator >>( Engine& ar, BaseObject *&ob)      THROWS (Engine::Exception);
00404 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const &ob) THROWS (Engine::Exception);
00406 CCXX_EXPORT(Engine&) operator <<( Engine& ar, BaseObject const *ob) THROWS (Engine::Exception);
00407 
00409 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int8& ob) THROWS (Engine::Exception);
00411 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int8 ob)  THROWS (Engine::Exception);
00412 
00414 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint8& ob) THROWS (Engine::Exception);
00416 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint8 ob)  THROWS (Engine::Exception);
00417 
00419 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int16& ob) THROWS (Engine::Exception);
00421 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int16 ob)  THROWS (Engine::Exception);
00422 
00424 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint16& ob) THROWS (Engine::Exception);
00426 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint16 ob)  THROWS (Engine::Exception);
00427 
00429 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int32& ob) THROWS (Engine::Exception);
00431 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int32 ob)  THROWS (Engine::Exception);
00432 
00434 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint32& ob) THROWS (Engine::Exception);
00436 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint32 ob)  THROWS (Engine::Exception);
00437 
00438 #ifdef  HAVE_64_BITS
00439 
00440 CCXX_EXPORT(Engine&) operator >>( Engine& ar, int64& ob) THROWS (Engine::Exception);
00442 CCXX_EXPORT(Engine&) operator <<( Engine& ar, int64 ob)  THROWS (Engine::Exception);
00443 
00445 CCXX_EXPORT(Engine&) operator >>( Engine& ar, uint64& ob) THROWS (Engine::Exception);
00447 CCXX_EXPORT(Engine&) operator <<( Engine& ar, uint64 ob)  THROWS (Engine::Exception);
00448 #endif
00449 
00451 CCXX_EXPORT(Engine&) operator >>( Engine& ar, float& ob) THROWS (Engine::Exception);
00453 CCXX_EXPORT(Engine&) operator <<( Engine& ar, float ob)  THROWS (Engine::Exception);
00454 
00456 CCXX_EXPORT(Engine&) operator >>( Engine& ar, double& ob) THROWS (Engine::Exception);
00458 CCXX_EXPORT(Engine&) operator <<( Engine& ar, double ob)  THROWS (Engine::Exception);
00459 
00461 CCXX_EXPORT(Engine&) operator >>( Engine& ar, String& ob) THROWS (Engine::Exception);
00463 CCXX_EXPORT(Engine&) operator <<( Engine& ar, String ob)  THROWS (Engine::Exception);
00464 
00466 CCXX_EXPORT(Engine&) operator >>( Engine& ar, bool& ob) THROWS (Engine::Exception);
00468 CCXX_EXPORT(Engine&) operator <<( Engine& ar, bool ob)  THROWS (Engine::Exception);
00469 
00479 template<class T>
00480 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (Engine::Exception)
00481 {
00482         ar << (uint32)ob.size();
00483         for(uint i=0; i < ob.size(); ++i)
00484                 ar << ob[i];
00485         return ar;
00486 }
00487 
00493 template<class T>
00494 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (Engine::Exception)
00495 {
00496         ob.clear();
00497         uint32 siz;
00498         ar >> siz;
00499         ob.resize(siz);
00500         for(uint32 i=0; i < siz; ++i)
00501                 ar >> ob[i];
00502         return ar;
00503 }
00504 
00510 template<class T>
00511 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (Engine::Exception)
00512 {
00513         ar << (uint32)ob.size();
00514   for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
00515                 ar << *it;
00516         return ar;
00517 }
00518 
00524 template<class T>
00525 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (Engine::Exception)
00526 {
00527         ob.clear();
00528         uint32 siz;
00529         ar >> siz;
00530         //ob.resize(siz);
00531         for(uint32 i=0; i < siz; ++i)
00532   {
00533     T node;
00534     ar >> node;
00535     ob.push_back(node);
00536                 //ar >> ob[i];
00537   }
00538         return ar;
00539 }
00540 
00546 template<class Key, class Value>
00547 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (Engine::Exception)
00548 {
00549         ar << (uint32)ob.size();
00550         for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
00551                 ar << it->first << it->second;
00552         return ar;
00553 }
00554 
00560 template<class Key, class Value>
00561 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (Engine::Exception)
00562 {
00563         ob.clear();
00564         uint32 siz;
00565         ar >> siz;
00566         for(uint32 i=0; i < siz; ++i) {
00567                 Key a;
00568                 ar >> a;
00569                 ar >> ob[a];
00570         }
00571         return ar;
00572 }
00573 
00574 #ifdef  CCXX_NAMESPACES
00575 };
00576 #endif
00577 
00578 #endif
00579 

Generated on Thu Jan 29 16:26:54 2004 for GNU CommonC++ by doxygen 1.3.4