00001
00002
00003
00004
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& , 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
00722
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
00764
00765
00766 ObjectSet object_out_;
00767
00768
00769
00770
00771
00772 ObjectList object_out_needed_;
00773
00774
00775
00776
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
00797
00798 template <typename T>
00799 bool PersistenceManager::checkObjectHeader(const T& ,
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
00936
00937
00938
00939
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 }
01034
01035 #endif // BALL_CONCEPT_PERSISTENCEMANAGER_H