IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> msgpack-c 官方文档整理翻译之pack -> 正文阅读

[C++知识库]msgpack-c 官方文档整理翻译之pack

msgpack::packer

Supported types

msgpack::packer 将任何数据打包成 msgpack 格式。目前支持以下格式:

https://github.com/msgpack/msgpack-c/tree/cpp_master/include/msgpack/adaptor

此外,您可以打包 msgpack::object。

您可以添加您的适配器类模板特化来支持打包那些包含您想要打包的类型的对象。

重载声明:

#include <msgpack.hpp>

namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {

template <>
struct pack<the_type_you_want_to_pack> {
    template <typename Stream>
    msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, the_type_you_want_to_pack const& v) const {
        // packing implementation.
        // o.pack_???(v.???);
        return o;
    }
};
} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack

您可以在pack实现中调用packer的打包成员函数。请参阅手动打包

另请参阅适配器(adaptor)

Buffer

您可以使用任何具有以下成员函数的类:

write(const char*, std::size_t);

在 C++ 标准库中,std::stringstream 有它。

std::tuple<int, bool, std::string> src(1, true, "example");
std::stringstream buffer;
msgpack::pack(buffer, src); // calls std::stringstream::write internally.

msgpack 提供了多种类型的缓冲区:

sbuffer

sbuffer 是简单的缓冲区。它在内部使用 malloc、free 和 realloc。当调用 msgpack::pack 时,src 被复制到缓冲区。 realloc 比新建、复制和删除操作更快。

vrefbuffer

vrefbuffer 是一种参考缓冲区。当调用 msgpack::pack 时,缓冲区可能会引用 src。所以你可以避免复制,但你需要保留 src 对象,直到缓冲区的提升时间结束。

vrefbuffer 有一个名为 m_ref_size 的阈值。如果序列化的 src 对象的大小大于或等于阈值,则引用该对象。

vrefbuffer.hpp

    void write(const char* buf, size_t len)
    {
        if(len < m_ref_size) {
            append_copy(buf, len);
        } else {
            append_ref(buf, len);
        }
    }
#ifndef MSGPACK_VREFBUFFER_REF_SIZE
#define MSGPACK_VREFBUFFER_REF_SIZE 32
#endif

#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE
#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192
#endif

namespace detail {
    // int64, uint64, double
    std::size_t const packer_max_buffer_size = 9;
} // detail

class vrefbuffer {
public:
    // ref_size is stored to m_ref_size
    vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE,
               size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE)
        :m_ref_size(std::max(ref_size, detail::packer_max_buffer_size + 1)),
         m_chunk_size(chunk_size)
    {
        ...
    }
};

你可以在构造函数上传递阈值大小,但是如果你给的 ref_size 小于 10,vrefbuffer::ref_size,实际的阈值应该是 10。因为 msgpack 格式固定对象的最大大小是 9,它们的缓冲区是在栈上分配如下:

pack.hpp

template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_int64(int64_t d)
{
    char buf[9];
    buf[0] = static_cast<char>(0xd3); _msgpack_store64(&buf[1], d);
    append_buffer(buf, 9);
    return *this;
    // buf's lifetime is finished, so can't use vrefbuffer::append_ref()
}

zbuffer

zbuffer的内容是使用 zlib 压缩的。

fbuffer

fbuffer 的内容使用 c 风格的 FILE*存储到文件中。

pack

如果要打包数据,请调用 pack()。第一个参数是缓冲区,第二个参数是要打包的值。您可以传递任何支持的类型

template <typename Stream, typename T>
inline void pack(Stream& s, const T& v);

pack manually(手动)

您也可以手动打包。请参见以下示例:

msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char c[] = { 1, 2, 3, 4, 5, 6 };
packer.pack_bin(sizeof(c));         // pack header and size
packer.pack_bin_body(c, sizeof(c)); // pack payload

