00001
00002
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& , 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
00723
00724
00725 void registerKernelClasses_();
00726
00727
00728
00729 void addPointerPair_(LongSize old_ptr, void* new_ptr);
00730
00731
00732
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
00765
00766
00767 ObjectSet object_out_;
00768
00769
00770
00771
00772
00773 ObjectList object_out_needed_;
00774
00775
00776
00777
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
00798
00799 template <typename T>
00800 bool PersistenceManager::checkObjectHeader(const T& ,
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
00937
00938
00939
00940
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 }
01035
01036 #endif // BALL_CONCEPT_PERSISTENCEMANAGER_H