cJSON的源码解读

前言

本博客内容主要是简单介绍一下cJSON的一些函数说明,由于源码不是很难,可以自己去看,如果嫌麻烦,可以直接看一下我的函数说明,然后大致看一下源码即可.

一定要去看源码,能需要很多;

cJSON的一些信息

这个地址可以下载到最新的源码: https://github.com/DaveGamble/cJSON

我看的源码比较老,学习为主,后期会阅读最新的源码;

以下是我看的源码部分:

链接:https://pan.baidu.com/s/1b7d4xsITPkUOCKbSDBsAmA 提取码:ame0

cJSON的数据结构

cJSON数据结构:
/* The cJSON structure: */
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;

内存申请:
typedef struct cJSON_Hooks {
   
   
      void *(*malloc_fn)(size_t sz);
      void (*free_fn)(void *ptr);
} cJSON_Hooks;

基本函数

cJSON的基本函数:
	• cJSON_strcasecmp —— 两个字符比较是否相同,相同返回0,否则为1
	* cJSON_strdup —— 申请一块内存,用来保存其内容;

内部静态函数

cJSON内部函数:
	• cJSON_New_Item  —— 申请一块cJSON结构体大小的内存,并初始化为0
	• parse_number —— 将字符串转换为整型数据int或者double; 此函数分别对正负/0/数字/小数点/指数进行判断(注意,这些处理是有顺序,还有这里的代码还是值得参考的),最后将值赋给形参,并赋予类型;
	• Pow2gt —— 返回比x大的最小的2的N次方数;具体算法可参看以下文章:https://blog.csdn.net/dlf1769/article/details/78918045?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
	• ensure —— 确保读取的大小在字符串的范围内; 如果需要的大小在总长度内,直接范围偏移地址;如果不够,则使用Pow2gt先申请更大的一块,复制内容后,释放原来的内存,再返回偏移值;
	• print_number  —— 根据值的大小,将整型值改为字符串格式;分别有0,21int64double数据
	• parse_hex4  —— 字符串转hex格式
	• parse_string  —— 申请指定大小的内存,将带转义字符\格式的字符串和\t这类的转换为字符串,赋值给cJSON结构的string类型,并判断其类型.(这里有utf16 -> utf8的转换过程,可以学习一下)
	• print_string_ptr  —— 将格式转换为纯字符串格式; 先判断是否有"和\或者\t这类的,如果没有,直接申请和拷贝数据后,添加2字节数据,返回申请的地址; 如果字符串为空,直接返回"";再获取长度后,添加指定的\t这类结构加入字符串
	• parse_value  —— 不同格式产生不同的数据和类型;
	• parse_array —— 确定array类型,新申请cJSON结构体,child指针指向; 获取值,如果还是array,则进行递归;如果是",",则再进行child的操作;
	• parse_object —— 基本操作于array一致
	• print_object  —— 将cJSON对象转换为字符串格式
	• print_array —— 将cJSON对象转换为字符串格式
print_value   —— 将cJSON对象转换为字符串格式

对外函数

cJSON对外接口函数:
	• cJSON_InitHooks  —— 初始化内存申请的函数为malloc和free,如果形参时有效的,则使用形参的内存申请函数(用于调用用户自己的malloc实现)
	• cJSON_Delete —— 删除所有申请的内存!这个函数采用的是递归删除,先递归到每一个child对象,然后释放string_value和string的内存,如此,一个child的子对象的内存释放递归结束,再一次进行释放;
	• cJSON_ParseWithOpts —— 申请一个cJSON对象,再赋值;
	• cJSON_Parse——cJSON_ParseWithOpts(value, 0, 0)
cJSON_Print/cJSON_PrintUnformatted —— print_value(item,0,1/0,0)

以下是简单的处理以下的对外函数就不写了,一看就能懂:
/* Get Array size/item / object item. */
int    cJSON_GetArraySize(cJSON *array)                         {
   
   cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item)                {
   
   cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)    {
   
   cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {
   
   prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {
   
   cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
void   cJSON_AddItemToArray(cJSON *array, cJSON *item)                      {
   
   cJSON *c=array->child;if (!item) return; if (!c) {
   
   array->child=item;} else {
   
   while (c && c->next) c=c->next; suffix_object(c,item);}}
void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)  {
   
   if (!item
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值