persistenceManager.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: persistenceManager.h,v 1.48.20.1 2007/08/07 12:31:05 oliver Exp $
00005 //
00006 
00007 #ifndef BALL_CONCEPT_PERSISTENCEMANAGER_H
00008 #define BALL_CONCEPT_PERSISTENCEMANAGER_H
00009 
00010 #ifndef BALL_COMMON_RTTI_H
00011 # include <BALL/COMMON/rtti.h>
00012 #endif
00013 
00014 #ifndef BALL_DATATYPE_HASHMAP_H
00015 # include <BALL/DATATYPE/hashMap.h>
00016 #endif
00017 
00018 #ifndef BALL_DATATYPE_STRINGHASHMAP_H
00019 # include <BALL/DATATYPE/stringHashMap.h>
00020 #endif
00021 
00022 #ifndef BALL_DATATYPE_HASHSET_H
00023 # include <BALL/DATATYPE/hashSet.h>
00024 #endif
00025 
00026 #ifndef BALL_CONCEPT_PERSISTENTOBJECT_H
00027 # include <BALL/CONCEPT/persistentObject.h>
00028 #endif
00029 
00030 #ifndef BALL_COMMON_GLOBAL_H
00031 # include <BALL/COMMON/global.h>
00032 #endif
00033 
00034 #include <fstream>
00035 #include <iomanip>
00036 
00037 #include <boost/shared_ptr.hpp>
00038 
00039 namespace BALL 
00040 {
00041 
00071   class BALL_EXPORT PersistenceManager
00072   {
00073     public:
00074 
00078       
00090     typedef void * (*CreateMethod) ();
00092 
00096 
00099     PersistenceManager();
00100 
00103     PersistenceManager(const PersistenceManager& pm);
00104 
00108     PersistenceManager(::std::istream& is);
00109       
00113     PersistenceManager(::std::ostream& os);
00114       
00119     PersistenceManager(::std::istream& is, ::std::ostream& os);
00120       
00126     virtual ~PersistenceManager();
00127 
00129 
00133 
00158     virtual void registerClass(String signature, const CreateMethod m);
00159 
00170     virtual void* createObject(String signature) const;
00171 
00176     virtual Size  getNumberOfClasses() const;
00177     
00181     virtual void setOstream(::std::ostream& s);
00182 
00186     virtual void setIstream(::std::istream& s);
00187 
00196     void startOutput();
00197 
00209     void endOutput();
00210 
00221     PersistentObject* readObject()
00222       throw(Exception::GeneralException);
00223 
00227     PersistenceManager& operator << (const PersistentObject& object);
00228 
00232     PersistenceManager& operator >> (PersistentObject*& object_ptr);
00233 
00235 
00239 
00246     template <typename T>
00247     bool checkObjectHeader(const T& /* object */, const char* name = 0);
00248 
00253     bool checkObjectHeader(const char* type_name);
00254 
00261     template <typename T>
00262     void writeObjectHeader(const T* object, const char* name = 0);
00263 
00267     void writeObjectTrailer(const char* name = 0);
00268 
00272     bool checkObjectTrailer(const char* name = 0);
00273 
00280     template <typename T>
00281     void writePrimitive(const T& t, const char* name); 
00282 
00289     template <typename T>
00290     bool readPrimitive(T& t, const char* name);
00291 
00297     template <typename T>
00298     void writeStorableObject(const T& t, const char* name);
00299 
00306     template <typename T>
00307     bool readStorableObject(T& t, const char* name);
00308 
00314     template <typename T>
00315     void writeObjectPointer(const T* object, const char* name);
00316  
00323     template <typename T>
00324     bool readObjectPointer(T*& object, const char* name);
00325 
00333     template <typename T>
00334     bool readObjectSmartPointer(boost::shared_ptr<T>& s_ptr, const char* name);
00335 
00341     template <typename T>
00342     void writeObjectReference(const T& object, const char* name);
00343 
00350     template <typename T>
00351     bool readObjectReference(T& object, const char* name);
00352 
00360     template <typename T>
00361     void writeObjectArray(const T* array, const char* name, Size size);
00362 
00370     template <typename T>
00371     bool readObjectArray(const T* array, const char* name, Size& size);
00372 
00380     template <typename T>
00381     void writeObjectPointerArray(T** arr, const char* name, const Size size);
00382   
00390     template <typename T>
00391     bool readObjectPointerArray(T** array, const char* name, Size& size);
00392    
00394 
00398       
00413     virtual void writeHeader(const char* type_name, const char* name,
00414         LongSize ptr) = 0;
00415 
00425     virtual bool checkHeader(const char* type_name, const char* name,
00426         LongSize& ptr) = 0;
00427 
00431     virtual void writeTrailer(const char* name = 0) = 0;
00432 
00438     virtual bool checkTrailer(const char* name = 0) = 0;
00439 
00440 
00443     virtual void writeStreamHeader() = 0;
00444 
00445 
00448     virtual void writeStreamTrailer() = 0;
00449 
00450 
00454     virtual bool checkStreamHeader() = 0;
00455 
00456 
00460     virtual bool checkStreamTrailer() = 0;
00461 
00462 
00468     virtual bool getObjectHeader(String& type_name, LongSize& ptr) = 0;
00469 
00470 
00474     virtual void writeName(const char* name) = 0;
00475 
00476 
00481     virtual bool checkName(const char* name) = 0;
00482 
00483 
00488     virtual void writeStorableHeader(const char* type_name,
00489         const char* name) = 0;
00490       
00495     virtual bool checkStorableHeader(const char* type_name,
00496         const char* name) = 0;
00497 
00500     virtual void writeStorableTrailer() = 0;
00501 
00502 
00506     virtual bool checkStorableTrailer() = 0;
00507 
00508 
00513     virtual void writePrimitiveHeader(const char* type_name,
00514         const char* name) = 0;
00515 
00521     virtual bool checkPrimitiveHeader(const char* type_name,
00522         const char* name) = 0;
00523 
00526     virtual void writePrimitiveTrailer() = 0;
00527 
00528 
00532     virtual bool checkPrimitiveTrailer() = 0;
00533 
00534 
00539     virtual void writeObjectPointerHeader(const char* type_name,
00540         const char* name) = 0;
00541 
00542 
00548     virtual bool checkObjectPointerHeader(const char* type_name,
00549         const char* name) = 0;
00550 
00551 
00556     virtual void writeObjectReferenceHeader(const char* type_name,
00557         const char* name) = 0;
00558 
00559 
00565     virtual bool checkObjectReferenceHeader(const char* type_name,
00566         const char* name) = 0;
00567 
00568 
00574     virtual void writeObjectPointerArrayHeader(const char* type_name,
00575         const char* name, Size size) = 0;
00576 
00577 
00584     virtual bool checkObjectPointerArrayHeader(const char* type_name,
00585         const char* name, Size& size) = 0;
00586 
00587 
00590     virtual void writeObjectPointerArrayTrailer() = 0;
00591 
00592 
00596     virtual bool checkObjectPointerArrayTrailer() = 0;
00597 
00598 
00601     virtual void initializeOutputStream();
00602 
00603 
00606     virtual void finalizeOutputStream();
00607 
00608 
00611     virtual void initializeInputStream();
00612 
00613 
00616     virtual void finalizeInputStream();
00617 
00619 
00638     
00641     virtual void put(const char c) = 0;
00642 
00645     virtual void put(const Byte c) = 0;
00646 
00649     virtual void put(const Index i) = 0;
00650 
00653     virtual void put(const Size p) = 0;
00654 
00657     virtual void put(const bool b) = 0;
00658 
00661     virtual void put(const Real f) = 0;
00662 
00665     virtual void put(const DoubleReal d) = 0;
00666 
00669     virtual void put(const string& s) = 0;
00670 
00673     virtual void put(const LongSize p) = 0;
00674 
00676 
00680 
00683     virtual void get(char& c) = 0;
00684 
00687     virtual void get(Byte& b) = 0;
00688 
00691     virtual void get(Index& s) = 0;
00692 
00695     virtual void get(Size& s) = 0;
00696 
00699     virtual void get(bool& b) = 0;
00700 
00703     virtual void get(Real& f) = 0;
00704 
00707     virtual void get(DoubleReal& d) = 0;
00708 
00711     virtual void get(string& s) = 0;
00712 
00715     virtual void get(LongSize& p) = 0;
00716 
00718 
00719     protected:
00720 
00721     /*_ Register all BALL kernel classes.
00722         This method is automatically called in the constructor.
00723     */
00724     void registerKernelClasses_();
00725 
00726     /*_
00727     */
00728     void addPointerPair_(LongSize old_ptr, void* new_ptr);
00729         
00730     /*_
00731     */
00732     void addNeededObjects_()
00733       throw(Exception::GeneralException);
00734 
00735     /*_
00736     */
00737     bool updatePointers_();
00738 
00739     /*_
00740     */
00741     typedef HashSet<const PersistentObject*>      ObjectSet;
00742     
00743     /*_
00744     */
00745     typedef std::list<const PersistentObject*>    ObjectList;
00746     
00747     /*_
00748     */
00749     typedef HashMap<LongSize, void*>        PointerMap;
00750     
00751     /*_
00752     */
00753     typedef std::list<std::pair<void**, LongSize> >   PointerList;
00754 
00755     /*_
00756     */
00757     typedef std::list<std::pair<boost::shared_ptr<PersistentObject>*, LongSize> > SmartPointerList;
00758 
00759     /*_
00760     */
00761     StringHashMap<CreateMethod>   create_methods_;
00762 
00763     /*_ a hash set containing the pointers of the 
00764         objects that were already written
00765     */
00766     ObjectSet   object_out_;
00767 
00768     /*_ a list of object pointers that were referenced
00769         by objects already written, but have not yet
00770         been written themselves
00771     */
00772     ObjectList  object_out_needed_;
00773 
00774     /*_ a map relating the pointers read from the stream (LongSize)
00775         with the pointers of the persistent objects that were created
00776         dynamically
00777     */
00778     PointerMap  pointer_map_;
00779     
00780     //_
00781     PointerList pointer_list_;
00782 
00783     //_
00784     SmartPointerList smart_pointer_list_;
00785 
00786     //_
00787     ObjectList  object_in_;
00788 
00789     //_
00790     ::std::ostream* ostr_;
00791     //_
00792     ::std::istream* istr_;
00793   };
00794 
00795 
00796   // implementation of templated methods
00797   
00798   template <typename T>
00799   bool PersistenceManager::checkObjectHeader(const T& /* object */,
00800       const char* name)
00801   {
00802     LongSize ptr;
00803     return checkHeader(RTTI::getStreamName<T>(), name, ptr);
00804   }
00805 
00806 
00807   template <typename T>
00808   void PersistenceManager::writeObjectHeader(const T* object,
00809       const char* name)
00810   {
00811     object_out_.insert(object);
00812     writeHeader(RTTI::getStreamName<T>(), name, (LongSize)reinterpret_cast<PointerSizeUInt>(object));
00813   }
00814 
00815 
00816   template <typename T>
00817   void PersistenceManager::writePrimitive(const T& t, const char* name)
00818   {
00819     writePrimitiveHeader(RTTI::getStreamName<T>(), name);
00820     put(t);
00821     writePrimitiveTrailer();
00822   }
00823 
00824 
00825   template <typename T>
00826   bool PersistenceManager::readPrimitive(T& t, const char* name)
00827   {
00828     if (!checkPrimitiveHeader(RTTI::getStreamName<T>(), name))
00829     {
00830       return false;
00831     }
00832 
00833     get(t);
00834     return checkPrimitiveTrailer();
00835   }
00836 
00837 
00838   template <typename T>
00839   void PersistenceManager::writeStorableObject(const T& t, const char* name)
00840   {
00841     writeStorableHeader(RTTI::getStreamName<T>(), name);
00842     t.write(*this);
00843     writeStorableTrailer();
00844   }
00845 
00846 
00847   template <typename T>
00848   bool PersistenceManager::readStorableObject(T& t, const char* name)
00849   {
00850     return (checkStorableHeader(RTTI::getStreamName<T>(), name) 
00851             && t.read(*this) && checkStorableTrailer());
00852   }
00853 
00854 
00855   template <typename T>
00856   void PersistenceManager::writeObjectPointer(const T* object, const char* name)
00857   {
00858     if (object != 0 && !object_out_.has(object))
00859     {
00860       object_out_needed_.push_back(object);
00861     }
00862 
00863     writeObjectPointerHeader(RTTI::getStreamName<T>(), name);
00864     put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(object)));
00865     writePrimitiveTrailer();
00866   }
00867 
00868 
00869   template <typename T>
00870   bool PersistenceManager::readObjectPointer(T*& object, const char* name)
00871   {
00872     if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00873     {
00874       return false;
00875     }
00876 
00877     LongSize ptr;
00878     get(ptr);
00879 
00880     if (ptr != 0)
00881     {
00882       pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00883     }
00884 
00885     object = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
00886 
00887     return checkPrimitiveTrailer();
00888   } 
00889 
00890   template <typename T>
00891   bool PersistenceManager::readObjectSmartPointer(boost::shared_ptr<T>& s_ptr, const char* name)
00892   {
00893     if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00894     {
00895       return false;
00896     }
00897 
00898     LongSize ptr;
00899     get(ptr);
00900 
00901     if (ptr != 0)
00902     {
00903       smart_pointer_list_.push_back(std::make_pair((boost::shared_ptr<PersistentObject>*)&s_ptr, (LongSize)((PersistentObject*)ptr)));
00904     }
00905 
00906     return checkPrimitiveTrailer();
00907   } 
00908 
00909   template <typename T>
00910   void PersistenceManager::writeObjectReference(const T& object,
00911       const char* name)
00912   {
00913     if (&object != 0 && !object_out_.has(&object))
00914     {
00915       object_out_needed_.push_back(&object);
00916     }
00917 
00918     writeObjectReferenceHeader(RTTI::getStreamName<T>(), name);
00919     put((LongSize)(void*)&object);
00920     writePrimitiveTrailer();
00921   } 
00922 
00923 
00924   template <typename T>
00925   bool PersistenceManager::readObjectReference(T& object, const char* name)
00926   {
00927     if (!checkObjectReferenceHeader(RTTI::getStreamName<T>(), name))
00928     {
00929       return false;
00930     }
00931 
00932     LongSize ptr;
00933     get(ptr);
00934 
00935     // store a zero in the corresponding pointer
00936     // since we cannot convert 64 bit pointers to
00937     // 32 bit pointers - this is required, if an object
00938     // written on a 64 bit architecture is read on a 32 bit
00939     // machine
00940     object = 0;
00941 
00942     if (ptr != 0)
00943     {
00944       pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00945     }
00946 
00947     return checkPrimitiveTrailer();
00948   }
00949 
00950   template <typename T>
00951   void PersistenceManager::writeObjectArray(const T* array, const char* name,
00952       Size size)
00953   {
00954     writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00955 
00956     for (Position i = 0; i < size; i++)
00957     {
00958       (*this) << array[i];
00959     }
00960 
00961     writeObjectPointerArrayTrailer();
00962   }
00963 
00964   template <typename T>
00965   bool PersistenceManager::readObjectArray
00966     (const T* array, const char* name, Size& size)
00967   {
00968     if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
00969     {
00970       return false;
00971     }
00972 
00973     T* ptr = const_cast<T*>(array);
00974     for (Position i = 0; i < size; i++) 
00975     {
00976       (*this) >> ptr[i];
00977     }
00978 
00979     bool result = checkObjectPointerArrayTrailer();
00980     return result;
00981   } 
00982 
00983   template <typename T>
00984   void PersistenceManager::writeObjectPointerArray
00985     (T** arr, const char* name, const Size size)
00986   {
00987     writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00988 
00989     PersistentObject* ptr;
00990     for (Position i = 0; i < size; i++)
00991     {
00992       ptr = (PersistentObject*)arr[i];
00993       put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(ptr)));
00994       if (ptr != 0 && !object_out_.has(ptr))
00995       {
00996         object_out_needed_.push_back(ptr);
00997       }
00998     }
00999     
01000     writeObjectPointerArrayTrailer();
01001   }
01002 
01003 
01004   template <typename T>
01005   bool PersistenceManager::readObjectPointerArray(T** array, const char* name,
01006       Size& size)
01007   {
01008     if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
01009     {
01010       return false;
01011     }
01012 
01013     LongSize ptr;
01014     for (Position i = 0; i < size; i++) 
01015     {
01016       get(ptr);
01017 
01018       if (ptr != 0)
01019       {
01020         pointer_list_.push_back(std::make_pair((void**)&(array[i]), ptr));
01021       }
01022 
01023       array[i] = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
01024     }
01025 
01026     return checkObjectPointerArrayTrailer();
01027   }
01028 
01029 #ifndef BALL_NO_INLINE_FUNCTIONS
01030 # include <BALL/CONCEPT/persistenceManager.iC>
01031 #endif
01032 
01033 } // namespace BALL
01034 
01035 #endif // BALL_CONCEPT_PERSISTENCEMANAGER_H