How to serialize into a vector or array?

998 views
Skip to first unread message

Hi-Angel

unread,
Dec 3, 2017, 5:41:18 AM12/3/17
to cereal serialization library
Sorry for the silly question, but googling came up with nothing, and
docs lack an example. I almost figured it out, see the code below. The
only problem I have is that the pre-last line (i.e. the
"ss_to_vec(v);") throws an exception:

terminate called after throwing an instance of 'cereal::Exception'
what(): Failed to read 8 bytes from input stream! Read 2

#include <cereal/archives/binary.hpp>
#include <cereal/types/vector.hpp>
#include <vector>
#include <sstream>
#include <cstdint>

struct MyClass {
uint8_t a, b;

template<class Archive>
void serialize(Archive & archive) {
archive(a, b);
}
};

int main() {
MyClass myclass = {1, 2};
std::stringstream ss(std::ios::binary | std::ios::out | std::ios::in);
cereal::BinaryOutputArchive class_to_ss(ss);
class_to_ss(myclass);

cereal::BinaryInputArchive ss_to_vec(ss);
std::vector<uint8_t> v;
ss_to_vec(v);
}

Erich Keane

unread,
Dec 3, 2017, 11:45:14 AM12/3/17
to Hi-Angel, cereal serialization library
Its throwing because you are writing 2 8 bit values, but trying to read
a heck of a lot more into a std::vector.   You have to make sure that
whatever you write is what you read.

The format for a std::vector isn't just the values themselves. The size
is also prepended, so it knows when to s top reading.

Hi-Angel

unread,
Dec 3, 2017, 12:28:59 PM12/3/17
to Erich Keane, cereal serialization library
Thanks, I thought the library figures out how much size it have to
write. Okay, can you elaborate a bit more, how do I point the size
that needs to be written? I tried preallocating a vector (well, not 8
bytes of course, but sizeof MyClass), but it changes nothing.

Erich Keane

unread,
Dec 3, 2017, 12:34:22 PM12/3/17
to Hi-Angel, cereal serialization library
The serialization format for vectror is in vector.hpp's code. You'll
want to look at that.

You will either need to 'output' a vector in order to read it back in,
or reverse-engineer the format (see vector.hpp) in order to reproduce it
perfectly.

If I recall correctly, vector's format is an 8 byte size encoded, THEN
each of the elements in order. SO vectors deserialization is something like:

archive(size); // size is size_t

for (size_type i =0 ;i < size; ++i){

  T thing;

  archive(thing);

  this->push_back(thing); // i'm sure there are tricks to avoid
moving/copying here,omitted for clarity

Hi-Angel

unread,
Dec 3, 2017, 1:25:55 PM12/3/17
to Erich Keane, cereal serialization library
So you're suggesting to serialize in addition to struct fields some
irrelevant values, like size. I don't know Cereal well, but from what
I know it looks wrong thing to do: α) it forces me to manually insert
some obscure values for some internal to Cereal reasons, β) It forces
me to rely on some undocumented and prone to changes behavior.

What it more likely is — some kind of bug, so I probably have to report it.

Hi-Angel

unread,
Dec 3, 2017, 1:35:09 PM12/3/17
to Erich Keane, cereal serialization library
On 3 December 2017 at 21:25, Hi-Angel <hiang...@gmail.com> wrote:
> So you're suggesting to serialize in addition to struct fields some
> irrelevant values, like size. I don't know Cereal well, but from what
> I know it looks wrong thing to do: α) it forces me to manually insert
> some obscure values for some internal to Cereal reasons, β) It forces
> me to rely on some undocumented and prone to changes behavior.

…γ) should cause problems with serializing to other formats (not that
I am interested though, just a point), and δ) defeats the purpose of
serialization to a vector — I need to send bytes over the network in a
very particular binary format.

Hi-Angel

unread,
Dec 3, 2017, 1:51:28 PM12/3/17
to Erich Keane, cereal serialization library
Reply all
Reply to author
Forward
0 new messages