[serialization] "stream error" when port from boost_1.33 to boost_1.36

I just port a project using boost_1.33_1 to use boost_1.36. The project has a Server class using a std::set<Server> serialization, the serialization save and load functions code see behind. I use gcc 4.1 and run on FC6. The porting problem is, when the old boost_1.33 generates(save) a xml file, then use boost_1.36 load the xml throws an exception "stream error"! the exception error code line : boost::archive::xml_iarchive ia(ifs); How can i sovle it? class Server { public: int id; std::string ip; int port; private: static std::set<Server> lst_; static int dirty_; }; #endif #ifdef USE_SERVER_SERIALIZATION #ifndef _SERVER_SERIALIZATION_ #define _SERVER_SERIALIZATION_ BOOST_CLASS_VERSION(Server, 1) namespace boost { namespace serialization { template <class archive> void serialize(archive & ar, Server & t, const unsigned int ver) { ar & BOOST_SERIALIZATION_NVP(t.id); ar & BOOST_SERIALIZATION_NVP(t.ip); ar & BOOST_SERIALIZATION_NVP(t.port); } } } #endif #endif int Server::save( const std::string & file) { try { std::ofstream ofs(file.c_str(), std::ios::binary); { boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(lst_); } } catch(...) { return ERROR_ERROR; } return ERROR_SUCCEED; } int Server::load(const std::string & file) { std::set<Server> Server::lst_; try { std::ifstream ifs(file.c_str(), std::ios::binary); { boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(lst_); } } catch(std::exception & e) { std::cout << e.what() << std::endl; } return 0; } -- Best regards, PangYongQiang

Take a look at the xml archive and see if there are any anomolies in it. Robert Ramey ipangth wrote:
I just port a project using boost_1.33_1 to use boost_1.36. The project has a Server class using a std::set<Server> serialization, the serialization save and load functions code see behind.
I use gcc 4.1 and run on FC6. The porting problem is, when the old boost_1.33 generates(save) a xml file, then use boost_1.36 load the xml throws an exception "stream error"!
the exception error code line : boost::archive::xml_iarchive ia(ifs);
How can i sovle it?
class Server { public: int id; std::string ip; int port;
private: static std::set<Server> lst_;
static int dirty_; };
#endif
#ifdef USE_SERVER_SERIALIZATION
#ifndef _SERVER_SERIALIZATION_ #define _SERVER_SERIALIZATION_
BOOST_CLASS_VERSION(Server, 1) namespace boost { namespace serialization {
template <class archive> void serialize(archive & ar, Server & t, const unsigned int ver) { ar & BOOST_SERIALIZATION_NVP(t.id); ar & BOOST_SERIALIZATION_NVP(t.ip); ar & BOOST_SERIALIZATION_NVP(t.port); }
} }
#endif
#endif
int Server::save( const std::string & file) { try { std::ofstream ofs(file.c_str(), std::ios::binary); { boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(lst_); } } catch(...) { return ERROR_ERROR; }
return ERROR_SUCCEED; }
int Server::load(const std::string & file) { std::set<Server> Server::lst_; try { std::ifstream ifs(file.c_str(), std::ios::binary);
{ boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(lst_); } } catch(std::exception & e) { std::cout << e.what() << std::endl; }
return 0; }
-- Best regards, PangYongQiang
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

