At unpack time, any integer value is always stored within a msgpack_object
as a fixed-width 64-bit integer (int64_t
if negative, uint64_t
otherwise).
See cpp/src/msgpack/object.h
for more details on msgpack_object
et al., and cpp/src/msgpack/unpack.c
to see how msgpack handles the unpacking logic, e.g.:
static inline int template_callback_int8(unpack_user* u,
int8_t d,
msgpack_object* o) {
if(d >= 0) {
o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d;
return 0;
}
else {
o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d;
return 0;
}
}
This is because at pack time, msgpack chooses dynamically the most optimal way to encode an integer according to its value, e.g. if you use msgpack_pack_uint16
to pack your integer then:
- it will be saved in 1 byte if the value is in [0, 127],
- 2 bytes with
0xcc
as first byte if the value is in [128, 255],
- 3 bytes with
0xcd
as first byte otherwise.
See msgpack_pack_real_uint16
from cpp/src/msgpack/pack_template.h
for more details.
In other words at unpack time, msgpack uses a large enough positive or negative (test if obj.type
is MSGPACK_OBJECT_POSITIVE_INTEGER
or MSGPACK_OBJECT_NEGATIVE_INTEGER
) to hold any integer value. So it's up to you to:
- cast if you can always assume that values will never overflow your cast type,
- or, check dynamically (with a mask) if the value is not large enough for your receiver type,
- or, always use an
int64_t
or uint64_t
.
At last, the C test suite (msgpack/cpp/test/msgpackc_test.cpp
) might be helpful to browse code samples.