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_False 1

 cJSON_True  2

 cJSON_NULL  4

 cJSON_Number   8

 cJSON_String 16

 cJSON_Array 32

 cJSON_Object 64

 cJSON_Raw   128

 

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个小人。

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

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值