When unpacking, any integer value is always stored in msgpack_object as an integer of 64-bit fixed width ( int64_t , if negative, uint64_t otherwise).
For more information on msgpack_object et al. And cpp/src/msgpack/unpack.c see cpp/src/msgpack/object.h to find out how msgpack handles unpacking logic, for example:
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 due to the fact that during the package msgpack dynamically selects the most optimal way to encode an integer according to its value, for example. if you use msgpack_pack_uint16 to pack your integer, then:
- it will be stored in 1 byte if the value is in [0, 127],
- 2 bytes with
0xcc as the first byte if the value is in [128, 255], - 3 bytes with
0xcd as the first byte otherwise.
See msgpack_pack_real_uint16 from cpp/src/msgpack/pack_template.h .
In other words, when unpacking, msgpack uses a sufficiently large positive or negative value (if obj.type is MSGPACK_OBJECT_POSITIVE_INTEGER or MSGPACK_OBJECT_NEGATIVE_INTEGER ) to save any integer value. So up to you:
- if you can always assume that the values will never overflow with your cast type,
- or, check dynamically (with a mask) if the value is not large enough for your receiver type,
- or always use
int64_t or uint64_t .
Finally, the C test suite ( msgpack/cpp/test/msgpackc_test.cpp ) may be useful for viewing sample code.
source share