从 C/C++ 获取指向 msgpack 数组中元素的指针和长度
Get pointer to and length of element in msgpack array from C/C++
我有一些数据是使用 C/C++ api 使用 msgpack 打包的,如下所示:
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);
稍后我需要解压缩该数组,但需要直接访问第三个元素以便我可以坚持 file/db/redis/memcached/etc。虽然数组的前两个元素是固定类型,但第三个元素可以是 msgpack 可接受的任何类型(int、string、vector、map 等)。
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 结构,简单的 strlen() 不会我无法获取长度,而且我看不到从哪里获取该项目的长度。我知道很多类型都有一个大小变量,但当该项目是数组或映射时,我不相信这是准确的。
这是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.
没错。 obj
已经解包。不适合执着。
我认为直接存储 msgpack 格式的二进制数据是更好的方法。首先,将 msgpack 分为前两个和第三个。然后,将前两个打包为一个数组。最后,简单地打包第三个值。那就是打包过程。
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);
// off has been set
解包后,offset已经设置好了。这样就可以得到第三个数据的起点。然后,存储msgpack格式的二进制数据。
std::string store; // file/db/redis/memcached/etc
std::copy(sbuf.data() + off, sbuf.data() + sbuf.size(), std::back_inserter(store));
也就是存储过程。
当您从存储中获取 msgpack 格式的二进制数据时,解压缩它们。
这是一个完整的代码示例:
#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++ api 使用 msgpack 打包的,如下所示:
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);
稍后我需要解压缩该数组,但需要直接访问第三个元素以便我可以坚持 file/db/redis/memcached/etc。虽然数组的前两个元素是固定类型,但第三个元素可以是 msgpack 可接受的任何类型(int、string、vector、map 等)。
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 结构,简单的 strlen() 不会我无法获取长度,而且我看不到从哪里获取该项目的长度。我知道很多类型都有一个大小变量,但当该项目是数组或映射时,我不相信这是准确的。
这是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.
没错。 obj
已经解包。不适合执着。
我认为直接存储 msgpack 格式的二进制数据是更好的方法。首先,将 msgpack 分为前两个和第三个。然后,将前两个打包为一个数组。最后,简单地打包第三个值。那就是打包过程。
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);
// off has been set
解包后,offset已经设置好了。这样就可以得到第三个数据的起点。然后,存储msgpack格式的二进制数据。
std::string store; // file/db/redis/memcached/etc
std::copy(sbuf.data() + off, sbuf.data() + sbuf.size(), std::back_inserter(store));
也就是存储过程。
当您从存储中获取 msgpack 格式的二进制数据时,解压缩它们。
这是一个完整的代码示例:
#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