Writing a serializable class

In order to write a C++ class serializable through TSL the 'invasive' solution consists of modifying the class making it derived from the tsl::serializable interface.  

 Supposing we have to serialize a class that has - among its private members - one string and one double, we have to modify it in the following way:

#include <tsl/xml_archive.h>

class test : public virtual tsl::Serializable {
public:
  test(const char *s) : _string(s) {}
  test() {}
  virtual void serialize(tsl::OArchive &out) const;
  virtual void deserialize(tsl::IArchive& in);
  bool operator==(const test &other) const {return ((_string==other._string) && (_double==other._double));}
private:
  std::string _string;
  double _double;
};

void test::serialize(tsl::OArchive& out) const {
   out & _string & _double;
}

void ptest::deserialize(tsl::IArchive& in) {
  in & _string & _double;
}

The mandatory parts for this task are:

  • default constructor: it is needed in order to rebuild the object from the serialized code
  • serialize() method: serialize class instances
  • deserialize() method: deserialize class instances

Note also the operator &() used inside both the serialization and deserialization methods. It's is very important that the order of the members serialization is kept the same.

In order to serialize instances of the test class we need the following code:

std::stringstream stream;
tsl::oxml_archive archive(stream);
test object_1("Serializable object #1",1.1), object_2("Serializable object #2",2.2);
archive & object_1 & object_2;

The resulting archive will look like:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<tsl_root>
  <object class="example_1::test" id="1">
    <string>Serializable object #1</string>
    <double>1.1000000000000001e00</double>
  </object>
  <object class="example_1::test" id="2">
    <string>Serializable object #2</string>
    <double>2.2000000000000002e00</double>
  </object>
</tsl_root>

To restored the saved archive instead:

tsl::IXmlArchive archive(stream);
archive & restored_1 & restored_2;

The complete source code is below:

#include <sstream>
#include <tsl/xml_archive.h>

namespace example_1 {
  
class test : public virtual tsl::Serializable {
public:
  test(const char *s,double d) : _string(s),_double(d) {}
  test() {}
  virtual void serialize(tsl::OArchive &out) const;
  virtual void deserialize(tsl::IArchive& in);
  bool operator==(const test &other) const {return ((_string==other._string) && (_double==other._double));}
private:
  std::string _string;
  double _double;
};
 
void test::serialize(tsl::OArchive& out) const {
  out & _string & _double;
}
 
void test::deserialize(tsl::IArchive& in) {
  in & _string & _double;
}

}

using namespace std;
using namespace example_1;

int main(int argc,const char * argv[]) {
  try {
    const test original_1("Serializable object #1",1.1), original_2("Serializable object #2",2.2);
    std::stringstream stream;
    {
      tsl::OXmlArchive archive(stream);
      archive & original_1 & original_2;
    }
    cout << stream.str() << endl;
    test restored_1,restored_2;
    {
      tsl::IXmlArchive archive(stream);
      archive & restored_1 & restored_2;
      assert((original_1==restored_1) && (original_2==restored_2));
    }
    cout << "the restored object match the originals ones!" << endl;
  } catch (const runtime_error & error) {
    cerr << "Exception: " << error.what() << endl;
  }
}
Joomla templates by a4joomla