00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CSERIALIZABLE_H
00029 #define CSERIALIZABLE_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/utils/CStream.h>
00033 #include <mrpt/utils/safe_pointers.h>
00034
00035
00036
00037
00038 namespace mrpt
00039 {
00042 namespace utils
00043 {
00044 class MRPTDLLIMPEXP CSerializable;
00046 typedef stlplus::smart_ptr_clone<CSerializable> CSerializablePtr;
00047
00050 struct MRPTDLLIMPEXP TRuntimeClassId
00051 {
00052 const char* className;
00053 int objectSize;
00056 CSerializable* (*ptrCreateObject)();
00059 const TRuntimeClassId* (*getBaseClass)();
00060
00061
00062 CSerializable* createObject() const;
00063 bool derivedFrom(const TRuntimeClassId* pBaseClass) const;
00064
00065
00066 void writeTo(mrpt::utils::CStream& out) const;
00067 static const TRuntimeClassId* loadFrom(mrpt::utils::CStream& in);
00068 };
00069
00072 typedef safe_ptr<TRuntimeClassId> TRuntimeClassIdPtr;
00073
00078 void MRPTDLLIMPEXP registerClass(const mrpt::utils::TRuntimeClassId* pNewClass);
00079
00083 std::vector<const mrpt::utils::TRuntimeClassId*> MRPTDLLIMPEXP getAllRegisteredClasses();
00084
00087 #define CLASS_ID(class_name) static_cast<const mrpt::utils::TRuntimeClassId*>(&class_name::class##class_name)
00088
00091 #define CLASS_ID_NAMESPACE(class_name,namespaceName) static_cast<const mrpt::utils::TRuntimeClassId*>(&namespaceName::class_name::class##class_name)
00092
00095 #define CLASS_ID_TEMPLATE(class_name,T) static_cast<const mrpt::utils::TRuntimeClassId*>(& template <class T> class_name<T>::class##class_name)
00096
00099 #define IS_CLASS( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()==CLASS_ID(class_name))
00100
00103 #define IS_DERIVED( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
00104
00107 struct MRPTDLLIMPEXP CLASSINIT
00108 {
00109 CLASSINIT(const mrpt::utils::TRuntimeClassId* pNewClass)
00110 {
00111 registerClass(pNewClass);
00112 }
00113 };
00114
00117 #define DEFINE_SERIALIZABLE(class_name) \
00118 protected: \
00119 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00120 static mrpt::utils::CLASSINIT _init_##class_name;\
00121 void writeToStream(mrpt::utils::CStream &out, int *getVersion) const;\
00122 void readFromStream(mrpt::utils::CStream &in, int version);\
00123 public: \
00124 typedef class_name##Ptr SmartPtr; \
00125 static mrpt::utils::TRuntimeClassId class##class_name; \
00126 static const mrpt::utils::TRuntimeClassId *classinfo; \
00127 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00128 static CSerializable* CreateObject(); \
00129 virtual CSerializable *duplicate() const;
00130
00133 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
00134 class class_name; \
00135 struct _LINKAGE_ class_name##Ptr : public mrpt::utils::CSerializablePtr \
00136 { \
00137 class_name##Ptr() : mrpt::utils::CSerializablePtr(static_cast<mrpt::utils::CSerializable*>(NULL)) { } \
00138 explicit class_name##Ptr(class_name* p) : mrpt::utils::CSerializablePtr( reinterpret_cast<mrpt::utils::CSerializable*>(p) ) { } \
00139 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : mrpt::utils::CSerializablePtr(p) { } \
00140 class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00141 const class_name * pointer() const { return reinterpret_cast<const class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00142 class_name* operator ->(void) { return reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00143 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00144 class_name& operator *(void) { return *reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00145 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00146 }; \
00147 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00148
00151 #define DEFINE_SERIALIZABLE_PRE(class_name) \
00152 DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name, MRPTDLLIMPEXP )
00153
00156 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
00157 class class_name; \
00158 struct _LINKAGE_ class_name##Ptr : public base_name##Ptr \
00159 { \
00160 class_name##Ptr() : base_name##Ptr(static_cast<base_name*>(NULL)) { } \
00161 explicit class_name##Ptr(class_name* p) : base_name##Ptr( reinterpret_cast<base_name*>(p) ) { } \
00162 explicit class_name##Ptr(const base_name##Ptr & p) : base_name##Ptr(p) { } \
00163 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : base_name##Ptr(p) { } \
00164 class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
00165 const class_name * pointer() const { return reinterpret_cast<const class_name*>(base_name##Ptr::pointer()); } \
00166 class_name* operator ->(void) { return reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00167 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00168 class_name& operator *(void) { return *reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00169 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00170 }; \
00171 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00172
00173
00176 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE(class_name, base_name) \
00177 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, MRPTDLLIMPEXP )
00178
00181 #define IMPLEMENTS_SERIALIZABLE(class_name, base,NameSpace) \
00182 mrpt::utils::CSerializable* class_name::CreateObject() \
00183 { return static_cast<mrpt::utils::CSerializable*>( new class_name ); } \
00184 const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
00185 { return CLASS_ID(base); } \
00186 mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
00187 #class_name, sizeof(class class_name), class_name::CreateObject, \
00188 &class_name::_GetBaseClass }; \
00189 const mrpt::utils::TRuntimeClassId *class_name::classinfo = & class_name::class##class_name; \
00190 const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
00191 { return CLASS_ID(class_name); } \
00192 mrpt::utils::CLASSINIT class_name::_init_##class_name(CLASS_ID(class_name)); \
00193 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj) \
00194 { pObj = class_name##Ptr( in.ReadObject() ); return in; } \
00195 mrpt::utils::CSerializable * class_name::duplicate() const \
00196 { return static_cast<mrpt::utils::CSerializable*>( new class_name(*this) ); }
00197
00198
00201 #define DEFINE_VIRTUAL_SERIALIZABLE(class_name) \
00202 protected: \
00203 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00204 public: \
00205 static const mrpt::utils::TRuntimeClassId class##class_name; \
00206 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00207 friend class mrpt::utils::CStream; \
00208
00209
00212 #define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name,NameSpace) \
00213 const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
00214 { return CLASS_ID(base_class_name); } \
00215 const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
00216 #class_name, sizeof(class class_name), NULL, \
00217 &class_name::_GetBaseClass }; \
00218 const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
00219 { return CLASS_ID(class_name); } \
00220 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj) \
00221 { pObj = class_name##Ptr( in.ReadObject() ); return in; }
00222
00223
00230 class MRPTDLLIMPEXP CSerializable
00231 {
00232 protected:
00233 static mrpt::utils::TRuntimeClassId* _GetBaseClass();
00234 public:
00235 static const mrpt::utils::TRuntimeClassId classCSerializable;
00236 friend class mrpt::utils::CStream;
00237
00240 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const;
00241
00244 virtual CSerializable *duplicate() const = 0;
00245
00247 CSerializable *clone() const { return duplicate(); }
00248
00249 virtual ~CSerializable();
00250
00251 protected:
00263 virtual void writeToStream(mrpt::utils::CStream &out, int *getVersion) const = 0;
00264
00275 virtual void readFromStream(mrpt::utils::CStream &in, int version) = 0;
00276 };
00277
00278
00287 std::string MRPTDLLIMPEXP ObjectToString(const CSerializable *o);
00288
00295 void MRPTDLLIMPEXP StringToObject(std::string &str, CSerializablePtr &obj);
00296
00302 void MRPTDLLIMPEXP ObjectToOctetVector(const CSerializable *o, vector_byte & out_vector);
00303
00310 void MRPTDLLIMPEXP OctetVectorToObject(const vector_byte & in_data, CSerializablePtr &obj);
00311
00319 struct ObjectMakeUnique
00320 {
00321 void operator()(CSerializablePtr &ptr)
00322 {
00323 ptr.make_unique();
00324 }
00325 };
00326
00328 struct ObjectPairMakeUnique
00329 {
00330 template <typename T>
00331 void operator()(T &ptr)
00332 {
00333 ptr.first.make_unique();
00334 ptr.second.make_unique();
00335 }
00336 };
00337
00339 struct ObjectClearUnique
00340 {
00341 void operator()(CSerializablePtr &ptr)
00342 {
00343 ptr.clear_unique();
00344 }
00345 };
00346
00348 struct ObjectReadFromStream
00349 {
00350 private:
00351 CStream *m_stream;
00352 public:
00353 ObjectReadFromStream(CStream *stream) : m_stream(stream) { }
00354
00355 void operator()(CSerializablePtr &ptr)
00356 {
00357 (*m_stream) >> ptr;
00358 }
00359 };
00360
00364 }
00365 }
00366
00367 #endif