How-To (de-)serialize integers in variable length

When space is at a premium and values may be small, it is may make sense to encode integer values in variable length. For this, liberate implements both the signed and unsigned variant of LEB128 encoding.

But simply, it encodes in the first bit of a byte whether the value should be shifted, and the next byte’s value added. This again takes the first bit into account, and so forth until the entire value is decoded.

SLEB128 and ULEB128 (the signed and unsigned variants) produce slightly different encoded results, so it’s vital that you use them consistently across serialization and deserialization.

Serialization

Serialization follows the same pattern as serialization of integers in fixed size, except you need to use a varint C++ type, and you need to specify where to use liberate::serialization::sleb128_serialize_varint() or liberate::serialization::uleb128_serialize_varint().

Serialize an integer in variable size
 1#include <liberate/serialization/varint.h>
 2#include <liberate/types/varint.h>
 3
 4using namespace liberate::serialization;
 5using namespace liberate::types;
 6
 7char buf[1024];
 8
 9varint val = 12345;
10
11auto used = sleb128_serialize_varint(buf, sizeof(buf),
12assert(used > 0);

Deserialization

Deserialization also holds no surprises at this point.

Deserialize an integer in variable size
1varint val = 0;
2
3auto used = sleb128_deserialize_varint(val, buf, sizeof(buf));
4assert(used > 0);