Serialization¶
Bakery comes with deserialization/serialization methods in order to load/save data from/to binary streams. Standard types and classes serialization is already defined by the Bakery library.
For types defined by the library users, serialization operation has to be
defined by implementing the template specialization of bakery::serializer<T>
struct.
Basic serialization implementation¶
This section shows how to implement serialization and deserialization for basic structures using a common code for both operations.
struct demo_t {
int x;
int y;
string label;
};
#include <bakery/serializers.hpp>
struct demo_t {
int x;
int y;
std::string label;
};
template <> struct bakery::serializer<demo_t> {
template <typename U, typename IO> void operator()(U u, IO & io) {
io(u.x)(u.y)(u.label);
}
};
This code both implements serialization and deserialization operator, thanks to
the template parameters U
and IO
. The C++ code defines the demo_t
structure identically as in the recipe file, but this is not mandatory as
long as the binary to data mapping is consistent (for example, the names of the
members in the recipe could be different).
Alternatively, the serialization implementation can be written using some Bakery macros, which hides a little bit the template magics:
BAKERY_BASIC_SERIALIZATION_BEGIN(demo_t)
io(u.x)(u.y)(u.label)
BAKERY_BASIC_SERIALIZATION_END
Advanced serialization implementation¶
When serialization and deserialization code cannot be the same, the two
operators can be defined separately. The following snippet shows how
std::string
serialization operators are defined in Bakery:
template <> struct bakery::serializer<std::string> {
// Deserialization
template <typename U, typename IO>
void operator()(std::string & u, IO & io) {
size_t size = 0;
io(size);
u.resize(size)
for (size_t i = 0; i < size; ++i)
io(u[i]);
}
// Serialization
// u is const reference
template typename U, typename IO>
void operator()(const std::string & u, IO & io) {
io(u.size());
for (char c: u)
io(c);
}
};