What are the anomolies? I debug the xml file with VC8, and the ifstream test retturn "failbit". See the xml file attached behind, i dont know how to find the "failbit". And some one can see the attach xml to help me? template<class CharType> bool basic_xml_grammar<CharType>::my_parse( BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is, const rule_t & rule_, CharType delimiter ){ if(is.fail()){ ////here return false, the stream state is "failbit" boost::throw_exception( archive_exception(archive_exception::stream_error) ); } 2008/9/26 Robert Ramey <ramey@rrsd.com>:
Take a look at the xml archive and see if there are any anomolies in it.
Robert Ramey
ipangth wrote:
I just port a project using boost_1.33_1 to use boost_1.36. The project has a Server class using a std::set<Server> serialization, the serialization save and load functions code see behind.
I use gcc 4.1 and run on FC6. The porting problem is, when the old boost_1.33 generates(save) a xml file, then use boost_1.36 load the xml throws an exception "stream error"!
the exception error code line : boost::archive::xml_iarchive ia(ifs);
How can i sovle it?
class Server { public: int id; std::string ip; int port;
private: static std::set<Server> lst_;
static int dirty_; };
#endif
#ifdef USE_SERVER_SERIALIZATION
#ifndef _SERVER_SERIALIZATION_ #define _SERVER_SERIALIZATION_
BOOST_CLASS_VERSION(Server, 1) namespace boost { namespace serialization {
template <class archive> void serialize(archive & ar, Server & t, const unsigned int ver) { ar & BOOST_SERIALIZATION_NVP(t.id); ar & BOOST_SERIALIZATION_NVP(t.ip); ar & BOOST_SERIALIZATION_NVP(t.port); }
} }
#endif
#endif
int Server::save( const std::string & file) { try { std::ofstream ofs(file.c_str(), std::ios::binary); { boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(lst_); } } catch(...) { return ERROR_ERROR; }
return ERROR_SUCCEED; }
int Server::load(const std::string & file) { std::set<Server> Server::lst_; try { std::ifstream ifs(file.c_str(), std::ios::binary);
{ boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(lst_); } } catch(std::exception & e) { std::cout << e.what() << std::endl; }
return 0; }
-- Best regards, PangYongQiang
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Best regards, PangYongQiang

One odd thing to me is the usage of std::ios::binary which will handle cr/lf as two characters rather than one. ipangth wrote:
What are the anomolies? I debug the xml file with VC8, and the ifstream test retturn "failbit". See the xml file attached behind, i dont know how to find the "failbit". And some one can see the attach xml to help me?
template<class CharType> bool basic_xml_grammar<CharType>::my_parse( BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is, const rule_t & rule_, CharType delimiter ){ if(is.fail()){ ////here return false, the stream state is "failbit" boost::throw_exception( archive_exception(archive_exception::stream_error) ); }
2008/9/26 Robert Ramey <ramey@rrsd.com>:
Take a look at the xml archive and see if there are any anomolies in it.
Robert Ramey
ipangth wrote:
I just port a project using boost_1.33_1 to use boost_1.36. The project has a Server class using a std::set<Server> serialization, the serialization save and load functions code see behind.
I use gcc 4.1 and run on FC6. The porting problem is, when the old boost_1.33 generates(save) a xml file, then use boost_1.36 load the xml throws an exception "stream error"!
the exception error code line : boost::archive::xml_iarchive ia(ifs);
How can i sovle it?
class Server { public: int id; std::string ip; int port;
private: static std::set<Server> lst_;
static int dirty_; };
#endif
#ifdef USE_SERVER_SERIALIZATION
#ifndef _SERVER_SERIALIZATION_ #define _SERVER_SERIALIZATION_
BOOST_CLASS_VERSION(Server, 1) namespace boost { namespace serialization {
template <class archive> void serialize(archive & ar, Server & t, const unsigned int ver) { ar & BOOST_SERIALIZATION_NVP(t.id); ar & BOOST_SERIALIZATION_NVP(t.ip); ar & BOOST_SERIALIZATION_NVP(t.port); }
} }
#endif
#endif
int Server::save( const std::string & file) { try { std::ofstream ofs(file.c_str(), std::ios::binary); { boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(lst_); } } catch(...) { return ERROR_ERROR; }
return ERROR_SUCCEED; }
int Server::load(const std::string & file) { std::set<Server> Server::lst_; try { std::ifstream ifs(file.c_str(), std::ios::binary);
{ boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(lst_); } } catch(std::exception & e) { std::cout << e.what() << std::endl; }
return 0; }
-- Best regards, PangYongQiang
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Best regards, PangYongQiang
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Thank you for reminding, the before xml file auto adding cr/lf while transfering from linux in text mode. I used the origin xml file to debug in it, and found the prolbem. in file <basic_xml_iarchive.ipp> boost_1.33 implimentation is : template<class Archive> BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) basic_xml_iarchive<Archive>::load_end(const char *name){ ..... if(0 != (this->get_flags() & no_xml_tag_checking)){ // double check that the tag matches what is expected - useful for debug if(0 != name[this->This()->gimpl->rv.object_name.size()] || ! std::equal( this->This()->gimpl->rv.object_name.begin(), this->This()->gimpl->rv.object_name.end(), name ) ){ boost::throw_exception( archive_exception(archive_exception::stream_error) ); } } } But in Boost 1.36 template<class Archive> BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) basic_xml_iarchive<Archive>::load_end(const char *name){ ..... if(0 == (this->get_flags() & no_xml_tag_checking)){ // double check that the tag matches what is expected - useful for debug if(0 != name[this->This()->gimpl->rv.object_name.size()] || ! std::equal( this->This()->gimpl->rv.object_name.begin(), this->This()->gimpl->rv.object_name.end(), name ) ){ boost::throw_exception( archive_exception(archive_exception::stream_error) ); } } } And in my case, this->get_flags() is 0, no_xml_tag_checking is 4, so (this->get_flags() & no_xml_tag_checking) is false in boost 1.33 and true in boost 1.36, then the "name" is "t.id", but rv.object_name is "id", so "0 != name[this->This()->gimpl->rv.object_name.size()" is true, boost 1.33 no archive_exception but 1.36 throws. This is the problem. Why boost 1.36 do the check? and why the "name" and rv.object_name dont match? And how do id fix it? Modify the boost_1.36 basic_xml_iarchive.ipp same to boost_1.33? Here is a xml example text(attach file): <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="3"> <lst_ class_id="0" tracking_level="0" version="0"> <count>2</count> <item class_id="1" tracking_level="0" version="0"> <id>2</id> <host>192.168.21.41</host> <port>7100</port> </item> <item> <id>4</id> <host>192.168.21.52</host> <port>7100</port> </item> </lst_> </boost_serialization> 2008/9/26 Robert Ramey <ramey@rrsd.com>:
One odd thing to me is the usage of std::ios::binary which will handle cr/lf as two characters rather than one.
ipangth wrote:
What are the anomolies? I debug the xml file with VC8, and the ifstream test retturn "failbit". See the xml file attached behind, i dont know how to find the "failbit". And some one can see the attach xml to help me?
template<class CharType> bool basic_xml_grammar<CharType>::my_parse( BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is, const rule_t & rule_, CharType delimiter ){ if(is.fail()){ ////here return false, the stream state is "failbit" boost::throw_exception( archive_exception(archive_exception::stream_error) ); }
2008/9/26 Robert Ramey <ramey@rrsd.com>:
Take a look at the xml archive and see if there are any anomolies in it.
Robert Ramey
ipangth wrote:
I just port a project using boost_1.33_1 to use boost_1.36. The project has a Server class using a std::set<Server> serialization, the serialization save and load functions code see behind.
I use gcc 4.1 and run on FC6. The porting problem is, when the old boost_1.33 generates(save) a xml file, then use boost_1.36 load the xml throws an exception "stream error"!
the exception error code line : boost::archive::xml_iarchive ia(ifs);
How can i sovle it?
class Server { public: int id; std::string ip; int port;
private: static std::set<Server> lst_;
static int dirty_; };
#endif
#ifdef USE_SERVER_SERIALIZATION
#ifndef _SERVER_SERIALIZATION_ #define _SERVER_SERIALIZATION_
BOOST_CLASS_VERSION(Server, 1) namespace boost { namespace serialization {
template <class archive> void serialize(archive & ar, Server & t, const unsigned int ver) { ar & BOOST_SERIALIZATION_NVP(t.id); ar & BOOST_SERIALIZATION_NVP(t.ip); ar & BOOST_SERIALIZATION_NVP(t.port); }
} }
#endif
#endif
int Server::save( const std::string & file) { try { std::ofstream ofs(file.c_str(), std::ios::binary); { boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(lst_); } } catch(...) { return ERROR_ERROR; }
return ERROR_SUCCEED; }
int Server::load(const std::string & file) { std::set<Server> Server::lst_; try { std::ifstream ifs(file.c_str(), std::ios::binary);
{ boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(lst_); } } catch(std::exception & e) { std::cout << e.what() << std::endl; }
return 0; }
-- Best regards, PangYongQiang
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Best regards, PangYongQiang
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Best regards, PangYongQiang

Good detective work!
This is the problem. Why boost 1.36 do the check? and why the "name" and rv.object_name dont match?
This is the question. You might investigate the program which created the archive. It is odd to me that one serilizes "t.id" rather than "t" which in turn serializaed "id". I suspect that this exception is trapping an error in the recent code.
And how do id fix it? Modify the boost_1.36 basic_xml_iarchive.ipp same to boost_1.33?
If you want to suppress the tag checking, open the input archive with the runtime flag options "no_tag_checking". Robert Ramey
participants (2)
-
ipangth
-
Robert Ramey