msgpack::packer 提供以下手动打包功能。当您通过 operator<< (packer& o, const the_type_you_want_to_pack& v) 实现自定义类型支持时,通常会使用这些函数。当然,您可以直接在应用程序中使用解包功能。

class packer {
public:
    packer<Stream>& pack_uint8(uint8_t d);
    packer<Stream>& pack_uint16(uint16_t d);
    packer<Stream>& pack_uint32(uint32_t d);
    packer<Stream>& pack_uint64(uint64_t d);
    packer<Stream>& pack_int8(int8_t d);
    packer<Stream>& pack_int16(int16_t d);
    packer<Stream>& pack_int32(int32_t d);
    packer<Stream>& pack_int64(int64_t d);

    packer<Stream>& pack_fix_uint8(uint8_t d);
    packer<Stream>& pack_fix_uint16(uint16_t d);
    packer<Stream>& pack_fix_uint32(uint32_t d);
    packer<Stream>& pack_fix_uint64(uint64_t d);
    packer<Stream>& pack_fix_int8(int8_t d);
    packer<Stream>& pack_fix_int16(int16_t d);
    packer<Stream>& pack_fix_int32(int32_t d);
    packer<Stream>& pack_fix_int64(int64_t d);

    packer<Stream>& pack_char(char d);
    packer<Stream>& pack_signed_char(signed char d);
    packer<Stream>& pack_short(short d);
    packer<Stream>& pack_int(int d);
    packer<Stream>& pack_long(long d);
    packer<Stream>& pack_long_long(long long d);
    packer<Stream>& pack_unsigned_char(unsigned char d);
    packer<Stream>& pack_unsigned_short(unsigned short d);
    packer<Stream>& pack_unsigned_int(unsigned int d);
    packer<Stream>& pack_unsigned_long(unsigned long d);
    packer<Stream>& pack_unsigned_long_long(unsigned long long d);

    packer<Stream>& pack_float(float d);
    packer<Stream>& pack_double(double d);

    packer<Stream>& pack_nil();
    packer<Stream>& pack_true();
    packer<Stream>& pack_false();

    packer<Stream>& pack_array(size_t n);

    packer<Stream>& pack_map(size_t n);

    packer<Stream>& pack_str(size_t l);
    packer<Stream>& pack_str_body(const char* b, size_t l);

    packer<Stream>& pack_bin(size_t l);
    packer<Stream>& pack_bin_body(const char* b, size_t l);

    packer<Stream>& pack_ext(size_t l, int8_t type);
    packer<Stream>& pack_ext_body(const char* b, size_t l);
};

packing classes

msgpack 提供了一个方便的宏来让你的类适应pack函数。

class my_class {
public:
    std::string value;
    int i;
    MSGPACK_DEFINE(value, i); // write the member variables that you want to pack
};

如果类有 MSGPACK_DEFINE() 宏,则可以打包类,可以将类转换为 msgpack::object,也可以将 msgpack::object 转换为类。

packing enums

msgpack 提供了一个方便的宏来使枚举变量适应pack函数。当你要打包的类有枚举成员变量时,你需要告诉msgpack你要打包的是哪个枚举类型。

#include <msgpack.hpp>

class TestEnumMemberClass
{
public:
  TestEnumMemberClass()
    : t1(STATE_A), t2(STATE_B), t3(STATE_C) {}

  enum TestEnumType {
    STATE_INVALID = 0,
    STATE_A = 1,
    STATE_B = 2,
    STATE_C = 3
  };
  TestEnumType t1;
  TestEnumType t2;
  TestEnumType t3;

  MSGPACK_DEFINE(t1, t2, t3);
};

// This macro should be written in the global namespace
MSGPACK_ADD_ENUM(TestEnumMemberClass::TestEnumType);

// ...
// pack enums

在 MSGPACK_ADD_ENUM() 定义之后,就可以pack枚举类型了。

请参阅示例

另请参阅 适配器

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:05:26  更:2022-03-30 18:09:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:51:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码