Discussion:
Different behavior of boost::serialization of strings on text archive
Andrea Ranieri
2013-07-03 10:25:26 UTC
Permalink
Hi all,

I'm having some issue serializing a `std::string` with
`boost::serialization` on a `text_oarchive`. AFAICT, I have two identical
pieces of code that behaves differently in two different programs.

This is the program that I believe is behaving correctly:

#include <iostream>
#include <string>
#include <sstream>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

template <typename T>
void serialize_deserialize(const T & src, T & dst)
{
std::string serialized_data_str;

std::cout << "original data: " << src << std::endl;

std::ostringstream archive_ostream;
boost::archive::text_oarchive oarchive(archive_ostream);
oarchive << src;
serialized_data_str = archive_ostream.str();
std::cout << "serialized data: " << serialized_data_str <<
std::endl;

std::istringstream archive_istream(serialized_data_str);
boost::archive::text_iarchive iarchive(archive_istream);
iarchive >> dst;
}


int main()
{
std::string archived_data_str = "abcd";
std::string restored_data_str;

serialize_deserialize<std::string>(archived_data_str,
restored_data_str);

std::cout << "restored data: " << restored_data_str << std::endl;

return 0;
}

And this is its output:

original data: abcd
serialized data: 22 serialization::archive 10 4 abcd
restored data: abcd

(You can compile it with: `g++ boost-serialization-string.cpp -o
boost-serialization-string -lboost_serialization`)

This one, on the other hand, is an excerpt of the program I'm writing
(derived from [boost_asio/example/serialization/connection.hpp][1]) that
serializes `std::string` data converting each character in its hex
representation:

/// Asynchronously write a data structure to the socket.
template <typename T, typename Handler>
void async_write(const T& t, Handler handler)
{
// Serialize the data first so we know how large it is.
std::cout << "original data: " << t << std::endl;
std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
archive << t;
outbound_data_ = archive_stream.str();
std::cout << "serialized data: " << outbound_data_ << std::endl;
[...]

And this is an excerpt of its output:

original data: abcd
serialized data: 22 serialization::archive 10 5 97 98 99 100 0

The version (`10`) is the same, right? So that should be the proof that I'm
using the same serialization library in both programs.

However, I really can't figure out what's going on here. I've been trying
to solve this puzzle for almost an entire work day now, and I'm out of
ideas.

For anyone that may want to reproduce this result, it should be sufficient
to download the [Boost serialization example][2], add the following line

connection_.async_write("abcd", boost::bind(&client::handle_write,
this, boost::asio::placeholders::error));

at line 50 of `client.cpp`, add the following member function in client.cpp

/// Handle completion of a write operation.
void handle_write(const boost::system::error_code& e)
{
// Nothing to do. The socket will be closed automatically when the
last
// reference to the connection object goes away.
}

add this `cout`:

std::cout << "serialized data: " << outbound_data_ << std::endl;

at `connection.hpp:59`

and compile with:

g++ -O0 -g3 client.cpp -o client -lboost_serialization -lboost_system
g++ -O0 -g3 server.cpp -o server -lboost_serialization -lboost_system

I'm using `g++ 4.8.1` under `Ubuntu 13.04 64bit` with `Boost 1.53`

Any help would be greatly appreciated.

Best regards
Avio

P.s. I'm posting this because the deserialization of the `std::string`s
isn't working at all! :)

[1]:
http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/serialization/connection.hpp
[2]:
http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html#boost_asio.examples.serialization
Bjorn Reese
2013-07-03 14:37:17 UTC
Permalink
Post by Andrea Ranieri
connection_.async_write("abcd", boost::bind(&client::handle_write,
this, boost::asio::placeholders::error));
What happens if you pass std::string("abcd") as the first argument
instead the "abcd" literal?
Avio
2013-07-07 17:05:30 UTC
Permalink
Post by Bjorn Reese
Post by Andrea Ranieri
connection_.async_write("abcd", boost::bind(&client::handle_write,
this, boost::asio::placeholders::error));
What happens if you pass std::string("abcd") as the first argument
instead the "abcd" literal?
Thanks to everybody for the answers, and sorry for my late reply.
Yes, this was indeed the problem: the compiler had no reason to convert
"abcd" to std::string, so I was passing a const char *, that is serialized
in a different way.
Post by Bjorn Reese
in your actual code?
I tested this one as well, with no luck. It seems that
boost/serialization/string.hpp is almost entirely commented out by `#if 0`
blocks in boost 1.53. There should be no need for this include anymore.

Thank you again and best regards
Avio




--
View this message in context: http://boost.2283326.n4.nabble.com/Different-behavior-of-boost-serialization-of-strings-on-text-archive-tp4649294p4649465.html
Sent from the Boost - Users mailing list archive at Nabble.com.

Robert Ramey
2013-07-03 17:16:30 UTC
Permalink
Post by Andrea Ranieri
Hi all,
I'm having some issue serializing a `std::string` with
`boost::serialization` on a `text_oarchive`. AFAICT, I have two
identical pieces of code that behaves differently in two different
programs.
#include <iostream>
#include <string>
#include <sstream>
...

try using

#include <boost/serialization/string>

Robert Ramey
Jeff Flinn
2013-07-03 16:14:40 UTC
Permalink
Post by Andrea Ranieri
Hi all,
I'm having some issue serializing a `std::string` with
`boost::serialization` on a `text_oarchive`. AFAICT, I have two
identical pieces of code that behaves differently in two different programs.
#include <iostream>
#include <string>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
template <typename T>
void serialize_deserialize(const T & src, T & dst)
{
Are you missing:

#include <boost/serialization/string.hpp>

in your actual code?

Jeff
Loading...