BALL
1.4.1
|
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