Permalink
Browse files

Impl sch serializa for matrices; add serialization docs

  • Loading branch information...
jlblancoc committed Aug 18, 2018
1 parent 26d686e commit fd2c89f0243d78ed99fc487e66dbd0e52d8b7e78
@@ -5,66 +5,106 @@
| Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
| See: http://www.mrpt.org/Authors - All rights reserved. |
| Released under BSD License. See details in http://www.mrpt.org/License |
+---------------------------------------------------------------------------+ */
+---------------------------------------------------------------------------+
*/

/** \defgroup mrpt_serialization_grp [mrpt-serialization]
Serialization (marshalling) portable library for C++ objects persistence.
<small> <a href="index.html#libs">Back to list of all libraries</a> | <a href="modules.html" >See all modules</a> </small>
<br>
<small> <a href="index.html#libs">Back to list of all libraries</a> | <a
href="modules.html" >See all modules</a> </small> <br>
# Library `mrpt-serialization`
<small> [New in MRPT 2.0.0] </small>
This library is part of MRPT and can be installed in Debian-based systems with:
sudo apt install libmrpt-serialization-dev
sudo apt install libmrpt-serialization-dev
## Binary serialization (most efficient)
Main classes and concepts associated with this library:
- mrpt::serialization::CArchive provides:
- An abstraction of I/O streams (e.g. std::stream's, MRPT's mrpt::io::CStream's, sockets)
- A portable API (endianness aware) for serialization of data structures on those streams.
- An abstraction of I/O streams (e.g. std::stream's, MRPT's
mrpt::io::CStream's, sockets)
- A portable API (endianness aware) for serialization of data structures on
those streams.
- mrpt::serialization::CSerializable provides:
- A generic way to define persistent C++ classes.
- Versioning: if class fields are added or removed, you'll still be able to read old data files.
- Versioning: if class fields are added or removed, you'll still be able to
read old data files.
Serialization happens via `archive << object` operators in all cases but, underneath, two mechanisms are provided:
- **Direct overloading of the `<<`/`>>` operators** for mrpt::serialization::CArchive objects.
Serialization happens via `archive << object` operators in all cases but,
underneath, two mechanisms are provided:
- **Direct overloading of the `<<`/`>>` operators** for
mrpt::serialization::CArchive objects.
- Pros: concise declaration (just the two operator functions).
- Cons: Cannot handle versioning. Cannot deserialize unknown types (i.e. no support for class factory).
- Cons: Cannot handle versioning. Cannot deserialize unknown types (i.e. no
support for class factory).
- **Via mrpt::serialization::CSerializable** and associated macros:
- Pros: Allows polymorphic classes to be (de)serialized. Allows versioning.
- Cons: Requires adding macros to class definitions. Requires **registering** the class with \ref mrpt_rtti_grp.
- Cons: Requires adding macros to class definitions. Requires
**registering** the class with \ref mrpt_rtti_grp.
Support for STL containers is provided via this "direct mechanism" for the container structure itself, but contained
elements can use any of the serialization mechanisms.
Support for STL containers is provided via this "direct mechanism" for the
container structure itself, but contained elements can use any of the
serialization mechanisms.
Serializing `shared_ptr<T>` is supported for any arbitrary type `T`. It is legal to serialize an empty (`nullptr`)
smart pointer; an empty pointer will be read back. Polymorphic classes can be also writen and read, although reading
a smart pointer to a polymorphic base class is only supported for classes derived from MRPT's CSerializable, since
that operation requires registering types in a class factory (see \a mrpt_rtti_grp and mrpt::serialization::CSerializable).
Serializing `shared_ptr<T>` is supported for any arbitrary type `T`. It is legal
to serialize an empty (`nullptr`) smart pointer; an empty pointer will be read
back. Polymorphic classes can be also writen and read, although reading a smart
pointer to a polymorphic base class is only supported for classes derived from
MRPT's CSerializable, since that operation requires registering types in a class
factory (see \a mrpt_rtti_grp and mrpt::serialization::CSerializable).
## Example #1: serialize STL container via MRPT `CStream`s
### Example #1: serialize STL container via MRPT `CStream`s
See: \ref serialization_stl/test.cpp
\snippet serialization_stl/test.cpp example
Output:
\include serialization_stl/console.out
## Example #2: serialize STL container via `std::ostream` and `std::istream`
### Example #2: serialize STL container via `std::ostream` and `std::istream`
See: \ref serialization_stl/test.cpp
\snippet serialization_stl/test.cpp example_stdio
Output:
\include serialization_stl/console.out
## Example #3: Serialization of existing MRPT classes
### Example #3: Serialization of existing MRPT classes
Write me!
## Example #4: Polymorphic serialization of user classes
### Example #4: Polymorphic serialization of user classes
Write me!
## Schema (plain-text) serialization (human readable)
An alternative mechanism to serialize objects is based on
mrpt::serialization::CSchemeArchive and allow objects to be (de)serialized in
plain text formats like XML, JSON, YAML, etc.
For now (Aug 2018) only JSON is implemented.
### Example #1: Easy JSON serialization
This method only requires having MRPT built against jsoncpp, but does not
enforce the user to also depend on that library.
See: \ref serialization_json_example/test.cpp
\snippet serialization_json_example/test.cpp example
Output:
\include serialization_json_example/console.out
### Example #2: JSON serialization with full access to jsoncpp
If you want to have full control on the JSON formatting and other details,
you may directly depend on jsoncpp and use the following, template-based access
to MRPT serialization:
See: \ref serialization_json_example/test.cpp
\snippet serialization_json_example/test.cpp example_raw
*/
@@ -22,25 +22,26 @@ namespace mrpt::math
class CMatrix : public mrpt::serialization::CSerializable, public CMatrixFloat
{
DEFINE_SERIALIZABLE(CMatrix)
DEFINE_SCHEMA_SERIALIZABLE()

public:
/** Constructor */
CMatrix() : CMatrixFloat(1, 1) {}
/** Constructor */
CMatrix(size_t row, size_t col) : CMatrixFloat(row, col) {}
/** Copy constructor
*/
*/
CMatrix(const CMatrixFloat& m) : CMatrixFloat(m) {}
/** Copy constructor
*/
*/
CMatrix(const CMatrixTemplateNumeric<double>& m) : CMatrixFloat(0, 0)
{
*this = m.eval().cast<float>();
}
MRPT_MATRIX_CONSTRUCTORS_FROM_POSES(CMatrix)

/** Assignment operator for float matrixes
*/
*/
template <class OTHERMAT>
inline CMatrix& operator=(const OTHERMAT& m)
{
@@ -66,5 +67,4 @@ class CMatrix : public mrpt::serialization::CSerializable, public CMatrixFloat
mrpt::serialization::CArchive& operator>>(
mrpt::serialization::CArchive& in, CMatrix::Ptr& pObj);

}

} // namespace mrpt::math
@@ -23,6 +23,7 @@ class CMatrixD : public mrpt::serialization::CSerializable,
public CMatrixTemplateNumeric<double>
{
DEFINE_SERIALIZABLE(CMatrixD)
DEFINE_SCHEMA_SERIALIZABLE()
public:
/** Constructor */
CMatrixD() : CMatrixTemplateNumeric<double>(1, 1) {}
@@ -63,5 +64,4 @@ class CMatrixD : public mrpt::serialization::CSerializable,
mrpt::serialization::CArchive& operator>>(
mrpt::serialization::CArchive& in, CMatrixD::Ptr& pObj);

}

} // namespace mrpt::math
@@ -12,6 +12,7 @@
#include <mrpt/math/CMatrix.h>
#include <mrpt/math/lightweight_geom_data.h>
#include <mrpt/serialization/CArchive.h>
#include <mrpt/serialization/CSchemeArchiveBase.h>

