Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2006-03-16 06:00:49


Hello,

Currently, output text archives implement string saving like this:

template<class Archive>
BOOST_ARCHIVE_DECL(void)
text_oarchive_impl<Archive>::save(const std::string &s)
{
    const std::size_t size = s.size();
    *this->This() << size;
    this->This()->newtoken();
    os << s;
}

which looks fine, except that some stdlib implementations don't
do the "os<<s" right when s contains embedded nulls --basically,
output stops at the first embedded null. Such a defective
stdlib implementation is for instance, that of MSVC 6.5, and I
have had conversations with Linux users leading me to
suspect some libstdc++ implementations as well. Besides,
the std requirements on operator<<(ostream,string) mandate
that this function does a lot more things than simply dump the
characters of the string, as
text_iarchive_impl<Archive>::load(std::string &)
assumes implicitly (reading is done through istream::read.)

The attached example shows the problem. It crashes in MSVC 6.5,
my hunch is that it'll fail in some other environments as well, though
not in every one. Using intermediate buffers of type vector<char>
fixes the problem.

My suggestion is that text_oarchive_impl<Archive>::save(const
std::string &s)
be changed so as to dump the string as follows:

template<class Archive>
BOOST_ARCHIVE_DECL(void)
text_oarchive_impl<Archive>::save(const std::string &s)
{
    const std::size_t size = s.size();
    *this->This() << size;
    this->This()->newtoken();
    os.write(s.data(),s.size());
}

so as to avoid problems with embedded nulls.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk