BALL  1.4.1
persistenceManager.h
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 
00005 #ifndef BALL_CONCEPT_PERSISTENCEMANAGER_H
00006 #define BALL_CONCEPT_PERSISTENCEMANAGER_H
00007 
00008 #ifndef BALL_COMMON_RTTI_H
00009 # include <BALL/COMMON/rtti.h>
00010 #endif
00011 
00012 #ifndef BALL_DATATYPE_HASHMAP_H
00013 # include <BALL/DATATYPE/hashMap.h>
00014 #endif
00015 
00016 #ifndef BALL_DATATYPE_STRINGHASHMAP_H
00017 # include <BALL/DATATYPE/stringHashMap.h>
00018 #endif
00019 
00020 #ifndef BALL_DATATYPE_HASHSET_H
00021 # include <BALL/DATATYPE/hashSet.h>
00022 #endif
00023 
00024 #ifndef BALL_CONCEPT_PERSISTENTOBJECT_H
00025 # include <BALL/CONCEPT/persistentObject.h>
00026 #endif
00027 
00028 #ifndef BALL_COMMON_GLOBAL_H
00029 # include <BALL/COMMON/global.h>
00030 #endif
00031 
00032 #include <fstream>
00033 #include <iomanip>
00034 
00035 #include <boost/shared_ptr.hpp>
00036 
00037 #define BALL_WRITE_PRIMITIVE_MEMBER(pm,x) pm.writePrimitive(x,#x)
00038 #define BALL_READ_PRIMITIVE_MEMBER(pm,x) pm.readPrimitive(x,#x)
00039 
00040 namespace BALL 
00041 {
00042 
00072   class BALL_EXPORT PersistenceManager
00073   {
00074     public:
00075 
00079       
00091     typedef void * (*CreateMethod) ();
00093 
00097 
00100     PersistenceManager();
00101 
00104     PersistenceManager(const PersistenceManager& pm);
00105 
00109     PersistenceManager(::std::istream& is);
00110       
00114     PersistenceManager(::std::ostream& os);
00115       
00120     PersistenceManager(::std::istream& is, ::std::ostream& os);
00121       
00127     virtual ~PersistenceManager();
00128 
00130 
00134 
00159     virtual void registerClass(String signature, const CreateMethod m);
00160 
00171     virtual void* createObject(String signature) const;
00172 
00177     virtual Size  getNumberOfClasses() const;
00178     
00182     virtual void setOstream(::std::ostream& s);
00183 
00187     virtual void setIstream(::std::istream& s);
00188 
00197     void startOutput();
00198 
00210     void endOutput();
00211 
00223     PersistentObject* readObject();
00224 
00228     PersistenceManager& operator << (const PersistentObject& object);
00229 
00233     PersistenceManager& operator >> (PersistentObject*& object_ptr);
00234 
00236 
00240 
00247     template <typename T>
00248     bool checkObjectHeader(const T& /* object */, const char* name = 0);
00249 
00254     bool checkObjectHeader(const char* type_name);
00255 
00262     template <typename T>
00263     void writeObjectHeader(const T* object, const char* name = 0);
00264 
00268     void writeObjectTrailer(const char* name = 0);
00269 
00273     bool checkObjectTrailer(const char* name = 0);
00274 
00281     template <typename T>
00282     void writePrimitive(const T& t, const char* name); 
00283 
00290     template <typename T>
00291     bool readPrimitive(T& t, const char* name);
00292 
00298     template <typename T>
00299     void writeStorableObject(const T& t, const char* name);
00300 
00307     template <typename T>
00308     bool readStorableObject(T& t, const char* name);
00309 
00315     template <typename T>
00316     void writeObjectPointer(const T* object, const char* name);
00317  
00324     template <typename T>
00325     bool readObjectPointer(T*& object, const char* name);
00326 
00334     template <typename T>
00335     bool readObjectSmartPointer(boost::shared_ptr<T>& s_ptr, const char* name);
00336 
00342     template <typename T>
00343     void writeObjectReference(const T& object, const char* name);
00344 
00351     template <typename T>
00352     bool readObjectReference(T& object, const char* name);
00353 
00361     template <typename T>
00362     void writeObjectArray(const T* array, const char* name, Size size);
00363 
00371     template <typename T>
00372     bool readObjectArray(const T* array, const char* name, Size& size);
00373 
00381     template <typename T>
00382     void writeObjectPointerArray(T** arr, const char* name, const Size size);
00383   
00391     template <typename T>
00392     bool readObjectPointerArray(T** array, const char* name, Size& size);
00393    
00395 
00399       
00414     virtual void writeHeader(const char* type_name, const char* name,
00415         LongSize ptr) = 0;
00416 
00426     virtual bool checkHeader(const char* type_name, const char* name,
00427         LongSize& ptr) = 0;
00428 
00432     virtual void writeTrailer(const char* name = 0) = 0;
00433 
00439     virtual bool checkTrailer(const char* name = 0) = 0;
00440 
00441 
00444     virtual void writeStreamHeader() = 0;
00445 
00446 
00449     virtual void writeStreamTrailer() = 0;
00450 
00451 
00455     virtual bool checkStreamHeader() = 0;
00456 
00457 
00461     virtual bool checkStreamTrailer() = 0;
00462 
00463 
00469     virtual bool getObjectHeader(String& type_name, LongSize& ptr) = 0;
00470 
00471 
00475     virtual void writeName(const char* name) = 0;
00476 
00477 
00482     virtual bool checkName(const char* name) = 0;
00483 
00484 
00489     virtual void writeStorableHeader(const char* type_name,
00490         const char* name) = 0;
00491       
00496     virtual bool checkStorableHeader(const char* type_name,
00497         const char* name) = 0;
00498 
00501     virtual void writeStorableTrailer() = 0;
00502 
00503 
00507     virtual bool checkStorableTrailer() = 0;
00508 
00509 
00514     virtual void writePrimitiveHeader(const char* type_name,
00515         const char* name) = 0;
00516 
00522     virtual bool checkPrimitiveHeader(const char* type_name,
00523         const char* name) = 0;
00524 
00527     virtual void writePrimitiveTrailer() = 0;
00528 
00529 
00533     virtual bool checkPrimitiveTrailer() = 0;
00534 
00535 
00540     virtual void writeObjectPointerHeader(const char* type_name,
00541         const char* name) = 0;
00542 
00543 
00549     virtual bool checkObjectPointerHeader(const char* type_name,
00550         const char* name) = 0;
00551 
00552 
00557     virtual void writeObjectReferenceHeader(const char* type_name,
00558         const char* name) = 0;
00559 
00560 
00566     virtual bool checkObjectReferenceHeader(const char* type_name,
00567         const char* name) = 0;
00568 
00569 
00575     virtual void writeObjectPointerArrayHeader(const char* type_name,
00576         const char* name, Size size) = 0;
00577 
00578 
00585     virtual bool checkObjectPointerArrayHeader(const char* type_name,
00586         const char* name, Size& size) = 0;
00587 
00588 
00591     virtual void writeObjectPointerArrayTrailer() = 0;
00592 
00593 
00597     virtual bool checkObjectPointerArrayTrailer() = 0;
00598 
00599 
00602     virtual void initializeOutputStream();
00603 
00604 
00607     virtual void finalizeOutputStream();
00608 
00609 
00612     virtual void initializeInputStream();
00613 
00614 
00617     virtual void finalizeInputStream();
00618 
00620 
00639     
00642     virtual void put(const char c) = 0;
00643 
00646     virtual void put(const Byte c) = 0;
00647 
00650     virtual void put(const Index i) = 0;
00651 
00654     virtual void put(const Size p) = 0;
00655 
00658     virtual void put(const bool b) = 0;
00659 
00662     virtual void put(const Real f) = 0;
00663 
00666     virtual void put(const DoubleReal d) = 0;
00667 
00670     virtual void put(const string& s) = 0;
00671 
00674     virtual void put(const LongSize p) = 0;
00675 
00677 
00681 
00684     virtual void get(char& c) = 0;
00685 
00688     virtual void get(Byte& b) = 0;
00689 
00692     virtual void get(Index& s) = 0;
00693 
00696     virtual void get(Size& s) = 0;
00697 
00700     virtual void get(bool& b) = 0;
00701 
00704     virtual void get(Real& f) = 0;
00705 
00708     virtual void get(DoubleReal& d) = 0;
00709 
00712     virtual void get(string& s) = 0;
00713 
00716     virtual void get(LongSize& p) = 0;
00717 
00719 
00720     protected:
00721 
00722     /*_ Register all BALL kernel classes.
00723         This method is automatically called in the constructor.
00724     */
00725     void registerKernelClasses_();
00726 
00727     /*_
00728     */
00729     void addPointerPair_(LongSize old_ptr, void* new_ptr);
00730         
00731     /*_
00732      * \throws Exception::GeneralException
00733     */
00734     void addNeededObjects_();
00735 
00736     /*_
00737     */
00738     bool updatePointers_();
00739 
00740     /*_
00741     */
00742     typedef HashSet<const PersistentObject*>      ObjectSet;
00743     
00744     /*_
00745     */
00746     typedef std::list<const PersistentObject*>    ObjectList;
00747     
00748     /*_
00749     */
00750     typedef HashMap<LongSize, void*>        PointerMap;
00751     
00752     /*_
00753     */
00754     typedef std::list<std::pair<void**, LongSize> >   PointerList;
00755 
00756     /*_
00757     */
00758     typedef std::list<std::pair<boost::shared_ptr<PersistentObject>*, LongSize> > SmartPointerList;
00759 
00760     /*_
00761     */
00762     StringHashMap<CreateMethod>   create_methods_;
00763 
00764     /*_ a hash set containing the pointers of the 
00765         objects that were already written
00766     */
00767     ObjectSet   object_out_;
00768 
00769     /*_ a list of object pointers that were referenced
00770         by objects already written, but have not yet
00771         been written themselves
00772     */
00773     ObjectList  object_out_needed_;
00774 
00775     /*_ a map relating the pointers read from the stream (LongSize)
00776         with the pointers of the persistent objects that were created
00777         dynamically
00778     */
00779     PointerMap  pointer_map_;
00780     
00781     //_
00782     PointerList pointer_list_;
00783 
00784     //_
00785     SmartPointerList smart_pointer_list_;
00786 
00787     //_
00788     ObjectList  object_in_;
00789 
00790     //_
00791     ::std::ostream* ostr_;
00792     //_
00793     ::std::istream* istr_;
00794   };
00795 
00796 
00797   // implementation of templated methods
00798   
00799   template <typename T>
00800   bool PersistenceManager::checkObjectHeader(const T& /* object */,
00801       const char* name)
00802   {
00803     LongSize ptr;
00804     return checkHeader(RTTI::getStreamName<T>(), name, ptr);
00805   }
00806 
00807 
00808   template <typename T>
00809   void PersistenceManager::writeObjectHeader(const T* object,
00810       const char* name)
00811   {
00812     object_out_.insert(object);
00813     writeHeader(RTTI::getStreamName<T>(), name, (LongSize)reinterpret_cast<PointerSizeUInt>(object));
00814   }
00815 
00816 
00817   template <typename T>
00818   void PersistenceManager::writePrimitive(const T& t, const char* name)
00819   {
00820     writePrimitiveHeader(RTTI::getStreamName<T>(), name);
00821     put(t);
00822     writePrimitiveTrailer();
00823   }
00824 
00825 
00826   template <typename T>
00827   bool PersistenceManager::readPrimitive(T& t, const char* name)
00828   {
00829     if (!checkPrimitiveHeader(RTTI::getStreamName<T>(), name))
00830     {
00831       return false;
00832     }
00833 
00834     get(t);
00835     return checkPrimitiveTrailer();
00836   }
00837 
00838 
00839   template <typename T>
00840   void PersistenceManager::writeStorableObject(const T& t, const char* name)
00841   {
00842     writeStorableHeader(RTTI::getStreamName<T>(), name);
00843     t.write(*this);
00844     writeStorableTrailer();
00845   }
00846 
00847 
00848   template <typename T>
00849   bool PersistenceManager::readStorableObject(T& t, const char* name)
00850   {
00851     return (checkStorableHeader(RTTI::getStreamName<T>(), name) 
00852             && t.read(*this) && checkStorableTrailer());
00853   }
00854 
00855 
00856   template <typename T>
00857   void PersistenceManager::writeObjectPointer(const T* object, const char* name)
00858   {
00859     if (object != 0 && !object_out_.has(object))
00860     {
00861       object_out_needed_.push_back(object);
00862     }
00863 
00864     writeObjectPointerHeader(RTTI::getStreamName<T>(), name);
00865     put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(object)));
00866     writePrimitiveTrailer();
00867   }
00868 
00869 
00870   template <typename T>
00871   bool PersistenceManager::readObjectPointer(T*& object, const char* name)
00872   {
00873     if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00874     {
00875       return false;
00876     }
00877 
00878     LongSize ptr;
00879     get(ptr);
00880 
00881     if (ptr != 0)
00882     {
00883       pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00884     }
00885 
00886     object = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
00887 
00888     return checkPrimitiveTrailer();
00889   } 
00890 
00891   template <typename T>
00892   bool PersistenceManager::readObjectSmartPointer(boost::shared_ptr<T>& s_ptr, const char* name)
00893   {
00894     if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00895     {
00896       return false;
00897     }
00898 
00899     LongSize ptr;
00900     get(ptr);
00901 
00902     if (ptr != 0)
00903     {
00904       smart_pointer_list_.push_back(std::make_pair((boost::shared_ptr<PersistentObject>*)&s_ptr, (LongSize)((PersistentObject*)ptr)));
00905     }
00906 
00907     return checkPrimitiveTrailer();
00908   } 
00909 
00910   template <typename T>
00911   void PersistenceManager::writeObjectReference(const T& object,
00912       const char* name)
00913   {
00914     if (&object != 0 && !object_out_.has(&object))
00915     {
00916       object_out_needed_.push_back(&object);
00917     }
00918 
00919     writeObjectReferenceHeader(RTTI::getStreamName<T>(), name);
00920     put((LongSize)(void*)&object);
00921     writePrimitiveTrailer();
00922   } 
00923 
00924 
00925   template <typename T>
00926   bool PersistenceManager::readObjectReference(T& object, const char* name)
00927   {
00928     if (!checkObjectReferenceHeader(RTTI::getStreamName<T>(), name))
00929     {
00930       return false;
00931     }
00932 
00933     LongSize ptr;
00934     get(ptr);
00935 
00936     // store a zero in the corresponding pointer
00937     // since we cannot convert 64 bit pointers to
00938     // 32 bit pointers - this is required, if an object
00939     // written on a 64 bit architecture is read on a 32 bit
00940     // machine
00941     object = 0;
00942 
00943     if (ptr != 0)
00944     {
00945       pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00946     }
00947 
00948     return checkPrimitiveTrailer();
00949   }
00950 
00951   template <typename T>
00952   void PersistenceManager::writeObjectArray(const T* array, const char* name,
00953       Size size)
00954   {
00955     writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00956 
00957     for (Position i = 0; i < size; i++)
00958     {
00959       (*this) << array[i];
00960     }
00961 
00962     writeObjectPointerArrayTrailer();
00963   }
00964 
00965   template <typename T>
00966   bool PersistenceManager::readObjectArray
00967     (const T* array, const char* name, Size& size)
00968   {
00969     if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
00970     {
00971       return false;
00972     }
00973 
00974     T* ptr = const_cast<T*>(array);
00975     for (Position i = 0; i < size; i++) 
00976     {
00977       (*this) >> ptr[i];
00978     }
00979 
00980     bool result = checkObjectPointerArrayTrailer();
00981     return result;
00982   } 
00983 
00984   template <typename T>
00985   void PersistenceManager::writeObjectPointerArray
00986     (T** arr, const char* name, const Size size)
00987   {
00988     writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00989 
00990     PersistentObject* ptr;
00991     for (Position i = 0; i < size; i++)
00992     {
00993       ptr = (PersistentObject*)arr[i];
00994       put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(ptr)));
00995       if (ptr != 0 && !object_out_.has(ptr))
00996       {
00997         object_out_needed_.push_back(ptr);
00998       }
00999     }
01000     
01001     writeObjectPointerArrayTrailer();
01002   }
01003 
01004 
01005   template <typename T>
01006   bool PersistenceManager::readObjectPointerArray(T** array, const char* name,
01007       Size& size)
01008   {
01009     if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
01010     {
01011       return false;
01012     }
01013 
01014     LongSize ptr;
01015     for (Position i = 0; i < size; i++) 
01016     {
01017       get(ptr);
01018 
01019       if (ptr != 0)
01020       {
01021         pointer_list_.push_back(std::make_pair((void**)&(array[i]), ptr));
01022       }
01023 
01024       array[i] = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
01025     }
01026 
01027     return checkObjectPointerArrayTrailer();
01028   }
01029 
01030 #ifndef BALL_NO_INLINE_FUNCTIONS
01031 # include <BALL/CONCEPT/persistenceManager.iC>
01032 #endif
01033 
01034 } // namespace BALL
01035 
01036 #endif // BALL_CONCEPT_PERSISTENCEMANAGER_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines