0%

cjson源码学习

cjson源码学习

本篇博客用于记录学习cjson源码历程

用途

cjson用于生成/解析json格式数据的轻量级源码

代码分析

cjson结构体

对于cjson结构体的数据结构类似于树的的结构对于array/object类型

1
2
3
4
5
6
7
8
9
10
11
12
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

int type; /* The type of the item, as above. */

char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */

char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

json格式

1
2
3
4
5
6
7
8
root (cJSON_Object)
├── "name" : "Jack (\"Bee\") Nimble" (cJSON_String)
└── "format" : fmt (cJSON_Object)
├── "type" : "rect" (cJSON_String)
├── "width" : 1920 (cJSON_Number)
├── "height" : 1080 (cJSON_Number)
├── "interlace" : false (cJSON_False)
└── "frame rate" : 24 (cJSON_Number)

数组解析

对于数组格式的json数据,如下代码展示如何通过child, next, prev指针构建链表进行解析。

这里新建了一个item,并赋值给child,先检测第一个数据并将其放在数组第一个位置上,这样保证链表头即是数组首个元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// +----------------+     +----------------+     +----------------+
// | cJSON object | --> | cJSON object | --> | cJSON object |
// | (array head) | | (next element) | | (next element) |
// +----------------+ +----------------+ +----------------+
// item->child child->next child->next
// / | \ / | \ |
// ... ... ... ... ... ... ...
// /* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return 0;} /* not an array! */

item->type=cJSON_Array;
value=skip(value+1);
if (*value==']') return value+1; /* empty array. */

item->child=child=cJSON_New_Item();
if (!item->child) return 0; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;

while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+1)));
if (!value) return 0; /* memory fail */
}

if (*value==']') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}