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 #define MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC(_CONTAINER) \
00288 template< typename K, typename V > \
00289 struct TTypeName <_CONTAINER<K,V> > { \
00290 static std::string get() { \
00291 return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<K>::get() )+ std::string(",")+std::string( TTypeName<V>::get() )+std::string(">"); \
00292 } \
00293 };
00294
00295 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::map )
00296 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::multimap )
00297
00298
00299 template< typename T1, typename T2 >
00300 struct TTypeName <std::pair<T1,T2> > {
00301 static std::string get() {
00302 return std::string("std::pair<")+std::string( TTypeName<T1>::get() )+ std::string(",")+std::string( TTypeName<T2>::get() )+std::string(">");
00303 }
00304 };
00305
00306
00307
00308
00309
00310
00311 #define DEFINE_SERIALIZABLE(class_name) \
00312 protected: \
00313 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00314 static mrpt::utils::CLASSINIT _init_##class_name;\
00315 void writeToStream(mrpt::utils::CStream &out, int *getVersion) const;\
00316 void readFromStream(mrpt::utils::CStream &in, int version);\
00317 public: \
00318 typedef class_name##Ptr SmartPtr; \
00319 static mrpt::utils::TRuntimeClassId class##class_name; \
00320 static const mrpt::utils::TRuntimeClassId *classinfo; \
00321 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00322 static CSerializable* CreateObject(); \
00323 static class_name##Ptr Create(); \
00324 virtual CSerializable *duplicate() const;
00325
00326
00327
00328 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
00329 class class_name; \
00330 struct _LINKAGE_ class_name##Ptr : public mrpt::utils::CSerializablePtr \
00331 { \
00332 class_name##Ptr() : mrpt::utils::CSerializablePtr(static_cast<mrpt::utils::CSerializable*>(NULL)) { } \
00333 explicit class_name##Ptr(class_name* p) : mrpt::utils::CSerializablePtr( reinterpret_cast<mrpt::utils::CSerializable*>(p) ) { } \
00334 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : mrpt::utils::CSerializablePtr(p) \
00335 { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00336 void setFromPointerDoNotFreeAtDtor(const class_name* p) { \
00337 this->set(const_cast<mrpt::utils::CSerializable*>(reinterpret_cast<const mrpt::utils::CSerializable*>(p))); m_holder->increment(); \
00338 } \
00339 class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00340 const class_name * pointer() const { return reinterpret_cast<const class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00341 class_name* operator ->(void) { return reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00342 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00343 class_name& operator *(void) { return *reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00344 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00345 };\
00346 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00347
00348
00349
00350
00351 #define DEFINE_SERIALIZABLE_PRE(class_name) \
00352 DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name, MRPTDLLIMPEXP )
00353
00354
00355
00356 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
00357 class class_name; \
00358 struct _LINKAGE_ class_name##Ptr : public base_name##Ptr \
00359 { \
00360 class_name##Ptr() : base_name##Ptr(static_cast<base_name*>(NULL)) { } \
00361 explicit class_name##Ptr(class_name* p) : base_name##Ptr( reinterpret_cast<base_name*>(p) ) { } \
00362 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) ) } \
00363 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) ) } \
00364 class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
00365 const class_name * pointer() const { return reinterpret_cast<const class_name*>(base_name##Ptr::pointer()); } \
00366 class_name* operator ->(void) { return reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00367 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00368 class_name& operator *(void) { return *reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00369 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00370 }; \
00371 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00372
00373
00374
00375
00376 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE(class_name, base_name) \
00377 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, MRPTDLLIMPEXP )
00378
00379
00380
00381 #define IMPLEMENTS_SERIALIZABLE(class_name, base,NameSpace) \
00382 mrpt::utils::CSerializable* NameSpace::class_name::CreateObject() \
00383 { return static_cast<mrpt::utils::CSerializable*>( new NameSpace::class_name ); } \
00384 NameSpace::class_name##Ptr NameSpace::class_name::Create() \
00385 { return NameSpace::class_name##Ptr( new NameSpace::class_name ); } \
00386 const mrpt::utils::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
00387 { return CLASS_ID(base); } \
00388 mrpt::utils::TRuntimeClassId NameSpace::class_name::class##class_name = { \
00389 #class_name, sizeof(class NameSpace::class_name), NameSpace::class_name::CreateObject, \
00390 &class_name::_GetBaseClass }; \
00391 const mrpt::utils::TRuntimeClassId *NameSpace::class_name::classinfo = & NameSpace::class_name::class##class_name; \
00392 const mrpt::utils::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
00393 { return CLASS_ID_NAMESPACE(class_name,NameSpace); } \
00394 mrpt::utils::CLASSINIT NameSpace::class_name::_init_##class_name(CLASS_ID(base)); \
00395 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, NameSpace::class_name##Ptr &pObj) \
00396 { pObj = NameSpace::class_name##Ptr( in.ReadObject() ); return in; } \
00397 mrpt::utils::CSerializable * NameSpace::class_name::duplicate() const \
00398 { return static_cast<mrpt::utils::CSerializable*>( new NameSpace::class_name(*this) ); }
00399
00400
00401
00402
00403 #define DEFINE_VIRTUAL_SERIALIZABLE(class_name) \
00404 protected: \
00405 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00406 public: \
00407 static const mrpt::utils::TRuntimeClassId class##class_name; \
00408 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00409 friend class mrpt::utils::CStream; \
00410
00411
00412
00413
00414 #define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name,NameSpace) \
00415 const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
00416 { return CLASS_ID(base_class_name); } \
00417 const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
00418 #class_name, sizeof(class class_name), NULL, \
00419 &class_name::_GetBaseClass }; \
00420 const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
00421 { return CLASS_ID(class_name); } \
00422 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj) \
00423 { pObj = class_name##Ptr( in.ReadObject() ); return in; }
00424
00425
00426 }
00427 }
00428
00429
00430 namespace std
00431 {
00432
00433
00434 template <typename T,typename C>
00435 bool operator == ( const stlplus::smart_ptr_base<T,C>&a,const stlplus::smart_ptr_base<T,C>&b) {
00436 return a.aliases(b);
00437 }
00438
00439
00440 template <typename T,typename C>
00441 bool operator != ( const stlplus::smart_ptr_base<T,C>&a,const stlplus::smart_ptr_base<T,C>&b) {
00442 return !a.aliases(b);
00443 }
00444 }
00445
00446 #endif