国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

mpack簡(jiǎn)明教程

這篇具有很好參考價(jià)值的文章主要介紹了mpack簡(jiǎn)明教程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

摘要

本文先簡(jiǎn)單介紹MessagePack的基本概念。

然后,介紹一個(gè)MessagePack C API - MPack的通常使用。

接著嘗試對(duì)MPack截?cái)鄶?shù)據(jù)的讀取。

注:本文完整代碼見倉(cāng)庫(kù)。


MessagePack簡(jiǎn)介

如果你使用過C/C++的json庫(kù),那么上手MessagePack是比較容易的。關(guān)于C/C++ Json庫(kù)的使用可見:C++ JSON庫(kù)的一般使用方法-CSDN博客。

這里,我先說下結(jié)論,對(duì)于用戶層面而言,MessagePack相對(duì)于json節(jié)省空間,但犧牲了可讀性(對(duì)于人類而言)。(更多區(qū)別見:Why Not Just Use JSON?)

下面我們來看兩個(gè)示例,了解下MessagPack是如何壓縮json內(nèi)容。這個(gè)壓縮過程,遵循MessagePack specification(MessagePack規(guī)范)

第一個(gè)示例,來自MessagePack首頁(yè)。它將27個(gè)字節(jié)的JSON內(nèi)容,壓縮到18個(gè)字節(jié)。

mpack簡(jiǎn)明教程,# c/c++編程,mpack,MessagePack

我們根據(jù)MessagePack規(guī)范來看下上面是如何壓縮的。

# 82的含義
## 對(duì)于元素個(gè)數(shù)不超過15個(gè)的map存儲(chǔ),遵循如下格式
## 82 == 1000 0010 表示該結(jié)構(gòu)為map,有兩個(gè)元素
+--------+~~~~~~~~~~~~~~~~~+
|1000XXXX|   N*2 objects   |
+--------+~~~~~~~~~~~~~~~~~+

# A7的含義
## 對(duì)于長(zhǎng)度不超過31的固定長(zhǎng)度字符串存儲(chǔ),遵循如下格式
## A7 == 1010 0111 表示該結(jié)構(gòu)為字符串,有7個(gè)字符
+--------+========+
|101XXXXX|  data  |
+--------+========+

# C3含義
## false:
+--------+
|  0xc2  |
+--------+
## true:
+--------+
|  0xc3  |
+--------+

# A6的含義--略,查詢過程同上面A7

# 00的含義
## 可以使用7-bit存儲(chǔ)的正整數(shù),遵循如下格式
## 00 = 0000 0000
+--------+
|0XXXXXXX|
+--------+

我們?cè)賮砜匆粋€(gè)示例,練習(xí)下。這個(gè)示例來自: mpack/docs/expect.md at develop · ludocode/mpack

[
  "hello",
  "world!",
  [
    1,
    2,
    3,
    4
  ]
]

上面這個(gè)json,使用MessagPack編碼如下。

93                     # an array containing three elements
  a5 68 65 6c 6c 6f    # "hello"
  a6 77 6f 72 6c 64 21 # "world!"
  94                   # an array containing four elements
    01                 # 1
    02                 # 2
    03                 # 3
    04                 # 4

MPACK的簡(jiǎn)單使用

了解了MessagePack的概念之后,我們看下它的C api的使用。MPACK是MessagePack C語(yǔ)言實(shí)現(xiàn)的API之一。mpack的stars沒有msgpack-c多。但是mpack對(duì)libc的版本沒有要求。下面是對(duì)mpack的使用教程。

JSON的使用包含兩個(gè)部分:將json數(shù)據(jù)寫入內(nèi)存/文件;從已有的json數(shù)據(jù)中讀取內(nèi)容。

mapck在使用結(jié)構(gòu)上,和json類似,分為寫和讀。MPack api是mpack的api文檔,接口使用的詳細(xì)介紹見文檔。寫數(shù)據(jù)的部分調(diào)用Write API。如果沒有內(nèi)存限制,讀取的時(shí)候使用Node API。如果有內(nèi)存限制,則使用Reader API+Expect API。(這里說的內(nèi)存限制是指,程序運(yùn)行的內(nèi)存限制,而不是數(shù)據(jù)存儲(chǔ)的內(nèi)存限制)

