【问题标题】:MessagePack C API消息包 C API
【发布时间】:2012-09-14 20:19:46
【问题描述】:

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

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

我在这里遗漏了什么吗?是不是期望先用粗物再施法?

应该如何正确拆包?

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

【问题讨论】:

标签: c msgpack messagepack


【解决方案1】:

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

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

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个字节中,
  • 如果值在 [128, 255] 中,2 bytes0xcc 作为第一个字节,
  • 3 bytes 0xcd 作为第一个字节,否则。

更多详情请参阅cpp/src/msgpack/pack_template.h 中的msgpack_pack_real_uint16


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

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

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

【讨论】:

  • 谢谢!我得出了同样的结论。 msgpack 在线上很高效,您需要了解适当转换的协议。这种效率的代价是它不能在解包时自动推断出原始类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 2010-12-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 2015-03-13
  • 2015-09-24
相关资源
最近更新 更多