Boost logo

Boost :

Subject: Re: [boost] [serialization] string serialization
From: troy d. straszheim (troy_at_[hidden])
Date: 2009-03-04 08:24:42


Robert Ramey wrote:
> Nope, It's not intentional.
>
> I don't remember why it is the way it is. Collections evolved
> to become more efficient and in the process collection_size_type
> came into being. Since std::string was already primitive and had
> a special implemention there hasn't been any motivation to mess
> with it. I'm not even that enthusiastic about colllection_size_type.
> Turns out that each std collection has its own size_type. So this
> makes thing even more confusing.
>
> It's the way it is because there was no obvious better choice.
>

I think it is a reasonable choice. The more control serialization gives
me over how things are stored, the less likely it is that a change in
the serialization library will make it impossible for me to maintain an
archive that is binary compatible with previous versions of
serialization. (In our case, the previous version is v1.33.1, and in
this case one needs special handling for strings anyhow.) For other
containers, the fact that serialization maps the varying size_types of
std collections to one type simplifies things. If I don't like it, I
can supply my own serialization routine for the container in question.
In the general case (as has already been discussed ad nauseam), I'd
argue that 'portable' has a context-dependent meaning (e.g. are ieee754
floats 'portable' for this use case? Is little/big endianness
required?) and it is up to the user to build an archive that implements
whatever 'portable' is to them.

Regarding the complaint about strings. For our (perhaps narrow)
definition of portable:

* 32/64 bit intel platforms, linux and osx, which implies little-endian
archives

* floats stored on disk in ieee754 format

* serializable types required to use stdint typedefs where types vary
across the platforms we run on (for us this basically means 'no plain
longs', but when/if 128 bit platforms come around, we may need to go
back and change our 'ints' to int32_t)

* binary compatible with archives from a venerable custom binary archive
built on top of 1.33.1.

We can get away with just the following in our
portable_binary_iarchive_impl:
template<class Archive, class Elem, class Tr>
class portable_binary_iarchive_impl :
   public basic_binary_iprimitive<Archive, Elem, Tr>,
   public basic_binary_iarchive<Archive>
{

// ...

void load_override(std::string& s, BOOST_PFTO int)
{
   uint32_t l;
   this->load(l);
   s.resize(l);
   this->load_binary(&(s[0]), l);
}

void load_override(class_name_type& t, BOOST_PFTO int)
{
   std::string cn;
   cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
   this->load_override(cn, 0);
   if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
     throw_exception(archive_exception(invalid_class_name));
   std::memcpy(t, cn.data(), cn.size());
   // borland tweak
   t.t[cn.size()] = '\0';
}

void load_override(boost::serialization::collection_size_type& t,
                    BOOST_PFTO int)
{
   uint32_t l;
   this->load(l);
   t = l;
}

-t


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