fraillt/bitsery

How to serialize a vector without size before data?

harsszegi opened this issue · 5 comments

Hello,
I have a serialization format that whenever a std::vector needs to be (de)serialized, the amount of data is defined by two other members in the struct that are (de)serialized prior the std::vector, something like that:
uint32_t lowBound;
uint32_t highBound;
std::vector<int32_t> data;

so within data there are highBound - lowBound + 1 elements, but the length is not being (de)serialized (e.g. only lowBound, highBound and the data itself is (de)serialized). How can I achieve this with bitsery?
Thanks,

Hi, so if I understand correctly, something like this should work.

template <class S>
void serialize(S& s, MyData& data) {
  s.value4b(data.low_bound);
  s.value4b(data.high_bound);
  for (auto i=data.low_bound; i < data.high_bound; ++i) {
    s.value4b(data.data[i]);
  }

I assume, that vector size is always >= high_bound.

Oh god, I am lame, you are 100% correct.
Thanks a lot!

Just a quick question though. During deserialize, how/when would data be resized, so that [] would work?
Thanks,

For this particular example, you need to take care of container resizing yourself.
I don't know all the constraints you have here.
You might also add a simple resize statement before for loop, as well :)

template <class S>
void serialize(S& s, MyData& data) {
  s.value4b(data.low_bound);
  s.value4b(data.high_bound);
  if data.data.size() < data.high_bound {
    data.data.resize(data.high_bound);
  }
  for (auto i=data.low_bound; i < data.high_bound; ++i) {
    s.value4b(data.data[i]);
  }
}

That should work in both serialize/deserialize flows.
However, this style of writing is not encouraged, as you might easily get into a situation where the same code doesn't work for serialization and deserialization.
Instead, you should create your own extension which allows you to customize serialize/deserialize flows separately.

Awesome, thansk!