輕量簡單好用的C++JSON庫CJsonObject

1. JSON概述

       JSON: JavaScript 對象表示法( JavaScript Object Notation) 。是一種輕量級的數據交換格式。 它基於ECMAScript的一個子集。許多編程語言都很容易找到JSON 解析器和 JSON 庫。 JSON 文本格式在語法上與建立 JavaScript 對象的代碼相同。不一樣語言的不一樣json庫對json標準的支持不盡相同,爲了能讓儘量多的json庫都能正常解析和生成json,定義JSON的規範很重要,推薦一個JSON規範《JSON風格指南》。ios

 

2. 經常使用C&C++ JSON庫

      經常使用且知名度較高的C&C++的JSON庫有cJSONjson-cJsonCpp等,騰訊員工開源的一個RapidJSON以高性能著稱。C&C++的JSON庫比較見RapidJSON做者的比較nativejson-benchmarkgit

3. 很是簡單易用的CJsonObject

      CJsonObject是基於cJSON全新開發一個C++版的JSON庫,CJsonObject的最大優點是輕量(只有4個文件,拷貝到本身代碼裏便可,無須編譯成庫,且跨平臺和編譯器)、簡單好用,開發效率極高,對多層嵌套json的讀取和生成使用很是簡單(大部分json解析庫若是要訪問多層嵌套json的最裏層很是麻煩)。 我一直使用的json庫是一個較老版本的cJSON,cJSON的好處是簡單易用,並且只有兩個文件,直接複製到本身的代碼中就能夠用。cJSON也有一個很是容易讓初用者頭痛的地方,一不當心就形成內存泄漏了。爲此,我基於cJSON封裝了一個C++版的CJsonObject,該庫比cJSON更簡單易用,且只要不是有意不釋放內存就不會發生內存泄漏。用CJsonObject的好處在於徹底不用文檔,看完Demo立刻就會用,不明白的看一下頭文件就知道,全部函數都十分通俗易懂,最爲關鍵的一點是解析JSON和生成JSON的編碼效率很是高。固然,畢竟是通過cJSON封裝而來,效率會略低於cJSON,cJSON不支持的CJsonObject也不支持。我的認爲,既然已經選了json,那一點點的解析性能差別就不重要了,若是追求性能能夠選protobuf。CJsonObject在我最近4年作過的8個項目中普遍應用,目前有超過20人在使用,至因而否有離職同事帶到其餘團隊去了就不太清楚。CJsonObject很是簡單易用,且表現穩定,2018年5月我把它開源https://github.com/Bwar/CJsonObject,並將持續維護。github

       來看看CJsonObject是如何簡單易用:編程

demo.cpp:json

#include <string>
#include <iostream>
#include "../CJsonObject.hpp"

int main()
{
    int iValue;
    std::string strValue;
    neb::CJsonObject oJson("{\"refresh_interval\":60,"
                        "\"dynamic_loading\":["
                            "{"
                                "\"so_path\":\"plugins/User.so\", \"load\":false, \"version\":1,"
                                "\"cmd\":["
                                     "{\"cmd\":2001, \"class\":\"neb::CmdUserLogin\"},"
                                     "{\"cmd\":2003, \"class\":\"neb::CmdUserLogout\"}"
                                "],"
                                "\"module\":["
                                     "{\"path\":\"im/user/login\", \"class\":\"neb::ModuleLogin\"},"
                                     "{\"path\":\"im/user/logout\", \"class\":\"neb::ModuleLogout\"}"
                                "]"
                             "},"
                             "{"
                             "\"so_path\":\"plugins/ChatMsg.so\", \"load\":false, \"version\":1,"
                                 "\"cmd\":["
                                      "{\"cmd\":2001, \"class\":\"neb::CmdChat\"}"
                                 "],"
                             "\"module\":[]"
                             "}"
                        "]"
                    "}");
     std::cout << oJson.ToString() << std::endl;
     std::cout << "-------------------------------------------------------------------" << std::endl;
     std::cout << oJson["dynamic_loading"][0]["cmd"][1]("class") << std::endl;
     oJson["dynamic_loading"][0]["cmd"][0].Get("cmd", iValue);
     std::cout << "iValue = " << iValue << std::endl;
     oJson["dynamic_loading"][0]["module"][0].Get("path", strValue);
     std::cout << "strValue = " << strValue << std::endl;
     std::cout << "-------------------------------------------------------------------" << std::endl;
     oJson.AddEmptySubObject("depend");
     oJson["depend"].Add("nebula", "https://github.com/Bwar/Nebula");
     oJson["depend"].AddEmptySubArray("bootstrap");
     oJson["depend"]["bootstrap"].Add("BEACON");
     oJson["depend"]["bootstrap"].Add("LOGIC");
     oJson["depend"]["bootstrap"].Add("LOGGER");
     oJson["depend"]["bootstrap"].Add("INTERFACE");
     oJson["depend"]["bootstrap"].Add("ACCESS");
     std::cout << oJson.ToString() << std::endl;
     std::cout << "-------------------------------------------------------------------" << std::endl;
     std::cout << oJson.ToFormattedString() << std::endl;
}

Demo執行結果:bootstrap

[bwar@nebula demo]$ ./CJsonObjectTest 
{"refresh_interval":60,"dynamic_loading":[{"so_path":"plugins/User.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdUserLogin"},{"cmd":2003,"class":"neb::CmdUserLogout"}],"module":[{"path":"im/user/login","class":"neb::ModuleLogin"},{"path":"im/user/logout","class":"neb::ModuleLogout"}]},{"so_path":"plugins/ChatMsg.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdChat"}],"module":[]}]}
-------------------------------------------------------------------
neb::CmdUserLogout
iValue = 2001
strValue = im/user/login
-------------------------------------------------------------------
{"refresh_interval":60,"dynamic_loading":[{"so_path":"plugins/User.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdUserLogin"},{"cmd":2003,"class":"neb::CmdUserLogout"}],"module":[{"path":"im/user/login","class":"neb::ModuleLogin"},{"path":"im/user/logout","class":"neb::ModuleLogout"}]},{"so_path":"plugins/ChatMsg.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdChat"}],"module":[]}],"depend":{"nebula":"https://github.com/Bwar/Nebula","bootstrap":["BEACON","LOGIC","LOGGER","INTERFACE","ACCESS"]}}
-------------------------------------------------------------------
{
	"refresh_interval":	60,
	"dynamic_loading":	[{
			"so_path":	"plugins/User.so",
			"load":	false,
			"version":	1,
			"cmd":	[{
					"cmd":	2001,
					"class":	"neb::CmdUserLogin"
				}, {
					"cmd":	2003,
					"class":	"neb::CmdUserLogout"
				}],
			"module":	[{
					"path":	"im/user/login",
					"class":	"neb::ModuleLogin"
				}, {
					"path":	"im/user/logout",
					"class":	"neb::ModuleLogout"
				}]
		}, {
			"so_path":	"plugins/ChatMsg.so",
			"load":	false,
			"version":	1,
			"cmd":	[{
					"cmd":	2001,
					"class":	"neb::CmdChat"
				}],
			"module":	[]
		}],
	"depend":	{
		"nebula":	"https://github.com/Bwar/Nebula",
		"bootstrap":	["BEACON", "LOGIC", "LOGGER", "INTERFACE", "ACCESS"]
	}
}

 

再來看看頭文件,一看就知道如何使用:api

/*******************************************************************************
 * Project:  neb
 * @file     CJsonObject.hpp
 * @brief    Json
 * @author   bwarliao
 * @date:    2014-7-16
 * @note
 * Modify history:
 ******************************************************************************/

#ifndef CJSONOBJECT_HPP_
#define CJSONOBJECT_HPP_

#include <stdio.h>
#include <stddef.h>
#include <malloc.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <math.h>
#include <float.h>
#include <string>
#include <map>
#include "cJSON.h"


namespace neb
{

class CJsonObject
{
public:     // method of ordinary json object or json array
    CJsonObject();
    CJsonObject(const std::string& strJson);
    CJsonObject(const CJsonObject* pJsonObject);
    CJsonObject(const CJsonObject& oJsonObject);
    virtual ~CJsonObject();

