Subject: [boost] Problem with boost deserialization.
From: Esteban RG (stbnrivas_at_[hidden])
Date: 2010-11-09 14:30:32


Hi,
 I need serialization in a project of mine. I have reduced my options to
boost and ProtocolBuffer, but in order to be able to decide which one to
use, I am trying to build a timing test for serialization and
deserialization. Let me explain a little about my setup:
a) Platform:
 - windows 7, 64bit version
 - visual studio 2008 express edition x32

b) Additional library:
 - ACE library for High resolution timer.

The code (an explanations) that I have used to implement the comparison is
at follows:

I build a class with four different lists of boost/serialization/list like
documentation states:

std::list<unsigned int> &lint_;
std::list<ACE_INT64> &llong_;
std::list<float> &lfloat_;
std::list<std::string> &lstring_;

The test is increasing the size of every list simultaneously. Then it gets
serializated and deserializated and finally I get the time results for this
process.
However there is one issue: Serialization always works, but deserialization
fails during execution time whenever the lists are bigger than 10 elements,
throws a exception "input stream error" into
boost/serialization/throw_exception.hpp as seen with the debugger in the
variable/const std::exception const &e (boost library)

Visual studio shows this message: Unhandled exception at 0x765cb727 in
prTestBoostSerialization2.exe: Microsoft C++ exception:
boost::archive::archive_exception at memory location 0x003fc564..

my class definition is:

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

#include <boost/serialization/string.hpp>
#include <boost/serialization/list.hpp>
//#include <boost/serialization/version.hpp>
//#include <boost/serialization/split_member.hpp>

#include <iostream>
#include <list>
#include <string>

class BoostSerializationClass {
public:

// Not required because al member are public
// friend class boost::serialization::access;

BoostSerializationClass(std::list<unsigned int> &lint
, std::list<float> &lfloat
, std::list<ACE_INT64> &llong
, std::list<std::string> &lstring)
: lint_(lint), lfloat_(lfloat), llong_(llong), lstring_(lstring) {
 //std::cout << std::endl << " max size " << lint_.max_size();
//std::cout << std::endl << " " << llong_.max_size();
//std::cout << std::endl << " " << lfloat_.max_size();
//std::cout << std::endl << " " << lstring_.max_size();
}

std::list<unsigned int> &lint_;
std::list<ACE_INT64> &llong_;
std::list<float> &lfloat_;
std::list<std::string> &lstring_;
};

namespace boost {
  namespace serialization {
template<class Archive>
void serialize(Archive &ar, BoostSerializationClass &c
, const unsigned int version){
ar & c.lint_;
ar & c.llong_;
ar & c.lfloat_;
ar & c.lstring_;
}
  }
}

-----------------------
And main function is:

#include <iostream>
#include <fstream>

//#include <cstdlib>
#include <ace/OS.h>
#include <ace/Time_Value.h>
#include <ace/High_Res_Timer.h> // high resolution timer

// include for BOOST
#include "../prTestProtocolBuffers/BoostSerializationClass.h"
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
//#include <list> <- dont include this use boost/serialization/list
#include <boost/serialization/list.hpp>

void gen_random_string(std::string &s, const int len);

int ACE_TMAIN(int argc, ACE_TCHAR* argv[]){

//int lengthList = 5;
//int lengthList = 10;
int lengthList = 15;
//int lengthList = 50;
// int lengthList = 100;
// int lengthList = 1000;

std::list<unsigned int> listInteger,listInteger2;
std::list<float> listFloat,listFloat2;
std::list<ACE_INT64> listLongs,listLongs2;
std::list<std::string> listString,listString2;

int rint = 0;
float rfloat = 0.f;
ACE_INT64 rint64 = 0;
std::string rstring = "";

std::cout << std::endl << "Begin random generate message. Please be
patient.";
// Generate random fields for messages
for (int i=0 ; i<lengthList ; i++){
listInteger.push_back( rand() );
listFloat.push_back( (float)rand()/(float)RAND_MAX );
listLongs.push_back( rand()*rand()*rand() );
gen_random_string(rstring, lengthList);
listString.push_back( rstring );
}

// BOOST SERIALIZATION
ACE_High_Res_Timer hrTimerBoost;

// Load fields into BoostSerializableClass
BoostSerializationClass boostSerializationClass( listInteger, listFloat,
listLongs, listString);

std::ofstream obfile("boost-file.bin");
boost::archive::binary_oarchive oba(obfile);
//ACE_Time_Value btvStart = ACE_OS::gettimeofday();
hrTimerBoost.start();
oba & boostSerializationClass; // boost serialization;
obfile.close();
hrTimerBoost.stop();

ACE_hrtime_t usecsBoost;
hrTimerBoost.elapsed_microseconds(usecsBoost);
//ACE_Time_Value btvEnd = ACE_OS::gettimeofday();
//ACE_Time_Value tvIncBoost( btvEnd.sec() - btvStart.sec() , btvEnd.msec() -
btvStart.msec() );
std::cout << std:: endl << " ===== BOOST SERIALIZATION =====" ;
//std::cout << std::endl << tvIncBoost.sec() << " seconds " <<
tvIncBoost.msec() << " mseconds" << std::endl ;
std::cout << std::endl << usecsBoost << " micro seconds " << std::endl ;

// BOOST DESERIALIZACION
BoostSerializationClass boostSerializationClass2( listInteger2, listFloat2,
listLongs2, listString2);
std::ifstream ibfile("boost-file.bin");
boost::archive::binary_iarchive iba(ibfile);
//btvStart = ACE_OS::gettimeofday();
hrTimerBoost.reset();
hrTimerBoost.start();
iba & boostSerializationClass2;
 ibfile.close();
hrTimerBoost.stop();

hrTimerBoost.elapsed_microseconds(usecsBoost);
//btvEnd = ACE_OS::gettimeofday();
//tvIncBoost = ACE_Time_Value( btvEnd.sec() - btvStart.sec() , btvEnd.msec()
- btvStart.msec() );
std::cout << std:: endl << " ===== BOOST DE-SERIALIZATION =====" ;
//std::cout << std::endl << tvIncBoost.sec() << " seconds " <<
tvIncBoost.msec() << " mseconds" << std::endl ;
std::cout << std::endl << usecsBoost << " micro seconds " << std::endl ;

ACE_OS::system("pause");
return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
void gen_random_string(std::string &s, const int len) {
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
s.clear();
    for (int i = 0; i < len ; ++i) {
s.push_back(rand() % (sizeof(alphanum) - 1) );
    }
}

Can anyone of you help me with this? Any help would be truly appreciated.

Thanks in advance.