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 {
00040
00041
00042 namespace utils
00043 {
00044 class MRPTDLLIMPEXP CSerializable;
00045
00046 typedef stlplus::smart_ptr_clone<CSerializable> CSerializablePtr;
00047
00048
00049
00050 struct MRPTDLLIMPEXP TRuntimeClassId
00051 {
00052 const char* className;
00053 int objectSize;
00054
00055
00056 CSerializable* (*ptrCreateObject)();
00057
00058
00059 const TRuntimeClassId* (*getBaseClass)();
00060
00061
00062 CSerializable* createObject() const;
00063 bool derivedFrom(const TRuntimeClassId* pBaseClass) const;
00064 bool derivedFrom(const char* pBaseClass_name) const;
00065
00066
00067 void writeTo(mrpt::utils::CStream& out) const;
00068 static const TRuntimeClassId* loadFrom(mrpt::utils::CStream& in);
00069 };
00070
00071
00072
00073 typedef safe_ptr<TRuntimeClassId> TRuntimeClassIdPtr;
00074
00075
00076
00077
00078
00079 void MRPTDLLIMPEXP registerClass(const mrpt::utils::TRuntimeClassId* pNewClass);
00080
00081
00082
00083
00084 std::vector<const mrpt::utils::TRuntimeClassId*> MRPTDLLIMPEXP getAllRegisteredClasses();
00085
00086
00087
00088
00089 const TRuntimeClassId MRPTDLLIMPEXP * findRegisteredClass(const std::string &className);
00090
00091
00092
00093
00094 #define CLASS_ID(class_name) static_cast<const mrpt::utils::TRuntimeClassId*>(&class_name::class##class_name)
00095
00096
00097
00098 #define CLASS_ID_NAMESPACE(class_name,namespaceName) static_cast<const mrpt::utils::TRuntimeClassId*>(&namespaceName::class_name::class##class_name)
00099
00100
00101
00102 #define CLASS_ID_TEMPLATE(class_name,T) static_cast<const mrpt::utils::TRuntimeClassId*>(& template <class T> class_name<T>::class##class_name)
00103
00104
00105
00106 #define IS_CLASS( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()==CLASS_ID(class_name))
00107
00108
00109
00110 #define IS_DERIVED( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
00111
00112
00113
00114 struct MRPTDLLIMPEXP CLASSINIT
00115 {
00116 CLASSINIT(const mrpt::utils::TRuntimeClassId* pNewClass)
00117 {
00118 registerClass(pNewClass);
00119 }
00120 };
00121
00122
00123
00124
00125
00126
00127
00128
00129 class MRPTDLLIMPEXP CSerializable
00130 {
00131 protected:
00132 static mrpt::utils::TRuntimeClassId* _GetBaseClass();
00133 public:
00134 static const mrpt::utils::TRuntimeClassId classCSerializable;
00135 friend class mrpt::utils::CStream;
00136
00137
00138
00139 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const;
00140
00141
00142
00143 virtual CSerializable *duplicate() const = 0;
00144
00145
00146 CSerializable *clone() const { return duplicate(); }
00147
00148 virtual ~CSerializable();
00149
00150 protected:
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 virtual void writeToStream(mrpt::utils::CStream &out, int *getVersion) const = 0;
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 virtual void readFromStream(mrpt::utils::CStream &in, int version) = 0;
00175 };
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 std::string MRPTDLLIMPEXP ObjectToString(const CSerializable *o);
00187
00188
00189
00190
00191
00192
00193
00194 void MRPTDLLIMPEXP StringToObject(const std::string &str, CSerializablePtr &obj);
00195
00196
00197
00198
00199
00200
00201 void MRPTDLLIMPEXP ObjectToOctetVector(const CSerializable *o, vector_byte & out_vector);
00202
00203
00204
00205
00206
00207
00208
00209 void MRPTDLLIMPEXP OctetVectorToObject(const vector_byte & in_data, CSerializablePtr &obj);
00210
00211
00212
00213
00214
00215
00216
00217 void MRPTDLLIMPEXP ObjectToRawString(const CSerializable *o, std::string & out_str);
00218
00219
00220
00221
00222
00223
00224
00225 void MRPTDLLIMPEXP RawStringToObject(const std::string & in_str, CSerializablePtr &obj);
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 template<typename T>
00245 struct TTypeName
00246 {
00247 static std::string get() {
00248 return std::string( T::classinfo->className );
00249 }
00250 };
00251
00252 #define MRPT_DECLARE_TTYPENAME(_TYPE) \
00253 template<> struct TTypeName <_TYPE > { \
00254 static std::string get() { return std::string(#_TYPE); } };
00255
00256 #define MRPT_DECLARE_TTYPENAME_PTR(_TYPE) \
00257 template<> struct TTypeName <_TYPE##Ptr> { \
00258 static std::string get() { return TTypeName<_TYPE>::get(); } };
00259
00260 MRPT_DECLARE_TTYPENAME(bool)
00261 MRPT_DECLARE_TTYPENAME(double)
00262 MRPT_DECLARE_TTYPENAME(float)
00263 MRPT_DECLARE_TTYPENAME(uint64_t)
00264 MRPT_DECLARE_TTYPENAME(int64_t)
00265 MRPT_DECLARE_TTYPENAME(uint32_t)
00266 MRPT_DECLARE_TTYPENAME(int32_t)
00267 MRPT_DECLARE_TTYPENAME(uint16_t)
00268 MRPT_DECLARE_TTYPENAME(int16_t)
00269 MRPT_DECLARE_TTYPENAME(uint8_t)
00270 MRPT_DECLARE_TTYPENAME(int8_t)
00271
00272 MRPT_DECLARE_TTYPENAME(std::string)
00273
00274 #define MRPT_DECLARE_TTYPENAME_CONTAINER(_CONTAINER) \
00275 template< typename V > \
00276 struct TTypeName <_CONTAINER<V> > { \
00277 static std::string get() { \
00278 return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<V>::get() ) + std::string(">"); \
00279 } \
00280 };
00281
00282 MRPT_DECLARE_TTYPENAME_CONTAINER( std::vector )
00283 MRPT_DECLARE_TTYPENAME_CONTAINER( std::deque )
00284 MRPT_DECLARE_TTYPENAME_CONTAINER( std::list )
00285 MRPT_DECLARE_TTYPENAME_CONTAINER( std::set )
00286
00287
00288 #define MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(_CONT) \
00289 template<> struct TTypeName <_CONT> : TTypeName<std::vector<_CONT::value_type> > { };
00290
00291 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_signed_byte )
00292 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_signed_word)
00293 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_int)
00294 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_long)
00295 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_float)
00296 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_double)
00297 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_byte)
00298 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_word)
00299 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_uint)
00300
00301 #if MRPT_WORD_SIZE!=32 // If it's 32 bit, size_t <=> uint32_t
00302 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_size_t)
00303 #endif
00304
00305
00306 #define MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC(_CONTAINER) \
00307 template< typename K, typename V > \
00308 struct TTypeName <_CONTAINER<K,V> > { \
00309 static std::string get() { \
00310 return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<K>::get() )+ std::string(",")+std::string( TTypeName<V>::get() )+std::string(">"); \
00311 } \
00312 };
00313
00314 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::map )
00315 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::multimap )
00316
00317
00318 template< typename T1, typename T2 >
00319 struct TTypeName <std::pair<T1,T2> > {
00320 static std::string get() {
00321 return std::string("std::pair<")+std::string( TTypeName<T1>::get() )+ std::string(",")+std::string( TTypeName<T2>::get() )+std::string(">");
00322 }
00323 };
00324
00325
00326
00327
00328
00329
00330 #define DEFINE_SERIALIZABLE(class_name) \
00331 protected: \
00332 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00333 static mrpt::utils::CLASSINIT _init_##class_name;\
00334 void writeToStream(mrpt::utils::CStream &out, int *getVersion) const;\
00335 void readFromStream(mrpt::utils::CStream &in, int version);\
00336 public: \
00337 typedef class_name##Ptr SmartPtr; \
00338 static mrpt::utils::TRuntimeClassId class##class_name; \
00339 static const mrpt::utils::TRuntimeClassId *classinfo; \
00340 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00341 static CSerializable* CreateObject(); \
00342 static class_name##Ptr Create(); \
00343 virtual CSerializable *duplicate() const;
00344
00345
00346
00347 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
00348 class class_name; \
00349 struct _LINKAGE_ class_name##Ptr : public mrpt::utils::CSerializablePtr \
00350 { \
00351 class_name##Ptr() : mrpt::utils::CSerializablePtr(static_cast<mrpt::utils::CSerializable*>(NULL)) { } \
00352 explicit class_name##Ptr(class_name* p) : mrpt::utils::CSerializablePtr( reinterpret_cast<mrpt::utils::CSerializable*>(p) ) { } \
00353 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : mrpt::utils::CSerializablePtr(p) \
00354 { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00355 void setFromPointerDoNotFreeAtDtor(const class_name* p) { \
00356 this->set(const_cast<mrpt::utils::CSerializable*>(reinterpret_cast<const mrpt::utils::CSerializable*>(p))); m_holder->increment(); \
00357 } \
00358 class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00359 const class_name * pointer() const { return reinterpret_cast<const class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00360 class_name* operator ->(void) { return reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00361 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00362 class_name& operator *(void) { return *reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00363 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00364 };\
00365 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00366
00367
00368
00369
00370 #define DEFINE_SERIALIZABLE_PRE(class_name) \
00371 DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name, MRPTDLLIMPEXP )
00372
00373
00374
00375 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
00376 class class_name; \
00377 struct _LINKAGE_ class_name##Ptr : public base_name##Ptr \
00378 { \
00379 class_name##Ptr() : base_name##Ptr(static_cast<base_name*>(NULL)) { } \
00380 explicit class_name##Ptr(class_name* p) : base_name##Ptr( reinterpret_cast<base_name*>(p) ) { } \
00381 explicit class_name##Ptr(const base_name##Ptr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00382 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00383 class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
00384 const class_name * pointer() const { return reinterpret_cast<const class_name*>(base_name##Ptr::pointer()); } \
00385 class_name* operator ->(void) { return reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00386 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00387 class_name& operator *(void) { return *reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00388 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00389 }; \
00390 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00391
00392
00393
00394
00395 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE(class_name, base_name) \
00396 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, MRPTDLLIMPEXP )
00397
00398
00399
00400 #define IMPLEMENTS_SERIALIZABLE(class_name, base,NameSpace) \
00401 mrpt::utils::CSerializable* NameSpace::class_name::CreateObject() \
00402 { return static_cast<mrpt::utils::CSerializable*>( new NameSpace::class_name ); } \
00403 NameSpace::class_name##Ptr NameSpace::class_name::Create() \
00404 { return NameSpace::class_name##Ptr( new NameSpace::class_name ); } \
00405 const mrpt::utils::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
00406 { return CLASS_ID(base); } \
00407 mrpt::utils::TRuntimeClassId NameSpace::class_name::class##class_name = { \
00408 #class_name, sizeof(class NameSpace::class_name), NameSpace::class_name::CreateObject, \
00409 &class_name::_GetBaseClass }; \
00410 const mrpt::utils::TRuntimeClassId *NameSpace::class_name::classinfo = & NameSpace::class_name::class##class_name; \
00411 const mrpt::utils::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
00412 { return CLASS_ID_NAMESPACE(class_name,NameSpace); } \
00413 mrpt::utils::CLASSINIT NameSpace::class_name::_init_##class_name(CLASS_ID(base)); \
00414 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, NameSpace::class_name##Ptr &pObj) \
00415 { pObj = NameSpace::class_name##Ptr( in.ReadObject() ); return in; } \
00416 mrpt::utils::CSerializable * NameSpace::class_name::duplicate() const \
00417 { return static_cast<mrpt::utils::CSerializable*>( new NameSpace::class_name(*this) ); }
00418
00419
00420
00421
00422 #define DEFINE_VIRTUAL_SERIALIZABLE(class_name) \
00423 protected: \
00424 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00425 public: \
00426 static const mrpt::utils::TRuntimeClassId class##class_name; \
00427 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00428 friend class mrpt::utils::CStream; \
00429
00430
00431
00432
00433 #define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name,NameSpace) \
00434 const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
00435 { return CLASS_ID(base_class_name); } \
00436 const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
00437 #class_name, sizeof(class class_name), NULL, \
00438 &class_name::_GetBaseClass }; \
00439 const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
00440 { return CLASS_ID(class_name); } \
00441 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj) \
00442 { pObj = class_name##Ptr( in.ReadObject() ); return in; }
00443
00444
00445 }
00446 }
00447
00448
00449 namespace std
00450 {
00451
00452
00453 template <typename T,typename C>
00454 bool operator == ( const stlplus::smart_ptr_base<T,C>&a,const stlplus::smart_ptr_base<T,C>&b) {
00455 return a.aliases(b);
00456 }
00457
00458
00459 template <typename T,typename C>
00460 bool operator != ( const stlplus::smart_ptr_base<T,C>&a,const stlplus::smart_ptr_base<T,C>&b) {
00461 return !a.aliases(b);
00462 }
00463 }
00464
00465 #endif