    CJsonObject& operator=(const CJsonObject& oJsonObject);
    bool operator==(const CJsonObject& oJsonObject) const;
    bool Parse(const std::string& strJson);
    void Clear();
    bool IsEmpty() const;
    bool IsArray() const;
    std::string ToString() const;
    std::string ToFormattedString() const;
    const std::string& GetErrMsg() const
    {
        return(m_strErrMsg);
    }

public:     // method of ordinary json object
    bool AddEmptySubObject(const std::string& strKey);
    bool AddEmptySubArray(const std::string& strKey);
    CJsonObject& operator[](const std::string& strKey);
    std::string operator()(const std::string& strKey) const;
    bool Get(const std::string& strKey, CJsonObject& oJsonObject) const;
    bool Get(const std::string& strKey, std::string& strValue) const;
    bool Get(const std::string& strKey, int32& iValue) const;
    bool Get(const std::string& strKey, uint32& uiValue) const;
    bool Get(const std::string& strKey, int64& llValue) const;
    bool Get(const std::string& strKey, uint64& ullValue) const;
    bool Get(const std::string& strKey, bool& bValue) const;
    bool Get(const std::string& strKey, float& fValue) const;
    bool Get(const std::string& strKey, double& dValue) const;
    bool Add(const std::string& strKey, const CJsonObject& oJsonObject);
    bool Add(const std::string& strKey, const std::string& strValue);
    bool Add(const std::string& strKey, int32 iValue);
    bool Add(const std::string& strKey, uint32 uiValue);
    bool Add(const std::string& strKey, int64 llValue);
    bool Add(const std::string& strKey, uint64 ullValue);
    bool Add(const std::string& strKey, bool bValue, bool bValueAgain);
    bool Add(const std::string& strKey, float fValue);
    bool Add(const std::string& strKey, double dValue);
    bool Delete(const std::string& strKey);
    bool Replace(const std::string& strKey, const CJsonObject& oJsonObject);
    bool Replace(const std::string& strKey, const std::string& strValue);
    bool Replace(const std::string& strKey, int32 iValue);
    bool Replace(const std::string& strKey, uint32 uiValue);
    bool Replace(const std::string& strKey, int64 llValue);
    bool Replace(const std::string& strKey, uint64 ullValue);
    bool Replace(const std::string& strKey, bool bValue, bool bValueAgain);
    bool Replace(const std::string& strKey, float fValue);
    bool Replace(const std::string& strKey, double dValue);

public:     // method of json array
    int GetArraySize();
    CJsonObject& operator[](unsigned int uiWhich);
    std::string operator()(unsigned int uiWhich) const;
    bool Get(int iWhich, CJsonObject& oJsonObject) const;
    bool Get(int iWhich, std::string& strValue) const;
    bool Get(int iWhich, int32& iValue) const;
    bool Get(int iWhich, uint32& uiValue) const;
    bool Get(int iWhich, int64& llValue) const;
    bool Get(int iWhich, uint64& ullValue) const;
    bool Get(int iWhich, bool& bValue) const;
    bool Get(int iWhich, float& fValue) const;
    bool Get(int iWhich, double& dValue) const;
    bool Add(const CJsonObject& oJsonObject);
    bool Add(const std::string& strValue);
    bool Add(int32 iValue);
    bool Add(uint32 uiValue);
    bool Add(int64 llValue);
    bool Add(uint64 ullValue);
    bool Add(int iAnywhere, bool bValue);
    bool Add(float fValue);
    bool Add(double dValue);
    bool AddAsFirst(const CJsonObject& oJsonObject);
    bool AddAsFirst(const std::string& strValue);
    bool AddAsFirst(int32 iValue);
    bool AddAsFirst(uint32 uiValue);
    bool AddAsFirst(int64 llValue);
    bool AddAsFirst(uint64 ullValue);
    bool AddAsFirst(int iAnywhere, bool bValue);
    bool AddAsFirst(float fValue);
    bool AddAsFirst(double dValue);
    bool Delete(int iWhich);
    bool Replace(int iWhich, const CJsonObject& oJsonObject);
    bool Replace(int iWhich, const std::string& strValue);
    bool Replace(int iWhich, int32 iValue);
    bool Replace(int iWhich, uint32 uiValue);
    bool Replace(int iWhich, int64 llValue);
    bool Replace(int iWhich, uint64 ullValue);
    bool Replace(int iWhich, bool bValue, bool bValueAgain);
    bool Replace(int iWhich, float fValue);
    bool Replace(int iWhich, double dValue);

private:
    CJsonObject(cJSON* pJsonData);

private:
    cJSON* m_pJsonData;
    cJSON* m_pExternJsonDataRef;
    std::string m_strErrMsg;
    std::map<unsigned int, CJsonObject*> m_mapJsonArrayRef;
    std::map<std::string, CJsonObject*> m_mapJsonObjectRef;
};

}

#endif /* CJSONHELPER_HPP_ */

      若是以爲CJsonObject不錯,別忘了給個star,謝謝。網絡

 

https://github.com/Bwar/Nebula  

相關文章
相關標籤/搜索