从C / C ++获取msgpack数组中的元素的指针和长度 [英] Get pointer to and length of element in msgpack array from C/C++

查看:1091
本文介绍了从C / C ++获取msgpack数组中的元素的指针和长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些数据使用C / C ++ api包装的msgpack如下:

I have some data that was packed with msgpack using the C/C++ api as follows:

msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> pk(&sbuf);

int var1 = 10;
std::string var2 = "test";
double var3 = 3.14159; // could be any type

pk.pack_array(3);
pk.pack(var1);
pk.pack(var2);
pk.pack(var3);

稍后我需要解压缩该数组,但需要直接访问第三个元素可以持久化到文件/ db / redis / memcached / etc。虽然数组的前两个元素是固定类型,第三个可以是msgpack(int,string,vector,map等)可接受的任何类型。

At a later point I need to unpack that array, but need direct access to the third element so I can persist to file/db/redis/memcached/etc. While the first two elements of the array are fixed types, the third can be any type acceptable to msgpack (int, string, vector, map, etc).

size_t off = 0;
msgpack::unpacked result = msgpack::unpack(sbuf.data(), sbuf.len(), off);
msgpack::object obj = result.get();

int var1;
obj.via.array.ptr[0].convert(&var1);

std::string var2;
obj.via.array.ptr[1].convert(&var2);

// now here I want to get a pointer & len to the 3rd item so I can persist
// this value that is already msgpack'd.

const char* dataptr = reinterpret_cast<const char*>(&obj.via.array.ptr[2]);
// now what is the length of the data pointed to by dataptr?

潜在地,我可以在obj.via.array.ptr [2]上做一个reinterpret_cast,但在二进制数据或一个msgpack'd结构的情况下,一个简单的strlen()不会得到我的长度,我不能看到在哪里得到项目的长度。我知道有很多类型的大小变量,但不相信这是准确的,当该项目是一个数组或地图。

Potentially I could do a reinterpret_cast on obj.via.array.ptr[2] as shown above, but in the case of binary data, or a msgpack'd struct, a simple strlen() wouldn't get me the length and I can't see where to get the item's length. I know there is a size variable in many of the types but don't believe this is accurate when that item is an array or map.

推荐答案

这里是msgpack-c的内存模型:
https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#memory-management

Here is a memory model of the msgpack-c: https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#memory-management


我知道在许多类型中有一个大小变量,但不相信这是准确的,当该项目是一个数组或地图。

I know there is a size variable in many of the types but don't believe this is accurate when that item is an array or map.

True。 obj 已解压缩。它不适合持久。
我认为直接存储msgpack格式的二进制数据是更好的方法。首先,将msgpack分成前两个和第三个。然后,打包前两个作为数组。最后,简单地打包第三个值。这是包装过程。

True. obj has already been unpacked. It is not suitable for persistent. I think that storing msgpack format binary data directly is better approach. First, separate the msgpack to the first two and the thrid one. Then, pack the first two as an array. Finally, simply pack the third value. That is packing process.

    pk.pack_array(2); // for the first two
    pk.pack(var1);
    pk.pack(var2);
    pk.pack(var3);    // for the thrid one

当解包时,使用offset解压前两个数据。

When unpacking, unpack the first two data with offset.

    // Unpacking
    size_t off = 0;
    msgpack::unpacked result = msgpack::unpack(sbuf.data(), sbuf.size(), off);
    // off has been set

打开包装后,已设置偏移。所以你可以得到第三个数据的起点。然后,存储msgpack格式的二进制数据。

After unpacking them, offset has been set. So you can get the start point of the third data. Then, store the msgpack format binary data.

    std::string store; // file/db/redis/memcached/etc
    std::copy(sbuf.data() + off, sbuf.data() + sbuf.size(), std::back_inserter(store));

这是存储进程。

您可以从存储中获取msgpack格式的二进制数据,然后解压缩。

When you get the msgpack format binary data from storage, unpack them.

这里是一个完整的代码示例:

Here is a whole code example:

#include <msgpack.hpp>

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    msgpack::sbuffer sbuf;
    msgpack::packer<msgpack::sbuffer> pk(&sbuf);

    int var1 = 10;
    std::string var2 = "test";
    double var3 = 3.14159; // could be any type

    // Separate the data into the two msgpacks
    pk.pack_array(2); // for the first two
    pk.pack(var1);
    pk.pack(var2);
    pk.pack(var3);    // for the thrid one

    // Unpacking
    size_t off = 0;
    msgpack::unpacked result = msgpack::unpack(sbuf.data(), sbuf.size(), off);
    msgpack::object obj = result.get();

    auto converted = obj.as<std::tuple<int, std::string>>();
    std::cout << std::get<0>(converted) << std::endl;
    std::cout << std::get<1>(converted) << std::endl;

    // Storing the thrid one
    std::cout << "off: " << off << std::endl;
    std::string store; // file/db/redis/memcached/etc
    std::copy(sbuf.data() + off, sbuf.data() + sbuf.size(), std::back_inserter(store));

    {
        // Unpack the thrid one from store
        msgpack::unpacked result = msgpack::unpack(store.data(), store.size());
        msgpack::object obj = result.get();
        if (obj.type == msgpack::type::FLOAT) {
            auto f = obj.as<float>();
            std::cout << f << std::endl;
        }
    }
}

上面的代码:
http://melpon.org/wandbox/permlink/uFfRGKQLqnIIiDrv

这篇关于从C / C ++获取msgpack数组中的元素的指针和长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