Unverified Commit 5abf0550 authored by Justin Carpentier's avatar Justin Carpentier Committed by GitHub
Browse files

Merge pull request #1437 from jcarpent/topic/serialization

Enhance serialization 
parents a0691339 fe1bf8de
Pipeline #14091 passed with stage
in 107 minutes and 30 seconds
......@@ -52,6 +52,11 @@ namespace pinocchio
bp::args("self","buffer"),"Saves *this inside a binary buffer.")
.def("loadFromBinary",(void (Derived::*)(boost::asio::streambuf &))&Derived::loadFromBinary,
bp::args("self","buffer"),"Loads *this from a binary buffer.")
.def("saveToBinary",(void (Derived::*)(serialization::StaticBuffer &) const)&Derived::saveToBinary,
bp::args("self","buffer"),"Saves *this inside a static binary buffer.")
.def("loadFromBinary",(void (Derived::*)(serialization::StaticBuffer &))&Derived::loadFromBinary,
bp::args("self","buffer"),"Loads *this from a static binary buffer.")
;
serialize<Derived>();
......
......@@ -41,6 +41,16 @@ namespace pinocchio
.def("prepare",prepare_proxy,"Reserve data.",bp::return_internal_reference<>())
;
typedef pinocchio::serialization::StaticBuffer StaticBuffer;
bp::class_<StaticBuffer>("StaticBuffer",
"Static buffer to save/load serialized objects in binary mode with pre-allocated memory.",
bp::init<size_t>(bp::args("self","size"),"Default constructor from a given size capacity."))
.def("size",&StaticBuffer::size,bp::arg("self"),
"Get the size of the input sequence.")
.def("reserve",&StaticBuffer::resize,bp::arg("new_size"),
"Increase the capacity of the vector to a value that's greater or equal to new_size.")
;
bp::def("buffer_copy",buffer_copy,
bp::args("dest","source"),
"Copy bytes from a source buffer to a target buffer.");
......
......@@ -25,12 +25,20 @@ namespace pinocchio
bp::scope current_scope = getOrCreatePythonNamespace("serialization");
bp::def("loadFromBinary",(void (*)(T &, boost::asio::streambuf &))pinocchio::serialization::loadFromBinary<T>,
bp::args("object","buffer"),
bp::args("object","stream_buffer"),
"Load an object from a binary buffer.");
bp::def("saveToBinary",(void (*)(const T &, boost::asio::streambuf &))pinocchio::serialization::saveToBinary<T>,
bp::args("object","buffer"),
bp::args("object","stream_buffer"),
"Save an object to a binary buffer.");
bp::def("loadFromBinary",(void (*)(T &, serialization::StaticBuffer &))pinocchio::serialization::loadFromBinary<T>,
bp::args("object","static_buffer"),
"Load an object from a static binary buffer.");
bp::def("saveToBinary",(void (*)(const T &, serialization::StaticBuffer &))pinocchio::serialization::saveToBinary<T>,
bp::args("object","static_buffer"),
"Save an object to a static binary buffer.");
}
} // namespace python
......
......@@ -6,6 +6,7 @@
#define __pinocchio_serialization_archive_hpp__
#include "pinocchio/serialization/fwd.hpp"
#include "pinocchio/serialization/static-buffer.hpp"
#include <fstream>
#include <string>
......@@ -19,6 +20,9 @@
#include <boost/archive/binary_oarchive.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/stream_buffer.hpp>
// Handle NAN inside TXT or XML archives
#include <boost/math/special_functions/nonfinite_num_facets.hpp>
......@@ -261,7 +265,7 @@ namespace pinocchio
/// \tparam T Type of the object to deserialize.
///
/// \param[out] object Object in which the loaded data are copied.
/// \param[in] container Input buffer containing the serialized data.
/// \param[in] buffer Input buffer containing the serialized data.
///
template<typename T>
inline void loadFromBinary(T & object,
......@@ -277,7 +281,7 @@ namespace pinocchio
/// \tparam T Type of the object to serialize.
///
/// \param[in] object Object in which the loaded data are copied.
/// \param[out] container Output buffer containing the serialized data.
/// \param[out] buffer Output buffer containing the serialized data.
///
template<typename T>
void saveToBinary(const T & object,
......@@ -286,8 +290,46 @@ namespace pinocchio
boost::archive::binary_oarchive oa(buffer);
oa & object;
}
///
/// \brief Loads an object from a static binary buffer.
/// The buffer should be of a sufficient size.
///
/// \tparam T Type of the object to deserialize.
///
/// \param[out] object Object in which the loaded data are copied.
/// \param[in] buffer Input buffer containing the serialized data.
///
template<typename T>
inline void loadFromBinary(T & object,
StaticBuffer & buffer)
{
boost::iostreams::stream_buffer< boost::iostreams::basic_array<char> > stream(buffer.data(), buffer.size());
boost::archive::binary_iarchive ia(stream);
ia >> object;
}
///
/// \brief Saves an object to a static binary buffer.
/// The buffer should be of a sufficient size.
///
/// \tparam T Type of the object to deserialize.
///
/// \param[in] object Object in which the loaded data are copied.
/// \param[out] buffer Output buffer containing the serialized data.
///
template<typename T>
inline void saveToBinary(const T & object,
StaticBuffer & buffer)
{
boost::iostreams::stream_buffer< boost::iostreams::basic_array<char> > stream(buffer.data(), buffer.size());
boost::archive::binary_oarchive oa(stream);
oa & object;
}
}
} // namespace serialization
} // namespace pinocchio
#endif // ifndef __pinocchio_serialization_archive_hpp__
......@@ -96,6 +96,18 @@ namespace pinocchio
pinocchio::serialization::saveToBinary(derived(),container);
}
/// \brief Loads a Derived object from a static binary container.
void loadFromBinary(StaticBuffer & container)
{
pinocchio::serialization::loadFromBinary(derived(),container);
}
/// \brief Saves a Derived object as a static binary container.
void saveToBinary(StaticBuffer & container) const
{
pinocchio::serialization::saveToBinary(derived(),container);
}
};
}
......
//
// Copyright (c) 2021 INRIA
//
#ifndef __pinocchio_serialization_static_buffer_hpp__
#define __pinocchio_serialization_static_buffer_hpp__
#include <vector>
namespace pinocchio
{
namespace serialization
{
/// \brief Static buffer with pre-allocated memory.
struct StaticBuffer
{
/// \brief Defautl constructor from a given size
explicit StaticBuffer(const size_t n)
: m_size(n)
{
m_data.reserve(n);
}
/// \brief Returns the current size of the buffer
size_t size() const
{
return m_size;
}
/// \brief Returns the pointer on the data
char * data()
{
return m_data.data();
}
/// \brief Returns the pointer on the data (const version)
const char * data() const
{
return m_data.data();
}
/// \brief Increase the capacity of the vector to a value that's greater or equal to new_size.
///
/// \param[in] new_size New capacity of the buffer.
///
void resize(const size_t new_size)
{
m_size = new_size;
m_data.reserve(new_size);
}
protected:
size_t m_size;
std::vector<char> m_data;
};
}
}
#endif // ifndef __pinocchio_serialization_static_buffer_hpp__
......@@ -140,6 +140,34 @@ void generic_test(const T & object,
// Check
BOOST_CHECK(run_call_equality_op(object_loaded,object));
}
// Load and save as static binary stream
pinocchio::serialization::StaticBuffer static_buffer(10000000);
saveToBinary(object,static_buffer);
{
T object_loaded;
loadFromBinary(object_loaded,static_buffer);
// Check
BOOST_CHECK(run_call_equality_op(object_loaded,object));
}
}
BOOST_AUTO_TEST_CASE(test_static_buffer)
{
using namespace pinocchio::serialization;
const size_t size = 10000000;
StaticBuffer static_buffer(size);
BOOST_CHECK(size == static_buffer.size());
const size_t new_size = 2*size;
static_buffer.resize(new_size);
BOOST_CHECK(new_size == static_buffer.size());
BOOST_CHECK(static_buffer.data() != NULL);
BOOST_CHECK(reinterpret_cast<const StaticBuffer &>(static_buffer).data() != NULL);
BOOST_CHECK(reinterpret_cast<const StaticBuffer &>(static_buffer).data() == static_buffer.data());
}
BOOST_AUTO_TEST_CASE(test_eigen_serialization)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment