cJSON代码分析(一)

前端之家收集整理的这篇文章主要介绍了cJSON代码分析(一)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

cJSON代码分析(一)

前言

cJSON采用双向链表来存储数据。双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

cJSON操作JSON对象实质就是操作链表的过程。本次分析cJSON添加对象和删除对象的操作。

cJSON返回结果的宏定义

在小端系统中,最高有效位存储在高地址内存中,最低有效位存储在低地址中。

#define cJSON_Invalid (0)

#define cJSON_False (1 << 0) 1最低有效位往最高有效位的方向移动0位。

#define cJSON_True (1 << 1) 1最低有效位往最高有效位的方向移动1位。

#define cJSON_NULL (1 << 2) 1最低有效位往最高有效位的方向移动2位。

#define cJSON_Number (1 << 3) 1最低有效位往最高有效位的方向移动3位。

#define cJSON_String (1 << 4) 1最低有效位往最高有效位的方向移动4位。

#define cJSON_Array (1 << 5) 1最低有效位往最高有效位的方向移动5位。

#define cJSON_Object (1 << 6) 1最低有效位往最高有效位的方向移动6位。

#define cJSON_Raw (1 << 7) /* raw json */ 1最低有效位往最高有效位的方向移动7位。

cJSON_Invalid 0

cJSON_False1

cJSON_True2

cJSON_NULL4

cJSON_Number 8

cJSON_String 16

cJSON_Array32

cJSON_Object 64

cJSON_Raw128

c JSON中最重要的结构体

struct cJSON

typedef struct cJSON

{

/* next/prev allow you to walk array/object chains. Alternatively,useGetArraySize/GetArrayItem/GetObjectItem */

struct cJSON *next;

struct cJSON *prev;

/* An array or object item will have a child pointer pointing to a chainof 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;

/* writing to valueint is DEPRECATED,use cJSON_SetNumberValue instead*/

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 thelist of subitems of an object. */

char *string;

} cJSON;

parse_buffer

typedef struct

{

const unsigned char *content;

size_t length;

size_t offset;

size_t depth; /* How deeply nested (in arrays/objects) is the input atthe current offset. */

internal_hooks hooks;

} parse_buffer;

error

typedef struct {

const unsigned char *json;

size_t position;

} error;

internal_hooks

typedef struct internal_hooks

{

void *(*allocate)(size_t size);

void (*deallocate)(void *pointer);

void *(*reallocate)(void *pointer,size_t size);

} internal_hooks;

创建JSON对象

CJSON_PUBLIC(cJSON *) cJSON_CreateObject创建JSON对象

CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void)

{

cJSON *item =cJSON_New_Item(&global_hooks);

if (item)

{

item->type = cJSON_Object;//指定item的类型为cJSON_OBJECT

}

return item;

}

/* Internal constructor. */

static cJSON *cJSON_New_Item初始化

static cJSON*cJSON_New_Item(const internal_hooks * const hooks)

{

cJSON* node =(cJSON*)hooks->allocate(sizeof(cJSON));// 调用malloc函数分配内存

if (node)

{

memset(node,'\0',sizeof(cJSON));//初始化

}

return node;

}

typedef struct internal_hooks

typedef structinternal_hooks

{

void *(*allocate)(size_t size);

void (*deallocate)(void *pointer);

void *(*reallocate)(void *pointer,size_tsize);

} internal_hooks;

static void*internal_malloc(size_t size)

{

return malloc(size);

}

static voidinternal_free(void *pointer)

{

free(pointer);

}

static void*internal_realloc(void *pointer,size_t size)

{

return realloc(pointer,size);

}

#defineinternal_malloc malloc

#defineinternal_free free

#defineinternal_realloc realloc

staticinternal_hooks global_hooks = { internal_malloc,internal_free,internal_realloc };

CJSON_PUBLIC(void) cJSON_AddItemToObject JSON对象添加成员

本质上还是调用cJSON_AddItemToArray 接口来添加数据。

CJSON_PUBLIC(void) cJSON_AddItemToArray 把成员添加到数组或对象中

/* Add item to array/object. */

CJSON_PUBLIC(void)cJSON_AddItemToArray(cJSON *array,cJSON *item)

{

cJSON *child = NULL;

if ((item == NULL) || (array == NULL))

{

return;

}

child = array->child;

if (child == NULL)

{

/* list is empty,start new one */

array->child = item; //如果当前JSON的child为空,把item挂载到当 //前child节点。

}

else

{

/* append to the end */

while (child->next) //循环到JSON的最后一个节点

{

child = child->next;

}

suffix_object(child,item); //把item放到双向链表的后面

//child节点next 指向item.

//item节点的prev 指向prev

}

}

//child节点next 指向item.

//item 节点的prev 指向prev

static voidsuffix_object(cJSON *prev,cJSON *item)

{

prev->next = item;

item->prev = prev;

}

删除JSON对象

CJSON_PUBLIC(void) cJSON_Delete删除对象

/* Delete a cJSONstructure. */

//递归删除节点

CJSON_PUBLIC(void)cJSON_Delete(cJSON *item)

{

cJSON *next = NULL;

while (item != NULL)

{

next = item->next;

if (!(item->type &cJSON_IsReference) && (item->child != NULL))

{

cJSON_Delete(item->child);

}

if (!(item->type &cJSON_IsReference) && (item->valuestring != NULL))

{

global_hooks.deallocate(item->valuestring);

}

if (!(item->type &cJSON_StringIsConst) && (item->string != NULL))

{

global_hooks.deallocate(item->string);

}

global_hooks.deallocate(item);

item = next;

}

}

基础宏

can_read

/* check if the given size is left to readin a given parse buffer (starting with 1) */

#define can_read(buffer,size) ((buffer !=NULL) && (((buffer)->offset + size) <= (buffer)->length))

can_access_at_index

/* check if the buffer can be accessed atthe given index (starting with 0) */

#define can_access_at_index(buffer,index)((buffer != NULL) && (((buffer)->offset + index) <(buffer)->length))

cannot_access_at_index

#define cannot_access_at_index(buffer,index) (!can_access_at_index(buffer,index))

buffer_at_offset

/* get a pointer to the buffer at theposition */

#define buffer_at_offset(buffer)((buffer)->content + (buffer)->offset)

附录

1)指针


指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

如上图所示,左边的小房子是一个变量,变量内容为1个小人。

右边的小房子是一个指针。指针内容是左边小房子的房号(房子的地址)。

猜你在找的Json相关文章