Main MRPT website > C++ reference
MRPT logo

CSerializable.h

Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                   http://mrpt.sourceforge.net/                            |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef  CSERIALIZABLE_H
00029 #define  CSERIALIZABLE_H
00030 
00031 #include <mrpt/utils/CObject.h>
00032 #include <mrpt/utils/CStream.h>
00033 #include <mrpt/utils/safe_pointers.h>
00034 
00035 namespace mrpt
00036 {
00037         /** Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
00038           */
00039         namespace utils
00040         {
00041                 DEFINE_MRPT_OBJECT_PRE( CSerializable )
00042 
00043                 /** The virtual base class which provides a unified interface for all persistent objects in MRPT.
00044                  *  Many important properties of this class are inherited from mrpt::utils::CObject. See that class for more details.
00045                  *       Refer to the tutorial about <a href="http://www.mrpt.org/Serialization" >serialization</a> in the wiki.
00046                  * \sa CStream
00047                  */
00048                 class BASE_IMPEXP CSerializable : public mrpt::utils::CObject
00049                 {
00050                         // This must be added to any CObject derived class:
00051                         DEFINE_VIRTUAL_MRPT_OBJECT( CSerializable )
00052 
00053                         virtual ~CSerializable() { }
00054 
00055                 protected:
00056                          /** Introduces a pure virtual method responsible for writing to a CStream.
00057                           *  This can not be used directly be users, instead use "stream << object;"
00058                           *   for writing it to a stream.
00059                           * \param out The output binary stream where object must be dumped.
00060                           * \param getVersion If NULL, the object must be dumped. If not, only the
00061                           *             version of the object dump must be returned in this pointer. This enables
00062                           *     the versioning of objects dumping and backward compatibility with previously
00063                           *     stored data.
00064                           *     \exception std::exception On any error, see CStream::WriteBuffer
00065                           * \sa CStream
00066                           */
00067                         virtual void  writeToStream(mrpt::utils::CStream &out, int *getVersion) const = 0;
00068 
00069                          /** Introduces a pure virtual method responsible for loading from a CStream
00070                           *  This can not be used directly be users, instead use "stream >> object;"
00071                           *   for reading it from a stream or "stream >> object_ptr;" if the class is
00072                           *   unknown apriori.
00073                           * \param in The input binary stream where the object data must read from.
00074                           * \param version The version of the object stored in the stream: use this version
00075                           *                number in your code to know how to read the incoming data.
00076                           *     \exception std::exception On any error, see CStream::ReadBuffer
00077                           * \sa CStream
00078                           */
00079                         virtual void  readFromStream(mrpt::utils::CStream &in, int version) = 0;
00080                 }; // End of class def.
00081 
00082 
00083                 /** @name Non-streaming serialization functions
00084                 @{ */
00085 
00086                 /** Used to pass MRPT objects into a CORBA-like object (strings). See doc about "Integration with BABEL".
00087                  * \param o The object to be serialized.
00088                  * \return The string containing the binay version of object.
00089                  * \sa StringToObject, <a href="http://www.mrpt.org/Integration_with_BABEL">Integration with BABEL</a>
00090                  */
00091                 std::string BASE_IMPEXP ObjectToString(const CSerializable *o);
00092 
00093                 /** Used to pass CORBA-like objects (strings) into a MRPT object.
00094                  * \param str An string generated with ObjectToString
00095                  * \param obj A currently empty pointer, where a pointer to the newly created object will be stored.
00096                  * \exception None On any internal exception, this function returns NULL.
00097                  * \sa ObjectToString, <a href="http://www.mrpt.org/Integration_with_BABEL">Integration with BABEL</a>
00098                  */
00099                 void BASE_IMPEXP StringToObject(const std::string &str, CSerializablePtr &obj);
00100 
00101                 /** Converts (serializes) an MRPT object into an array of bytes.
00102                  * \param o The object to be serialized.
00103                  * \param out_vector The vector which at return will contain the data. Size will be set automatically.
00104                  * \sa OctetVectorToObject, ObjectToString
00105                  */
00106                 void BASE_IMPEXP ObjectToOctetVector(const CSerializable *o, vector_byte & out_vector);
00107 
00108                 /** Converts back (de-serializes) a sequence of binary data into a MRPT object, without prior information about the object's class.
00109                  * \param in_data The serialized input data representing the object.
00110                  * \param obj The newly created object will be stored in this smart pointer.
00111                  * \exception None On any internal exception, this function returns a NULL pointer.
00112                  * \sa ObjectToOctetVector, StringToObject
00113                  */
00114                 void BASE_IMPEXP OctetVectorToObject(const vector_byte & in_data, CSerializablePtr &obj);
00115 
00116                 /** Converts (serializes) an MRPT object into an array of bytes within a std::string, without codifying to avoid NULL characters.
00117                  *  This is therefore more efficient than ObjectToString
00118                  * \param o The object to be serialized.
00119                  * \param out_vector The string which at return will contain the data. Size will be set automatically.
00120                  * \sa RawStringToObject, ObjectToOctetVector
00121                  */
00122                 void BASE_IMPEXP ObjectToRawString(const CSerializable *o, std::string & out_str);
00123 
00124                 /** Converts back (de-serializes) a sequence of binary data within a std::string into a MRPT object, without prior information about the object's class.
00125                  * \param in_data The serialized input data representing the object.
00126                  * \param obj The newly created object will be stored in this smart pointer.
00127                  * \exception None On any internal exception, this function returns a NULL pointer.
00128                  * \sa ObjectToRawString
00129                  */
00130                 void BASE_IMPEXP RawStringToObject(const std::string & in_str, CSerializablePtr &obj);
00131 
00132                 /** @} */
00133 
00134 
00135 
00136                 /** @name Conversion of type to string at compile time
00137                   * IMPORTANT: See also the implementation of Serialization for STL containers in mrpt/utils/stl_extensions.h
00138                 @{ */
00139 
00140                 /** A template to obtain the type of its argument as a string at compile time.
00141                   *  It works with all classes derived from  CSerializable, plus many specializations for the plain data types (bool, double, uint8_t, etc...)
00142                   *   For example:
00143                   *  \code
00144                   *     cout << TTypeName<double>::get() << endl;                          // "double"
00145                   *     cout << TTypeName<CPose2D>::get() << endl;                         // "CPose2D"
00146                   *     cout << TTypeName<mrpt::slam::COccupancyGridMap2D>::get() << endl; // "COccupancyGridMap2D"
00147                   *  \endcode
00148                   *
00149                   *  Users can extend this for custom structs/classes with the macro DECLARE_CUSTOM_TTYPENAME:
00150                   *  \code
00151                   *     class MyClass { ... };
00152                   *     DECLARE_CUSTOM_TTYPENAME(MyClass)
00153                   *     cout << TTypeName<MyClass>::get() << endl;                          // "MyClass"
00154                   *  \endcode
00155                   *  
00156                   *  The following types are NOT ALLOWED since they have platform-dependant sizes:
00157                   *  - int, unsigned int
00158                   *  - long, unsigned long
00159                   *  - short, unsigned short
00160                   *  - size_t
00161                   *
00162                   */
00163                 template<typename T>
00164                 struct TTypeName
00165                 {
00166                         static std::string get() {
00167                                 return std::string( T::classinfo->className );
00168                         }
00169                 };
00170 
00171                 /** Identical to MRPT_DECLARE_TTYPENAME but intended for user code.
00172                   * MUST be placed at the GLOBAL namespace.
00173                   */
00174                 #define DECLARE_CUSTOM_TTYPENAME(_TYPE) \
00175                         namespace mrpt { namespace utils { MRPT_DECLARE_TTYPENAME(_TYPE) } }
00176 
00177                 #define MRPT_DECLARE_TTYPENAME(_TYPE) \
00178                         template<> struct TTypeName <_TYPE > { \
00179                                 static std::string get() { return std::string(#_TYPE); } };
00180 
00181                 #define MRPT_DECLARE_TTYPENAME_PTR(_TYPE) \
00182                         template<> struct TTypeName <_TYPE##Ptr> { \
00183                         static std::string get() { return TTypeName<_TYPE>::get(); }    };
00184 
00185                 MRPT_DECLARE_TTYPENAME(bool)
00186                 MRPT_DECLARE_TTYPENAME(double)
00187                 MRPT_DECLARE_TTYPENAME(float)
00188                 MRPT_DECLARE_TTYPENAME(uint64_t)
00189                 MRPT_DECLARE_TTYPENAME(int64_t)
00190                 MRPT_DECLARE_TTYPENAME(uint32_t)
00191                 MRPT_DECLARE_TTYPENAME(int32_t)
00192                 MRPT_DECLARE_TTYPENAME(uint16_t)
00193                 MRPT_DECLARE_TTYPENAME(int16_t)
00194                 MRPT_DECLARE_TTYPENAME(uint8_t)
00195                 MRPT_DECLARE_TTYPENAME(int8_t)
00196 
00197                 MRPT_DECLARE_TTYPENAME(std::string)
00198 
00199 
00200                 #define MRPT_DECLARE_TTYPENAME_CONTAINER(_CONTAINER) \
00201                         template< typename V > \
00202                         struct TTypeName <_CONTAINER<V> > { \
00203                                 static std::string get() { \
00204                                         return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<V>::get() ) + std::string(">"); \
00205                                 } \
00206                         };
00207 
00208                 MRPT_DECLARE_TTYPENAME_CONTAINER( std::vector )
00209                 MRPT_DECLARE_TTYPENAME_CONTAINER( std::deque )
00210                 MRPT_DECLARE_TTYPENAME_CONTAINER( std::list )
00211                 MRPT_DECLARE_TTYPENAME_CONTAINER( std::set )
00212 
00213                 // These ones act as a "translation" between vector_XXX types and their base classes:
00214                 #define MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(_CONT) \
00215                         template<> struct TTypeName <_CONT> : TTypeName<std::vector<_CONT::Scalar> > { };
00216 
00217                 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_float)
00218                 MRPT_DECLARE_TTYPENAME_MAP_FOR_VECTOR(vector_double)
00219 
00220                 // These ones are not needed since typedef's of "std::vector<>" are automatically supported
00221                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_signed_byte )
00222                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_signed_word)
00223                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_int)
00224                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_long)
00225                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_byte)
00226                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_word)
00227                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_uint)
00228         //#if MRPT_WORD_SIZE!=32  // If it's 32 bit, size_t <=> uint32_t
00229                 //MRPT_DECLARE_TTYPENAME_MAP_FOR_STDVECTOR(vector_size_t)
00230         //#endif
00231 
00232 
00233                 #define MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC(_CONTAINER) \
00234                         template< typename K, typename V > \
00235                         struct TTypeName <_CONTAINER<K,V> > { \
00236                                 static std::string get() { \
00237                                         return std::string( #_CONTAINER )+std::string("<")+std::string( TTypeName<K>::get() )+ std::string(",")+std::string( TTypeName<V>::get() )+std::string(">"); \
00238                                 } \
00239                         };
00240 
00241                 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::map )
00242                 MRPT_DECLARE_TTYPENAME_CONTAINER_ASSOC( std::multimap )
00243 
00244 
00245                 template< typename T1, typename T2 >
00246                 struct TTypeName <std::pair<T1,T2> >    {
00247                         static std::string get() {
00248                                 return std::string("std::pair<")+std::string( TTypeName<T1>::get() )+ std::string(",")+std::string( TTypeName<T2>::get() )+std::string(">");
00249                         }
00250                 };
00251 
00252                 /** @} */
00253 
00254 
00255                 /** This declaration must be inserted in all CSerializable classes definition, within the class declaration.
00256                   */
00257                 #define DEFINE_SERIALIZABLE(class_name) \
00258                         DEFINE_MRPT_OBJECT(class_name) \
00259                 protected: \
00260                         /*! @name CSerializable virtual methods */ \
00261                         /*! @{ */ \
00262                         void  writeToStream(mrpt::utils::CStream &out, int *getVersion) const;\
00263                         void  readFromStream(mrpt::utils::CStream &in, int version); \
00264                         /*! @} */
00265 
00266                 /**  This declaration must be inserted in all CSerializable classes definition, before the class declaration.
00267                   */
00268                 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
00269                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, CSerializable, _LINKAGE_ class_name) \
00270                         _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00271 
00272 
00273                 /**  This declaration must be inserted in all CSerializable classes definition, before the class declaration.
00274                   */
00275                 #define DEFINE_SERIALIZABLE_PRE(class_name) \
00276                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, CSerializable, BASE_IMPEXP class_name) \
00277                         BASE_IMPEXP ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00278 
00279                 /**  This declaration must be inserted in all CSerializable classes definition, before the class declaration.
00280                   */
00281                 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
00282                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, _LINKAGE_ class_name) \
00283                         _LINKAGE_ ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00284 
00285 
00286                 /**  This declaration must be inserted in all CSerializable classes definition, before the class declaration.
00287                   */
00288                 #define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE(class_name, base_name) \
00289                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, BASE_IMPEXP ) \
00290                         BASE_IMPEXP ::mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj);
00291 
00292                 /** This must be inserted in all CSerializable classes implementation files:
00293                   */
00294                 #define IMPLEMENTS_SERIALIZABLE(class_name, base,NameSpace) \
00295                         IMPLEMENTS_MRPT_OBJECT(class_name, base,NameSpace) \
00296                         mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, NameSpace::class_name##Ptr &pObj) \
00297                         { pObj = NameSpace::class_name##Ptr( in.ReadObject() ); return in; }
00298 
00299                 /** This declaration must be inserted in virtual CSerializable classes definition:
00300                   */
00301                 #define DEFINE_VIRTUAL_SERIALIZABLE(class_name) \
00302                         DEFINE_VIRTUAL_MRPT_OBJECT(class_name)
00303 
00304                 /** This must be inserted as implementation of some required members for
00305                   *  virtual CSerializable classes:
00306                   */
00307                 #define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name,NameSpace) \
00308                         IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base_class_name,NameSpace) \
00309                         mrpt::utils::CStream& NameSpace::operator>>(mrpt::utils::CStream& in, class_name##Ptr &pObj) \
00310                         { pObj = class_name##Ptr( in.ReadObject() ); return in; }
00311 
00312 
00313         } // End of namespace
00314 } // End of namespace
00315 
00316 #endif



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011