|
Boost : |
From: Matthew Vogt (mvogt_at_[hidden])
Date: 2004-03-21 20:27:53
Is anyone else interested in using Robert Ramey's serialization library for
the purpose of marshalling data into pre-determined binary formats?
This is not related to serialization in a general sense, but employing the
syntax and underlying fundamentals of the library, to a somewhat related
purpose.
This is a test program demonstrating what I'm doing - I'm interested to know
if anyone else is doing anything similar...
Matt
test.cpp: ------------------------------------------------------------------
#include <sstream>
#include <cassert>
#include "marshall.hpp"
#include "network_oarchive.hpp"
#include "network_iarchive.hpp"
class test
{
struct subobject;
// Basic fixed-size primitives
uint8_t a;
uint16_t b;
uint32_t c;
uint64_t d;
// String data that must be serialized to a pre-determined length
marshall::fixed_length<std::string, 20> e;
marshall::fixed_length<std::wstring, 10> f;
// String data that must be serialized with a prepended length
// (whose size is itself predetermined)
marshall::variable_length<std::string, uint8_t> g;
marshall::variable_length<std::wstring, uint8_t> h;
// Arbitrary data that must be serialized to a pre-determined length
marshall::fixed_length<std::vector<uint16_t>, 5> i;
marshall::fixed_length<std::vector<subobject>, 2> j;
// Arbitrary data that must be serialized with a prepended length
// (whose size is itself predetermined)
marshall::variable_length<std::vector<uint16_t>, uint32_t> k;
marshall::variable_length<std::vector<char>, uint32_t> l;
// A sub-object of arbitrary complexity
struct subobject
{
subobject(void) : a(0), b(0) {}
subobject(uint32_t x, uint32_t y) : a(x), b(y) {}
bool operator== (const subobject& other) const
{ return (a == other.a && b == other.b); }
private:
uint32_t a;
uint32_t b;
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& archive, const unsigned version)
{
archive & a & b;
}
};
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& archive, const unsigned version)
{
archive & a & b & c & d & e & f & g & h & i & j & k & l;
}
public:
test(void) :
a(0x01),
b(0x0203),
c(0x04050607),
d(0x08090a0b0c0d0e0f),
e("abcdefg"),
g("xyz")
{
f[0] = 'A';
f[1] = 'B';
f[2] = 'C';
h.push_back('w');
i[0] = 255;
i[1] = 254;
i[2] = 253;
j[0] = subobject(99, 100);
k.push_back(1);
k.push_back(2);
k.push_back(3);
l.push_back('l');
}
test(bool) {} // Don't initialize everything
bool operator== (const test& other) const
{
return (a == other.a &&
b == other.b &&
c == other.c &&
d == other.d &&
e == other.e &&
f == other.f &&
g == other.g &&
h == other.h &&
i == other.i &&
j == other.j &&
k == other.k &&
l == other.l);
}
};
int main(int, char**)
{
test t1;
// Serialize object to binary format, in network byte order
std::ostringstream oss;
boost::archive::network_oarchive oa(oss);
oa << t1;
// Create uninitialized object
test t2(false);
// De-serialize object from binary format, in network byte order
std::istringstream iss(oss.str());
boost::archive::network_iarchive ia(iss);
ia >> t2;
assert(t1 == t2);
return 0;
}
This produces the following binary output: -------------------------------
0000000 |01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 61
|a |b |c |d |e
0000020 |62 63 64 65 66 67 00 00 00 00 00 00 00 00 00 00
|
0000040 |00 00 00 00 00 00 41 00 00 00 42 00 00 00 43 00
| | f
0000060 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
0000100 |00 00 00 00 00 00 00 00 00 00 00 03 78 79 7a 01
| |g |h
0000120 |00 00 00 77 00 ff 00 fe 00 fd 00 00 00 00 00 00
| |i |j
0000140 |00 63 00 00 00 64 00 00 00 00 00 00 00 00 00 00
| |k
0000160 |00 03 00 01 00 02 00 03 00 00 00 01 6c
| |l
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk