2015-11-16 2 views
0

Я пытаюсь использовать msgpack (в версии c, а не C++), чтобы заменить наш собственный метод сериализации, который находится в основном на основе xml. Очень просто собрать некоторые обычные данные. Тем не менее, у нас есть много структур, основанных к-V, какКак упаковать карту с несколькими ключами с msgpack-c

struct Table { 
    struct Key { 
    // Multi-keys 
    int key1; 
    int key2; 
    }; 
    struct Attr { 
    // Attributes 
    int attr1; 
    bool attr2; 
    char[8] attr3; 
    }; 
} 

Как упаковать несколько ключей таблицы с msg_pack_map в msgpack-с? (К сожалению, наша система отключена исключение, поэтому я не могу использовать 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 паковать-структуру ,

Является ли мой код правильным, или есть ли лучший способ сделать это?

ответ

1

Да, вы правы. В фрагменте кода есть две тонкие ошибки. 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 API в упаковочной части. Вы можете проверить распакованный объект msgpack. Он также преобразован как карта C++ успешно.

Настоящая документация по API C: https://github.com/msgpack/msgpack-c/wiki/v1_1_c_overview