c++ - Boost serialization : read varying type of data -


i have c++ / cli project uses boost serialization serialize 3 different classes. know if possible parse first line of boost serialization archive in order know class serialized in archive, , create object of appropriate class , deserialize archive object. line contain id (maybe int or value of enum class) identify class serialized.

the file format handled choice of archive implementation.

in practice boost::archive::text_oarchive, boost::archive::binary_oarchive, boost::archive::xml_oarchive.

as long archive type doesn't vary, can use boost variant distinguish payloads. in other words, make serialization framework work you, instead of "duct taping" around it:

here's demo serializes 3 different (compound) payloads , roundtrips fine without external knowledge of payload there:

live on coliru

#include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp>  #include <boost/serialization/variant.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/string.hpp>  #include <boost/serialization/access.hpp>  struct {     int simple;    private:     friend class boost::serialization::access;     template <typename ar> void serialize(ar& ar, unsigned) {         ar & simple;     } };  struct b {     std::string text;    private:     friend class boost::serialization::access;     template <typename ar> void serialize(ar& ar, unsigned) {         ar & text;     } };  struct c {     composed_a;     b composed_b;    private:     friend class boost::serialization::access;     template <typename ar> void serialize(ar& ar, unsigned) {         ar & composed_a & composed_b;     } };  struct filecontents { // conventions...     boost::variant<a, b, c> payload;    private:     friend class boost::serialization::access;     template <typename ar> void serialize(ar& ar, unsigned) {         ar & payload;     } };   #include <sstream> #include <boost/lexical_cast.hpp>  ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // our roundtrip test, implement streaming can independently check equivalence inline static std::ostream& operator<<(std::ostream& os, const& v) {     return os << "a{" << v.simple << "}"; } inline static std::ostream& operator<<(std::ostream& os, b const& v) {     return os << "b{" << v.text << "}"; } inline static std::ostream& operator<<(std::ostream& os, c const& v) {     return os << "c{" << v.composed_a << ", " << v.composed_b << "}"; }  void roundtrip_test(filecontents const& original) {     std::stringstream ss;     {         boost::archive::text_oarchive oa(ss);         oa << original;     }      {         boost::archive::text_iarchive ia(ss);          filecontents clone;         ia >> clone;          std::string const before = boost::lexical_cast<std::string>(original.payload);         std::string const after  = boost::lexical_cast<std::string>(clone.payload);          std::cout << "roundtrip '" << before << "': " << std::boolalpha << (before == after) << "\n";     } }  int main() {     roundtrip_test({ { 42 } });     roundtrip_test({ b { "life universe , everything" } });     roundtrip_test({ c { {42}, { "life universe , everything" } } }); } 

the output being:

roundtrip 'a{42}': true roundtrip 'b{life universe , everything}': true roundtrip 'c{a{42}, b{life universe , everything}}': true 

Comments

Popular posts from this blog

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -

YouTubePlayerFragment cannot be cast to android.support.v4.app.Fragment -