Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ boost serialization with stringstream

I am new to boost and c++ and is attempting to serialize an object to binary and then unserialize it.

I'm using the classes from the example in: http://en.highscore.de/cpp/boost/serialization.html

So suppose this is the class I am trying to serialize:

class person 
{ 
public: 
  person() { } 

  person(int age) : age_(age) {  } 

  int age() const { return age_; } 

private:
  friend class boost::serialization::access;

  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version)
  {
    ar & age_;
  }

  int age_;
}; 

This is the serialization code:

const char * save(Object ss)
{
    boost::archive::binary_oarchive oa(ss);
    person p(31);
    oa << p;

    return ss.str().data();
}

This is the unserialization code:

void load(const char * str)
    {

        stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        person p;
        ia >> p;
        std::cout << p.age() << std::endl;

    }

When I attempt to run this code, I receive this error:

terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  stream error

Which brings me to ask, is there a proper way of doing this?

Thanks, much appreciated.

EDIT: This version works:

This is the serialization code:

string save()
{
    boost::archive::binary_oarchive oa(ss);
    person p(31);
    oa << p;

    return ss.str();
}

This is the unserialization code:

void load(string str)
    {

        stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        person p;
        ia >> p;
        std::cout << p.age() << std::endl;

    }

EDIT2: This version does not work. Would appreciate comments on a fix. Thanks.

void Serialization::save()
{
    stringstream ss;
    {
        boost::archive::binary_oarchive oa(ss);
        person p(31);
        oa << p;
     }


        const char * temp1 = ss.str().data();

        stringstream s;
        s << temp1;

        cout << "UNSERIALIZING\n";
        boost::archive::binary_iarchive ia(s);
        person p1;
        ia >> p1;
        std::cout << p1.age() << std::endl;

}
like image 893
user459811 Avatar asked Mar 03 '11 23:03

user459811


1 Answers

Using binary archives with std::stringstream is allowed, as any character can be stored in a std::stringstream/std::string.

The problem is passing around the resulting data as a null terminated C-string, as binary data is highly likely to have embedded nulls thus upon load your data will be truncated. Additionally, your save function is returning data pointing into a destroyed object, invoking undefined behavior.

like image 131
ildjarn Avatar answered Oct 06 '22 17:10

ildjarn