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(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
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 template<typename T>
00228 struct TTypeName
00229 {
00230 static std::string get() {
00231 return std::string( T::classinfo->className );
00232 }
00233 };
00234
00235 #define MRPT_DECLARE_TTYPENAME(_TYPE) \
00236 template<> struct TTypeName <_TYPE > { \
00237 static std::string get() { return std::string(#_TYPE); } };
00238
00239 #define MRPT_DECLARE_TTYPENAME_PTR(_TYPE) \
00240 template<> struct TTypeName <_TYPE##Ptr> { \
00241 static std::string get() { return TTypeName<_TYPE>::get(); } };
00242
00243 MRPT_DECLARE_TTYPENAME(bool)
00244 MRPT_DECLARE_TTYPENAME(double)
00245 MRPT_DECLARE_TTYPENAME(float)
00246 MRPT_DECLARE_TTYPENAME(uint64_t)
00247 MRPT_DECLARE_TTYPENAME(int64_t)
00248 MRPT_DECLARE_TTYPENAME(uint32_t)
00249 MRPT_DECLARE_TTYPENAME(int32_t)
00250 MRPT_DECLARE_TTYPENAME(uint16_t)
00251 MRPT_DECLARE_TTYPENAME(int16_t)
00252 MRPT_DECLARE_TTYPENAME(uint8_t)
00253 MRPT_DECLARE_TTYPENAME(int8_t)
00254
00255 MRPT_DECLARE_TTYPENAME(std::string)
00256
00257 #define MRPT_DECLARE_TTYPENAME_CONTAINER(_CONTAINER) \
00258 template< typename V > \
00259 struct TTypeName <_CONTAINER<V> > { \
00260 static std::string get() { \
00261 return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<V>::get() ) + std::string(">"); \
00262 } \
00263 };
00264
00265 MRPT_DECLARE_TTYPENAME_CONTAINER( std::vector )
00266 MRPT_DECLARE_TTYPENAME_CONTAINER( std::deque )
00267 MRPT_DECLARE_TTYPENAME_CONTAINER( std::list )
00268 MRPT_DECLARE_TTYPENAME_CONTAINER( std::set )
00269
00270 #define MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC(_CONTAINER) \
00271 template< typename K, typename V > \
00272 struct TTypeName <_CONTAINER<K,V> > { \
00273 static std::string get() { \
00274 return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<K>::get() )+ std::string(",")+std::string( TTypeName<V>::get() )+std::string(">"); \
00275 } \
00276 };
00277
00278 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::map )
00279 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::multimap )
00280
00281
00282 template< typename T1, typename T2 >
00283 struct TTypeName <std::pair<T1,T2> > {
00284 static std::string get() {
00285 return std::string("std::pair<")+std::string( TTypeName<T1>::get() )+ std::string(",")+std::string( TTypeName<T2>::get() )+std::string(">");
00286 }
00287 };
00288
00289
00290
00291
00292
00293
00294 #define DEFINE_SERIALIZABLE(class_name) \
00295 protected: \
00296 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00297 static mrpt::utils::CLASSINIT _init_##class_name;\
00298 void writeToStream(mrpt::utils::CStream &out, int *getVersion) const;\
00299 void readFromStream(mrpt::utils::CStream &in, int version);\
00300 public: \
00301 typedef class_name##Ptr SmartPtr; \
00302 static mrpt::utils::TRuntimeClassId class##class_name; \
00303 static const mrpt::utils::TRuntimeClassId *classinfo; \
00304 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00305 static CSerializable* CreateObject(); \
00306 static class_name##Ptr Create(); \
00307 virtual CSerializable *duplicate() const;
00308
00309
00310
00311 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
00312 class class_name; \
00313 struct _LINKAGE_ class_name##Ptr : public mrpt::utils::CSerializablePtr \
00314 { \
00315 class_name##Ptr() : mrpt::utils::CSerializablePtr(static_cast<mrpt::utils::CSerializable*>(NULL)) { } \
00316 explicit class_name##Ptr(class_name* p) : mrpt::utils::CSerializablePtr( reinterpret_cast<mrpt::utils::CSerializable*>(p) ) { } \
00317 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : mrpt::utils::CSerializablePtr(p) \
00318 { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00319 void setFromPointerDoNotFreeAtDtor(const class_name* p) { \
00320 this->set(const_cast<mrpt::utils::CSerializable*>(reinterpret_cast<const mrpt::utils::CSerializable*>(p))); m_holder->increment(); \
00321 } \
00322 class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00323 const class_name * pointer() const { return reinterpret_cast<const class_name*>(mrpt::utils::CSerializablePtr::pointer()); } \
00324 class_name* operator ->(void) { return reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00325 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00326 class_name& operator *(void) { return *reinterpret_cast<class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00327 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( mrpt::utils::CSerializablePtr::operator ->() ); } \
00328 };\
00329 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00330
00331
00332
00333
00334 #define DEFINE_SERIALIZABLE_PRE(class_name) \
00335 DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name, MRPTDLLIMPEXP )
00336
00337
00338
00339 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
00340 class class_name; \
00341 struct _LINKAGE_ class_name##Ptr : public base_name##Ptr \
00342 { \
00343 class_name##Ptr() : base_name##Ptr(static_cast<base_name*>(NULL)) { } \
00344 explicit class_name##Ptr(class_name* p) : base_name##Ptr( reinterpret_cast<base_name*>(p) ) { } \
00345 explicit class_name##Ptr(const base_name##Ptr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00346 explicit class_name##Ptr(const mrpt::utils::CSerializablePtr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
00347 class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
00348 const class_name * pointer() const { return reinterpret_cast<const class_name*>(base_name##Ptr::pointer()); } \
00349 class_name* operator ->(void) { return reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00350 const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00351 class_name& operator *(void) { return *reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00352 const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00353 }; \
00354 _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00355
00356
00357
00358
00359 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE(class_name, base_name) \
00360 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, MRPTDLLIMPEXP )
00361
00362
00363
00364 #define IMPLEMENTS_SERIALIZABLE(class_name, base,NameSpace) \
00365 mrpt::utils::CSerializable* NameSpace::class_name::CreateObject() \
00366 { return static_cast<mrpt::utils::CSerializable*>( new NameSpace::class_name ); } \
00367 NameSpace::class_name##Ptr NameSpace::class_name::Create() \
00368 { return NameSpace::class_name##Ptr( new NameSpace::class_name ); } \
00369 const mrpt::utils::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
00370 { return CLASS_ID(base); } \
00371 mrpt::utils::TRuntimeClassId NameSpace::class_name::class##class_name = { \
00372 #class_name, sizeof(class NameSpace::class_name), NameSpace::class_name::CreateObject, \
00373 &class_name::_GetBaseClass }; \
00374 const mrpt::utils::TRuntimeClassId *NameSpace::class_name::classinfo = & NameSpace::class_name::class##class_name; \
00375 const mrpt::utils::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
00376 { return CLASS_ID_NAMESPACE(class_name,NameSpace); } \
00377 mrpt::utils::CLASSINIT NameSpace::class_name::_init_##class_name(CLASS_ID(base)); \
00378 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, NameSpace::class_name##Ptr &pObj) \
00379 { pObj = NameSpace::class_name##Ptr( in.ReadObject() ); return in; } \
00380 mrpt::utils::CSerializable * NameSpace::class_name::duplicate() const \
00381 { return static_cast<mrpt::utils::CSerializable*>( new NameSpace::class_name(*this) ); }
00382
00383
00384
00385
00386 #define DEFINE_VIRTUAL_SERIALIZABLE(class_name) \
00387 protected: \
00388 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00389 public: \
00390 static const mrpt::utils::TRuntimeClassId class##class_name; \
00391 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00392 friend class mrpt::utils::CStream; \
00393
00394
00395
00396
00397 #define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name,NameSpace) \
00398 const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
00399 { return CLASS_ID(base_class_name); } \
00400 const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
00401 #class_name, sizeof(class class_name), NULL, \
00402 &class_name::_GetBaseClass }; \
00403 const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
00404 { return CLASS_ID(class_name); } \
00405 mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj) \
00406 { pObj = class_name##Ptr( in.ReadObject() ); return in; }
00407
00408
00409 }
00410 }
00411
00412
00413 namespace std
00414 {
00415
00416
00417 template <typename T,typename C>
00418 bool operator == ( const stlplus::smart_ptr_base<T,C>&a,const stlplus::smart_ptr_base<T,C>&b) {
00419 return a.aliases(b);
00420 }
00421
00422
00423 template <typename T,typename C>
00424 bool operator != ( const stlplus::smart_ptr_base<T,C>&a,const stlplus::smart_ptr_base<T,C>&b) {
00425 return !a.aliases(b);
00426 }
00427 }
00428
00429 #endif