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()
.
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.
1varint val = 0;
2
3auto used = sleb128_deserialize_varint(val, buf, sizeof(buf));
4assert(used > 0);