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 namespace BALL
00038 {
00039
00069 class BALL_EXPORT PersistenceManager
00070 {
00071 public:
00072
00076
00088 typedef void * (*CreateMethod) ();
00090
00094
00097 PersistenceManager();
00098
00101 PersistenceManager(const PersistenceManager& pm);
00102
00106 PersistenceManager(::std::istream& is);
00107
00111 PersistenceManager(::std::ostream& os);
00112
00117 PersistenceManager(::std::istream& is, ::std::ostream& os);
00118
00124 virtual ~PersistenceManager();
00125
00127
00131
00156 virtual void registerClass(String signature, const CreateMethod m);
00157
00168 virtual void* createObject(String signature) const;
00169
00174 virtual Size getNumberOfClasses() const;
00175
00179 virtual void setOstream(::std::ostream& s);
00180
00184 virtual void setIstream(::std::istream& s);
00185
00194 void startOutput();
00195
00207 void endOutput();
00208
00219 PersistentObject* readObject()
00220 throw(Exception::GeneralException);
00221
00225 PersistenceManager& operator << (const PersistentObject& object);
00226
00230 PersistenceManager& operator >> (PersistentObject*& object_ptr);
00231
00233
00237
00244 template <typename T>
00245 bool checkObjectHeader(const T& , const char* name = 0);
00246
00251 bool checkObjectHeader(const char* type_name);
00252
00259 template <typename T>
00260 void writeObjectHeader(const T* object, const char* name = 0);
00261
00265 void writeObjectTrailer(const char* name = 0);
00266
00270 bool checkObjectTrailer(const char* name = 0);
00271
00278 template <typename T>
00279 void writePrimitive(const T& t, const char* name);
00280
00287 template <typename T>
00288 bool readPrimitive(T& t, const char* name);
00289
00295 template <typename T>
00296 void writeStorableObject(const T& t, const char* name);
00297
00304 template <typename T>
00305 bool readStorableObject(T& t, const char* name);
00306
00312 template <typename T>
00313 void writeObjectPointer(const T* object, const char* name);
00314
00321 template <typename T>
00322 bool readObjectPointer(T*& object, const char* name);
00323
00331 template <typename T>
00332 bool readObjectSmartPointer(boost::shared_ptr<T>& s_ptr, const char* name);
00333
00339 template <typename T>
00340 void writeObjectReference(const T& object, const char* name);
00341
00348 template <typename T>
00349 bool readObjectReference(T& object, const char* name);
00350
00358 template <typename T>
00359 void writeObjectArray(const T* array, const char* name, Size size);
00360
00368 template <typename T>
00369 bool readObjectArray(const T* array, const char* name, Size& size);
00370
00378 template <typename T>
00379 void writeObjectPointerArray(T** arr, const char* name, const Size size);
00380
00388 template <typename T>
00389 bool readObjectPointerArray(T** array, const char* name, Size& size);
00390
00392
00396
00411 virtual void writeHeader(const char* type_name, const char* name,
00412 LongSize ptr) = 0;
00413
00423 virtual bool checkHeader(const char* type_name, const char* name,
00424 LongSize& ptr) = 0;
00425
00429 virtual void writeTrailer(const char* name = 0) = 0;
00430
00436 virtual bool checkTrailer(const char* name = 0) = 0;
00437
00438
00441 virtual void writeStreamHeader() = 0;
00442
00443
00446 virtual void writeStreamTrailer() = 0;
00447
00448
00452 virtual bool checkStreamHeader() = 0;
00453
00454
00458 virtual bool checkStreamTrailer() = 0;
00459
00460
00466 virtual bool getObjectHeader(String& type_name, LongSize& ptr) = 0;
00467
00468
00472 virtual void writeName(const char* name) = 0;
00473
00474
00479 virtual bool checkName(const char* name) = 0;
00480
00481
00486 virtual void writeStorableHeader(const char* type_name,
00487 const char* name) = 0;
00488
00493 virtual bool checkStorableHeader(const char* type_name,
00494 const char* name) = 0;
00495
00498 virtual void writeStorableTrailer() = 0;
00499
00500
00504 virtual bool checkStorableTrailer() = 0;
00505
00506
00511 virtual void writePrimitiveHeader(const char* type_name,
00512 const char* name) = 0;
00513
00519 virtual bool checkPrimitiveHeader(const char* type_name,
00520 const char* name) = 0;
00521
00524 virtual void writePrimitiveTrailer() = 0;
00525
00526
00530 virtual bool checkPrimitiveTrailer() = 0;
00531
00532
00537 virtual void writeObjectPointerHeader(const char* type_name,
00538 const char* name) = 0;
00539
00540
00546 virtual bool checkObjectPointerHeader(const char* type_name,
00547 const char* name) = 0;
00548
00549
00554 virtual void writeObjectReferenceHeader(const char* type_name,
00555 const char* name) = 0;
00556
00557
00563 virtual bool checkObjectReferenceHeader(const char* type_name,
00564 const char* name) = 0;
00565
00566
00572 virtual void writeObjectPointerArrayHeader(const char* type_name,
00573 const char* name, Size size) = 0;
00574
00575
00582 virtual bool checkObjectPointerArrayHeader(const char* type_name,
00583 const char* name, Size& size) = 0;
00584
00585
00588 virtual void writeObjectPointerArrayTrailer() = 0;
00589
00590
00594 virtual bool checkObjectPointerArrayTrailer() = 0;
00595
00596
00599 virtual void initializeOutputStream();
00600
00601
00604 virtual void finalizeOutputStream();
00605
00606
00609 virtual void initializeInputStream();
00610
00611
00614 virtual void finalizeInputStream();
00615
00617
00636
00639 virtual void put(const char c) = 0;
00640
00643 virtual void put(const Byte c) = 0;
00644
00647 virtual void put(const Index i) = 0;
00648
00651 virtual void put(const Size p) = 0;
00652
00655 virtual void put(const bool b) = 0;
00656
00659 virtual void put(const Real f) = 0;
00660
00663 virtual void put(const DoubleReal d) = 0;
00664
00667 virtual void put(const string& s) = 0;
00668
00671 virtual void put(const LongSize p) = 0;
00672
00674
00678
00681 virtual void get(char& c) = 0;
00682
00685 virtual void get(Byte& b) = 0;
00686
00689 virtual void get(Index& s) = 0;
00690
00693 virtual void get(Size& s) = 0;
00694
00697 virtual void get(bool& b) = 0;
00698
00701 virtual void get(Real& f) = 0;
00702
00705 virtual void get(DoubleReal& d) = 0;
00706
00709 virtual void get(string& s) = 0;
00710
00713 virtual void get(LongSize& p) = 0;
00714
00716
00717 protected:
00718
00719
00720
00721
00722 void registerKernelClasses_();
00723
00724
00725
00726 void addPointerPair_(LongSize old_ptr, void* new_ptr);
00727
00728
00729
00730 void addNeededObjects_()
00731 throw(Exception::GeneralException);
00732
00733
00734
00735 bool updatePointers_();
00736
00737
00738
00739 typedef HashSet<const PersistentObject*> ObjectSet;
00740
00741
00742
00743 typedef std::list<const PersistentObject*> ObjectList;
00744
00745
00746
00747 typedef HashMap<LongSize, void*> PointerMap;
00748
00749
00750
00751 typedef std::list<std::pair<void**, LongSize> > PointerList;
00752
00753
00754
00755 typedef std::list<std::pair<boost::shared_ptr<PersistentObject>*, LongSize> > SmartPointerList;
00756
00757
00758
00759 StringHashMap<CreateMethod> create_methods_;
00760
00761
00762
00763
00764 ObjectSet object_out_;
00765
00766
00767
00768
00769
00770 ObjectList object_out_needed_;
00771
00772
00773
00774
00775
00776 PointerMap pointer_map_;
00777
00778
00779 PointerList pointer_list_;
00780
00781
00782 SmartPointerList smart_pointer_list_;
00783
00784
00785 ObjectList object_in_;
00786
00787
00788 ::std::ostream* ostr_;
00789
00790 ::std::istream* istr_;
00791 };
00792
00793
00794
00795
00796 template <typename T>
00797 bool PersistenceManager::checkObjectHeader(const T& ,
00798 const char* name)
00799 {
00800 LongSize ptr;
00801 return checkHeader(RTTI::getStreamName<T>(), name, ptr);
00802 }
00803
00804
00805 template <typename T>
00806 void PersistenceManager::writeObjectHeader(const T* object,
00807 const char* name)
00808 {
00809 object_out_.insert(object);
00810 writeHeader(RTTI::getStreamName<T>(), name, (LongSize)reinterpret_cast<PointerSizeUInt>(object));
00811 }
00812
00813
00814 template <typename T>
00815 void PersistenceManager::writePrimitive(const T& t, const char* name)
00816 {
00817 writePrimitiveHeader(RTTI::getStreamName<T>(), name);
00818 put(t);
00819 writePrimitiveTrailer();
00820 }
00821
00822
00823 template <typename T>
00824 bool PersistenceManager::readPrimitive(T& t, const char* name)
00825 {
00826 if (!checkPrimitiveHeader(RTTI::getStreamName<T>(), name))
00827 {
00828 return false;
00829 }
00830
00831 get(t);
00832 return checkPrimitiveTrailer();
00833 }
00834
00835
00836 template <typename T>
00837 void PersistenceManager::writeStorableObject(const T& t, const char* name)
00838 {
00839 writeStorableHeader(RTTI::getStreamName<T>(), name);
00840 t.write(*this);
00841 writeStorableTrailer();
00842 }
00843
00844
00845 template <typename T>
00846 bool PersistenceManager::readStorableObject(T& t, const char* name)
00847 {
00848 return (checkStorableHeader(RTTI::getStreamName<T>(), name)
00849 && t.read(*this) && checkStorableTrailer());
00850 }
00851
00852
00853 template <typename T>
00854 void PersistenceManager::writeObjectPointer(const T* object, const char* name)
00855 {
00856 if (object != 0 && !object_out_.has(object))
00857 {
00858 object_out_needed_.push_back(object);
00859 }
00860
00861 writeObjectPointerHeader(RTTI::getStreamName<T>(), name);
00862 put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(object)));
00863 writePrimitiveTrailer();
00864 }
00865
00866
00867 template <typename T>
00868 bool PersistenceManager::readObjectPointer(T*& object, const char* name)
00869 {
00870 if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00871 {
00872 return false;
00873 }
00874
00875 LongSize ptr;
00876 get(ptr);
00877
00878 if (ptr != 0)
00879 {
00880 pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00881 }
00882
00883 object = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
00884
00885 return checkPrimitiveTrailer();
00886 }
00887
00888 template <typename T>
00889 bool PersistenceManager::readObjectSmartPointer(boost::shared_ptr<T>& s_ptr, const char* name)
00890 {
00891 if (!checkObjectPointerHeader(RTTI::getStreamName<T>(), name))
00892 {
00893 return false;
00894 }
00895
00896 LongSize ptr;
00897 get(ptr);
00898
00899 if (ptr != 0)
00900 {
00901 smart_pointer_list_.push_back(std::make_pair((boost::shared_ptr<PersistentObject>*)&s_ptr, (LongSize)((PersistentObject*)ptr)));
00902 }
00903
00904 return checkPrimitiveTrailer();
00905 }
00906
00907 template <typename T>
00908 void PersistenceManager::writeObjectReference(const T& object,
00909 const char* name)
00910 {
00911 if (&object != 0 && !object_out_.has(&object))
00912 {
00913 object_out_needed_.push_back(&object);
00914 }
00915
00916 writeObjectReferenceHeader(RTTI::getStreamName<T>(), name);
00917 put((LongSize)(void*)&object);
00918 writePrimitiveTrailer();
00919 }
00920
00921
00922 template <typename T>
00923 bool PersistenceManager::readObjectReference(T& object, const char* name)
00924 {
00925 if (!checkObjectReferenceHeader(RTTI::getStreamName<T>(), name))
00926 {
00927 return false;
00928 }
00929
00930 LongSize ptr;
00931 get(ptr);
00932
00933
00934
00935
00936
00937
00938 object = 0;
00939
00940 if (ptr != 0)
00941 {
00942 pointer_list_.push_back(std::make_pair((void**)&object, ptr));
00943 }
00944
00945 return checkPrimitiveTrailer();
00946 }
00947
00948 template <typename T>
00949 void PersistenceManager::writeObjectArray(const T* array, const char* name,
00950 Size size)
00951 {
00952 writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00953
00954 for (Position i = 0; i < size; i++)
00955 {
00956 (*this) << array[i];
00957 }
00958
00959 writeObjectPointerArrayTrailer();
00960 }
00961
00962 template <typename T>
00963 bool PersistenceManager::readObjectArray
00964 (const T* array, const char* name, Size& size)
00965 {
00966 if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
00967 {
00968 return false;
00969 }
00970
00971 T* ptr = const_cast<T*>(array);
00972 for (Position i = 0; i < size; i++)
00973 {
00974 (*this) >> ptr[i];
00975 }
00976
00977 bool result = checkObjectPointerArrayTrailer();
00978 return result;
00979 }
00980
00981 template <typename T>
00982 void PersistenceManager::writeObjectPointerArray
00983 (T** arr, const char* name, const Size size)
00984 {
00985 writeObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size);
00986
00987 PersistentObject* ptr;
00988 for (Position i = 0; i < size; i++)
00989 {
00990 ptr = (PersistentObject*)arr[i];
00991 put(static_cast<LongSize>(reinterpret_cast<PointerSizeUInt>(ptr)));
00992 if (ptr != 0 && !object_out_.has(ptr))
00993 {
00994 object_out_needed_.push_back(ptr);
00995 }
00996 }
00997
00998 writeObjectPointerArrayTrailer();
00999 }
01000
01001
01002 template <typename T>
01003 bool PersistenceManager::readObjectPointerArray(T** array, const char* name,
01004 Size& size)
01005 {
01006 if (!checkObjectPointerArrayHeader(RTTI::getStreamName<T>(), name, size))
01007 {
01008 return false;
01009 }
01010
01011 LongSize ptr;
01012 for (Position i = 0; i < size; i++)
01013 {
01014 get(ptr);
01015
01016 if (ptr != 0)
01017 {
01018 pointer_list_.push_back(std::make_pair((void**)&(array[i]), ptr));
01019 }
01020
01021 array[i] = reinterpret_cast<T*>(static_cast<PointerSizeUInt>(ptr));
01022 }
01023
01024 return checkObjectPointerArrayTrailer();
01025 }
01026
01027 #ifndef BALL_NO_INLINE_FUNCTIONS
01028 # include <BALL/CONCEPT/persistenceManager.iC>
01029 #endif
01030
01031 }
01032
01033 #endif // BALL_CONCEPT_PERSISTENCEMANAGER_H