using namespace mrpt;
using namespace mrpt::math;
@@ -53,3 +54,28 @@ void CMatrix::serializeFrom(mrpt::serialization::CArchive& in, uint8_t version)
MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(version)
};
}

/** Serialize CSerializable Object to CSchemeArchiveBase derived object*/
void CMatrix::serializeTo(mrpt::serialization::CSchemeArchiveBase& out) const
{
SCHEMA_SERIALIZE_DATATYPE_VERSION(1);
out["nrows"] = this->rows();
out["ncols"] = this->cols();
out["data"] = this->inMatlabFormat();
}
/** Serialize CSchemeArchiveBase derived object to CSerializable Object*/
void CMatrix::serializeFrom(mrpt::serialization::CSchemeArchiveBase& in)
{
uint8_t version;
SCHEMA_DESERIALIZE_DATATYPE_VERSION();
switch (version)
{
case 1:
{
this->fromMatlabStringFormat(static_cast<std::string>(in["data"]));
}
break;
default:
MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(version)
}
}
@@ -12,6 +12,7 @@
#include <mrpt/math/CMatrixD.h>
#include <mrpt/math/lightweight_geom_data.h>
#include <mrpt/serialization/CArchive.h>
#include <mrpt/serialization/CSchemeArchiveBase.h>

