1、介紹
RyanJson是一個(gè)小巧的c語言json解析器,包含json文本文件解析 / 生成,專門針對(duì)內(nèi)存占用進(jìn)行優(yōu)化,相比cJSON內(nèi)存占用減少30% - 60%,運(yùn)行速度和cJSON差不多。
低內(nèi)存占用:使用動(dòng)態(tài)擴(kuò)展技術(shù),在32位系統(tǒng)下,一個(gè)基礎(chǔ)json節(jié)點(diǎn)僅占用8字節(jié)。
開發(fā)人員友好:僅有一個(gè)c文件和頭文件輕松集成,hook函數(shù)方便自定義內(nèi)存鉤子。類cJSON的api,遷移成本低。
嚴(yán)格但不嚴(yán)苛:符合 RFC 8295 大部分JSON標(biāo)準(zhǔn),支持無限的json嵌套級(jí)別(需注意堆棧空間)、靈活的配置修改項(xiàng)
可擴(kuò)展性:允許注釋(需調(diào)用mini函數(shù)清除注釋后再解析)、尾隨逗號(hào)等無效字符(parse時(shí)可配置是否允許)等
2、設(shè)計(jì)
RyanJson設(shè)計(jì)時(shí)大量借鑒了 json 和 cJSON ! 是從 json 的基礎(chǔ)上修改來的
json語法是JavaScript對(duì)象語法的子集
在json語法中,數(shù)據(jù)以鍵值對(duì)的形式存儲(chǔ)(數(shù)組沒有key)
在RyanJson解析器中,使用結(jié)構(gòu)體來表示一個(gè)鍵值對(duì),是存儲(chǔ)的最小單元,結(jié)構(gòu)如下:
struct RyanJsonNode
{
uint32_t info; // 包含類型,key等標(biāo)志
struct RyanJsonNode *next; // 單鏈表node節(jié)點(diǎn)
// [char key] 有key的json節(jié)點(diǎn), 會(huì)動(dòng)態(tài)創(chuàng)建指針
// 有value值的節(jié)點(diǎn), 會(huì)動(dòng)態(tài)創(chuàng)建指針
// [int32_t value / double value / char value / RyanJson_t item]
};
typedef struct RyanJsonNode *RyanJson_t;
此結(jié)構(gòu)體包含兩個(gè)固定成員 info 和 next;
info:為當(dāng)前節(jié)點(diǎn)的配置信息用來表示 節(jié)點(diǎn)數(shù)據(jù)類型 和 flag標(biāo)志位。
bits low --> high
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | NA | NA | .......
______________________________/ | | |
low 8bits | | |
| | | |
V | | |
RyanJsonTypeUnknow (bit0) | | |
RyanJsonTypeNull (bit1) | | |
RyanJsonTypeBool (bit2) | | +----> RyanJsonWithKeyFlag (1 << 10)
RyanJsonTypeNumber (bit3) | |
RyanJsonTypeString (bit4) | +--------> RyanJsonValueNumberIntFlag (1 << 9)
RyanJsonTypeArray (bit5) |
RyanJsonTypeObject (bit6) +------------> RyanJsonValueBoolTrueFlag (1 << 8)
spare (bit7)
next:指針指向鏈表下一個(gè)節(jié)點(diǎn)
{
"name": "RyanJson",
next (
"version": "xxx",
next (
"repository": "https://github.com/Ryan-CW-Code/RyanJson",
next (
"keywords": ["json", "streamlined", "parser"],
next ( _ item _/ _ next _/ _ next _/
"others": {
...
}
}
此結(jié)構(gòu)體還包括兩個(gè)可能動(dòng)態(tài)創(chuàng)建的成員 key 和 value;
key:存儲(chǔ)鍵值對(duì)的 key 信息,當(dāng)存在key時(shí)會(huì)在申請(qǐng)RyanJsonNode內(nèi)存時(shí),動(dòng)態(tài)添加。
value:存儲(chǔ)鍵值對(duì)的 value 信息,會(huì)根據(jù)不同節(jié)點(diǎn)類型創(chuàng)建不同的value值。會(huì)在申請(qǐng)RyanJsonNode內(nèi)存時(shí),動(dòng)態(tài)添加。
3、測試
測試代碼可在本項(xiàng)目根目錄查看。
性能測試
RyanDocs文檔中心,有基于 yyjson_benchmark 的測試結(jié)果
內(nèi)存占用測試
RFC 8295 標(biāo)準(zhǔn)測試,大部分嵌入式場景不會(huì)出現(xiàn)復(fù)雜的特殊json結(jié)構(gòu)
RyanJson和cJSON都不適合處理復(fù)雜的UTF-16字符集,如果項(xiàng)目需要兼容Unicode字符集,可以考慮yyjson / json-c
4、局限性
使用int / double表示json中的number類型,精度有所丟失。建議64位的number類型最好用string字符串表示。
對(duì)象中允許有重復(fù)的key,RyanJson庫采用單向鏈表,會(huì)訪問到第一個(gè)對(duì)象。
-
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7366瀏覽量
163092 -
C語言
+關(guān)注
關(guān)注
180文章
7575瀏覽量
134086 -
RFC
+關(guān)注
關(guān)注
0文章
16瀏覽量
10084 -
JSON
+關(guān)注
關(guān)注
0文章
113瀏覽量
6899
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論