2

在查看 MessagePack 的 C API 时,有许多函数可以根据类型适当地序列化(打包)数据:msgpack_pack_uint8, msgpack_pack_int32, ...

API 中似乎没有等效的调用来解包数据。 msgpack_unpack_next返回一个msgpack_object。这些对象仅具有粗粒度的类型(最大的类型:int64、double、...),基于包含的枚举。

我在这里错过了什么吗?是否期望使用粗对象然后进行投射?

应该如何正确拆包?

此外,是否有任何好的文档或使用示例?网站上的那些都是微不足道的。

4

1 回答 1

10

在解包时,任何整数值始终msgpack_object作为固定宽度的 64 位整数存储在 a 中(int64_t如果为负,则为负uint64_t)。

有关等人cpp/src/msgpack/object.h的更多详细信息,请参阅 msgpack 如何处理解包逻辑,例如:msgpack_objectcpp/src/msgpack/unpack.c

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;
    }
}

这是因为在打包时,msgpack 会根据整数的值动态选择最佳编码方式,例如,如果您使用msgpack_pack_uint16打包整数,则:

  • 如果值在 [0, 127] 中,它将保存在 1 个字节中,
  • 0xcc如果值在 [128, 255] 中,则2 个字节作为第一个字节,
  • 3 个字节0xcd否则作为第一个字节。

有关msgpack_pack_real_uint16更多cpp/src/msgpack/pack_template.h详细信息,请参阅。


换句话说,在解包时,msgpack 使用足够大的正数或负数(测试 if obj.typeis MSGPACK_OBJECT_POSITIVE_INTEGERor MSGPACK_OBJECT_NEGATIVE_INTEGER)来保存任何整数值。所以这取决于你:

  • 如果您始终可以假设值永远不会溢出您的转换类型,则进行转换,
  • 或者,如果该值对于您的接收器类型来说不够大,则动态检查(使用掩码),
  • 或者,总是使用int64_tor uint64_t

最后,C 测试套件 ( msgpack/cpp/test/msgpackc_test.cpp) 可能有助于浏览代码示例。

于 2012-09-25T10:27:12.683 回答