Saturday 15 September 2012

c++ - Boost Serialization Binary Archive giving incorrect output -



c++ - Boost Serialization Binary Archive giving incorrect output -

i trying serialize class.

class definition:

class startpeersessionrequest { public: startpeersessionrequest(); virtual ~startpeersessionrequest(); void composerequestwithhardcodevalues(); void save(); stringstream serializedrequest; /*boost::serialization::binary_object serlreq;*/ private: startpeersessionrequest(const startpeersessionrequest &); uint16_t mprotocolversion; uint16_t msessionflags; uint16_t mmaxresponselength; string mmake; string mmodel; string mserialnumber; uint8_t mtrackdelay; string mheadunitmodel; string mcarmodelyear; string mvin; uint16_t mvehiclemileage; uint8_t mshoutformat; uint8_t mnotificationinterval; friend class boost::serialization::access; template <typename archive> void serialize(archive &ar, const unsigned int version); }; startpeersessionrequest::startpeersessionrequest() { mprotocolversion = 1 * 10000 + 14 * 100 + 4; msessionflags = 1; mmaxresponselength = 0; mmake = "mymake"; mmodel = "mymodel"; mserialnumber = "10000"; mtrackdelay = 0; mheadunitmodel = "headunit"; mcarmodelyear = "2014"; mvin = "1234567980"; mvehiclemileage = 1000; mshoutformat = 3; mnotificationinterval = 1; } template <class archive> void startpeersessionrequest::serialize(archive &ar, const unsigned int version) { ar & mprotocolversion; ar & msessionflags; ar & mmaxresponselength; ar & mmake; ar & mmodel; ar & mserialnumber; ar & mtrackdelay; ar & mheadunitmodel; ar & mcarmodelyear; ar & mvin; ar & mvehiclemileage; ar & mshoutformat; ar & mnotificationinterval; } void startpeersessionrequest::save() { boost::archive::binary_oarchive oa(serlreq, boost::archive::no_header); oa << (*this); /*cout<<"\n binary_oarchive :"<<serlreq.size();*/ boost::archive::text_oarchive ota(serializedrequest, boost::archive::no_header); ota << (*this); cout << "\n text_oarchive :" << serializedrequest.str() << "size :" << serializedrequest.str().size(); }

serializedrequest.str.size() provides me length of 87

actually should provide me 65 bytes. (i've counted u can figure out constructor)

i suspect appending lengths in between.

i have tried using text_archive doesnt work.

what need plain serialize class members is.

i guess need utilize traits or wrappers.

please allow me know

thanks

okay, so, see how i'd do, i've tried reach optimum sizes calculated on of napkin:

i can see how you'd expect 57, 63, or 75 bytes

mprotocolversion = 1*10000+14*100+4; // 2 bytes msessionflags = 1; // 2 bytes mmaxresponselength = 0; // 2 bytes mmake = "mymake"; // 6 bytes + length mmodel = "mymodel"; // 7 bytes + length mserialnumber = "10000"; // 5 bytes + length mtrackdelay = 0; // 1 byte mheadunitmodel = "headunit"; // 8 bytes + length mcarmodelyear = "2014"; // 4 bytes + length mvin = "1234567980"; // 10 bytes + length mvehiclemileage = 1000; // 2 byte mshoutformat = 3; // 1 byte mnotificationinterval = 1; // 1 byte // -------------------------------------- // 51 bytes + 6 x length

in instance, created binary serialization code using boost spirit (karma serialization , qi de-serialization). made size of length field configurable (8,16,32 or 64 bit unsigned).

here's working proof of concept: live on coliru

generate()

the const generate fellow member function delegates work helper functions in separate namespace:

template <typename container> bool generate(container& bytes) const { auto out = std::back_inserter(bytes); using my_serialization_helpers::do_generate; homecoming do_generate(out, mprotocolversion) && do_generate(out, msessionflags) && do_generate(out, mmaxresponselength) && do_generate(out, mmake) && do_generate(out, mmodel) && do_generate(out, mserialnumber) && do_generate(out, mtrackdelay) && do_generate(out, mheadunitmodel) && do_generate(out, mcarmodelyear) && do_generate(out, mvin) && do_generate(out, mvehiclemileage) && do_generate(out, mshoutformat) && do_generate(out, mnotificationinterval); }

note

do_generate overloads can freely added required future types the container can switched e.g. std::vector<unsigned char>, e.g. boost::interprocess::containers::string<char, char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> >. parse()

the parse method similar except delegates do_parse overloads work.

testing

the test programme roundtrips possible configurations:

8-bit length field, net 57 bytes, boost serialization: 70 16-bit length field, net 63 bytes, boost serialization: 76 32-bit length field, net 75 bytes, boost serialization: 88 64-bit length field, net 99 bytes, boost serialization: 112

as can see it's not that outrageous natural boost serialization solution would take 107 bytes on system (it's 8 bytes more lastly configuration).

note also, since karma generators take output iterator, should relatively easy wire straight low-level boost archive operations performance , avoid allocating intermediate storage.

c++ boost boost-serialization binary-serialization

No comments:

Post a Comment