如何用msgpack-c打包多键映射
how to pack multi-key map with msgpack-c
我正在尝试使用 msgpack(在 c 版本中,而不是在 c++ 中)来替换我们自己的序列化方法,该方法主要基于 xml。打包一些普通数据非常简单。但是,我们有很多基于 k-v 的结构,例如
struct Table {
struct Key {
// Multi-keys
int key1;
int key2;
};
struct Attr {
// Attributes
int attr1;
bool attr2;
char[8] attr3;
};
}
如何在msgpack-c中用msg_pack_map打包多键table? (不幸的是,我们的系统是异常禁用的,所以我不能使用c++版本"msgpack.hpp")
我的代码片段:
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_packer_map(&pk, 10) // 10 pairs
for(int i= 0; i<10; ++i) {
// key
msgpack_pack_array(&pk, 2);
msgpack_pack_int(&pk, i);
msgpack_pack_int(&pk, 100+i);
// attr
msgpack_pack_array(&pk, 3);
msgpack_pack_int(&pk, 1);
msgpack_pack_true(&pk);
msgpack_pack_str(&pk, 7);
msgpack_pack_str_body(&pk, "example");
}
我假设在 msgpack 中,我们必须使用 msgpack_pack_array 来打包结构。
我的代码是否正确,或者有更好的方法吗?
是的,你是对的。您的代码片段中有两个细微的错误。
msgpack_packer_map 应该是 msgpack_pack_map。 msgpack_pack_str_body 需要字符串的长度作为第三个参数。
我更新了你的代码片段,并添加了测试代码。
参见:
http://melpon.org/wandbox/permlink/RuZKLmzwStHej5TP
#include <msgpack.h>
#include <msgpack.hpp>
#include <map>
#include <iostream>
struct Key {
// Multi-keys
int key1;
int key2;
MSGPACK_DEFINE(key1, key2);
};
inline bool operator<(Key const& lhs, Key const& rhs) {
if (lhs.key1 < rhs.key1) return true;
if (lhs.key1 > rhs.key1) return false;
if (lhs.key2 < rhs.key2) return true;
return false;
}
struct Attr {
// Attributes
int attr1;
bool attr2;
std::string attr3;
MSGPACK_DEFINE(attr1, attr2, attr3);
};
int main() {
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_map(&pk, 10); // 10 pairs
for(int i= 0; i<10; ++i) {
// key
msgpack_pack_array(&pk, 2);
msgpack_pack_int(&pk, i);
msgpack_pack_int(&pk, 100+i);
// attr
msgpack_pack_array(&pk, 3);
msgpack_pack_int(&pk, 1);
msgpack_pack_true(&pk);
msgpack_pack_str(&pk, 7);
msgpack_pack_str_body(&pk, "example", 7);
}
{
auto upd = msgpack::unpack(sbuf.data, sbuf.size);
std::cout << upd.get() << std::endl;
auto tbl = upd.get().as<std::map<Key, Attr>>();
}
msgpack_sbuffer_destroy(&sbuf);
}
那是一个c++代码,但我在打包部分使用了C API。您可以检查解压后的 msgpack 对象。它也成功转换为C++映射。
这是 C API 文档:
https://github.com/msgpack/msgpack-c/wiki/v1_1_c_overview
我正在尝试使用 msgpack(在 c 版本中,而不是在 c++ 中)来替换我们自己的序列化方法,该方法主要基于 xml。打包一些普通数据非常简单。但是,我们有很多基于 k-v 的结构,例如
struct Table {
struct Key {
// Multi-keys
int key1;
int key2;
};
struct Attr {
// Attributes
int attr1;
bool attr2;
char[8] attr3;
};
}
如何在msgpack-c中用msg_pack_map打包多键table? (不幸的是,我们的系统是异常禁用的,所以我不能使用c++版本"msgpack.hpp")
我的代码片段:
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_packer_map(&pk, 10) // 10 pairs
for(int i= 0; i<10; ++i) {
// key
msgpack_pack_array(&pk, 2);
msgpack_pack_int(&pk, i);
msgpack_pack_int(&pk, 100+i);
// attr
msgpack_pack_array(&pk, 3);
msgpack_pack_int(&pk, 1);
msgpack_pack_true(&pk);
msgpack_pack_str(&pk, 7);
msgpack_pack_str_body(&pk, "example");
}
我假设在 msgpack 中,我们必须使用 msgpack_pack_array 来打包结构。
我的代码是否正确,或者有更好的方法吗?
是的,你是对的。您的代码片段中有两个细微的错误。 msgpack_packer_map 应该是 msgpack_pack_map。 msgpack_pack_str_body 需要字符串的长度作为第三个参数。
我更新了你的代码片段,并添加了测试代码。
参见:
http://melpon.org/wandbox/permlink/RuZKLmzwStHej5TP
#include <msgpack.h>
#include <msgpack.hpp>
#include <map>
#include <iostream>
struct Key {
// Multi-keys
int key1;
int key2;
MSGPACK_DEFINE(key1, key2);
};
inline bool operator<(Key const& lhs, Key const& rhs) {
if (lhs.key1 < rhs.key1) return true;
if (lhs.key1 > rhs.key1) return false;
if (lhs.key2 < rhs.key2) return true;
return false;
}
struct Attr {
// Attributes
int attr1;
bool attr2;
std::string attr3;
MSGPACK_DEFINE(attr1, attr2, attr3);
};
int main() {
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_map(&pk, 10); // 10 pairs
for(int i= 0; i<10; ++i) {
// key
msgpack_pack_array(&pk, 2);
msgpack_pack_int(&pk, i);
msgpack_pack_int(&pk, 100+i);
// attr
msgpack_pack_array(&pk, 3);
msgpack_pack_int(&pk, 1);
msgpack_pack_true(&pk);
msgpack_pack_str(&pk, 7);
msgpack_pack_str_body(&pk, "example", 7);
}
{
auto upd = msgpack::unpack(sbuf.data, sbuf.size);
std::cout << upd.get() << std::endl;
auto tbl = upd.get().as<std::map<Key, Attr>>();
}
msgpack_sbuffer_destroy(&sbuf);
}
那是一个c++代码,但我在打包部分使用了C API。您可以检查解压后的 msgpack 对象。它也成功转换为C++映射。
这是 C API 文档: https://github.com/msgpack/msgpack-c/wiki/v1_1_c_overview