using namespace mrpt;
using namespace mrpt::math;
@@ -51,3 +52,28 @@ void CMatrixD::serializeFrom(mrpt::serialization::CArchive& in, uint8_t version)
MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(version)
};
}

/** Serialize CSerializable Object to CSchemeArchiveBase derived object*/
void CMatrixD::serializeTo(mrpt::serialization::CSchemeArchiveBase& out) const
{
SCHEMA_SERIALIZE_DATATYPE_VERSION(1);
out["nrows"] = this->rows();
out["ncols"] = this->cols();
out["data"] = this->inMatlabFormat();
}
/** Serialize CSchemeArchiveBase derived object to CSerializable Object*/
void CMatrixD::serializeFrom(mrpt::serialization::CSchemeArchiveBase& in)
{
uint8_t version;
SCHEMA_DESERIALIZE_DATATYPE_VERSION();
switch (version)
{
case 1:
{
this->fromMatlabStringFormat(static_cast<std::string>(in["data"]));
}
break;
default:
MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(version)
}
}
@@ -1 +1,32 @@

{
"pose" :
{
"datatype" : "CPose2D",
"phi" : 0,
"version" : 1,
"x" : 5,
"y" : 6
},
"pose_pdf" :
{
"cov" :
{
"data" : "[0.000000e+00 0.000000e+00 0.000000e+00 ;0.000000e+00 0.000000e+00 0.000000e+00 ;0.000000e+00 0.000000e+00 0.000000e+00 ]",
"datatype" : "CMatrixD",
"ncols" : 3,
"nrows" : 3,
"version" : 1
},
"datatype" : "CPosePDFGaussian",
"mean" :
{
"datatype" : "CPose2D",
"phi" : 1.5707963267948966,
"version" : 1,
"x" : 1,
"y" : 2
},
"version" : 1
}
}
read pose:[5.000000 6.000000 0.000000deg]
@@ -40,7 +40,7 @@ void WriteAndReadExample()
ss << arch;

// also, print to cout for illustration purposes:
std::cout << arch;
std::cout << arch << std::endl;

// --------------------
// JSON Deserialization
@@ -82,3 +82,29 @@ int main(int argc, char** argv)
return -1;
}
}

#if 0 // code disabled, only present as an example for the docs:

//! [example_raw]
#include <json/json.h>

void test()
{
Json::Value val;
auto arch = mrpt::serialization::CSchemeArchiveBase(
std::make_unique<CSchemeArchive<Json::Value>>(val));

mrpt::poses::CPose2D pt1{1.0, 2.0, 3.0};
// Store any CSerializable object into the JSON value:
arch = pt1;
// Alternative:
// arch["pose"] = pt1;

std::stringstream ss;
ss << val;
std::cout << val << std::endl;
}

//! [example_raw]

#endif

0 comments on commit fd2c89f

Please sign in to comment.