這個(gè)參考示例不錯(cuò),在開始之前,可以一讀:一個(gè)C語(yǔ)言MessagePack庫(kù):mpack

下面我們開始寫demo。寫一個(gè)最簡(jiǎn)單,也是最常用的demo:存儲(chǔ)數(shù)據(jù)的內(nèi)存無(wú)限制時(shí),使用mpack進(jìn)行數(shù)據(jù)的寫入和讀取。示例參考自官方的README:ludocode/mpack: MPack - A C encoder/decoder for the MessagePack serialization format / msgpack.org[C]. 這里對(duì)這些API進(jìn)行簡(jiǎn)單的介紹,詳細(xì)介紹見官方文檔。

  • mpack_writer_init_growable(mpack_writer_t* writer, char** target_data, size_t* target_size)使用一個(gè)會(huì)增長(zhǎng)的buffer。
  • 在調(diào)用mpack_writer_destroy后,將上面target_data指向?qū)懭霐?shù)據(jù)的地址。
  • 最后必須調(diào)用MPACK_FREE()釋放申請(qǐng)的數(shù)據(jù)。
  • 使用mpack_build_map開始構(gòu)建一個(gè)map,我們此時(shí)不知道m(xù)ap中元素的個(gè)數(shù)。如果知道元素個(gè)數(shù),使用mpack_start_map()替代。
  • 使用mpack_build_map后,后面必須跟偶數(shù)個(gè)數(shù)的元素,在結(jié)束的時(shí)候調(diào)用 mpack_complete_map()。
  • 使用Node API讀取數(shù)據(jù)。
#include "mpack.h"
#include <stdio.h>

/*
{
    "name": "3-1",
    "number": 56,
    "students": [
        {
            "name": "zhangsan",
            "score": 76.8
        },
        {
            "name": "lisi",
            "score": 77
        }
    ]
}
*/

mpack_error_t class_information_serialize(char **data, size_t *size) {
  mpack_writer_t writer;
  mpack_writer_init_growable(&writer, data, size);

  mpack_build_map(&writer);

  mpack_write_cstr(&writer, "name");
  mpack_write_cstr(&writer, "3-1");

  mpack_write_cstr(&writer, "number");
  mpack_write_u8(&writer, 56);

  mpack_write_cstr(&writer, "students");
  mpack_build_array(&writer);

  mpack_start_map(&writer, 2);
  mpack_write_cstr(&writer, "name");
  mpack_write_cstr(&writer, "zhangsan");
  mpack_write_cstr(&writer, "score");
  mpack_write_float(&writer, 76.8);
  mpack_finish_map(&writer);

  mpack_start_map(&writer, 2);
  mpack_write_cstr(&writer, "name");
  mpack_write_cstr(&writer, "lisi");
  mpack_write_cstr(&writer, "score");
  mpack_write_float(&writer, 77);
  mpack_finish_map(&writer);

  mpack_complete_array(&writer);

  mpack_complete_map(&writer);

  mpack_error_t ret = mpack_writer_destroy(&writer);

  return ret;
}

mpack_error_t class_information_deserialize(const char *data, size_t length) {
  mpack_tree_t tree;
  mpack_tree_init_data(&tree, data, length);
  mpack_tree_parse(&tree);

  mpack_node_t root = mpack_tree_root(&tree);
  const char *name = mpack_node_str(mpack_node_map_cstr(root, "name"));
  size_t name_len = mpack_node_strlen(mpack_node_map_cstr(root, "name"));
  uint8_t number = mpack_node_u8(mpack_node_map_cstr(root, "number"));
  printf("name:%.*s\n", name_len, name);
  printf("number:%u\n", number);

  printf("students:\n");
  mpack_node_t students = mpack_node_map_cstr(root, "students");
  size_t student_num = mpack_node_array_length(students);
  for (unsigned int i = 0; i < student_num; i++) {
    mpack_node_t student = mpack_node_array_at(students, i);
    const char *name = mpack_node_str(mpack_node_map_cstr(student, "name"));
    size_t name_len = mpack_node_strlen(mpack_node_map_cstr(student, "name"));
    float score = mpack_node_float(mpack_node_map_cstr(student, "score"));
    printf("  name:%.*s\n", name_len, name);
    printf("  score:%.2f\n", score);
  }

  mpack_error_t ret = mpack_tree_destroy(&tree);
  return ret;
}

int main(int argc, char *argv[]) {
  char *data = NULL;
  size_t size = 0;
  class_information_serialize(&data, &size);
  class_information_deserialize(data, size);
  MPACK_FREE(data);
}

程序輸出如下。

name:3-1
number:56
students:
  name:zhangsan
  score:76.80
  name:lisi
  score:77.00

在定長(zhǎng)的buffer存儲(chǔ)不定長(zhǎng)的數(shù)據(jù)

工作的時(shí)候,會(huì)想使用比較奇怪的調(diào)用。首先,所有的數(shù)據(jù)都要存儲(chǔ)在一個(gè)定長(zhǎng)的buffer里面。因?yàn)檫@個(gè)buffer是從一個(gè)內(nèi)存池中取出的,所以它的長(zhǎng)度是定長(zhǎng)的。但是,往里面寫入數(shù)據(jù)的時(shí)候,會(huì)寫多次,長(zhǎng)度不一定。

修改上面的示例:現(xiàn)在要寫入不定個(gè)數(shù)的student到數(shù)組中;允許截?cái)啵?/p>

截?cái)嗟臅r(shí)候發(fā)生了什么?截?cái)嗪筮€能否讀???

遇到截?cái)?,writer會(huì)設(shè)置錯(cuò)誤的標(biāo)記位。正常編碼的時(shí)候,這個(gè)writer數(shù)據(jù)不應(yīng)該在后續(xù)進(jìn)行讀取。因?yàn)樗呀?jīng)被標(biāo)記為錯(cuò)誤。

但是,總有些頭鐵的需求,想用發(fā)生截?cái)鄷r(shí),已經(jīng)寫入內(nèi)存的數(shù)據(jù)。這個(gè)從API文檔里面是看不出來的,要看mpack的源碼。

我先說結(jié)論:

  • 從前往后,不斷將build中的內(nèi)容,復(fù)制寫入buffer。寫之前檢查空間是否足夠,不夠則停止寫入,并標(biāo)記錯(cuò)誤。
  • 使用 node api 無(wú)法讀取。因?yàn)閿?shù)據(jù)被截?cái)啵缓戏ā?/li>

大體結(jié)構(gòu)圖如下。

mpack簡(jiǎn)明教程,# c/c++編程,mpack,MessagePack

示例代碼如下。

#include "mpack.h"
#include <stdio.h>

/*
{
    "name": "3-1",
    "number": 56,
    "students": [
        {
            "name": "zhangsan",
            "score": 76.8
        },
        {
            "name": "lisi",
            "score": 77
        }
    ]
}
*/

mpack_error_t class_information_serialize(char *data, size_t *size) {
  mpack_writer_t writer;
  mpack_writer_init(&writer, data, *size);

  mpack_build_map(&writer);

  mpack_write_cstr(&writer, "name");
  mpack_write_cstr(&writer, "3-1");

  mpack_write_cstr(&writer, "number");
  mpack_write_u8(&writer, 56);

  mpack_write_cstr(&writer, "students");

  mpack_build_array(&writer);

  for (unsigned int i = 0; i < 56; i++) {
    mpack_start_map(&writer, 2);
    mpack_write_cstr(&writer, "name");
    mpack_write_cstr(&writer, "zhangsan");
    mpack_write_cstr(&writer, "score");
    mpack_write_float(&writer, 76.8);

    if (mpack_writer_error(&writer) != mpack_ok) {
      printf("error_%u: %d\n", i, mpack_writer_error(&writer));
    }
    mpack_finish_map(&writer);
  }

  mpack_complete_array(&writer);

  mpack_complete_map(&writer);

  if (mpack_writer_error(&writer) != mpack_ok) {
    printf("after write all students error: %d\n", mpack_writer_error(&writer));
  }

  *size = mpack_writer_buffer_used(&writer);
  mpack_error_t ret = mpack_writer_destroy(&writer);

  return ret;
}

mpack_error_t class_information_deserialize(const char *data, size_t length) {
  mpack_tree_t tree;
  mpack_tree_init_data(&tree, data, length);
  mpack_tree_parse(&tree);

  if (mpack_tree_error(&tree) != mpack_ok) {
    printf("parse tree error: %d\n", mpack_tree_error(&tree));
  }

  mpack_node_t root = mpack_tree_root(&tree);
  const char *name = mpack_node_str(mpack_node_map_cstr(root, "name"));
  size_t name_len = mpack_node_strlen(mpack_node_map_cstr(root, "name"));
  uint8_t number = mpack_node_u8(mpack_node_map_cstr(root, "number"));
  printf("name:%.*s\n", name_len, name);
  printf("number:%u\n", number);

  printf("students:\n");
  mpack_node_t students = mpack_node_map_cstr(root, "students");
  size_t student_num = mpack_node_array_length(students);
  for (unsigned int i = 0; i < student_num; i++) {
    mpack_node_t student = mpack_node_array_at(students, i);
    const char *name = mpack_node_str(mpack_node_map_cstr(student, "name"));
    size_t name_len = mpack_node_strlen(mpack_node_map_cstr(student, "name"));
    float score = mpack_node_float(mpack_node_map_cstr(student, "score"));
    printf("  name:%.*s\n", name_len, name);
    printf("  score:%.2f\n", score);
  }

  mpack_error_t ret = mpack_tree_destroy(&tree);
  return ret;
}

int main(int argc, char *argv[]) {
#define DATA_BUFFER_SIZE 35
  char data[DATA_BUFFER_SIZE] = {0};
  size_t size = DATA_BUFFER_SIZE;
  class_information_serialize(data, &size);
  class_information_deserialize(data, size);
}

輸出如下。

after write all students error: 6
parse tree error: 3
name:
number:0
students:

讀取截?cái)嗟臄?shù)據(jù)

既然使用node api解析數(shù)據(jù)會(huì)失敗。那不要解析,順序讀取,一直讀取到異常。

參考自:Using the Expect API。代碼如下。

#include "mpack.h"
#include <stdio.h>

/*
[
  {
    "name": "zhangsan",
    "score": 76.8
  },
  {
    "name": "lisi",
    "score": 77
  }
  ...
]

*/

mpack_error_t class_information_serialize(char *data, size_t *size) {
  mpack_writer_t writer;
  mpack_writer_init(&writer, data, *size);

  mpack_build_array(&writer);

  for (unsigned int i = 0; i < 56; i++) {
    mpack_build_map(&writer);
    mpack_write_cstr(&writer, "name");
    mpack_write_cstr(&writer, "zhangsan");
    mpack_write_cstr(&writer, "score");
    mpack_write_float(&writer, 76.8);
    mpack_complete_map(&writer);
  }

  mpack_complete_array(&writer);

  if (mpack_writer_error(&writer) != mpack_ok) {
    printf("after write all students error: %d\n", mpack_writer_error(&writer));
  }

  *size = mpack_writer_buffer_used(&writer);
  mpack_error_t ret = mpack_writer_destroy(&writer);

  return ret;
}

mpack_error_t class_information_deserialize(const char *data, size_t length) {
  mpack_reader_t reader;
  mpack_reader_init_data(&reader, data, length);

  uint32_t students_num = mpack_expect_array(&reader);
  printf("students num: %u\n", students_num);
  for (unsigned int i = 0; i < students_num; i++) {
    uint32_t elem_cnt = mpack_expect_map(&reader);
    mpack_expect_cstr_match(&reader, "name");
    char name[20];
    size_t name_len = mpack_expect_str_buf(&reader, name, 20);
    mpack_expect_cstr_match(&reader, "score");
    float score = mpack_expect_float(&reader);

    if (mpack_reader_error(&reader) != mpack_ok) {
      break;
    }

    printf("name:%.*s\n", name_len, name);
    printf("score:%.2f\n", score);
    mpack_done_map(&reader);
  }

  return mpack_ok;
}

int main(int argc, char *argv[]) {
#define DATA_BUFFER_SIZE 100
  char data[DATA_BUFFER_SIZE] = {0};
  size_t size = DATA_BUFFER_SIZE;
  class_information_serialize(data, &size);
  class_information_deserialize(data, size);
}

輸出如下。文章來源地址http://www.zghlxwxcb.cn/news/detail-830380.html

after write all students error: 6
students num: 56
name:zhangsan
score:76.80
name:zhangsan
score:76.80
name:zhangsan
score:76.80

到了這里,關(guān)于mpack簡(jiǎn)明教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • SAP報(bào)表簡(jiǎn)明教程

    SAP報(bào)表簡(jiǎn)明教程

    SAP 報(bào)表簡(jiǎn)明教程 ? 一、 報(bào)表需求,根據(jù)物料編碼和物料類型 查詢報(bào)表。用戶輸入界面要求如下: ? ? 二、 開始寫代碼。先進(jìn)入 TCODE:SE38 ,新建一個(gè)程序。 ? ?? 點(diǎn)擊創(chuàng)建按鈕,如下圖:? ? ? 輸入標(biāo)題,寫明 此程序的功能 作者,創(chuàng)建時(shí)間,點(diǎn)保存, ? ? 輸入自己事先建

    2024年02月04日
    瀏覽(18)
  • Husky使用簡(jiǎn)明教程

    Husky 是一個(gè)流行的 Git 鉤子工具,用于在不同的 Git 操作(如提交和推送)前自動(dòng)運(yùn)行腳本。比如代碼格式化、靜態(tài)檢查等。這有助于保持代碼庫(kù)的質(zhì)量和一致性。本教程將詳細(xì)介紹 Husky 的原理、使用方式、配置方法以及如何在開發(fā)中集成 Husky。 Husky 原理 安裝 Husky 配置 Hus

    2024年04月10日
    瀏覽(21)
  • Docker入門簡(jiǎn)明教程

    Docker入門簡(jiǎn)明教程

    Docker 是基于 Go 語(yǔ)言實(shí)現(xiàn)的云開源項(xiàng)目,是基于 Linux 的多項(xiàng)開源技術(shù)提供高效、敏捷和輕量級(jí)的容器方案。創(chuàng)建于 2013 年初,自從開源后就受到了廣泛的關(guān)注,從長(zhǎng)遠(yuǎn)的眼光來看,Docker 是未來虛擬化的一個(gè)發(fā)展的趨勢(shì)。帶來了更輕量快捷的的體驗(yàn),一臺(tái)主機(jī)可以同時(shí)運(yùn)行數(shù)千

    2024年01月23日
    瀏覽(21)
  • AI繪畫工具簡(jiǎn)明教程

    AI繪畫工具簡(jiǎn)明教程

    官方地址 首先需要郵箱注冊(cè),等待邀請(qǐng)(可能需要等待一兩天) 能成功登錄后會(huì)進(jìn)入這樣一個(gè)界面 https://app.scenario.com/generators 創(chuàng)建模型 提供的圖片集上傳的時(shí)候得是jpg,還需要裁剪成正方形。批量修改圖片在線網(wǎng)站:https://www.birme.net/ 根據(jù)圖集生成圖片 官方網(wǎng)址:https://

    2024年02月11日
    瀏覽(28)
  • shell簡(jiǎn)明教程3函數(shù)

    shell簡(jiǎn)明教程3函數(shù)

    在本章中,您將了解為什么以及何時(shí)需要使用函數(shù)。 你將學(xué)習(xí)如何創(chuàng)建函數(shù)以及如何使用函數(shù)。 我們將討論變量及其作用域。 學(xué)習(xí)如何使用參數(shù)訪問傳遞給函數(shù)的參數(shù)。 最后,您還將學(xué)習(xí)如何使用函數(shù)處理退出狀態(tài)和返回代碼。 計(jì)算機(jī)編程和應(yīng)用程序開發(fā)中有一個(gè)概念叫

    2024年02月11日
    瀏覽(28)
  • WebGPU開發(fā)簡(jiǎn)明教程【2023】

    WebGPU開發(fā)簡(jiǎn)明教程【2023】

    WebGPU 是一種全新的現(xiàn)代 API,用于在 Web 應(yīng)用程序中訪問 GPU 的功能。 在 WebGPU 之前,有 WebGL,它提供了 WebGPU 功能的子集。 它啟用了新一類豐富的網(wǎng)絡(luò)內(nèi)容,開發(fā)人員用它構(gòu)建了令人驚嘆的東西。 然而,它基于 2007 年發(fā)布的 OpenGL ES 2.0 API,而該 API 又基于更舊的 OpenGL API。

    2024年02月16日
    瀏覽(26)
  • Blender骨骼動(dòng)畫簡(jiǎn)明教程

    Blender骨骼動(dòng)畫簡(jiǎn)明教程

    Blender 是首選的開源3D動(dòng)畫軟件之一。 令人驚訝的是,開始創(chuàng)建簡(jiǎn)單的角色動(dòng)畫并不需要太多時(shí)間。 一旦獲得最終的 3D 角色模型,你就可以使用該軟件的眾多動(dòng)畫功能和工具將其變?yōu)楝F(xiàn)實(shí)。 推薦:用 NSDT編輯器 快速搭建可編程3D場(chǎng)景 例如,Blender 的綁定工具將幫助你實(shí)現(xiàn)角色

    2024年02月07日
    瀏覽(22)
  • 電商3D產(chǎn)品渲染簡(jiǎn)明教程

    電商3D產(chǎn)品渲染簡(jiǎn)明教程

    3D 渲染讓動(dòng)作電影看起來更酷,讓建筑設(shè)計(jì)變得栩栩如生,現(xiàn)在還可以幫助營(yíng)銷人員推廣他們的產(chǎn)品。 從最新的《阿凡達(dá)》電影到 Spotify 的上一次營(yíng)銷活動(dòng),3D 的應(yīng)用讓一切變得更加美好。 在營(yíng)銷領(lǐng)域,3D 產(chǎn)品渲染可幫助品牌創(chuàng)建產(chǎn)品的高分辨率圖像和視頻,這些圖像和視

    2024年02月13日
    瀏覽(19)
  • stable diffusion使用簡(jiǎn)明教程

    stable diffusion使用簡(jiǎn)明教程

    controlNet模塊使用 上面骨骼圖是通過Openpose Editor調(diào)整姿勢(shì)然后send to txt2img到這里的,使用Openpose Edito中姿勢(shì)生成需要將Openpose Editor指定為none狀態(tài)。 Preprocessor選項(xiàng): Preprocessor部分選項(xiàng)使用教程 官方教程鏈接:Control human pose in Stable Diffusion Stable Diffusion Art (stable-diffusion-art.com) 1.

    2024年02月02日
    瀏覽(18)
  • 匯編語(yǔ)言簡(jiǎn)明教程習(xí)題答案

    (2)判斷題 AX被稱為累加器,在8086程序中使用很頻繁。(?) 指令指針I(yè)P寄存器屬于通用寄存器。(?) 8086具有8個(gè)32位通用寄存器。(×) 解析:8086的寄存器有8個(gè)16位通用寄存器、4個(gè)16位段寄存器、1個(gè)16位標(biāo)志寄存器和1個(gè)16位指令指針寄存器 8086編程使用邏輯地址,將其中

    2023年04月08日
    瀏覽(74)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包