cJSON源码解析


   cJSONC语言中的一个JSON编解码器,非常轻量级,C开源代码汇总,代码量少,不到一千行,代码的可读性高,很适合作为 C 语言项目进行学习。
   对于 json 格式编码与解码,其实就是类似于一个解释器,主要的原理是运用递归。
  首先看下 cJSON.h 中定义的 cJSON数据结构,

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;

  不管是数据类型、字符串类型还是对象类型都使用这个结构体,类型的信息通过type 来标记, cJSON 共定义了 7 中类型。

/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3  //整型
#define cJSON_String 4 //字符串类型 
#define cJSON_Array 5  //array 类型
#define cJSON_Object 6  //对象类型

   如果是对象或者数组,采用的是双向链表来实现,链表中的每个节点表示数组中的一个元素或者对象中的一个字段。其中 child 表示头结点,nextprev 分别表示下一个节点和前一个节点。valuestringvalueintvaluedouble分别表示字符串、整数、浮点数的字面量。string 表示对象中的某一字段的名称,比如有这样的一个json 字符串,其中的 age 就用 string来表示。

{
   'age' : 20}

   cJSON 的 API 使用起来很简单,text 表示你需要解析的文件内容,注意释放内存,以免泄露。

	char *out;cJSON *json;
	
	json=cJSON_Parse(text);
	if (!json) {
   printf("Error before: [%s]\n",cJSON_GetErrorPtr());}
	else
	{
   
		out=cJSON_Print(json);
		cJSON_Delete(json);
		printf("%s\n",out);
		free(out);
	}
1、JSON的解析

   进行解析分析前,我们先了解下 JSON 文件的格式。

Some JSON:
{
   
    "name": "Jack (\"Bee\") Nimble", 
    "format": {
   
        "type":       "rect", 
        "width":      1920, 
        "height":     1080, 
        "interlace":  false, 
        "frame rate": 24
    }
}

   JSON 的字符串的解析主要是通过 cJSON_Parse 函数来完成的。

cJSON *cJSON_Parse(const char *value) 
	{
   return cJSON_ParseWithOpts(value,0,0);}
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
   
	const char *end=0;
	cJSON *c=cJSON_New_Item();
	ep=0;
	if (!c) return 0;       /* memory fail */

	end=parse_value(c,skip(value));
	if (!end)	{
   cJSON_Delete(c);return 0;}	/* parse failure. ep is set. */

	/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
	if (require_null_terminated) {
   end=skip(end);if (*end) {
   cJSON_Delete(c);ep=end;return 0;}}
	if (return_parse_end) *return_parse_end=end;
	return c;
}
  • 第一步:先调用 cJSON_New_Item函数 创建一个 cJSON 节点,函数就是为 节点分配内存,并将对应的内存初始化为 0;
static cJSON *cJSON_New_Item(void)
{
   
	cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
	if (node) memset(node,0,sizeof(cJSON));
	
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值