c语言json映射,GitHub - xujun621/cson: 基于C语言的json数据映射解析库
CSON
基于cJSON,運(yùn)行于C語言平臺(tái)的json-struct模型解析工具
簡(jiǎn)介
CSON是一個(gè)簡(jiǎn)單的cJSON的二次封裝,相比于使用原生cJSON一層一層解析的方式,CSON采用模型映射的方式,使用模型將結(jié)構(gòu)體的特征進(jìn)行描述,然后根據(jù)模型,將json數(shù)據(jù)直接解析成結(jié)構(gòu)體,免去使用原生cJSON需要多次調(diào)用API的復(fù)雜性,可以很大程度減少代碼冗余,增加代碼邏輯性。
CSON的模型映射借鑒了高級(jí)語言(比如說Java)的反射機(jī)制,通過建立數(shù)據(jù)模型,記錄結(jié)構(gòu)體的元素,類型,偏移,然后直接在內(nèi)存層面進(jìn)行操作,對(duì)C語言提供類似于gson這樣的高效json解析工具
使用
CSON通過數(shù)據(jù)模型將結(jié)構(gòu)體和json建立映射關(guān)系,因此,你需要做的就是在聲明結(jié)構(gòu)體的時(shí)候同時(shí),使用數(shù)據(jù)模型對(duì)結(jié)構(gòu)體進(jìn)行描述,之后,只需要直接調(diào)用CSON的api即可
聲明結(jié)構(gòu)體
/** 項(xiàng)目結(jié)構(gòu)體 */
struct project
{
int id;
char *name;
};
/** 倉庫結(jié)構(gòu)體 */
struct hub
{
int id;
char *user;
struct project *cson;
};
定義數(shù)據(jù)模型
對(duì)每一個(gè)需要使用cson的結(jié)構(gòu)體,都需要定義相對(duì)應(yīng)的數(shù)據(jù)模型
/** 項(xiàng)目結(jié)構(gòu)體數(shù)據(jù)模型 */
CsonModel projectModel[] =
{
CSON_MODEL_OBJ(struct project),
CSON_MODEL_INT(struct project, id),
CSON_MODEL_STRING(struct project, name),
};
/** 倉庫結(jié)構(gòu)體數(shù)據(jù)模型 */
CsonModel hubModel[] =
{
CSON_MODEL_OBJ(struct hub),
CSON_MODEL_INT(struct hub, id),
CSON_MODEL_STRING(struct hub, user),
CSON_MODEL_STRUCT(struct hub, cson, projectModel, sizeof(projectModel)/sizeof(CsonModel))
};
使用CSON解析
只需要定義好數(shù)據(jù)模型,就可以使用CSON讀json進(jìn)行序列化和反序列化
void csonDemo(void)
{
char *jsonDemo = "{\"id\": 1, \"user\": \"Letter\", \"cson\": {\"id\": 2, \"name\": \"cson\"}}";
/** 解析json */
struct hub *pHub = csonDecode(jsonDemo, hubModel, sizeof(hubModel)/sizeof(CsonModel));
printf("hub: id: %d, user: %s, project id: %d, project name: %s\r\n",
pHub->id, pHub->user, pHub->cson->id, pHub->cson->name);
/** 序列化對(duì)象 */
char *formatJson = csonEncodeFormatted(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));
printf("format json: %s\r\n", formatJson);
/** 釋放結(jié)構(gòu)體對(duì)象 */
csonFree(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));
/** 釋放序列化生成的json字符串 */
csonFreeJson(formatJson);
}
運(yùn)行結(jié)果:
hub: id: 1, user: Letter, project id: 2, project name: cson
format json: {
"id": 1,
"user": "Letter",
"cson": {
"id": 2,
"name": "cson"
}
}
可以看到,無論是解析json,還是序列化結(jié)構(gòu)體到j(luò)son,在使用CSON的情況下,都只需要一行代碼就可以解決,同樣的操作,在使用原生cJSON的情況下,你可能需要多次判斷,解析元素
結(jié)構(gòu)體數(shù)據(jù)類型
CSON采用數(shù)據(jù)模型對(duì)結(jié)構(gòu)體進(jìn)行解析,在方便json操作的同時(shí),也給結(jié)構(gòu)體的定義帶來了一些限制,目前,CSON所支持在結(jié)構(gòu)體中定義的數(shù)據(jù)類型包括:
整數(shù)(char, short, int, long)
浮點(diǎn)數(shù)(float, double)
字符串(char *)
基本類型數(shù)組(char[], short[], int[], long[], float[], double[], *char[])
子結(jié)構(gòu)體(指針形式)
鏈表(CsonList)
其中,為了方便解析,CSON定義了一個(gè)專用的鏈表(CsonList),用于對(duì)json中復(fù)雜結(jié)構(gòu)的數(shù)組映射
CSON支持的數(shù)據(jù)類型基本包括絕大多數(shù)使用場(chǎng)景,對(duì)于一些之前就定義好的結(jié)構(gòu)體,可能需要稍微做一點(diǎn)修改
數(shù)據(jù)模型映射
CSON采用數(shù)據(jù)模型建立結(jié)構(gòu)體同json之間的映射,數(shù)據(jù)模型通過結(jié)構(gòu)體數(shù)組進(jìn)行定義,數(shù)據(jù)模型定義如下:
/**
* @brief CSON數(shù)據(jù)模型定義
*
*/
typedef struct cson_model
{
CsonType type; /**< 數(shù)據(jù)類型 */
char *key; /**< 元素鍵值 */
short offset; /**< 元素偏移 */
union
{
struct
{
struct cson_model *model; /**< 子結(jié)構(gòu)體模型 */
short size; /**< 子結(jié)構(gòu)體模型大小 */
} sub; /**< 子結(jié)構(gòu)體 */
struct
{
CsonType eleType; /**< 數(shù)組元素類型 */
short size; /**< 數(shù)組大小 */
} array; /**< 數(shù)組 */
int objSize; /**< 對(duì)象大小 */
CsonType basicListType; /**< 基礎(chǔ)數(shù)據(jù)鏈表類型 */
} param;
} CsonModel;
對(duì)于每一個(gè)需要使用CSON的結(jié)構(gòu)體,都需要定義一個(gè)數(shù)據(jù)模型,每一個(gè)數(shù)據(jù)模型都需要包含一條結(jié)構(gòu)體描述CSON_MODEL_OBJ(type)以及若干個(gè)數(shù)據(jù)描述,取決于結(jié)構(gòu)體的成員數(shù)量
一般情況下,你只需要使用CSON提供的宏進(jìn)行數(shù)據(jù)模型條目的定義,數(shù)據(jù)模型宏與對(duì)應(yīng)的數(shù)據(jù)類型對(duì)應(yīng)如下:
數(shù)據(jù)模型宏
數(shù)據(jù)類型
備注
CSON_MODEL_OBJ(type)
結(jié)構(gòu)體
用于描述整個(gè)結(jié)構(gòu)體,每一個(gè)數(shù)據(jù)模型都需要包含此條目
CSON_MODEL_CHAR(type, key)
char
CSON_MODEL_SHORT(type, key)
short
CSON_MODEL_INT(type, key)
int
CSON_MODEL_LONG(type, key)
long
CSON_MODEL_FLOAT(type, key)
float
CSON_MODEL_DOUBLE(type, key)
double
CSON_MODEL_BOOL(type, key)
bool
C沒有bool,對(duì)應(yīng)為char
CSON_MODEL_STRING(type, key)
char *
CSON_MODEL_STRUCT(type, key, submodel, subsize)
子結(jié)構(gòu)體
子結(jié)構(gòu)體必須是結(jié)構(gòu)體指針的形式
CSON_MODEL_LIST(type, key, submodel, subsize)
CsonList
CSON定義的鏈表
CSON_MODEL_ARRAY(type, key, elementType, arraySize
數(shù)組
支持基本數(shù)據(jù)類型, 數(shù)組的每一個(gè)元素必須合法
API
CSON源文件有完整的注釋,可以通過Doxygen等工具導(dǎo)出完整的API文檔,以下是幾個(gè)關(guān)鍵API的說明
初始化
初始化CSON,提供內(nèi)存分配和內(nèi)存釋放函數(shù),對(duì)于標(biāo)準(zhǔn)C庫可以使用malloc和free
void csonInit(void *malloc, void *free)
參數(shù)
malloc 內(nèi)存分配函數(shù)
free 內(nèi)存釋放函數(shù)
反序列化
解析json,將json字符串反序列化成結(jié)構(gòu)體對(duì)象
void *csonDecode(const char *jsonStr, CsonModel *model, int modelSize)
參數(shù)
jsonStr json字符串
model 描述目標(biāo)結(jié)構(gòu)體的數(shù)據(jù)模型
modelSize 數(shù)據(jù)模型大小
返回
void * 反序列化得到的結(jié)構(gòu)體對(duì)象
序列化
編碼結(jié)構(gòu)體,將結(jié)構(gòu)體對(duì)象序列化成json字符串
char* csonEncode(void *obj, CsonModel *model, int modelSize, int bufferSize, int fmt)
參數(shù)
obj 源結(jié)構(gòu)體對(duì)象
model 描述源結(jié)構(gòu)體的數(shù)據(jù)模型
modelSize 數(shù)據(jù)模型大小
bufferSize 可分配給json字符串的空間大小,需要根據(jù)內(nèi)容估計(jì)大小
fmt 是否格式化json字符串
返回
char * 序列化得到的json字符串
空間釋放
CSON提供了兩個(gè)釋放內(nèi)存的函數(shù),用于釋放CSON生成的結(jié)構(gòu)體對(duì)象和json字符串
釋放結(jié)構(gòu)體對(duì)象
void csonFree(void *obj, CsonModel *model, int modelSize)
參數(shù)
obj 待釋放的結(jié)構(gòu)體對(duì)象
model 待釋放的結(jié)構(gòu)體數(shù)據(jù)模型
modelSize 待釋放的結(jié)構(gòu)體數(shù)據(jù)模型大小
釋放json字符串
void csonFreeJson(const char *jsonStr)
參數(shù)
jsonStr 待釋放的json字符串
注意
數(shù)據(jù)模型根據(jù)結(jié)構(gòu)體不同而不同,數(shù)據(jù)模型的數(shù)量=結(jié)構(gòu)體成員數(shù)量+1,多出來的一條是定義結(jié)構(gòu)體CSON_MODEL_OBJ(type)
數(shù)組類型映射時(shí)會(huì)處理給進(jìn)去的數(shù)組大小,所以請(qǐng)確保每一個(gè)數(shù)組元素都是合法的
基本數(shù)據(jù)類型鏈表采用類似子結(jié)構(gòu)體的方式,CSON默認(rèn)定義了基本數(shù)據(jù)類型鏈表元素的數(shù)據(jù)模型,通過類似CSON_MODEL_LIST(struct test, strList, CSON_MODEL_STRING_LIST, CSON_BASIC_LIST_MODEL_SIZE)進(jìn)行定義即可
總結(jié)
以上是生活随笔為你收集整理的c语言json映射,GitHub - xujun621/cson: 基于C语言的json数据映射解析库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql数据变化通通知机制_深入理解N
- 下一篇: ios uiview 如何刷新_ios-