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 void registerSmartPointer(boost::shared_ptr<PersistentObject>& s_ptr, PersistentObject* ptr);
00334
00340 template <typename T>
00341 void writeObjectReference(const T& object, const char* name);
00342
00349 template <typename T>
00350 bool readObjectReference(T& object, const char* name);
00351
00359 template <typename T>
00360 void writeObjectArray(const T* array, const char* name, Size size);
00361
00369 template <typename T>
00370 bool readObjectArray(const T* array, const char* name, Size& size);
00371
00379 template <typename T>
00380 void writeObjectPointerArray(T** arr, const char* name, const Size size);
00381
00389 template <typename T>
00390 bool readObjectPointerArray(T** array, const char* name, Size& size);
00391
00393
00397
00412 virtual void writeHeader(const char* type_name, const char* name,
00413 LongSize ptr) = 0;
00414
00424 virtual bool checkHeader(const char* type_name, const char* name,
00425 LongSize& ptr) = 0;
00426
00430 virtual void writeTrailer(const char* name = 0) = 0;
00431
00437 virtual bool checkTrailer(const char* name = 0) = 0;
00438
00439
00442 virtual void writeStreamHeader() = 0;
00443
00444
00447 virtual void writeStreamTrailer() = 0;
00448
00449
00453 virtual bool checkStreamHeader() = 0;
00454
00455
00459 virtual bool checkStreamTrailer() = 0;
00460
00461
00467 virtual bool getObjectHeader(String& type_name, LongSize& ptr) = 0;
00468
00469
00473 virtual void writeName(const char* name) = 0;
00474
00475
00480 virtual bool checkName(const char* name) = 0;
00481
00482
00487 virtual void writeStorableHeader(const char* type_name,
00488 const char* name) = 0;
00489
00494 virtual bool checkStorableHeader(const char* type_name,
00495 const char* name) = 0;
00496
00499 virtual void writeStorableTrailer() = 0;
00500
00501
00505 virtual bool checkStorableTrailer() = 0;
00506
00507
00512 virtual void writePrimitiveHeader(const char* type_name,
00513 const char* name) = 0;
00514
00520 virtual bool checkPrimitiveHeader(const char* type_name,
00521 const char* name) = 0;
00522
00525 virtual void writePrimitiveTrailer() = 0;
00526
00527
00531 virtual bool checkPrimitiveTrailer() = 0;
00532
00533
00538 virtual void writeObjectPointerHeader(const char* type_name,
00539 const char* name) = 0;
00540
00541
00547 virtual bool checkObjectPointerHeader(const char* type_name,
00548 const char* name) = 0;
00549
00550
00555 virtual void writeObjectReferenceHeader(const char* type_name,
00556 const char* name) = 0;
00557
00558
00564 virtual bool checkObjectReferenceHeader(const char* type_name,
00565 const char* name) = 0;
00566
00567
00573 virtual void writeObjectPointerArrayHeader(const char* type_name,
00574 const char* name, Size size) = 0;
00575
00576
00583 virtual bool checkObjectPointerArrayHeader(const char* type_name,
00584 const char* name, Size& size) = 0;
00585
00586
00589 virtual void writeObjectPointerArrayTrailer() = 0;
00590
00591
00595 virtual bool checkObjectPointerArrayTrailer() = 0;
00596
00597
00600 virtual void initializeOutputStream();
00601
00602
00605 virtual void finalizeOutputStream();
00606
00607
00610 virtual void initializeInputStream();
00611
00612
00615 virtual void finalizeInputStream();
00616
00618
00637
00640 virtual void put(const char c) = 0;
00641
00644 virtual void put(const Byte c) = 0;
00645
00648 virtual void put(const Index i) = 0;
00649
00652 virtual void put(const Size p) = 0;
00653
00656 virtual void put(const bool b) = 0;
00657
00660 virtual void put(const Real f) = 0;
00661
00664 virtual void put(const DoubleReal d) = 0;
00665
00668 virtual void put(const string& s) = 0;
00669
00672 virtual void put(const LongSize p) = 0;
00673
00675
00679
00682 virtual void get(char& c) = 0;
00683
00686 virtual void get(Byte& b) = 0;
00687
00690 virtual void get(Index& s) = 0;
00691
00694 virtual void get(Size& s) = 0;
00695
00698 virtual void get(bool& b) = 0;
00699
00702 virtual void get(Real& f) = 0;
00703
00706 virtual void get(DoubleReal& d) = 0;
00707
00710 virtual void get(string& s) = 0;
00711
00714 virtual void get(LongSize& p) = 0;
00715
00717
00718 protected:
00719
00720
00721
00722
00723 void registerKernelClasses_();
00724
00725
00726
00727 void addPointerPair_(LongSize old_ptr, void* new_ptr);
00728
00729
00730
00731 void addNeededObjects_()
00732 throw(Exception::GeneralException);
00733
00734
00735
00736 bool updatePointers_();
00737
00738
00739
00740 typedef HashSet<const PersistentObject*> ObjectSet;
00741
00742
00743
00744 typedef std::list<const PersistentObject*> ObjectList;
00745
00746
00747
00748 typedef HashMap<LongSize, void*> PointerMap;
00749
00750
00751
00752 typedef std::list<std::pair<void**, LongSize> > PointerList;
00753
00754
00755
00756 typedef std::list<std::pair<boost::shared_ptr<PersistentObject>*, LongSize> > SmartPointerList;
00757
00758
00759
00760 StringHashMap<CreateMethod> create_methods_;
00761
00762
00763
00764
00765 ObjectSet object_out_;
00766
00767
00768
00769
00770
00771 ObjectList object_out_needed_;
00772
00773
00774
00775
00776
00777 PointerMap pointer_map_;
00778
00779
00780 PointerList pointer_list_;
00781
00782
00783 SmartPointerList smart_pointer_list_;
00784
00785
00786 ObjectList object_in_;
00787
00788
00789 ::std::ostream* ostr_;
00790
00791 ::std::istream* istr_;
00792 };
00793
00794
00795
00796
00797 template <typename T>
00798 bool PersistenceManager::checkObjectHeader(const T& ,
00799 const char* name)
00800 {
00801 LongSize ptr;
00802 return checkHeader(RTTI::getStreamName<T>(), name, ptr);
00803 }
00804
00805
00806 template <typename T>
00807 void PersistenceManager::writeObjectHeader(const T* object,
00808 const char* name)
00809 {
00810 object_out_.insert(object);
00811 writeHeader(RTTI::getStreamName<T>(), name, (LongSize)reinterpret_cast<PointerSizeUInt>(object));
00812 }
00813
00814
00815 template <typename T>
00816 void PersistenceManager::writePrimitive(const T& t, const char* name)
00817 {
00818 writePrimitiveHeader(RTTI::getStreamName<T>(), name);
00819 put(t);
00820 writePrimitiveTrailer();
00821 }
00822
00823
00824 template <typename T>
00825 bool PersistenceManager::readPrimitive(T& t, const char* name)
00826 {
00827 if (!checkPrimitiveHeader(RTTI::getStreamName<T>(), name))
00828 {
00829 return false;
00830 }
00831
00832 get(t);
00833 return checkPrimitiveTrailer();
00834 }
00835
00836
00837 template <typename T>
00838 void PersistenceManager::writeStorableObject(const T& t, const char* name)
00839 {
00840 writeStorableHeader(RTTI::getStreamName<T>(), name);
00841 t.write(*this);
00842 writeStorableTrailer();
00843 }
00844
00845
00846 template <typename T>
00847 bool PersistenceManager::readStorableObject(T& t, const char* name)
00848 {
00849 return (checkStorableHeader(RTTI::getStreamName<T>(), name)
00850 && t.read(*this) && checkStorableTrailer());
00851 }
00852
00853
00854 template <typename T>
00855 void PersistenceManager::writeObjectPointer(const T* object, const char* name)
00856 {
00857 if (object != 0 && !object_out_.has(object))
00858 {
00859 object_out_needed_.push_back(object);
00860 }
00861
00862 writeObjectPointerHeader(RTTI::getStreamName<T>(), name);
00863 put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(object)));
00864 writePrimitiveTrailer();
00865 }
00866
00867
00868 template <typename T>
00869 bool PersistenceManager::readObjectPointer(T*& object, const char* name)
00870 {
00871 if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00872 {
00873 return false;
00874 }
00875
00876 LongSize ptr;
00877 get(ptr);
00878
00879 if (ptr != 0)
00880 {
00881 pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00882 }
00883
00884 object = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
00885
00886 return checkPrimitiveTrailer();
00887 }
00888
00889 template <typename T>
00890 void PersistenceManager::writeObjectReference(const T& object,
00891 const char* name)
00892 {
00893 if (&object != 0 && !object_out_.has(&object))
00894 {
00895 object_out_needed_.push_back(&object);
00896 }
00897
00898 writeObjectReferenceHeader(RTTI::getStreamName<T>(), name);
00899 put((LongSize)(void*)&object);
00900 writePrimitiveTrailer();
00901 }
00902
00903
00904 template <typename T>
00905 bool PersistenceManager::readObjectReference(T& object, const char* name)
00906 {
00907 if (!checkObjectReferenceHeader(RTTI::getStreamName<T>(), name))
00908 {
00909 return false;
00910 }
00911
00912 LongSize ptr;
00913 get(ptr);
00914
00915
00916
00917
00918
00919
00920 object = 0;
00921
00922 if (ptr != 0)
00923 {
00924 pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00925 }
00926
00927 return checkPrimitiveTrailer();
00928 }
00929
00930 template <typename T>
00931 void PersistenceManager::writeObjectArray(const T* array, const char* name,
00932 Size size)
00933 {
00934 writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00935
00936 for (Position i = 0; i < size; i++)
00937 {
00938 (*this) << array[i];
00939 }
00940
00941 writeObjectPointerArrayTrailer();
00942 }
00943
00944 template <typename T>
00945 bool PersistenceManager::readObjectArray
00946 (const T* array, const char* name, Size& size)
00947 {
00948 if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
00949 {
00950 return false;
00951 }
00952
00953 T* ptr = const_cast<T*>(array);
00954 for (Position i = 0; i < size; i++)
00955 {
00956 (*this) >> ptr[i];
00957 }
00958
00959 bool result = checkObjectPointerArrayTrailer();
00960 return result;
00961 }
00962
00963 template <typename T>
00964 void PersistenceManager::writeObjectPointerArray
00965 (T** arr, const char* name, const Size size)
00966 {
00967 writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00968
00969 PersistentObject* ptr;
00970 for (Position i = 0; i < size; i++)
00971 {
00972 ptr = (PersistentObject*)arr[i];
00973 put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(ptr)));
00974 if (ptr != 0 && !object_out_.has(ptr))
00975 {
00976 object_out_needed_.push_back(ptr);
00977 }
00978 }
00979
00980 writeObjectPointerArrayTrailer();
00981 }
00982
00983
00984 template <typename T>
00985 bool PersistenceManager::readObjectPointerArray(T** array, const char* name,
00986 Size& size)
00987 {
00988 if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
00989 {
00990 return false;
00991 }
00992
00993 LongSize ptr;
00994 for (Position i = 0; i < size; i++)
00995 {
00996 get(ptr);
00997
00998 if (ptr != 0)
00999 {
01000 pointer_list_.push_back(std::make_pair((void**)&(array[i]), ptr));
01001 }
01002
01003 array[i] = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
01004 }
01005
01006 return checkObjectPointerArrayTrailer();
01007 }
01008
01009 #ifndef BALL_NO_INLINE_FUNCTIONS
01010 # include <BALL/CONCEPT/persistenceManager.iC>
01011 #endif
01012
01013 }
01014
01015 #endif // BALL_CONCEPT_PERSISTENCEMANAGER_H