【源码分析】cJSON库学习
cJSON库是什么?cJSON是一个轻量级的json解析库。使用起来非常简单,整个库非常地简洁,核心功能的实现都在cJSON.c文件,非常适合阅读源代码来学习C语言。最近读完这个库的源码,分享自己收获的一些心得。 什么是json,照搬json官网的说法:
cJSON库里面有什么?cjson库github地址:https://github.com/DaveGamble/cJSON 两个函数的原型如下: CJSON_PUBLIC(cJSON*)cJSON_Parse(constchar*value); CJSON_PUBLIC(cJSON*)cJSON_ParseWithOpts(constchar*value,constchar**return_parse_end,cJSON_boolrequire_null_terminated); 函数接收一段字符串,然后进行解析后返回。解析完返回的是一个cjson结构,cJSON结构的定义如下: typedefstructcJSON {structcJSON*next;//向后指针 structcJSON*prev;//向前指针 structcJSON*child;//指向子元素,比如子数组或者子对象 inttype;//元素的类型 char*valuestring;//元素的字符串值,如果type==cJSON_String或者type==cJSO_Raw intvalueint;//已废弃,现在使用cJSON_SetNumberValue设置整型值 doublevaluedouble;//元素的整型值,如果type==cJSON_Number char*string;//表示元素键值的值,如果它有子元素的话}cJSON; 如何解析一个json字符串?json的官网在这里,http://www.json.org json使用两种结构构建,对象或者数组。 对象使用 因此,我们可以得知: 1、可以根据json的首字母判断整个json的类型,如果json以 2、如果是对象,那么它的一定有键名,先解析它的键名,然后解析它的值,解析值的过程与第一步一样,递归解析 3、如果是数组,则逐个解析数组内的元素,直到遇到 这就是根据json官网的定义得出解析json字符串的思路,接下来看看cJSON库是如何实现的。cJSON_Parse的实现流程图如下: cJSON_ParseWithOpts函数里面调用了parse_value,是整个函数的核心实现。 可以看到,parse_value是对json值的开头进行判断,然后进入相应的分支进行解析,下面对每一个分支进行分析。解析出来的值是保存在cJSON的结构体中,以下命名为item。 常量如果json值是以'null','true','false',则分别将item的type设置为cJSON_NULL、cJSON_TRUE、cJSON_FALSE。然后继续解析剩下的json值。 string如果遇到"开头,则说明json值是字符串,就解析它的值,此时只需要拿到两个"之间的值即可。保存字符串也是一个结构体,需要申请内存,计算长度的过程中,当遇到转义字符时,需要记录,因为转义符不保存。 number当遇到数字开头时,将其后面的数字字符记录起来,然后转成整型数字,然后做值的范围检查。 array解析数组时,为数组的元素创建一个新的json结构体new_item,然后继续解析数组里面的值,用','判断下一个元素的位置,得到的值保存到结构体中,并将多个元素用链表连接起来。一直解析,直到遇到']'符号。 object解析对象的过程与数组的类似,为对象的元素创建一个新的json结构体new_item,然后继续解析对象里面的值,对象是有键值对组成的,因此先得到键的值,然后用':'判断值的位置,进而继续解析得到值,多个键值对之间用','分隔开,最后用链表连接起来。一直解析,直到遇到'}'符号。 其他在解析所有值之前,会调用skip_whitespace函数过滤字符串两边的所有空白字符。此处是ASCII码小于等于32的字符,如:t、n。函数如下: staticconstunsignedchar*skip_whitespace(constunsignedchar*in) {while(in&&*in&&(*in<=32)) {in++; }returnin; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |