json原理和应用

JSON定义:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。它是基于 JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999 的一个子集。 JSON采用完全独立于程序语言的文本格式,但是也使用了类C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

应用场景:
json本身只是一种数据存储格式,嵌在http协议报文进行网络数据交互是常见用法之一,在rpc调用中,如果涉及到json的传输,一般需要嵌套在其他协议中,以便于进行json边界处理,cjson和jsoncpp是常用的json解析库,其实cjson和jsoncpp本身不是做序列化和反序列化的工具库,只是一个json格式字符串的解析器,如果把json用于rpc的话,也还是需要第三方工具对json数据进行序列化。

1. Json 语法
JSON 语法是JavaScript 语法的子集。
比如下面就是一个json 对象,里面包含了字符串、整数、浮点数、普通数组、对象、
对象数组,从中可以窥探到json 的语法。
Key-value

{
    
    
"name": "milo",
"age": 80,
"professional": {
    
    
	"english": 4,
	"putonghua": 2,
	"computer": 3,
	},
"languages": ["C++", "C"],
"phone": {
    
    
		"number": "18570368134",
		"type": "home"
	},
	"books": [{
    
    
		"name": "Linux kernel development",
		"price": 7.7
}, {
    
    
		"name": "Linux server development",
		"price": 8.0
}],
"vip": true,
"address": null
}

数组的表示"languages": [“C++”, “C”],
数组,成员是对象

"books": [{
    
    
	"name": "Linux kernel development",
	"price": 7.7
	}, {
    
    
	"name": "Linux server development",
	"price": 8.0
}],

1.1 JSON 语法规则
JSON 语法是JavaScript 对象表示语法的子集。
 数据在名称/值对中
 数据由逗号分隔
 大括号保存对象
 中括号保存数组
1.2 JSON 名称/值对
JSON 数据的书写格式是:名称/值对。
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
“name” : “milo”
1.3 JSON 值
JSON 值可以是:
 数字(整数或浮点数)
 字符串(在双引号中)
 逻辑值(true 或false)
 数组(在中括号中)
 对象(在大括号中)
 null
1.3.1 JSON 数字
JSON 数字可以是整型或者浮点型:
{ “age”:30 }
1.3.2 JSON 对象
JSON 对象在大括号({})中书写:
对象可以包含多个名称/值对:
{ “name”:“Linux 服务器开发” , “url”:“www.0voice.com” }
1.3.3 JSON 数组
JSON 数组在中括号中书写:
数组可包含多个对象:
{
“sites”: [
{ “name”:“Linux 服务器开发” , “url”:“www.0voice.com” },
{ “name”:“google” , “url”:“www.google.com” },
{ “name”:“微博” , “url”:“www.weibo.com” }
]
}
在上面的例子中,对象"sites" 是包含三个对象的数组。每个对象代表一条关于某
个网站(name、url)的记录。

1.3.4 JSON 布尔值
JSON 布尔值可以是true 或者false:
{ “flag”:true }
1.3.5 JSON null
JSON 可以设置null 值:
{ “address”:null }

2. Jsoncpp
2.1 Jsoncpp 安装
jsoncpp 是一个c++封装的json 包,跨平台支持windows、linux、unix 等多系统。
jsoncpp 源码地址:https://github.com/open-source-parsers/jsoncpp
ubuntu 安装

sudo apt-get install libjsoncpp-dev

引用头文件
库的头文件安装在/usr/include/jsoncpp 中,
库API 文档默认在/usr/share/doc/libjsoncpp-dev/jsoncpp-api-html/目录下

#include <jsoncpp/json/json.h>

示例代码jsoncpp_test.c

#include <iostream>
#include <string>
#include "jsoncpp/json/json.h"
#include "jsoncpp/json/value.h"
#include "jsoncpp/json/writer.h"
using namespace std;
int main()
{
    
    
cout << "Hello World!" << endl;
Json::Value root;
Json::FastWriter fast;
root["ModuleType"] = Json::Value(1);
root["MOduleCode"] = Json::Value("China");
cout<<fast.write(root)<<endl;
Json::Value sub;
sub["version"] = Json::Value("1.0");
sub["city"] = Json::Value(root);
fast.write(sub);
cout<<sub.toStyledString()<<endl;
return 0;
}

编译

g++ jsoncpp_test.c -o test -ljsoncpp

2.2 Jsoncpp 支持的值
jsoncpp 使用Json::Value 对象来保存JSON 串,Json::Value 对象可以表示如下数据类
型:
在这里插入图片描述
2.3 读取数据
在知道如何描述JSON 串后,我们来看下Json::Value 类提供了哪些方法来访问保存
的数据:
2.3.1 检测保存的数据类型
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;

2.3.2 基础数据类型的访问
const char* asCString() const;
JSONCPP_STRING asString() const;
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;

2.3.3 数组风格
// ValueType::arrayValue 和ValueType::objectValue 数据类型的访问,操作方式很类似
C++的vector,可以使用数组风格或者迭代器风格来操作数据

root["name"] = "milo";


ArrayIndex size() const;
Value& operator[](ArrayIndex index);
Value& operator[](int index);
const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;
Value get(ArrayIndex index, const Value& defaultValue) const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
// ValueType::objectValue 数据类型的访问,操作方式很类似C++的map
Value& operator[](const char* key);
const Value& operator[](const char* key) const;
Value& operator[](const JSONCPP_STRING& key);
const Value& operator[](const JSONCPP_STRING& key) const;
Value& operator[](const StaticString& key);
Value& operator[](const CppTL::ConstString& key);
const Value& operator[](const CppTL::ConstString& key) const;
Value get(const char* key, const Value& defaultValue) const;
Value get(const char* begin, const char* end, const Value& defaultValue) const;
Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
Value get(const CppTL::ConstString& key, const Value& defaultValue) const;

2.4 修改数据
知道如何获取Json::Value 对象或其子对象后,我们来看下如何修改Json::Value 保存
的数据:

// 直接使用=赋值就可以了
Value& operator=(Value other);
// 因为Json::Value 已经实现了各种数据类型的构造函数
Value(ValueType type = nullValue);
Value(Int value);
Value(UInt value);
Value(Int64 value);
Value(UInt64 value);
Value(double value);
Value(const char* value);
Value(const char* begin, const char* end);
Value(const StaticString& value);
Value(const JSONCPP_STRING& value);
Value(const CppTL::ConstString& value);
Value(bool value);
Value(const Value& other);
Value(Value&& other);

2.5 注意事项
(1)对于Int、Uint、Int64、UInt64 等类型,注意类型。
root[“age”] = 80; 默认为Int 类型
可以类似root[“age”] = (Json::Uint)80; 强制转换类型
(2)如果要将变量设置为null,则使用
root[“address”] = Json::nullValue; // 不要用NULL
2.6 使用范例

见代码

3. cJSON
3.1 cJSON 编译安装
github 地址:https://github.com/DaveGamble/cJSON
下载
git clone https://github.com/DaveGamble/cJSON.git
参考Readme 进行编译
可以直接使用cJSON.h 和cJSON.c 加入到源文件。
3.2 数据结构定义
3.2.1 cJSON 结构

/* The cJSON structure: */
typedef struct cJSON
{
    
    
/* next/prev allow you to walk array/object chains. Alternatively, use Get
ArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain o
f the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* The item's number, if type==cJSON_Number */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list
of subitems of an object. */
char *string;
} cJSON;

next、prev 用于遍历数组或对象链的前向后向链表指针;child 指向数组或对象的孩子
节点;type 是value 的类型;valuestring 是字符串值;valueint 是整数值;valuedouble
是浮点数值;string 是key 的名字。

3.2.2 cJSON 支持的类型

/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */

 valuestring,当类型为cJSON_String 或cJSON_Raw 时,value 的值,type 不符时
为NULL
 valueint,当类型为cJSON_Number 时,value 的值
 valuedouble,当类型为cJSON_NUmber 时,value 的值(主要用这个)
 string, 代表key,value 键值对中key 的值
3.3 重点函数
3.3.1 cJSON_Parse

/* Supply a block of JSON, and this returns a cJSON object
you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
//作用:将一个JSON 字符串,按照cJSON 结构体的结构序列化整个数据包,并在堆中开辟一块内
//存存储cJSON 结构体。
//返回值:成功返回一个指向内存块中的cJSON 的指针,失败返回NULL。

3.3.2 cJSON_Delete

/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);

//作用:释放位于堆中cJSON 结构体内存。
//返回值:无
//注意:在使用cJSON_Parse()获取cJSON 指针后,若不再使用了,则需要调用cJSON_Delete()
//对其释放,否则会导致内存泄漏。

3.3.3 cJSON_Print

/* Render a cJSON entity to text for transfer/storage.
Free the char* when finished. */
extern char *cJSON_Print(const cJSON *item);
//作用:将cJSON 数据解析成JSON 字符串,并在堆中开辟一块char*的内存空间存储JSON 字符
//串。cJSON_PrintUnformatted()与cJSON_Print()类似,只是打印输出不带格式,而只是一个
//字符串数据。
//返回值:成功返回一个char*指针该指针指向位于堆中JSON 字符串,失败返回NULL。
//注意:通过cJSON_Print()可以将cJSON 链表中所有的cJSON 对象打印出来,但是需要手动去
//释放对应的资源:free(char *)。

3.3.4 cJSON_Version

/* returns the version of cJSON as a string */
extern const char* cJSON_Version(void);
//作用:获取当前使用的cJSON 库的版本号。
//返回值:返回一个字符串数据。

3.3.5 cJSON_GetArrayItem

/* Retrieve item number "item" from array "array".
Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(const cJSON *array, int item);
//作用:从object 的cJSON 链中寻找key 为string 的cJSON 对象。
//返回值:成功返回一个指向cJSON 类型的结构体指针,失败返回NULL。

//与cJSON_GetObjectItem()类似的接口还有:

/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(const cJSON *array);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string)
;
extern int cJSON_HasObjectItem(const cJSON *object, const char *string);

3.4 所有函数简介
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5 使用范例
下面的例子是将json嵌在http中,服务端将http报文解析出对应的json字段:
注释:收发双方按照约定的json格式(json字段)进行解析

//解析用户登陆信息的json包login_buf
//用户名保存在username,密码保存在pwd
int get_login_info(char *login_buf, char *username, char *pwd)
{
    
    
    int ret = 0;

    //解析json包
    //解析一个json字符串为cJSON对象
    cJSON * root = cJSON_Parse(login_buf);
    if(NULL == root)
    {
    
    
        LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "cJSON_Parse err\n");
        ret = -1;
        goto END;
    }

    //返回指定字符串对应的json对象
    //用户
    cJSON *child1 = cJSON_GetObjectItem(root, "user");
    if(NULL == child1)
    {
    
    
        LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "cJSON_GetObjectItem err\n");
        ret = -1;
        goto END;
    }

    //LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
    strcpy(username, child1->valuestring); //拷贝内容

    //密码
    cJSON *child2 = cJSON_GetObjectItem(root, "pwd");
    if(NULL == child2)
    {
    
    
        LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "cJSON_GetObjectItem err\n");
        ret = -1;
        goto END;
    }

    //LOG(LOGIN_LOG_MODULE, LOGIN_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
    strcpy(pwd, child2->valuestring); //拷贝内容

END:
    if(root != NULL)
    {
    
    
        cJSON_Delete(root);//删除json对象
        root = NULL;
    }

    return ret;
}

cjson使用案例:

/*
 * @Descripttion: cjson测试
 * @version: 1.0
 * @Author: Darren
 * @Date: 2019-10-29 10:14:51
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2020-06-09 20:28:49
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>

#include "cJSON.h"

static uint64_t getNowTime()
{
    
    
    struct timeval tval;
    uint64_t nowTime;

    gettimeofday(&tval, NULL);

    nowTime = tval.tv_sec * 1000L + tval.tv_usec / 1000L;
    return nowTime;
}

char *CJsonEncode()
{
    
     // 创建json对象
    cJSON *root = cJSON_CreateObject();
    // 添加键值对
    cJSON_AddItemToObject(root, "name", cJSON_CreateString("darren"));
    cJSON_AddItemToObject(root, "age", cJSON_CreateNumber(80));
    // 创建json数组
    cJSON *languages = cJSON_CreateArray();
    cJSON_AddItemToArray(languages, cJSON_CreateString("C++"));
    cJSON_AddItemToArray(languages, cJSON_CreateString("Java"));
    cJSON_AddItemToObject(root, "languages", languages);

    cJSON *phone = cJSON_CreateObject();
    cJSON_AddItemToObject(phone, "number", cJSON_CreateString("18570368134"));
    cJSON_AddItemToObject(phone, "type", cJSON_CreateString("home"));
    cJSON_AddItemToObject(root, "phone", phone);

    cJSON *book0 = cJSON_CreateObject();
    cJSON_AddItemToObject(book0, "name", cJSON_CreateString("Linux kernel development"));
    cJSON_AddItemToObject(book0, "price", cJSON_CreateNumber(7.7));
    cJSON *book1 = cJSON_CreateObject();
    cJSON_AddItemToObject(book1, "name", cJSON_CreateString("Linux server development"));
    cJSON_AddItemToObject(book1, "price", cJSON_CreateNumber(8.0));
    // 创建json数组
    cJSON *books = cJSON_CreateArray();
    cJSON_AddItemToArray(books, book0);
    cJSON_AddItemToArray(books, book1);
    cJSON_AddItemToObject(root, "books", books);

    cJSON_AddItemToObject(root, "vip", cJSON_CreateBool(1));
    cJSON_AddItemToObject(root, "address", cJSON_CreateString("yageguoji")); // NULL值的问题

    // 格式化json对象
    char *text = cJSON_Print(root);
    // size_t len = strlen(text) + 1;
    // char *strJson = malloc(len);
    // memcpy(strJson, text, len);
    // printf("text:%s\n", text);
    // FILE* fp = fopen("root.json", "w");
    // fwrite(text, 1, strlen(text), fp);
    // fclose(fp);
    cJSON_Delete(root);
    return text;
}

void printCJson(cJSON *root)
{
    
    
    cJSON *name = cJSON_GetObjectItem(root, "name");
    cJSON *age = cJSON_GetObjectItem(root, "age");
    cJSON *languages = cJSON_GetObjectItem(root, "languages");
    cJSON *phone = cJSON_GetObjectItem(root, "phone");
    cJSON *books = cJSON_GetObjectItem(root, "books");
    cJSON *vip = cJSON_GetObjectItem(root, "vip");
    cJSON *address = cJSON_GetObjectItem(root, "address");

    printf("name: %s\n", name->valuestring);
    printf("age: %d\n", age->valueint);
    printf("languages: ");
    for (int i = 0; i < cJSON_GetArraySize(languages); i++)
    {
    
    
        cJSON *lang = cJSON_GetArrayItem(languages, i);
        if (i != 0)
        {
    
    
            printf(", ");
        }
        printf("%s", lang->valuestring);
    }
    printf("\n");

    cJSON *number = cJSON_GetObjectItem(phone, "number");
    cJSON *type = cJSON_GetObjectItem(phone, "type");
    printf("phone number: %s, type: %s\n", number->valuestring, type->valuestring);

    for (int i = 0; i < cJSON_GetArraySize(books); i++)
    {
    
    
        cJSON *book = cJSON_GetArrayItem(books, i);
        cJSON *name = cJSON_GetObjectItem(book, "name");
        cJSON *price = cJSON_GetObjectItem(book, "price");
        printf("book name: %s, price: %lf\n", name->valuestring, price->valuedouble);
    }

    printf("vip: %d\n", vip->valueint);
    if (address && !cJSON_IsNull(address))
    {
    
    
        printf("address: %s\n", address->valuestring);
    }
    else
    {
    
    
        printf("address is null\n");
    }
}

int CJsonDecode(const char *strJson)
{
    
    
    if (!strJson)
    {
    
    
        printf("strJson is null\n");
        return -1;
    }
    cJSON *root = cJSON_Parse(strJson);
    // printCJson(root);
    cJSON_Delete(root);
    return 0;
}

#define TEST_COUNT 100000

int main(void)
{
    
    
    char *strJson = NULL;
    strJson = CJsonEncode();
    printf("strJson size:%lu, string:%s\n", strlen(strJson), strJson);
    CJsonDecode(strJson);
    free(strJson);
#if 0   
    uint64_t startTime;
    uint64_t nowTime;
    startTime = getNowTime();
    printf("cjson encode time testing\n");
    for (int i = 0; i < TEST_COUNT; i++)
    {
    
    
        strJson = CJsonEncode();
        if (strJson)
        {
    
    
            free(strJson);
            strJson = NULL;
        }
    }
    nowTime = getNowTime();
    printf("cjson encode %u time, need time: %lums\n", TEST_COUNT, nowTime - startTime);

    strJson = CJsonEncode();
    startTime = getNowTime();
    printf("\ncjson decode time testing\n");
    for (int i = 0; i < TEST_COUNT; i++)
    {
    
    
        CJsonDecode(strJson);
    }
    nowTime = getNowTime();
    printf("cjson decode %u time, need time: %lums\n", TEST_COUNT, nowTime - startTime);
    free(strJson);
#endif
    return 0;
}

jsoncpp使用案例:

/*
 * @Descripttion: 测试jsoncpp的使用方法和性能
 * @version: 1.0
 * @Author: Darren
 * @Date: 2019-10-27 20:49:58
 * @LastEditors: Darren
 * @LastEditTime: 2019-10-30 14:44:48
 */
#include <iostream>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <json/json.h>
/*

{
  "name": "darren",
  "age": 80,
  "languages": ["C++", "C"],
  "phone": {
    "number": "18570368134",
    "type": "home"
  },
  "books":[
      {
          "name": "Linux kernel development",
          "price":7.7
      },
      {
          "name": "Linux server development",
          "price": 8.0
      }
  ],
  "vip":true,
  "address": null
}
 */

static uint64_t getNowTime()
{
    
    
    struct timeval tval;
    uint64_t nowTime;

    gettimeofday(&tval, NULL);

    nowTime = tval.tv_sec * 1000L + tval.tv_usec / 1000L;
    return nowTime;
}

std::string JsoncppEncodeNew()
{
    
    
    std::string jsonStr;
    // 一个value是可以包含多个键值对
    Json::Value root, languages, phone, book, books;

    // 姓名
    root["name"] = "darren";
    // 年龄
    root["age"] = 80;

    // 语言
    languages[0] = "C++";
    languages[1] = "Java";
    root["languages"] = languages;

    // 电话
    phone["number"] = "18570368134";
    phone["type"] = "home";
    root["phone"] = phone;

    // 书籍
    book["name"] = "Linux kernel development";
    book["price"] = 7.7;
    books[0] = book;    // 深拷贝
    book["name"] = "Linux server development";
    book["price"] = 8.0;
    books[1] = book;    // 深拷贝
    root["books"] = books;

    // 是否为vip
    root["vip"] = true;

    // address信息空null
    root["address"] = "yageguoji";

    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;
    std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
    jsonWriter->write(root, &os);
    jsonStr = os.str();

    // std::cout << "Json:\n" << jsonStr << std::endl;
    return jsonStr;
}

std::string JsoncppEncodeOld()
{
    
    
    std::string jsonStr;
    Json::Value root, languages, phone, book, books;

    // 姓名
     root["name"] = "darren";
    //root["name"] = Json::nullValue;
    // 年龄
    root["age"] =  80; 

    // 语言
    languages[0] = "C++";
    languages[1] = "Java";
    root["languages"] = languages;

    // 电话
    phone["number"] = "18570368134";
    phone["type"] = "home";
    root["phone"] = phone;

    // 书籍
    book["name"] = "Linux kernel development";
    book["price"] = (float)7.7;
    books[0] = book;
    book["name"] = "Linux server development";
    book["price"] = (float)8.0;
    books[1] = book;
    root["books"] = books;

    // 是否为vip
    root["vip"] = true;

    // address信息空null
    root["address"] = "yageguoji"; //;// Json::nullValue; // 如果是null,则要用自定义的Json::nullValue,不能用NULL

    Json::FastWriter writer;
    jsonStr = writer.write(root);

    // std::cout << "Json:\n" << jsonStr << std::endl;
    return jsonStr;
}

// 不能返回引用
Json::Value JsoncppEncodeOldGet()
{
    
    
    Json::Value root;
    Json::Value languages, phone, book, books;

    // 姓名
    root["name"] = "darren";
    //root["name"] = Json::nullValue;
    // 年龄
    root["age"] =  80; 

    // 语言
    languages[0] = "C++";
    languages[1] = "Java";
    root["languages"] = languages;

    // 电话
    phone["number"] = "18570368134";
    phone["type"] = "home";
    root["phone"] = phone;

    // 书籍
    book["name"] = "Linux kernel development";
    book["price"] = (float)7.7;
    books[0] = book;
    book["name"] = "Linux server development";
    book["price"] = (float)8.0;
    books[1] = book;
    root["books"] = books;

    // 是否为vip
    root["vip"] = true;

    // address信息空null
    root["address"] = Json::nullValue; //"yageguoji";// Json::nullValue; // 如果是null,则要用自定义的Json::nullValue,不能用NULL

 

    std::cout << "JsoncppEncodeOldGet:\n"  << std::endl;
    return root;
}

void printJsoncpp(Json::Value &root)
{
    
    
    if(root["name"].isNull())
    {
    
    
        std::cout << "name null\n";
    }
    std::cout << "name: " << root["name"].asString() << std::endl;
    std::cout << "age: " << root["age"].asInt() << std::endl;

    Json::Value &languages = root["languages"];
    std::cout << "languages: ";
    for (uint32_t i = 0; i < languages.size(); ++i)
    {
    
    
        if (i != 0)
        {
    
    
            std::cout << ", ";
        }
        std::cout << languages[i].asString();
    }
    std::cout << std::endl;

    Json::Value &phone = root["phone"];
    std::cout << "phone number: " << phone["number"].asString() << ", type: " << phone["type"].asString() << std::endl;

    Json::Value &books = root["books"];
    for (uint32_t i = 0; i < books.size(); ++i)
    {
    
    
        Json::Value &book = books[i];
        std::cout << "book name: " << book["name"].asString() << ", price: " << book["price"].asFloat() << std::endl;
    }
    std::cout << "vip: " << root["vip"].asBool() << std::endl;

    if (!root["address"].isNull())
    {
    
    
        std::cout << "address: " << root["address"].asString() << std::endl;
    }
    else
    {
    
    
        std::cout << "address is null" << std::endl;
    }
}

bool JsoncppDecodeNew(const std::string &info)
{
    
    
    if (info.empty())
        return false;

    bool res;
    JSONCPP_STRING errs;
    Json::Value root;
    Json::CharReaderBuilder readerBuilder;
    std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
    res = jsonReader->parse(info.c_str(), info.c_str() + info.length(), &root, &errs);
    if (!res || !errs.empty())
    {
    
    
        std::cout << "parseJson err. " << errs << std::endl;
        return false;
    }
    // printJsoncpp(root);

    return true;
}

bool JsoncppDecodeOld(const std::string &strJson)
{
    
    
    if (strJson.empty())
        return false;

    bool res;

    Json::Value root;
    Json::Reader jsonReader;

    res = jsonReader.parse(strJson, root);
    if (!res)
    {
    
    
        std::cout << "jsonReader.parse err. " << std::endl;
        return false;
    }

    // printJsoncpp(root);

    return true;
}

const char *strCjson = "{                 \
	\"name\":	\"darren\",         \
	\"age\":	80,                 \
	\"languages\":	[\"C++\", \"C\"],\
	\"phone\":	{                       \
		\"number\":	\"18570368134\",    \
		\"type\":	\"home\"            \
	},                                  \
	\"books\":	[{                         \
			\"name\":	\"Linux kernel development\",   \
			\"price\":	7.700000        \
		}, {                            \
			\"name\":	\"Linux server development\",   \
			\"price\":	8               \
		}],                             \
	\"vip\":	true,                   \
	\"address\":	null                \
}                                      \
";
#define TEST_COUNT 100000
int main()
{
    
    
    std::string jsonStrNew;
    std::string jsonStrOld;

    jsonStrNew = JsoncppEncodeNew();
    // JsoncppEncodeNew size: 337
    std::cout << "JsoncppEncodeNew size: " << jsonStrNew.size() << std::endl;
    std::cout << "JsoncppEncodeNew string: " << jsonStrNew << std::endl;
    JsoncppDecodeNew(jsonStrNew);

    jsonStrOld = JsoncppEncodeOld();
    // JsoncppEncodeOld size: 248
    std::cout << "\n\nJsoncppEncodeOld size: " << jsonStrOld.size() << std::endl;
    std::cout << "JsoncppEncodeOld string: " << jsonStrOld << std::endl;
    JsoncppDecodeOld(jsonStrOld);

    Json::Value root = JsoncppEncodeOldGet();
    Json::FastWriter writer;
    std::cout << "writer:\n"  << std::endl;
    std::string jsonStr = writer.write(root);
    std::cout << "\n\njsonStr string: " << jsonStrOld << std::endl;
#if 1
    uint64_t startTime;
    uint64_t nowTime;
    
    startTime = getNowTime();
    std::cout << "jsoncpp encode time testing" << std::endl;
    for(int i = 0; i < TEST_COUNT; i++)
    {
    
    
        JsoncppEncodeNew();
    }
    nowTime = getNowTime();
    std::cout << "jsoncpp encode " << TEST_COUNT << " time, need time: "
         << nowTime-startTime << "ms"  << std::endl;

    startTime = getNowTime();
    std::cout << "\njsoncpp encode time testing" << std::endl;
    for(int i = 0; i < TEST_COUNT; i++)
    {
    
    
        JsoncppEncodeOld();
    }
    nowTime = getNowTime();
    std::cout << "jsoncpp encode " << TEST_COUNT << " time, need time: "
         << nowTime-startTime << "ms"  << std::endl;

    startTime = getNowTime();
    std::cout << "\njsoncpp decode time testing" << std::endl;
    for(int i = 0; i < TEST_COUNT; i++)
    {
    
    
        JsoncppDecodeNew(jsonStrNew);
    }
    nowTime = getNowTime();
    std::cout << "jsoncpp decode " << TEST_COUNT << " time, need time: "
         << nowTime-startTime << "ms"  << std::endl;

    startTime = getNowTime();
    std::cout << "\njsoncpp decode time testing" << std::endl;
    for(int i = 0; i < TEST_COUNT; i++)
    {
    
    
        JsoncppDecodeOld(jsonStrNew);
    }
    nowTime = getNowTime();
    std::cout << "jsoncpp decode " << TEST_COUNT << " time, need time: "
         << nowTime-startTime << "ms"  << std::endl;
#endif

    return 0;
}

RapidJSON也是json生成器和解析器之一,这里就不过多介绍了,具体可以参考:
https://blog.csdn.net/fengbingchun/article/details/91139889

猜你喜欢

转载自blog.csdn.net/wangrenhaioylj/article/details/109163496