Error[8]: Undefined offset: 4880, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述ANSI C中的超轻量级JSON解析器 JSON(JavaScript对象表示法)是一种轻量级的数据交换格式。人类易于阅读和书写。机器很容易解析和生成。它基于JavaScript编程语言标准ECMA-

ANSI C中的超轻量级JsON解析器

JsON(JavaScript对象表示法)是一种轻量级的数据交换格式。人类易于阅读和书写。机器很容易解析和生成。它基于JavaScript编程语言标准ECMA-262第三版(1999年12月)的子集 。JsON是一种完全独立于语言的文本格式,但是使用C语言家族(包括C,C ++,C#,Java,JavaScript,Perl,Python等)的程序员熟悉的约定。这些属性使JsON成为理想的数据交换语言。

cJsON旨在成为您可以完成工作的最简单的解析器。它是资源只有一个C的头文件和C文件,所以方便移植。它可以为你各种需要的Json字符串处理,包括打包、解析、修改、删除、添加等。在这里将一探究竟。

在这里将着重叙述Json的打包和解析,更多处理玩法,见文章末尾链接。

开始cJsON

cJsON合并到您的项目

因为整个库只有一个C文件和一个头文件,所以您只需复制cJsON.h并复制cJsON.c到项目源并开始使用它。

cJsON用ANSI C(C89)编写,以便支持尽可能多的平台和编译器。

 

下载:

https://github.com/DaveGamble/cJSON/releases

 

CJson结构体

/* The cJsON structure: */typedef struct cJsON{    struct cJsON *next;    prev;    child;    int type;    char *valuestring;     valueint;    double valuedouble;    string;} cJsON;

结构体项解析:

next 和prev :CJson结构体作为一个双向连表的环,可以通过 next 和prev 指针进行连表遍历

child:可以是cJsON_Array、cJsON_Object类型数据

type:当前项的类型

valuestring:内容存储,当类型是cJsON_String和cJsON_Raw

valueint:内容存储,整型,可以是cJsON_False、cJsON_True数据

valuedouble:内容存储,浮点型,当类型是cJsON_Number

string:键名

数据类型

l  cJsON_InvalID表示一个不包含任何值的无效项目。如果将项目设置为全零字节,则将自动具有此类型。

l  cJsON_False表示一个false布尔值。您也可以使用来检查布尔值cJsON_IsBool

l  cJsON_True表示一个true布尔值。您也可以使用来检查布尔值cJsON_IsBool

l  cJsON_NulL表示一个null值

l  cJsON_Number 表示一个数字值。该值存储为double in valuedouble和in valueint。如果数字超出整数范围,INT_MAX或INT_MIN用于valueint

l  cJsON_String表示一个字符串值。它以零终止字符串的形式存储在中valuestring

l  cJsON_Array表示一个数组值。这是通过指向表示数组中值child的cJsON项目的链接列表来实现的。使用next和将元素链接在一起prev,其中第一个元素具有prev.next == NulL和最后一个元素next == NulL

l  cJsON_Object 表示一个对象值。对象的存储方式与数组相同,唯一的区别是对象中的项将其键存储在中string

l  cJsON_Raw表示以JsON字符存储的零终止形式的任何JsON valuestring。例如,可以使用它来避免一遍又一遍地打印相同的静态JsON以节省性能。解析时,cJsON永远不会创建此类型。另请注意,cJsON不会检查其是否为有效JsON。

类型

#define cJsON_InvalID (0)#define cJsON_False  (1 << 0)#define cJsON_True   (1 << 1)#define cJsON_NulL   (1 << 2)#define cJsON_Number (1 << 3)#define cJsON_String (1 << 4)#define cJsON_Array  (1 << 5)#define cJsON_Object (1 << 6)#define cJsON_Raw    (1 << 7) /* raw Json */

类型判断

cJsON_IsInvalID(const cJsON * const item);cJsON_IsFalse( item);cJsON_IsTrue( item);cJsON_IsBool( item);cJsON_IsNull( item);cJsON_IsNumber( item);cJsON_Isstring( item);cJsON_IsArray( item);cJsON_IsObject( item);cJsON_IsRaw(const item);

注意

创建cJson对象后,处理完需要进行内存释放:

如果是cJson里的对象,请使用cJsON_Delete()

如果不是对象:cJsON_free()或free()

 

零字符

cJsON不支持包含零字符'\0'或的字符串\u0000。对于当前的API,这是不可能的,因为字符串以零结尾。

 

字符编码

cJsON仅支持UTF-8编码的输入。但是在大多数情况下,它不会拒绝无效的UTF-8作为输入,而只是将其原样传播。只要输入不包含无效的UTF-8,输出将始终是有效的UTF-8。

 

C标准

cJsON用ANSI C(或C89,C90)编写。如果您的编译器或C库未遵循此标准,则不能保证正确的行为。

 

注意:ANSI C不是C ++,因此不应使用C ++编译器进行编译。您可以使用C编译器对其进行编译,然后将其与C ++代码链接。尽管可以使用C ++编译器进行编译,但是不能保证正确的行为。

 

浮点数字

double除IEEE754双精度浮点数外,cJsON不正式支持任何实现。它可能仍然可以与其他实现一起使用,但是这些实现的错误将被视为无效。

 

目前,cJsON支持的浮点文字的最大长度为63个字符。

 

数组和对象的深层嵌套

cJsON不支持嵌套太深的数组和对象,因为这会导致堆栈溢出。为了防止这种CJsON_nesTING_liMIT情况,默认情况下,cJsON将深度限制为1000,但是可以在编译时进行更改。

格式化输出

按标准的格式输出Json字符串,输出完后一定要记得释放内存

 代码

 1 #include <stdio.h> 2 #include "cJsON.h" 3 #include cJsON.c 4 voID main(){ 5     //待解析字符串  6     char *Json_str={\"key1\":\"dongxiaodong\",\"key2\":1998,\"key3\":55778}"; 7      8     输出原字符串 9     printf(原字符串:%s\r\n,Json_str); 10 11     解析成Json对象 12     cJsON * Json_obj = cJsON_Parse(Json_str); 13 14     格式输出15     char *Json_print_str=NulL;16     Json_print_str=cJsON_Print(Json_obj);17     printf(\r\n输出内容:\r\n\r\n%s\r\n18     19     释放资源 20     free(Json_print_str);21     22     23     cJsON_Delete(Json_obj);24 }
Json打包

cJsON_CreateObject函数可创建一个根数据项,在此之后就可以添加各种数据类型的子节点了,使用完成后需要通过cJsON_Delete()释放内存。

创建一层级的Json

 代码:

 5     cJsON *root_obj = NulL;根,Json对象 char *out_str = NulL; 输出结果  7     root_obj =cJsON_CreateObject();创建  8      添加一个字符串,参数(根对象,键,值)  9     cJsON_AddStringToObject(root_obj,key1",1)">dongxiaodong);10     添加一个整型,参数(根对象,键,值) 11     cJsON_AddNumberToObject(root_obj,1)">key2199812     添加一个浮点型,参数(根对象,键,值) 13     cJsON_AddNumberToObject(root_obj,1)">key322.33添加一个bool类型,参数(根对象,键,值) bool值可以是0/1或false/true 16     cJsON_AddBoolToObject(root_obj,1)">key4017     将Json对象打包成字符串 18     out_str = cJsON_PrintUnformatted(root_obj);销毁Json对象,释放内存 20     cJsON_Delete(root_obj); 21     输出值:{"key1":"dongxiaodong","key2":1998,"key3":22.33,"key4":false} 22     printf(%s23 }

类型创建函数还有:

cJsON_AddNullToObject(cJsON * const object,const char * const name);

cJsON_AddTruetoObject(cJsON * const object,const char * const name);

cJsON_AddFalsetoObject(cJsON * const object,const char * const name);

cJsON_AddBoolToObject(cJsON * const object,const char * const name,const cJsON_bool boolean);

cJsON_AddNumberToObject(cJsON * const object,const double number);

cJsON_AddStringToObject(cJsON * const object,const char * const string);

cJsON_AddRawToObject(cJsON * const object,const char * const raw);

cJsON_AddobjectToObject(cJsON * const object,const char * const name);

cJsON_AddArrayToObject(cJsON * const object,const char * const name);

创建多层级的Json

 代码:

 6     cJsON *item_obj = NulL;二级Json对象  7      8      9     root_obj =cJsON_CreateObject();10      11     cJsON_AddStringToObject(root_obj,1)">14     创建一个子Json对象16     item_obj= cJsON_AddobjectToObject(root_obj,1)">myson); 向孩子对象中添加内容18     cJsON_AddStringToObject(item_obj,1)">sonkey1东小东19     cJsON_AddNumberToObject(item_obj,1)">sonkey2202020       22     out_str =23     24 25     26     printf(27 }

创建多层Json(数组形式)

 

 代码

数组对象 创建一个子数组对象 16     item_obj= cJsON_AddArrayToObject(root_obj,1)">向数组对象中添加内容18     cJsON_AddItemToArray(item_obj,cJsON_CreateTrue()); 19     cJsON_AddItemToArray(item_obj,cJsON_CreateNumber(22));27 }

创建的对象还可以是下面这些

cJsON_CreateNull(voID);

cJsON_CreateTrue(voID);

cJsON_CreateFalse(voID);

cJsON_CreateBool(cJsON_bool boolean);

cJsON_CreateNumber(double num);

cJsON_CreateString(const char *string);

cJsON_Createraw(const char *raw);

cJsON_CreateArray(voID);

cJsON_CreateObject(voID);

创建混合Json

 代码

 6     cJsON *son_obj=NulL;  7     cJsON *item_obj = NulL;输出结果  9     根对象 11     root_obj =cJsON_CreateObject();13     cJsON_AddStringToObject(root_obj,1)">15     cJsON_AddNumberToObject(root_obj,1)">16     18     item_obj= cJsON_AddArrayToObject(root_obj,1)">21     cJsON_AddItemToArray(item_obj,1)">22     子对象 24     son_obj =cJsON_CreateObject();26     cJsON_AddStringToObject(son_obj,1)">son127     28     cJsON_AddNumberToObject(son_obj,1)">son229 30     31     32     out_str =33     34 35     36     printf(37 }
Json解析

解析一层级的Json

 

代码:

 8     cJsON * Json_obj =项存储 11     cJsON *item=12     13     14     printf(15     16     获取string类型 17     item=cJsON_GetobjectItem(Json_obj,1)">);  18     printf(\r\nkey1:%s\r\nvaluestring);19     cJsON_Delete(item);释放资源 20      获取数字 22     item=cJsON_GetobjectItem(Json_obj,1)">23     printf(\r\nkey2:%d\r\nvalueint);24     cJsON_Delete(item);25     26     27     item=cJsON_GetobjectItem(Json_obj,1)">28     printf(\r\nkey3:%f\r\nvaluedouble);29     cJsON_Delete(item);获取bool 32     item=cJsON_GetobjectItem(Json_obj,1)">33     printf(\r\nkey4:%d\r\n34     cJsON_Delete(item);35     36     是否资源 37 38 }

解析多层级的Json

 

代码

内部项存储13     cJsON * item_item=16     printf(17     18     19     item=cJsON_GetobjectItem(Json_obj,1)">20     printf(21     cJsON_Delete(item);22      24     item=cJsON_GetobjectItem(Json_obj,1)">25     printf(26     cJsON_Delete(item);27     28     子串29     item=cJsON_GetobjectItem(Json_obj,1)">30     item_item=cJsON_GetobjectItem(item,1)">31     printf(\r\nmyson(sonkey1):%s\r\n32     cJsON_Delete(item_item);33     34     item_item=cJsON_GetobjectItem(item,1)">35     printf(\r\nmyson(sonkey2):%d\r\n36     cJsON_Delete(item_item);37     38     cJsON_Delete(item);39     40     41 42 }

 解析多层Json(数组形式)

 

 

代码

获取子串 输出数组大小 32     printf(\r\n数组大小:%d\r\n34     输出项1内容 35     item_item=cJsON_GetArrayItem(item,1)">\r\nmyson(0):%d\r\n37     cJsON_Delete(item_item);38     39     输出项2内容 40     item_item=cJsON_GetArrayItem(item,1)">141     printf(\r\nmyson(1):%d\r\n42     cJsON_Delete(item_item);43     44     cJsON_Delete(item);45     46     47 48 }

  解析混合Json

代码

44     项3内容45     item_item=cJsON_GetArrayItem(item,1)">246     cJsON *item_item_son=47     48     item_item_son =cJsON_GetobjectItem(item_item,1)">49     printf(\r\nmyson(2)(son1):%s\r\n50     cJsON_Delete(item_item_son);51     52     item_item_son =cJsON_GetobjectItem(item_item,1)">53     printf(\r\nmyson(2)(son2):%d\r\n54     cJsON_Delete(item_item_son);释放资源55     cJsON_Delete(item_item);释放资源   56     57     cJsON_Delete(item);58     59     60 61 }

 附件:

cJsON.h

  1 /*  2   copyright (c) 2009-2017 Dave Gamble and cJsON contributors  3   4   Permission is hereby granted,free of charge,to any person obtaining a copy  5   of this software and associated documentation files (the "Software"),to deal  6   in the Software without restriction,including without limitation the rights  7   to use,copy,modify,merge,publish,distribute,sublicense,and/or sell  8   copIEs of the Software,and to permit persons to whom the Software is  9   furnished to do so,subject to the following conditions: 10  11   The above copyright notice and this permission notice shall be included in 12   all copIEs or substantial portions of the Software. 13  14   THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR 15   IMPLIED,INCLUDING BUT NOT liMITED TO THE WARRANTIES OF MERCHANTABIliTY, 16   fitness FOR A PARTIculaR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17   AUTHORS OR copYRIGHT HolDERS BE liABLE FOR ANY CLaim,damAGES OR OTHER 18   liABIliTY,WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE,ARISING FROM,1)"> 19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEAliNGS IN 20   THE SOFTWARE. 21 */ 22  23 #ifndef cJsON__h 24 #define cJsON__h 25  26 #ifdef __cplusplus 27 extern C 28 { 29 #endif 30  31 #if !defined(__windows__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) 32 #define __windows__ 33  34  35 #ifdef __windows__ 36  37  When compiling for windows,we specify a specific calling convention to avoID issues where we are being called from a project with a different default calling convention.  For windows you have 3 define options: 38  39 CJsON_HIDE_SYMBolS - define this in the case where you don't want to ever dllexport symbols 40 CJsON_EXPORT_SYMBolS - define this on library build when you want to dllexport symbols (default) 41 CJsON_import_SYMBolS - define this if you want to dllimport symbol 42  43 For *nix builds that support visibility attribute,you can define similar behavior by 44  45 setting default visibility to hIDden by adding 46 -fvisibility=hIDden (for gcc) 47 or 48 -xldscope=hIDden (for sun cc) 49 to CFLAGS 50  51 then using the CJsON_API_VISIBIliTY flag to "export" the same symbols the way CJsON_EXPORT_SYMBolS does 52  53  54  55 #define CJsON_CDECL __cdecl 56 #define CJsON_STDCALL __stdcall 57  58  export symbols by default,this is necessary for copy pasting the C and header file  59 #if !defined(CJsON_HIDE_SYMBolS) && !defined(CJsON_import_SYMBolS) && !defined(CJsON_EXPORT_SYMBolS) 60 #define CJsON_EXPORT_SYMBolS 61  62  63 #if defined(CJsON_HIDE_SYMBolS) 64 #define CJsON_PUBliC(type)   type CJsON_STDCALL 65 #elif defined(CJsON_EXPORT_SYMBolS) 66 #define CJsON_PUBliC(type)   __declspec(dllexport) type CJsON_STDCALL 67 #elif defined(CJsON_import_SYMBolS) 68 #define CJsON_PUBliC(type)   __declspec(dllimport) type CJsON_STDCALL 69  70 #else /* !__windows__ */ 71 #define CJsON_CDECL 72 #define CJsON_STDCALL 73  74 #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJsON_API_VISIBIliTY) 75 #define CJsON_PUBliC(type)   __attribute__((visibility("default"))) type 76 #else 77 #define CJsON_PUBliC(type) type 78  79  80  81  project version  82 #define CJsON_VERSION_MAJOR 1 83 #define CJsON_VERSION_MInor 7 84 #define CJsON_VERSION_PATCH 13 85  86 #include <stddef.h> 87  88  cJsON Types:  89  90  91  92  93  94  95  96  97 #define cJsON_Raw    (1 << 7) /* raw Json */ 98  99 #define cJsON_IsReference 256100 #define cJsON_StringIsConst 512101 102 103 typedef  cJsON104 105      next/prev allow you to walk array/object chains. Alternatively,use GetArraySize/GetArrayItem/GetobjectItem 106     next;107     prev;108      An array or object item will have a child pointer pointing to a chain of the items in the array/object. 109     child;110 111      The type of the item,as above. 112      type;113 114      The item's string,if type==cJsON_String  and type == cJsON_Raw 115     valuestring;116      writing to valueint is DEPRECATED,use cJsON_SetNumberValue instead 117      valueint;118      The item's number,if type==cJsON_Number 119      valuedouble;120 121      The item's name string,if this item is the child of,or is in the List of subitems of an object. 122     123 } cJsON;124 125 typedef  cJsON_Hooks126 127        malloc/free are CDECL on windows regardless of the default calling convention of the compiler,so ensure the hooks allow passing those functions directly. 128       voID *(CJsON_CDECL *malloc_fn)(size_t sz);129       voID (CJsON_CDECL *free_fn)(voID *ptr);130 } cJsON_Hooks;131 132 typedef  cJsON_bool;133 134  limits how deeply nested arrays/objects can be before cJsON rejects to parse them.135  * This is to prevent stack overflows. 136 #ifndef CJsON_nesTING_liMIT137 #define CJsON_nesTING_liMIT 1000138 139 140  returns the version of cJsON as a string 141 CJsON_PUBliC(const char*) cJsON_Version(142 143  Supply malloc,realloc and free functions to cJsON 144 CJsON_PUBliC(voID) cJsON_InitHooks(cJsON_Hooks* hooks);145 146  Memory Management: the caller is always responsible to free the results from all variants of cJsON_Parse (with cJsON_Delete) and cJsON_Print (with stdlib free,cJsON_Hooks.free_fn,or cJsON_free as appropriate). The exception is cJsON_PrintPreallocated,where the caller has full responsibility of the buffer. 147  Supply a block of JsON,and this returns a cJsON object you can interrogate. 148 CJsON_PUBliC(cJsON *) cJsON_Parse(value);149 CJsON_PUBliC(cJsON *) cJsON_ParseWithLength(value,size_t buffer_length);150  ParseWithOpts allows you to require (and check) that the JsON is null terminated,and to retrIEve the pointer to the final byte parsed. 151  If you supply a ptr in return_parse_end and parsing fails,then return_parse_end will contain a pointer to the error so will match cJsON_GetErrorPtr(). 152 CJsON_PUBliC(cJsON *) cJsON_ParseWithOpts(char *value,char **return_parse_end,cJsON_bool require_null_terminated);153 CJsON_PUBliC(cJsON *) cJsON_ParseWithLengthOpts(154 155  Render a cJsON entity to text for transfer/storage. 156 CJsON_PUBliC(char *) cJsON_Print(const cJsON *item);157  Render a cJsON entity to text for transfer/storage without any formatting. 158 CJsON_PUBliC(char *) cJsON_PrintUnformatted(159  Render a cJsON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted,=1 gives formatted 160 CJsON_PUBliC(char *) cJsON_PrintBuffered(const cJsON *item,1)"> prebuffer,cJsON_bool fmt);161  Render a cJsON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. 162  NOTE: cJsON is not always 100% accurate in estimating how much memory it will use,so to be safe allocate 5 bytes more than you actually need 163 CJsON_PUBliC(cJsON_bool) cJsON_PrintPreallocated(cJsON *item,1)">char *buffer,1)">int length,1)"> cJsON_bool format);164  Delete a cJsON entity and all subentitIEs. 165 CJsON_PUBliC(voID) cJsON_Delete(cJsON *166 167  Returns the number of items in an array (or object). 168 CJsON_PUBliC(int) cJsON_GetArraySize(array);169  RetrIEve item number "index" from array "array". Returns NulL if unsuccessful. 170 CJsON_PUBliC(cJsON *) cJsON_GetArrayItem(const cJsON *array,1)"> index);171  Get item "string" from object. Case insensitive. 172 CJsON_PUBliC(cJsON *) cJsON_GetobjectItem(object,1)">char * 173 CJsON_PUBliC(cJsON *) cJsON_GetobjectItemCaseSensitive(174 CJsON_PUBliC(cJsON_bool) cJsON_HasObjectItem(175  For analysing Failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. defined when cJsON_Parse() returns 0. 0 when cJsON_Parse() succeeds. 176 CJsON_PUBliC(char *) cJsON_GetErrorPtr(177 178  Check item type and return its value 179 CJsON_PUBliC(char *) cJsON_GetStringValue(cJsON *180 CJsON_PUBliC(double) cJsON_GetNumberValue(cJsON *181 182  These functions check the type of an item 183 CJsON_PUBliC(cJsON_bool) cJsON_IsInvalID( item);184 CJsON_PUBliC(cJsON_bool) cJsON_IsFalse(185 CJsON_PUBliC(cJsON_bool) cJsON_IsTrue(186 CJsON_PUBliC(cJsON_bool) cJsON_IsBool(187 CJsON_PUBliC(cJsON_bool) cJsON_IsNull(188 CJsON_PUBliC(cJsON_bool) cJsON_IsNumber(189 CJsON_PUBliC(cJsON_bool) cJsON_Isstring(190 CJsON_PUBliC(cJsON_bool) cJsON_IsArray(191 CJsON_PUBliC(cJsON_bool) cJsON_IsObject(192 CJsON_PUBliC(cJsON_bool) cJsON_IsRaw(193 194  These calls create a cJsON item of the appropriate type. 195 CJsON_PUBliC(cJsON *) cJsON_CreateNull(196 CJsON_PUBliC(cJsON *) cJsON_CreateTrue(197 CJsON_PUBliC(cJsON *) cJsON_CreateFalse(198 CJsON_PUBliC(cJsON *) cJsON_CreateBool(cJsON_bool boolean);199 CJsON_PUBliC(cJsON *) cJsON_CreateNumber( num);200 CJsON_PUBliC(cJsON *) cJsON_CreateString(201  raw Json 202 CJsON_PUBliC(cJsON *) cJsON_Createraw(raw);203 CJsON_PUBliC(cJsON *) cJsON_CreateArray(204 CJsON_PUBliC(cJsON *) cJsON_CreateObject(205 206  Create a string where valuestring references a string so207  * it will not be freed by cJsON_Delete 208 CJsON_PUBliC(cJsON *) cJsON_CreateStringReference(209  Create an object/array that only references it's elements so210  * they will not be freed by cJsON_Delete 211 CJsON_PUBliC(cJsON *) cJsON_CreateObjectReference(child);212 CJsON_PUBliC(cJsON *) cJsON_CreateArrayReference(213 214  These utilitIEs create an Array of count items.215  * The parameter count cannot be greater than the number of elements in the number array,otherwise array access will be out of bounds.216 CJsON_PUBliC(cJsON *) cJsON_CreateIntArray(int *numbers,1)"> count);217 CJsON_PUBliC(cJsON *) cJsON_CreatefloatArray(float *numbers,1)">218 CJsON_PUBliC(cJsON *) cJsON_CreateDoubleArray(double *numbers,1)">219 CJsON_PUBliC(cJsON *) cJsON_CreateStringArray(const *strings,1)">220 221  Append item to the specifIEd array/object. 222 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToArray(cJsON *array,cJsON *223 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObject(cJsON *string,1)">224  Use this when string is definitely const (i.e. a literal,or as good as),and will definitely survive the cJsON object.225  * WARNING: When this function was used,make sure to always check that (item->type & cJsON_StringIsConst) is zero before226  * writing to `item->string` 227 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObjectCS(cJsON *228  Append reference to item to the specifIEd array/object. Use this when you want to add an existing cJsON to a new cJsON,but don't want to corrupt your existing cJsON. 229 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoArray(cJsON *array,1)">230 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoObject(cJsON *231 232  Remove/Detach items from Arrays/Objects. 233 CJsON_PUBliC(cJsON *) cJsON_DetachItemViaPointer(cJsON *parent,cJsON * 234 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromArray(cJsON *array,1)"> which);235 CJsON_PUBliC(voID) cJsON_DeleteItemFromArray(cJsON *array,1)">236 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObject(cJsON *237 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObjectCaseSensitive(cJsON *238 CJsON_PUBliC(voID) cJsON_DeleteItemFromObject(cJsON *239 CJsON_PUBliC(voID) cJsON_DeleteItemFromObjectCaseSensitive(cJsON *240 241  Update array items. 242 CJsON_PUBliC(cJsON_bool) cJsON_InsertItemInArray(cJsON *array,1)">int which,cJsON *newitem);  Shifts pre-existing items to the right. 243 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemViaPointer(cJsON * const parent,1)">const item,1)"> replacement);244 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInArray(cJsON *array,1)">newitem);245 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObject(cJsON *246 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObjectCaseSensitive(cJsON *247 248  Duplicate a cJsON item 249 CJsON_PUBliC(cJsON *) cJsON_Duplicate(item,cJsON_bool recurse);250  Duplicate will create a new,IDentical cJsON item to the one you pass,in new memory that will251  * need to be released. With recurse!=0,it will duplicate any children connected to the item.252  * The item->next and ->prev pointers are always zero on return from Duplicate. 253  Recursively compare two cJsON items for equality. If either a or b is NulL or invalID,they will be consIDered unequal.254  * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) 255 CJsON_PUBliC(cJsON_bool) cJsON_Compare(const a,1)">const b,1)"> cJsON_bool case_sensitive);256 257  Minify a strings,remove blank characters(such as ' ','\t','\r','\n') from strings.258  * The input pointer Json cannot point to a read-only address area,such as a string constant,1)">259  * but should point to a readable and writable adress area. 260 CJsON_PUBliC(voID) cJsON_Minify(Json);261 262  Helper functions for creating and adding items to an object at the same time.263  * They return the added item or NulL on failure. 264 CJsON_PUBliC(cJsON*) cJsON_AddNullToObject(cJsON *  name);265 CJsON_PUBliC(cJsON*) cJsON_AddTruetoObject(cJsON * 266 CJsON_PUBliC(cJsON*) cJsON_AddFalsetoObject(cJsON * 267 CJsON_PUBliC(cJsON*) cJsON_AddBoolToObject(cJsON * const name,1)"> cJsON_bool boolean);268 CJsON_PUBliC(cJsON*) cJsON_AddNumberToObject(cJsON *  number);269 CJsON_PUBliC(cJsON*) cJsON_AddStringToObject(cJsON * 270 CJsON_PUBliC(cJsON*) cJsON_AddRawToObject(cJsON *  raw);271 CJsON_PUBliC(cJsON*) cJsON_AddobjectToObject(cJsON * 272 CJsON_PUBliC(cJsON*) cJsON_AddArrayToObject(cJsON * 273 274  When assigning an integer value,it needs to be propagated to valuedouble too. 275 #define cJsON_SetIntValue(object,number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))276  helper for the cJsON_SetNumberValue macro 277 CJsON_PUBliC(double) cJsON_SetNumberHelper(cJsON *278 #define cJsON_SetNumberValue(object,number) ((object != NulL) ? cJsON_SetNumberHelper(object,(double)number) : (number))279  Change the valuestring of a cJsON_String object,only takes effect when type of object is cJsON_String 280 CJsON_PUBliC(char*) cJsON_SetValuestring(cJsON *281 282  Macro for iterating over an array or object 283 #define cJsON_ArrayForEach(element,array) for(element = (array != NulL) ? (array)->child : NulL; element != NulL; element = element->next)284 285  malloc/free objects using the malloc/free functions that have been set with cJsON_InitHooks 286 CJsON_PUBliC() cJsON_malloc(size_t size);287 CJsON_PUBliC(voID) cJsON_free(object288 289 290 }291 292 293 #endif
VIEw Code

cJsON.c

   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23  cJsON   24  JsON parser in C.   25   26  disable warnings about old C89 functions in MSVC   27 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)  28 #define _CRT_SECURE_NO_DEPRECATE  29   30   31 #ifdef __GNUC__  32 #pragma GCC visibility push(default)  33   34 #if defined(_MSC_VER)  35 #pragma warning (push)  36  disable warning about single line comments in system headers   37 #pragma warning (disable : 4001)  38   39   40 #include <string.h>  41 #include <stdio.h>  42 #include <math.h>  43 #include <stdlib.h>  44 #include <limits.h>  45 #include <ctype.h>  46 #include <float.h>  47   48 #ifdef ENABLE_LOCALES  49 #include <locale.h>  50   51   52   53 #pragma warning (pop)  54   55   56 #pragma GCC visibility pop  57   58   59 #include   60   61  define our own boolean type   62 #ifdef true  63 #undef true  64   65 #define true ((cJsON_bool)1)  66   67 #ifdef false  68 #undef false  69   70 #define false ((cJsON_bool)0)  71   72  define isnan and isinf for ANSI C,if in C99 or above,isnan and isinf has been defined in math.h   73 #ifndef isinf  74 #define isinf(d) (isnan((d - d)) && !isnan(d))  75   76 #ifndef isnan  77 #define isnan(d) (d != d)  78   79   80 #ifndef NAN  81 #define NAN 0.0/0.0  82   83   84 typedef  {  85     const unsigned Json;  86     size_t position;  87 } error;  88 static error global_error = { NulL,1)"> };  89   90 CJsON_PUBliC()  91   92     return (char*) (global_error.Json + global_error.position);  93   94   95 CJsON_PUBliC(item)   96   97     if (!cJsON_Isstring(item))   98     {  99         return NulL; 100     } 101  102     return item-> 103  104  105 CJsON_PUBliC( 106  107     cJsON_IsNumber(item))  108  109          NAN; 110  111  112     valuedouble; 113  114  115  This is a safeguard to prevent copy-pasters from using incompatible C and header files  116 #if (CJsON_VERSION_MAJOR != 1) || (CJsON_VERSION_MInor != 7) || (CJsON_VERSION_PATCH != 13) 117     #error cJsON.h and cJsON.c have different versions. Make sure that both have the same. 118  119  120 CJsON_PUBliC( 121  122     static char version[15]; 123     sprintf(version,1)">%i.%i.%i 124  125      version; 126  127  128  Case insensitive string comparison,doesn't consIDer two NulL pointers equal though  129 int case_insensitive_strcmp(char *string1,1)">string2) 130  131     if ((string1 == NulL) || (string2 == NulL)) 132  133         return  134  135  136     if (string1 == string2) 137  138          139  140  141     for(; tolower(*string1) == tolower(*string2); (voID)string1++,string2++ 142  143         if (*string1 == '' 144        {  145 146                     }  147 148  149 return     string2); tolower(*string1) - tolower(* 150 151  152  internal_hooks typedef  153 154 allocate)(size_t size);      155voID     pointer); (CJsON_CDECL *deallocate)( 156voID     pointer,size_t size); *(CJsON_CDECL *reallocate)( 157} internal_hooks;  158 159  160  work around MSVC error C2322: '...' address of dllimport '...' is not static   161 CJsON_CDECL internal_malloc(size_t size)  162 163 return     malloc (size); 164 165 voID pointer) CJsON_CDECL internal_free( 166 167 (pointer);      168 169 voID  170 * CJsON_CDECL internal_realloc( 171 realloc     (pointer,size); 172 173  174 #define  175 internal_malloc malloc#define  176 internal_free free#define  177 internal_realloc realloc 178  179  strlen of character literals resolved at compile time   180#define  181 static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) 182 static  { internal_malloc,internal_free,internal_realloc }; internal_hooks global_hooks = 183 184 static char unsigned char* cJsON_strdup(const*  hooks) internal_hooks *  185 186  187     size_t length = char     unsigned  188 *copy = 189 if     string ( NulL) == 190 191  192          193  194 char     length = strlen((string*)sizeof) + ""( 195char     copy = (unsigned allocate(length);*)hooks-> 196if      197 (copy == 198  199          200  201     memcpy(copy,length); 202  copy;      203 204  205  206 CJsON_PUBliC( 207 if      208 (hooks == 209  reset hooks           210 211         global_hooks.allocate =  212         global_hooks.deallocate =  213         global_hooks.reallocate =  214          215  216  217     global_hooks.allocate = if      218 (hooks->malloc_fn != 219 malloc_fn;         global_hooks.allocate = hooks-> 220 221  222  223     global_hooks.deallocate = if      224 (hooks->free_fn != 225 free_fn;         global_hooks.deallocate = hooks-> 226 227  228  use realloc only if both free and malloc are used       229 230     global_hooks.reallocate =if     malloc ((global_hooks.allocate == ))) && (global_hooks.deallocate ==  231 232  233         global_hooks.reallocate =  234  235  236  Internal constructor.   237static  238 cJsON *cJsON_New_Item( 239 sizeof     cJsON* node = (cJsON*)hooks->allocate((cJsON)); 240if      (node) 241 242  244         memset(node,1)">',1)"> 243  245  node;      246 247  248  Delete a cJsON structure.   249item) CJsON_PUBliC( 250 251  252     cJsON *next =while      253 (item != 254  255         next = item->if          256 (!(item->type & cJsON_IsReference) && (item->child != 257  258             cJsON_Delete(item-> 259 if          260 (!(item->type & cJsON_IsReference) && (item->valuestring != 261  262             global_hooks.deallocate(item-> 263 if         string (!(item->type & cJsON_StringIsConst) && (item-> 264 != 265  266             global_hooks.deallocate(item-> 267         global_hooks.deallocate(item);  268 next;         item = 269 270  271  272  get the decimal point character of the current locale   273char  274 get_decimal_point( 275  276 struct      localeconv(); lconv *lconv = 277return     char (unsigned  278) lconv->decimal_point[ 279 .      280 281  282  283 struct typedef  284 285 content;      286    size_t length;  287    size_t offset;  288 How deeply nested (in arrays/objects) is the input at the current offset.      size_t depth;  289    internal_hooks hooks;  290} parse_buffer;  291 292  check if the given size is left to read in a given parse buffer (starting with 1)   293#define  294 can_read(buffer,size) ((buffer != NulL) && (((buffer)->offset + size) <= (buffer)->length)) check if the buffer can be accessed at the given index (starting with 0)   295#define  296 can_access_at_index(buffer,index) ((buffer != NulL) && (((buffer)->offset + index) < (buffer)->length))#define  297 cannot_access_at_index(buffer,index) (!can_access_at_index(buffer,index)) get a pointer to the buffer at the position   298#define  299 buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) 300  Parse the input text to generate a number,and populate the result into item.   301static  input_buffer) cJsON_bool parse_number(cJsON *  302 303 double      304 number = char     unsigned  305 *after_end =char     unsigned 64 number_c_string[ 306char     unsigned  get_decimal_point(); decimal_point = 307 308     size_t i =  309 if      310 ((input_buffer == NulL) || (input_buffer->content == 311 false          312 313  314  copy the number into a temporary buffer and replace '.' with the decimal point      315     * of the current locale (for strtod)  316     * This also takes care of ' 317' not necessarily being available for marking the end of the input  for0     sizeof (i = 1; (i < ( 318(number_c_string) -  319)) && can_access_at_index(input_buffer,i); i++switch  (buffer_at_offset(input_buffer)[i])          320 321case 0             :  3221 323             2 324             3 325             4 326             5 327             6 328             7 329             8 330             9 331             + 332             - 333             e 334             E 335              buffer_at_offset(input_buffer)[i]; 336                 number_c_string[i] =break 337                  338 339  decimal_point;              340                 number_c_string[i] = 341 342                 default  343             goto loop_end;                  344 345 346 loop_end:  347  348 349     number_c_string[i] = char char     number = strtod((after_end);*)number_c_string,( 350**)&if after_end)      351 (number_c_string == 352false  parse_error           353;  354 355  number;  356     item->valuedouble = 357 use saturation in case of overflow   358     if INT_MAX)      359 (number >= 360 INT_MAX;  361         item->valueint = 362else if     )INT_MIN)  363 (number <= ( 364 INT_MIN;  365         item->valueint = 366else  367      368)number;  369         item->valueint = ( 370 371  cJsON_Number;  372     item->type = 373 number_c_string);  374     input_buffer->offset += (size_t)(after_end -true 375      376 377  don't ask me,but the original cJsON_SetNumberValue returns an integer or double   378  number) 379 CJsON_PUBliC( 380 381  382     object  383          384->valueint = 385  386      387  388          389  390     object  391          392->valueint = ( 393 object  394      395->valuedouble = 396 valuestring)  397 CJsON_PUBliC( 398 399  if object's type is not cJsON_String or is cJsON_IsReference,it should not set valuestring       400     ifobject     object (!( cJsON_IsReference))->type & cJsON_String) || ( 401->type & 402 403  404         if object     valuestring)) (strlen(valuestring) <= strlen( 405-> 406valuestring,valuestring);  407         strcpy( 408 409         char char     copy = (global_hooks);*) cJsON_strdup(( 410*)valuestring,& 411 412      413  414         object  415      416->valuestring != 417  418         cJsON_free(object  419      420->valuestring = 421  422      423  424  425 typedef buffer;  426     unsigned  427 428  current nesting depth (for formatted printing)   429     size_t depth;     cJsON_bool noalloc; 430  is this print a formatted print  431     cJsON_bool format;  432} printbuffer;  433  434 realloc printbuffer if necessary to have at least "needed" bytes more   435 char p,size_t needed)  436* ensure(printbuffer *  437char  438     unsigned  439 *newbuffer = 440     size_t newsize = if  441      442 ((p == NulL) || (p->buffer == 443  444          445 if 0     length)) ((p->length >  446) && (p->offset >= p-> 447 make sure that offset is valID   448          449 450          451 if  452      453 (needed > sizes bigger than INT_MAX are currently not supported   454          455 456          457  458 if     needed += p->offset + length)      459 (needed <= p-> 460return offset;          461 p->buffer + p-> 462 463 if noalloc) {      464 (p-> 465 466          467  calculate new buffer size   468     if 469      470 (needed > (INT_MAX /  overflow of int,use INT_MAX if possible   471         if 472          473 (needed <= 474  475             newsize = 476  477          478  479              480  481  482      483  484         newsize = needed *  485 if  486      487 (p->hooks.reallocate != reallocate with realloc if available   488         charbuffer,newsize);         newbuffer = (unsigned  489*)p->hooks.reallocate(p->if 490          491 (newbuffer ==buffer);  492             p->hooks.deallocate(p-> 493 494             p->length =  495             p->buffer = 496  497              498  499  500      otherwise reallocate manually   501         charhooks.allocate(newsize);         newbuffer = (unsigned  502*)p->newbuffer) 503          504 505  506             p->hooks.deallocate(p-> 507             p->length =  508             p->buffer = 509  510              (newbuffer)  511          512 513  514             memcpy(newbuffer,p->buffer,p->offset +  515  516         p->hooks.deallocate(p-> newsize;  517     p->length = newbuffer; 518     p->buffer = 519return  520      521 newbuffer + p-> 522  calculate the new length of the string in a printbuffer and update the offset   523 voID buffer)  524 update_offset(printbuffer *  525char  526     if *buffer_pointer = 527      528 ((buffer == NulL) || (buffer->buffer == 529  530          531  532     buffer_pointer = buffer->buffer + buffer->char )buffer_pointer);     buffer->offset += strlen(( 533* 534 535  securely comparison of floating-point variables   536 staticdouble  537 cJsON_bool compare_double( 538 a,1)"> b)double  fabs(a) : fabs(b);      539 maxVal = fabs(a) > fabs(b) ?return DBL_EPSILON);      540 (fabs(a - b) <= maxVal * 541 542  Render the number nicely from the given item into a string.   543 static output_buffer)  544 cJsON_bool print_number( 545char  546     unsigned double *output_pointer = 547     int d = item-> 548      549 length = char     size_t i = 26     unsigned 0 number_buffer[ temporary buffer to print the number into ] = { 550};  551double     unsigned 0.0      552 test =  553if  554      555 (output_buffer == 556  557          558  This checks for NaN and Infinity   559     if isinf(d))      560 (isnan(d) || 561char  562         length = sprintf(( 563*)number_buffer,1)">null 564  565      Try 15 decimal places of precision to avoID nonsignificant nonzero digits   566         %1.15g 567         length = sprintf(( 568 Check whether the original double can be recovered   569         if%lg         1 ((sscanf(()test,d)) 570) || !compare_double(( 571 If not,print with 17 decimal places of precision   572             %1.17g 573             length = sprintf(( 574 575  576  sprintf Failed or buffer overrun occurred   577     if0     int ((length < sizeof) || (length > ())))( 578(number_buffer) -  579 580  581          582  reserve appropriate space in the output   583      584if     output_pointer = ensure(output_buffer,(size_t)length +  585      586 (output_pointer == 587  588          589  copy the printed number to the output and replace locale  590          * dependent decimal point with '.'  591 0 592      593; i < ((size_t)length); i++if  decimal_point)          594 (number_buffer[i] == 595 596 continue             output_pointer[i] =  597              598 599  number_buffer[i];  600         output_pointer[i] = 601 602  603     output_pointer[i] =  (size_t)length;  604     output_buffer->offset += 605 606  607      608  parse 4 digit hexadecimal number   609 static input)  610 unsigned parse_hex4( 611int  612     unsigned  613 h =  614     size_t i = 0 4      615; i <  616; i++ parse digit   617         if'          618 ((input[i] >=  619) && (input[i] <= int  620             h += (unsigned  621) input[i] - A F          622 623int 10             h += (unsigned  624)  625 + input[i] - a f          626 627 628  629             h += (unsigned  invalID   630          631 632  633              634 if 3          635 (i <  636 shift left to make place for the next nibble   637             4 638             h = h <<  639 640  641  h;  642      643 644  converts a UTF-16 literal to UTF-8  645  * A literal can be one or two sequences of the form \uXXXX  646 charconst output_pointer) utf16_literal_to_utf8( 647 input_pointer,1)">const input_end,unsigned  648long int      649 unsigned int codepoint =  650     unsigned char first_code =  input_pointer;      651 *first_sequence =char 652     unsigned char utf8_length =  653     unsigned char utf8_position =  654     unsigned char sequence_length =  655     unsigned  656 first_byte_mark = if 6      657 ((input_end - first_sequence) <  658 input ends unexpectedly   659          fail; 660          661 662  get the first utf16 sequence   663      664 665     first_code = parse_hex4(first_sequence +  check that the code is valID   666     if0xDC00     0xDFFF (((first_code >=  667) && (first_code <=  668 669  670          671  UTF16 surrogate pair   672     if0xD800     0xDBFF ((first_code >=  673) && (first_code <=  674char  675         int *second_sequence = first_sequence +  676         unsigned 12 second_code =  \uXXXX\uXXXX          sequence_length =  677;  678if  679          680 ((input_end - second_sequence) <  681  682              683              684 if 0         \ ((second_sequence['] != 1u) || (second_sequence[ 685] !=  686 missing second half of the surrogate pair   687              688 689              690  get the second utf16 sequence   691          692 693         second_code = parse_hex4(second_sequence + if         0xDC00          694 ((second_code <  695) || (second_code >  invalID second half of the surrogate pair   696              697 698              699  700  calculate the unicode codepoint from the surrogate pair   701         0x100000x3FF         codepoint = 10 + (((first_code & 0x3FF) <<  702) | (second_code &  703 704  705     6  \uXXXX          sequence_length =  706;  first_code; 707         codepoint = 708 709  encode as UTF-8  710          * takes at maximum 4 bytes to encode: 711      * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  712 if0x80      713 (codepoint <  714 normal ascii,enCoding 0xxxxxxx   715          716 717         utf8_length = 0x800  718      719 two bytes,enCoding 110xxxxx 10xxxxxx   720          7210xC0         utf8_length =  11000000          first_byte_mark =  722;  7230x10000  724      725 three bytes,enCoding 1110xxxx 10xxxxxx 10xxxxxx   726          7270xE0         utf8_length =  11100000          first_byte_mark =  728;  729if 0x10FFFF      730 (codepoint <=  731 four bytes,enCoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx   732          7330xF0         utf8_length =  11110000          first_byte_mark =  734;  735 736  737      invalID unicode codepoint   738          739 740          741  encode as utf8   742     forchar     1 (utf8_position = (unsigned 0)(utf8_length -  743); utf8_position >  744; utf8_position-- 10xxxxxx   745         char0x80         (*output_pointer)[utf8_position] = (unsigned 0xBF)((codepoint |  746) &  747 748         codepoint >>=  encode first byte   749     if 750      751 (utf8_length > 0 char         (*output_pointer)[0xFF] = (unsigned  752)((codepoint | first_byte_mark) &  753 754  755     char 0x7F         (*output_pointer)[ 756)(codepoint &  757 758  utf8_length;  759     *output_pointer += 760 sequence_length;  761      762fail:  763  764 765      766  Parse the input text into an unescaped cinput,and populate item.   767 static 768  769 cJsON_bool parse_string(cJsON * char  770     char *input_pointer = buffer_at_offset(input_buffer) +  771      772 *input_end = buffer_at_offset(input_buffer) + char     unsigned  773     unsigned  774 *output = not a string   775     if\"      776 (buffer_at_offset(input_buffer)[ 777 778  779          780  781  calculate approximate size of the output (overestimate)   782          783 784         size_t allocation_length = while         size_t skipped_bytes =  785          786 (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end !=  is escape sequence   787             if0              788 (input_end[            {] ==  789 if1                  790 ((size_t)(input_end +                 { - input_buffer->content) >= input_buffer-> 791  prevent buffer overflow when last input character is a backslash  792                      793                }                      794  795 796                 skipped_bytes++            }                 input_end++ 797  798 799             input_end++if  800          801 (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != goto  string ended unexpectedly               802 fail;  803 804  This is at most how much we need for the output   805          skipped_bytes; 806         allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) -char 807         output = (unsigned if*)input_buffer->hooks.allocate(allocation_length +  808          809 (output == allocation failure   810              811 812  813  output;  814     output_pointer = loop through the string literal  815     while input_end)      816 (input_pointer < 817if  818          819 (*input_pointer !=  820  821             *output_pointer++ = *input_pointer++ escape sequence   822          823 824          825 if             unsigned  826              827 ((input_end - input_pointer) <  828  829                  830 switch ])              831 (input_pointer[ 832b  833                 \b 834                     *output_pointer++ =  835 836                     \f                  837                     *output_pointer++ =  838n                      839                 \n 840                     *output_pointer++ =  841r                      842                 \r 843                     *output_pointer++ =  844t                      845                 \t 846                     *output_pointer++ =  847 848                      849                 /                  850                  851 852                     *output_pointer++ = input_pointer[ 853                      UTF-16 literal   854                  855 856                 if                     sequence_length = utf16_literal_to_utf8(input_pointer,input_end,1)">output_pointer); 857                                         { (sequence_length ==  858  Failed to convert UTF16-literal to UTF-8  859                          860                    }                          861  862 863                      864  865                  866                      867  868             input_pointer += 869  870  zero terminate the output   871      872 873     *output_pointer =  cJsON_String;  874     item->type =)output; 875     item->valuestring = ( 876content);  877     input_buffer->offset = (size_t) (input_end - input_buffer-> 878 879     input_buffer->offset++ 880  881      882 if  883      884 (output !=hooks.deallocate(output);  885         input_buffer-> 886 887 if  888      889 (input_pointer != 890  891         input_buffer->offset = (size_t)(input_pointer - input_buffer-> 892  893  894      895  Render the cstring provIDed to an escaped version that can be printed.   896 staticconst  898 cJsON_bool print_string_ptr(char input,1)"> 897  899      900 *input_pointer = 901     unsigned  902     unsigned  numbers of additional characters needed for escaPing      size_t output_length =  903      904 905     size_t escape_characters =  906  907      908  909          910  empty string   911     if 912      913 (input == 914  915         output = ensure(output_buffer,1)">\"\" 916          917  918             char  920         strcpy(( 921*)output,1)"> 919  922          923  set "flag" to 1 if something needs to be escaped   924     for 925      926 (input_pointer = input; *input_pointer; input_pointer++switch input_pointer)          927 (* 928 929  930              931              932              933              934              935              one character escape sequence               936                  937 938                 escape_characters++ 939                 if             32                  940 (*input_pointer <  941 UTF-16 escape sequence uXXXX   942                     5 943                     escape_characters +=  944 945  946                  947  escape_characters;  948     output_length = (size_t)(input_pointer - input) + 949 950  951     output = ensure(output_buffer,output_length +  952      953  954          955  no characters have to be escaped   956     if 957      958 (escape_characters == 0  959         output[ 960] = 1         memcpy(output +  961         output[output_length + 2] =  962         output[output_length +  963] =  964  965          966  967  968     output[ copy the string      output_pointer = output +  969     for'     voID (input_pointer = input; *input_pointer !=  970; ( 971)input_pointer++,output_pointer++if 31         ' ((*input_pointer >  972) && (*input_pointer !=  973) && (*input_pointer !=  normal character,copy   974             input_pointer; 975             *output_pointer = * 976 977  978          character needs to be escaped   979              980 981             *output_pointer++ =  982              983  984                  985                     *output_pointer =  986                      987                  988                     *output_pointer =  989                      990                  991                     *output_pointer =  992                      993                  994                     *output_pointer =  995                      996                  997                     *output_pointer =  998                      999                 1000                     *output_pointer = 1001                     1002                 1003                     *output_pointer = 1004                      escape and print as unicode codepoint                  1005                     charinput_pointer);                     sprintf((1006*)output_pointer,1)">u%04x10071008                     output_pointer += 1009                     1010 1011 1012 1013     output[output_length + 1014     output[output_length + 1015 1016     1017  Invoke print_string_ptr (which is useful) on an item.  1018 static p) 1019 cJsON_bool print_string(1020return char     1021 print_string_ptr((unsigned 1022*)item->1023  Predeclare these prototypes.  1024 static input_buffer); 1025 cJsON_bool parse_value(cJsON * static output_buffer); 1026 cJsON_bool print_value(static1027 static cJsON_bool parse_array(cJsON * 1028 static cJsON_bool print_array(1029 static cJsON_bool parse_object(cJsON * 1030 1031 cJsON_bool print_object( Utility to jump whitespace and cr/lf  1032 static1033 1034 parse_buffer *buffer_skip_whitespace(parse_buffer * if 1035     1036 ((buffer == NulL) || (buffer->content ==1037 1038         1039 if 1041      buffer; (cannot_access_at_index(buffer,1)">1040 1042         10431044 while 0     1045 (can_access_at_index(buffer,1)">0) && (buffer_at_offset(buffer)[1046] <= 1047 1048        buffer->offset++1049 if 1050     1051 (buffer->offset == buffer->1052 1053         buffer->offset--1054 1055 1056     1057  skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer  1058 static1059 1060 parse_buffer *skip_utf8_bom(parse_buffer * if 1061     1062 ((buffer == NulL) || (buffer->content == NulL) || (buffer->offset != 1063 1064         1065 if char     3 (can_access_at_index(buffer,1)">4) && (strncmp((1066*)buffer_at_offset(buffer),1)">\xEF\xBB\xBF1067) == 1068 1069         buffer->offset += 1070 1071 1072     1073 1074 1075 CJsON_PUBliC(cJsON *) cJsON_ParseWithOpts(    size_t buffer_length; 1076 1077if  value)     1078 (NulL ==10791080 1081         1082  Adding null character size due to require_null_terminated.  1083     10841085     buffer_length = strlen(value) +  cJsON_ParseWithLengthOpts(value,buffer_length,return_parse_end,require_null_terminated); 1086     10871088  Parse an object - create a new root,and populate.  1089 10901091 CJsON_PUBliC(cJsON *) cJsON_ParseWithLengthOpts(0  } };     parse_buffer buffer = { 1092,{ 10931094     cJsON *item = reset error position  1095     10961097     global_error.Json =1098     global_error.position = if 0      buffer_length) (value == NulL || 1099 ==11001101 1102         1103 )value; 1104     buffer.content = ( buffer_length; 1105     buffer.length =1106 global_hooks;     buffer.offset = 1107     buffer.hooks =11081109 if     item = cJsON_New_Item(& memory fail      1110 (item == NulL) 11111112 1113         1114 if buffer))))     1115 (!parse_value(item,buffer_skip_whitespace(skip_utf8_bom(&1116 parse failure. ep is set.  1117         11181119         1120  if we require null-terminated JsON without appended garbage,skip and then check for a null terminator  1121      (require_null_terminated)1122     11231124 if         buffer_skip_whitespace(&1125         1126 ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[1127 1128             1129  (return_parse_end) 1130     1131char 1132         *return_parse_end = (1133*)buffer_at_offset(&1134  item; 1135     11361137 if 1138     1139 (item !=        cJsON_Delete(item); 1140 11411142 if 1143     1144 (value !=        error local_error; 1145 11461147         local_error.Json = (1148         local_error.position = if  buffer.length)         1149 (buffer.offset <1150 buffer.offset; 1151             local_error.position =1152if 1153         1154 (buffer.length > 1155 1156             local_error.position = buffer.length - 1157 if 1158         1159 (return_parse_end !=char  local_error.position;             *return_parse_end = (1160*)local_error.Json +11611162  local_error; 1163         global_error =11641165 1166 1167     1168  Default options for cJsON_Parse  1169 value)1170 CJsON_PUBliC(cJsON *) cJsON_Parse(1171return 1173     1174 cJsON_ParseWithOpts(value,1)">1172 1175 1176 CJsON_PUBliC(cJsON *) cJsON_ParseWithLength(return 1178     1179 cJsON_ParseWithLengthOpts(value,1)">1177 #define 1180 1181 cJson_min(a,b) (((a) < (b)) ? (a) : (b))char 1182 1183 *print(const 256     1184 size_t default_buffer_size = 1185char     printbuffer buffer[1186     unsigned 1187 *printed =1188 1189     memset(buffer,1)">(buffer)); create buffer  1190     charallocate(default_buffer_size);     buffer->buffer = (unsigned 1191*) hooks-> default_buffer_size;1192     buffer->length = format;1193     buffer->format =hooks;1194     buffer->hooks = *if1195     1196 (buffer->buffer ==1197 1198         1199  print the value  1200     print_value(item,buffer))1201     12021203 1204             update_offset(buffer); 1205 1206 check if reallocate is available  1207     if1208     1209 (hooks->reallocate !=char 1210         printed = (unsigned if*) hooks->reallocate(buffer->buffer,buffer->offset +  NulL) {         1211 (printed ==12121213             1214 1215         buffer->buffer = otherwise copy the JsON over to a new buffer  1216     1217char 1218         printed = (unsigned 1219*) hooks->allocate(buffer->offset + 1220         1221 1222             '  just to be sure          memcpy(printed,buffer->buffer,cJson_min(buffer->length,1)">1223         printed[buffer->offset] = 1224; 1225 free the buffer  1226         12271228         hooks->deallocate(buffer->1229  printed; 1230     12311232 if 1233     1234 (buffer->buffer !=1235 1236         hooks->deallocate(buffer->1237 if 1238     1239 (printed !=deallocate(printed); 1240         hooks->12411242 1243 1244     1245  Render a cJsON item/entity/structure to text.  1246 12471248 CJsON_PUBliC(char 1250     1251*)print(item,1)">true,1)">1249 1252 1253 CJsON_PUBliC(false 1255     1256,1)">1254 1257 1258 CJsON_PUBliC(1259 1260     printbuffer p = { if 1261     1262 (prebuffer < 1263 1264         1265 )global_hooks.allocate((size_t)prebuffer); 1266     p.buffer = (unsigned p.buffer)1267     12681269 1270         1271  (size_t)prebuffer; 1272     p.length =12731274     p.offset =  fmt;     p.noalloc = 1275     p.format =12761277     p.hooks =if 1278     1279 (!print_value(item,1)">p))        global_hooks.deallocate(p.buffer); 1280 12811282         1283 )p.buffer; 1284     12851286 1287 1288 CJsON_PUBliC(cJsON_bool) cJsON_PrintPreallocated(cJsON *item,1)"> cJsON_bool format)1289 1290     printbuffer p = { 0 1291     1292) || (buffer ==1293 1294         1295 )buffer; 1296     p.buffer = (unsigned 12971298     p.length =1299     p.offset = 1300     p.noalloc = 1301     p.format =1302     p.hooks =return 1303     1304 print_value(item,1)">p);1305  Parser core - when encountering text,process appropriately.  1306 13071308 1309 1310      no input  1311         13121313  parse the different types of values  1314      null 1315     if1316     1317 (can_read(input_buffer,1)">char*)buffer_at_offset(input_buffer),1)">4) ==  cJsON_NulL; 1318         item->type =13191320         input_buffer->offset += 1321          false  1322     5false     5) && (strncmp((13231324) ==  cJsON_False; 1325         item->type =13261327         input_buffer->offset += 1328          true  1329     true1330     1331 cJsON_True; 1332         item->type =13331334         item->valueint = 1335         input_buffer->offset += 1336          string  1337     if1338     1339 (can_access_at_index(input_buffer,1)">0) && (buffer_at_offset(input_buffer)[ parse_string(item,input_buffer); 1340         1341 number  1342     0'     0) && ((buffer_at_offset(input_buffer)[') || ((buffer_at_offset(input_buffer)[))))] >= 1343) && (buffer_at_offset(input_buffer)[13441346  array           parse_number(item,1)">1345 1347     [1348     13491351  object           parse_array(item,1)">1350 1352     {1353     13541356 1357          parse_object(item,1)">1355 1358 1359     1360  Render a value to text.  1361 13621363 1364 1365     unsigned if 1366     1367 ((item == NulL) || (output_buffer ==1368 1369         1370 switch 1371     1372 ((item->type) & case  cJsON_NulL:         137313751376             output = ensure(output_buffer,1)">1374             1377 1378                 1379 1380             strcpy((1381              cJsON_False: 1382         13841385             output = ensure(output_buffer,1)">1383             1386 1387                 1388 1389             strcpy((1390              cJsON_True: 1391         13931394             output = ensure(output_buffer,1)">1392             1395 1396                 1397 1398             strcpy((1399              cJsON_Number: 1400          print_number(item,output_buffer);1401             1402 cJsON_Raw: 1403         14041405 if             size_t raw_length = 1406             1407 (item->valuestring ==1408 1409                 1410 1411  ensure(output_buffer,raw_length);             raw_length = strlen(item->valuestring) + 1412             output =14131414             1415 1416                 1418 1419             memcpy(output,1)">1417             1420  cJsON_String: 1421         1423 cJsON_Array:              print_string(item,1)">1422 1424         1426 cJsON_Object:              print_array(item,1)">1425 1427         14291430              print_object(item,1)">1428 1431         1432             1433 1434  Build an array from input text.  1435 14361437  head of the linked List  1438     cJsON *head = NulL; 14391440     cJsON *current_item =if  CJsON_nesTING_liMIT)     1441 (input_buffer->depth >=1442 to deeply nested  1443         14441445 1446     input_buffer->depth++1447 1448      not an array  1449         14501451         1452 1453     buffer_skip_whitespace(input_buffer);     input_buffer->offset++1454 ]1455     1456 empty array  1457          success;1458         14591460  check if we skipped to the end of the buffer  1461     if1463     1464 (cannot_access_at_index(input_buffer,1)">1462 1465         input_buffer->offset--1466         1467  step back to character in front of the first element  1468     1469 loop through the comma separated array elements      input_buffer->offset--1470     do1471     1472 allocate next item  1473         hooks));1474         cJsON *new_item = cJsON_New_Item(&(input_buffer->if1475         1476 (new_item ==1477 1478             1479  attach next item to List  1480         if1481         1482 (head == start the linked List  1483              new_item;1484             current_item = head =14851486 1487          add to the end and advance  1488             1489 current_item;             current_item->next =1490             new_item->prev =14911492             current_item =1493  parse next value  1494         1495        buffer_skip_whitespace(input_buffer);         input_buffer->offset++1496 parse_value(current_item,input_buffer))1497         1498 Failed to parse value  1499             15001501 1502 while 1503     1504 (can_access_at_index(input_buffer,0 1505     1506) || buffer_at_offset(input_buffer)[ expected end of array  1507         15081509 success: 1510 15111512     input_buffer->depth-- cJsON_Array; 1513     item->type = head;1514     item->child =15151516 1517     input_buffer->offset++1518 1519     1520 if 1521     1522 (head !=        cJsON_Delete(head); 1523 15241525 1526 1527     1528  Render an array to text  1529 15301531 1532 1533     unsigned 1534     size_t length = 1535     cJsON *current_element = item->1536 1537     1538 1539         1540  Compose the output array.  1541      opening square bracket 1542     15441545     output_pointer = ensure(output_buffer,1)">1543     1546 1547         1548 1549 1550     *output_pointer = 1551     output_buffer->offset++1552     output_buffer->depth++while 1553     1554 (current_element !=print_value(current_element,output_buffer)) 1555         15561557 1558                     update_offset(output_buffer); 1559 ifnext)         1560 (current_element->15612 1562             length = (size_t) (output_buffer->format ? 1563 : 1564             output_pointer = ensure(output_buffer,length + 1565             1566 1567                 1568 if             *output_pointer++ = format)             1569(output_buffer->1570' 1571                 *output_pointer++ = 1572 1573  length;             *output_pointer = 1574             output_buffer->offset +=15751576 1577         current_element = current_element->1578 1580 1581     output_pointer = ensure(output_buffer,1)">1579     1582 1583         1584 1585     *output_pointer++ = 1586     *output_pointer = 1587     output_buffer->depth--1588 1589     1590  Build an object from the text.  1591 15921593  linked List head  1594     cJsON *head = NulL; 15951596     cJsON *current_item =1597 1598     1599 1600         1601 1602     input_buffer->depth++0 1603     1604) || (buffer_at_offset(input_buffer)[ not an object  1605         16061607 1608 1609     input_buffer->offset++} 1610     1611goto  empty object          1612 success; 16131614 1615 1616     1617     1618 1619         input_buffer->offset--1620         1621 1622 1623     1624     input_buffer->offset--1625     1626     1627 1628         1629         cJsON *new_item = cJsON_New_Item(&(input_buffer->1630         1631 1632             1633 1634 1635         1636         1637 1638             1639             current_item = head =1640 1641         1642 1643             1644             current_item->next =1645             new_item->prev =1646             current_item =1647  parse the name of the child  1648         16491650         input_buffer->offset++1652  Failed to parse name          parse_string(current_item,1)">1651 1653             16541655 1656  swap valuestring and string,because we parsed the name  1657         string1658         current_item->1659 = current_item->1660         current_item->valuestring =: 1661         1662 invalID object  1663             16641665  parse the value  1666         16671668         input_buffer->offset++1669 1670         1671 1672             1673 1674 1675 1676     1677 1678      expected end of object  1679         16801681 1682 1683 1684     input_buffer->depth-- cJsON_Object; 1685     item->type =16861687     item->child =1688 1689     input_buffer->offset++1690     1691 1692 1693     1694 1695 1696 1697 1698     1699  Render an object to text.  1700 17011702 1703 1704     unsigned 1705     size_t length = 1706     cJsON *current_item = item->1707 1708     1709 1710         1711  Compose the output:  1712     1 fmt: {\n      length = (size_t) (output_buffer->format ? 1713); 17151716     output_pointer = ensure(output_buffer,1)">1714     1717 1718         1719 1720 1721     *output_pointer++ = if     output_buffer->depth++1722     1723 (output_buffer->1724 1725         *output_pointer++ = 1726 1727     output_buffer->offset +=while  (current_item)     172817291730 1731                     size_t i; 1732 depth);1733             output_pointer = ensure(output_buffer,output_buffer->17341735             1736 1737                 0 1738             1739; i < output_buffer->depth; i++1740 1741                 *output_pointer++ = depth; 1742             output_buffer->offset += output_buffer->17431744  print key  1745         ifchar         1746 (!print_string_ptr((unsigned 1747*)current_item->1748 1749             1750 1751 1752 1753         length = (size_t) (output_buffer->format ? 1754         output_pointer =1755         1756 1757             1758 1759         *output_pointer++ = 1760         1761 1762             *output_pointer++ = 1763 1764         output_buffer->offset += print value  1765         17671768         print_value(current_item,1)">1766 1769             1770 1771  print comma if not last  1772         10         length = ((size_t)(output_buffer->format ? 1773 : 1775) + (size_t)(current_item->next ? 1776         output_pointer = ensure(output_buffer,1)">1774         1777 1778             if 1779         1780 (current_item->1781 1782             *output_pointer++ = 1783 1784 1785         1786 1787             *output_pointer++ = 1788 1789         *output_pointer = 1790         output_buffer->offset +=1791 1792         current_item = current_item->1793 1 1794     output_pointer = ensure(output_buffer,output_buffer->format ? (output_buffer->depth + 1795) : 1796     1797 1798         1799 1800             size_t i; 1801 01         1802; i < (output_buffer->depth - 1803); i++1804 1805             *output_pointer++ = 1806 1807 1808     *output_pointer++ = 1809     *output_pointer = 1810     output_buffer->depth--1811 1812     1813  Get Array size/item / object item.  1814 array)1815 CJsON_PUBliC(18161817 1818     cJsON *child =1819     size_t size = if 1820     1821 (array ==1822 1823         1824 1825 1826     child = array->while 1827     1828(child !=1829 1830         size++1831         child = child->1832  FIXME: Can overflow here. Cannot be fixed without breaking the API  1833     1834)size; 1835     18361837 static array,size_t index) 1838 cJsON* get_array_item(18391840 1841     cJsON *current_child =1842 1843     1844 1845         1846 1847 while     current_child = array->1848     1849 ((current_child != NulL) && (index > 1850 1851         index--1852         current_child = current_child->1853  current_child; 1854     18551856  index) 1857 CJsON_PUBliC(cJsON *) cJsON_GetArrayItem(1858if 1859     1860 (index < 1861 1862         1863  get_array_item(array,(size_t)index); 1864     18651866 static  cJsON_bool case_sensitive) 1867 cJsON *get_object_item(18681869 1870     cJsON *current_element =if object     1871 ((1872 == NulL) || (name ==1873 1874         1875 1876  (case_sensitive)     current_element = 1877     1878while string         string ((current_element != NulL) && (current_element->1879 != NulL) && (strcmp(name,current_element->1880) != 1881 1882             current_element = current_element->1883 1884 1885     while char         string ((current_element != NulL) && (case_insensitive_strcmp((1886*)name,1)">char*)(current_element->1887)) != 1888 1889             current_element = current_element->1890 1891 if  NulL)) {     1892 ((current_element == NulL) || (current_element->18931894         1895  current_element; 1896     18971898 1899 1900 CJsON_PUBliC(cJsON *) cJsON_GetobjectItem(return 1901     1902 get_object_item(1903 1904 1905 CJsON_PUBliC(cJsON *) cJsON_GetobjectItemCaseSensitive(1906 1907     1908 1909 1910 CJsON_PUBliC(cJsON_bool) cJsON_HasObjectItem(return string     1911 cJsON_GetobjectItem(1912) ? 1913  Utility for array List handling.  1914 voID1916 1917 suffix_object(cJsON *prev,1)">1915  prev;     prev->next =1918     item->prev =19191920  Utility for handling references.  1921 static1922 1923 cJsON *create_reference(1924 if     cJsON *reference =1925     1926 (item ==1927 1928         1929  cJsON_New_Item(hooks); 1930     reference =if1931     1932 (reference ==1933 1934         1935 string 1937     memcpy(reference,item,1)">1936     reference-> cJsON_IsReference; =1938     reference->type |=1939 reference;     reference->next = reference->prev =1940     19411942 static 1944 1945 cJsON_bool add_item_to_array(cJsON *array,1)">1943 1946     cJsON *child =if  item))     1947 ((item == NulL) || (array == NulL) || (array ==19481949 1950         1951 1952 1953     child = array->     * To find the last item in array quickly,we use prev in array     1954 1955if      1956     1957 (child == List is empty,start new one  1958         19591960         array->child =1961         item->prev =1962         item->next =1963 1964      append to the end  1965         ifprev)         1966 (child->1967prev,item); 1968             suffix_object(child->19691970             array->child->prev =1971 1972         while 1973             1974 (child->1975 1976                 child = child->1978 1979             suffix_object(child,1)">1977             array->child->prev =1980 1981 1982 1983     1984  Add item to array/object.  1985 19871989 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToArray(cJsON *array,1)">1986 1990      add_item_to_array(array,1)">1988 #if 1991 #pragma defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MInor__ > 5))))1992     1993 GCC diagnostic push1994 #pragma 1995 1996 GCC diagnostic ignored "-Wcast-qual" helper function to cast away const  1997 voIDvoID 1998* cast_away_const(1999* voID 2000     2001*)2002 #pragma 2003     2004 GCC diagnostic pop2005 2006 static const 2007 cJsON_bool add_item_to_object(cJsON * 2008 hooks,1)"> cJsON_bool constant_key)char 2009     int *new_key = cJsON_InvalID;     2010 new_type =2011object string     object == NulL) || (2012 == NulL) || (item == NulL) || (2013 ==2014 2015         2016  (constant_key) 2017     2018char 2019         new_key = ( cJsON_StringIsConst;*)cast_away_const(2020         new_type = item->type |20212022 2023     char 2024         new_key = (if*)cJsON_strdup((2025         2026 (new_key ==2027 2028             2029 cJsON_StringIsConst; 2030         new_type = item->type & ~20312032 2033 2034     2035 2036         hooks->deallocate(item->2037  new_key; 2038     item-> new_type;2039     item->type =2040return 2041     2042 add_item_to_array(2043 2044 2045 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObject(cJsON *return 2046     2047 add_item_to_object(2048  Add an item to an object with constant string as key  2049 20502051 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObjectCS(cJsON *2052 2053     2054 2056 2057 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoArray(cJsON *array,1)">2055 2058     2059 2060         2061 return 2062     2063 add_item_to_array(array,create_reference(item,1)">global_hooks));2064 2065 2066 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoObject(cJsON *2067 2068     2069 2070         2071 2072 2073     2074  name) 2075 CJsON_PUBliC(cJsON*) cJsON_AddNullToObject(cJsON * 2076null  cJsON_CreateNull();     cJsON *2077 =ifnull     2079 (add_item_to_object(null,1)">2078 2080         20812082 2083 2084     cJsON_Delete(2085     2086 2087 2088 CJsON_PUBliC(cJsON*) cJsON_AddTruetoObject(cJsON *  cJsON_CreateTrue(); 2089     cJsON *true_item =20902091      true_item; 2092         20932094     cJsON_Delete(true_item); 2095 20962097     2098 2099 2100 CJsON_PUBliC(cJsON*) cJsON_AddFalsetoObject(cJsON *  cJsON_CreateFalse(); 2101     cJsON *false_item =21022103      false_item; 2104         21052106     cJsON_Delete(false_item); 2107 21082109     2110  cJsON_bool boolean) 2111 CJsON_PUBliC(cJsON*) cJsON_AddBoolToObject(cJsON * 2112 cJsON_CreateBool(boolean); 2113     cJsON *bool_item =21142115      bool_item; 2116         21172118     cJsON_Delete(bool_item); 2119 21202121     2122 2123 2124 CJsON_PUBliC(cJsON*) cJsON_AddNumberToObject(cJsON *  cJsON_CreateNumber(number); 2125     cJsON *number_item =21262127      number_item; 2128         21292130     cJsON_Delete(number_item); 2131 21322133     2134 2135 2136 CJsON_PUBliC(cJsON*) cJsON_AddStringToObject(cJsON * 2137 2138     cJsON *string_item = cJsON_CreateString(2139      string_item; 2140         21412142     cJsON_Delete(string_item); 2143 21442145     2146  raw) 2147 CJsON_PUBliC(cJsON*) cJsON_AddRawToObject(cJsON * 2148 cJsON_Createraw(raw); 2149     cJsON *raw_item =21502151      raw_item; 2152         21532154     cJsON_Delete(raw_item); 2155 21562157     2158 2159 2160 CJsON_PUBliC(cJsON*) cJsON_AddobjectToObject(cJsON *  cJsON_CreateObject(); 2161     cJsON *object_item =21622163      object_item; 2164         21652166     cJsON_Delete(object_item); 2167 21682169     2170 2171 2172 CJsON_PUBliC(cJsON*) cJsON_AddArrayToObject(cJsON *  cJsON_CreateArray(); 2173     cJsON *array =21742175      array; 2176         21772178     cJsON_Delete(array); 2179 21802181     2182 2183 2184 CJsON_PUBliC(cJsON *) cJsON_DetachItemViaPointer(cJsON *parent,1)"> item)if 2185     2186 ((parent == NulL) || (item ==2187 2188         2189 if child)     2190 (item != parent->2191 not the first element  2192         21932194         item->prev->next = item->if 2195     2196 (item->next != not the last element  2197         21982199         item->next->prev = item->2200 if 2201     2202 (item == parent-> first element  2203         22042205         parent->child = item-> make sure the detached item doesn't point anywhere anymore  2206     22072208     item->prev =2209     item->next =2210 2211     2212 2213 2214 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromArray(cJsON *array,1)"> which)if 2215     2216 (which < 2217 2218         2219  cJsON_DetachItemViaPointer(array,get_array_item(array,(size_t)which)); 2220     22212222 2223 2224 CJsON_PUBliC(    cJsON_Delete(cJsON_DetachItemFromArray(array,which)); 2225 22262227 2228 2229 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObject(cJsON *2230 2231     cJsON *to_detach = cJsON_GetobjectItem(return 2232     2233 cJsON_DetachItemViaPointer(2234 2235 2236 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObjectCaseSensitive(cJsON *2237 2238     cJsON *to_detach = cJsON_GetobjectItemCaseSensitive(2239 2240     2241 2242 2243 CJsON_PUBliC(2244 2245     cJsON_Delete(cJsON_DetachItemFromObject(2246 2247 2248 CJsON_PUBliC(2249 2250     cJsON_Delete(cJsON_DetachItemFromObjectCaseSensitive(2251  Replace array/object items with new ones.  2252 22532254 CJsON_PUBliC(cJsON_bool) cJsON_InsertItemInArray(cJsON *array,1)">newitem)2255 2256     cJsON *after_inserted =2257 2258     2259 2260         2261 2262 if     after_inserted =2263     2264 (after_inserted ==2265 2266         2267  after_inserted; 2268     newitem->next =2269 newitem;     newitem->prev = after_inserted->2270     after_inserted->prev =if2271     2272 (after_inserted == array->2273 2274         array->child =2275 2276     2277 2278         newitem->prev->next =2279 2280     2281  replacement) 2282 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemViaPointer(cJsON * 2283if 2284     2285 ((parent == NulL) || (replacement == NulL) || (item ==2286 2287         2288 if 2289     2290 (replacement ==2291 2292         2293 2294 2295     replacement->next = item->2296     replacement->prev = item->if 2297     2298 (replacement->next != replacement; 2299         replacement->next->prev =2300if 2301     2302 (parent->child ==2303 2304         parent->child =2305 2306              * To find the last item in array quickly,we use prev in array.     {   2307          * We can't modify the last item's next pointer where this item was the parent's child2308 2309if          2310         2311 (replacement->prev !=2312 2313             replacement->prev->next =2314 2315 2316 2317     item->next =    cJsON_Delete(item);     item->prev =2318 23192320 2321     2322 2324 2325 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInArray(cJsON *array,1)">2323 2326     2327 2328         2329 2331 2332      cJsON_ReplaceItemViaPointer(array,(size_t)which),1)">2330 static replacement,cJsON_bool case_sensitive) 2333 cJsON_bool replace_item_in_object(cJsON *2334if 2335     2336 ((replacement == NulL) || (2337 2338         2339  replace the name in the replacement  2340     if2341     2342 (!(replacement->type & cJsON_StringIsConst) && (replacement->2343 2344         cJsON_free(replacement->string 2345     replacement->2346 = (2347     replacement->type &= ~return 2348     2349 cJsON_ReplaceItemViaPointer(2350 2351 2352 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObject(cJsON *return 2353     2354 replace_item_in_object(2355 2356 2357 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObjectCaseSensitive(cJsON *2358 2359     2360  Create basic types:  2361 23622363 CJsON_PUBliC(cJsON *) cJsON_CreateNull(2364 (item)     cJsON *item = cJsON_New_Item(&2365     23662367 2368         item->type =2369 2370 2371     2372 2373 2374 CJsON_PUBliC(cJsON *) cJsON_CreateTrue(2375 2376     cJsON *item = cJsON_New_Item(&2377     2378 2379         item->type =2380 2381 2382     2383 2384 2385 CJsON_PUBliC(cJsON *) cJsON_CreateFalse(2386 2387     cJsON *item = cJsON_New_Item(&2388     2389 2390         item->type =2391 2392 2393     2394 ) cJsON_CreateBool(cJsON_bool boolean) 2395 CJsON_PUBliC(cJsON *23962397 2398     cJsON *item = cJsON_New_Item(&2399      cJsON_True : cJsON_False; 2400         item->type = boolean ?24012402 2403 2404     2405  num) 2406 CJsON_PUBliC(cJsON *) cJsON_CreateNumber(24072408 2409     cJsON *item = cJsON_New_Item(&2410     2411  num;         item->type =2412         item->valuedouble =24132414 if         2415         2416 (num >=2417 2418             item->valueint =if 2419         2420 (num <= (2421 2422             item->valueint =2423 2424         )num; 2425             item->valueint = (24262427 2428 2429 2430     2431 2432 2433 CJsON_PUBliC(cJsON *) cJsON_CreateString(2434 2435     cJsON *item = cJsON_New_Item(&2436     2437 2438         item->type =if         item->valuestring = (2439         2440(!item->            cJsON_Delete(item); 2441 24422443             2444 2445 2446 2447     2448 2449 2450 CJsON_PUBliC(cJsON *) cJsON_CreateStringReference(2451 2452     cJsON *item = cJsON_New_Item(&2453     2454 2455         item->type = cJsON_String |2456         item->valuestring = (2457 2458 2459     2460 2461 2462 CJsON_PUBliC(cJsON *) cJsON_CreateObjectReference(2463 2464     cJsON *item = cJsON_New_Item(&2465     )cast_away_const(child);         item->type = cJsON_Object |2466         item->child = (cJsON*24672468 2469 2470     2471 child) { 2472 CJsON_PUBliC(cJsON *) cJsON_CreateArrayReference(24732474     cJsON *item = cJsON_New_Item(&2475     2476         item->type = cJsON_Array |2477         item->child = (cJsON*2478 2479 2480     2481 raw) 2482 CJsON_PUBliC(cJsON *) cJsON_Createraw(24832484 2485     cJsON *item = cJsON_New_Item(&2486      cJsON_Raw; 2487         item->type =char2489         item->valuestring = (2490*)raw,1)">2488         2491 2492 2493             2494 2495 2496 2497     2498 2499 2500 CJsON_PUBliC(cJsON *) cJsON_CreateArray(2501 2502     cJsON *item = cJsON_New_Item(&2503     cJsON_Array; 2504         item->type=25052506 2507 2508     2509 2510 2511 CJsON_PUBliC(cJsON *) cJsON_CreateObject(2512  (item)     cJsON *item = cJsON_New_Item(&2513     25142515 2516         item->type =2517 2518 2519     2520  Create Arrays:  2521  count)2522 CJsON_PUBliC(cJsON *) cJsON_CreateIntArray(25232524 2525     size_t i = 2526     cJsON *n =2527     cJsON *p =2528     cJsON *a =if 0     2529 ((count < 2530) || (numbers ==2531 2532         2533 2534 for     a =0     2535(i = 2536; a && (i < (size_t)count); i++ cJsON_CreateNumber(numbers[i]); 2537         n =n)2538         2539            cJsON_Delete(a); 2540 25412542             if i)         2543(!2544 n; 2545             a->child =25462547 2548                     suffix_object(p,n); 2549 25502551 2552         p =2553  a; 2554     25552556 2557 2558 CJsON_PUBliC(cJsON *) cJsON_CreatefloatArray(2559 2560     size_t i = 2561     cJsON *n =2562     cJsON *p =2563     cJsON *a =2564 2565     2566 2567         2568 2569 2570     a =2571 2572     )numbers[i]); 2573         n = cJsON_CreateNumber((25742575         2576 2577 2578             2579 2580         2581 2582             a->child =2583 2584         2585 2586 2587 2588         p =2589 2590 2591     2592 2593 2594 CJsON_PUBliC(cJsON *) cJsON_CreateDoubleArray(2595 2596     size_t i = 2597     cJsON *n =2598     cJsON *p =2599     cJsON *a =2600 2601     2602 2603         2604 2605 2606     a =0 2607     2608;a && (i < (size_t)count); i++2609 2610         n =2611         2612 2613 2614             2615 2616         2617 2618             a->child =2619 2620         2621 2622 2623 2624         p =2625 2626 2627     2628 2629 2630 CJsON_PUBliC(cJsON *) cJsON_CreateStringArray(2631 2632     size_t i = 2633     cJsON *n =2634     cJsON *p =2635     cJsON *a =0 2636     2637) || (strings ==2638 2639         2640 2641 2642     a =2643 2644      cJsON_CreateString(strings[i]); 2645         n =26462647         2648 2649 2650             2651 2652         2653 2654             a->child =2655 2656         2657 2658 2659 2660         p =2661 2662 2663     2664  Duplication  2665 26662667 CJsON_PUBliC(cJsON *) cJsON_Duplicate(2668 2669     cJsON *newitem =2670     cJsON *child =2671     cJsON *next =2672     cJsON *newchild = Bail on bad ptr  2673     26742675     2676 2677          Create new item  2678     26792680     newitem = cJsON_New_Item(&2681     2682 2683          copy over all vars  2684     cJsON_IsReference);2685     newitem->type = item->type & (~valueint;2686     newitem->valueint = item->2687if     newitem->valuedouble = item->2688     2689 (item->char char         newitem->valuestring = (if*)cJsON_strdup((unsigned 2691*)item->valuestring,1)">2690         2692 (!newitem->2693 2694             2695 2696 2697     string string         newitem->2698 = (item->type&cJsON_StringIsConst) ? item->2699 : (2700         2701 2702             2703  If non-recursive,then we're done!  2704     recurse)2705     27062707 2708          Walk the ->next chain for the child.  2709     2710while     child = item->2711     2712 (child != Duplicate (with recurse) each item in the ->next chain  2713         newchild = cJsON_Duplicate(child,1)">true); newchild)2714         27152716 2717             if 2718         2719 (next != If newitem->child already set,then crosswire ->prev and ->next and move on  2720              newchild;2721             next->next =27222723             newchild->prev =2724             next =2725 2726          Set newitem->child and move to it  2727             27282729             newitem->child =2730             next =2731 2732         child = child->2733 2734 2735     2736 if 2737     2738 (newitem !=        cJsON_Delete(newitem); 2739 27402741 2742 2743     2744 voID input) 2745 skip_oneline_comment(2746// 2747     *input += static_strlen(2748for '     input)) (; (*input)[2749; ++(*2750if ) {         2751 ((*input)[27522753             *input += static_strlen(2754             2755 2756 2757 voID 2758 2759 skip_multiline_comment(/* 2760     *input += static_strlen(27612762 2763     if *         ' (((*input)[12764) && ((*input)[2765] == */ 2766             *input += static_strlen(27672768             2769 2770 2771 voID char 2772 Minify_string(0 **input,1)">output) {2773     (*output)[2774] = (*input)[2775     *input += static_strlen(2776     *output += static_strlen(2777 voID output)) {     2778)++(*input),++(*27792780         (*output)[2781 2782         2783             (*output)[2784             *input += static_strlen(2785             *output += static_strlen()) {             2786         } 12787             (*output)[2788] = (*input)[2789             *input += static_strlen(2790             *output += static_strlen(2791 2792 2793 Json) 2794 CJsON_PUBliC(2795char  Json;     2796 *into =2797if 2798     2799 (Json ==2800 2801         2802 while 2803     2804 (Json[switch 2805         2806 (Json[2807 2808             2809             2810             2811             2812                 Json++2813                 2814 if             2815                 2816 (Json[2817 2818                     skip_oneline_comment(&2819 2820                 2821 else                     skip_multiline_comment(&2822                 } 28232824                     Json++2825 2826                 2827 2828             2829                 Minify_string(&Json,1)">into);2830                 2831 0             2832                 into[2833] = Json[2834                 Json++2835                 into++2836 2837  and null-terminate.  2838     28392840     *into = 2841 2842 2843 CJsON_PUBliC(cJsON_bool) cJsON_IsInvalID(2844 2845     2846 2847         2848 return 0xFF     2849 (item->type & 2850) ==2851 2852 2853 CJsON_PUBliC(cJsON_bool) cJsON_IsFalse(2854 2855     2856 2857         2858 2859 2860     2861 2862 2863 CJsON_PUBliC(cJsON_bool) cJsON_IsTrue(2864 2865     2866 2867         2868 0xff 2869     2870) ==2871 2872 2873 2874 CJsON_PUBliC(cJsON_bool) cJsON_IsBool(2875 2876     2877 2878         2879 return 2880     2881 (item->type & (cJsON_True | cJsON_False)) != 2882 2883 CJsON_PUBliC(cJsON_bool) cJsON_IsNull(2884 2885     2886 2887         2888 2889 2890     2891 2892 2893 CJsON_PUBliC(cJsON_bool) cJsON_IsNumber(2894 2895     2896 2897         2898 2899 2900     2901 2902 2903 CJsON_PUBliC(cJsON_bool) cJsON_Isstring(2904 2905     2906 2907         2908 2909 2910     2911 2912 2913 CJsON_PUBliC(cJsON_bool) cJsON_IsArray(2914 2915     2916 2917         2918 2919 2920     2921 2922 2923 CJsON_PUBliC(cJsON_bool) cJsON_IsObject(2924 2925     2926 2927         2928 2929 2930     2931 2932 2933 CJsON_PUBliC(cJsON_bool) cJsON_IsRaw(2934 2935     2936 2937         2938 2939 2940     2941 2942 2943 CJsON_PUBliC(cJsON_bool) cJsON_Compare(if 0xFF     0xFF ((a == NulL) || (b == NulL) || ((a->type &  cJsON_IsInvalID(a))) != (b->type & 2944)) ||29452946 2947         2948  check if type is valID  2949     switch2950     2951 (a->type & 2952 2953         2954         2955         2956         2957         2958         2959         2960         2961             2962 2963         2964             2965  IDentical objects are equal  2966     if2967     2968 (a ==2969 2970         2971 2972 2973      in these cases and equal type is enough  2974         29752976         2977         2978         2979             2980 if         valuedouble))             2981 (compare_double(a->valuedouble,b->29822983 2984                 2985 2986             2987 2988         if         2989             2990 ((a->valuestring == NulL) || (b->valuestring ==2991 2992                 if 2993             2994 (strcmp(a->valuestring,b->valuestring) == 2995 2996                 2997 2998 2999             3000 3001         3002 3003             cJsON *a_element = a->3004             cJsON *b_element = b->for  NulL);)             3005 (; (a_element != NulL) && (b_element !=3006cJsON_Compare(a_element,b_element,case_sensitive)) 3007                 30083009 3010                     3011 3012 3013                 a_element = a_element->3014                 b_element = b_element->3015  one of the arrays is longer than the other  3016             if b_element) {             3017 (a_element !=30183019                 3020 3021 3022             3023 3024 3025         3026 3027             cJsON *a_element =            cJsON_ArrayForEach(a_element,a)             cJsON *b_element =3028 3029 Todo This has O(n^2) runtime,which is horrible!  3030                 3031if                 b_element = get_object_item(b,a_element->3032                 3033 (b_element ==3034 3035                     3036 3037 3038                 3039 3040                     3041 3042  doing this twice,once on a and b to prevent true comparison if a subset of b 3043                          * Todo: Do this the proper way,this is just a fix for Now 3044             cJsON_ArrayForEach(b_element,b)3045 30463047 if                 a_element = get_object_item(a,b_element->3048                 3049 (a_element ==3050 3051                     3052 3054 3055                 cJsON_Compare(b_element,a_element,1)">3053 3056                     3057 3058 3059 3060             3061 3062 3063         3064             3065 3066 ) cJsON_malloc(size_t size) 3067 CJsON_PUBliC(3068 global_hooks.allocate(size); 3069     30703071 3072 3073 CJsON_PUBliC(3074 VIEw Code     global_hooks.deallocate([+++] }
[+++]

 

 参考:

https://blog.csdn.net/shizhe0123/article/details/94742514

https://blog.csdn.net/fengxinlinux/article/details/53121287

https://www.cnblogs.com/skullboyer/p/8152157.html

总结

以上是内存溢出为你收集整理的不可不知的JSON处理库(cJSON)全部内容,希望文章能够帮你解决不可不知的JSON处理库(cJSON)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 4881, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述ANSI C中的超轻量级JSON解析器 JSON(JavaScript对象表示法)是一种轻量级的数据交换格式。人类易于阅读和书写。机器很容易解析和生成。它基于JavaScript编程语言标准ECMA-

ANSI C中的超轻量级JsON解析器

JsON(JavaScript对象表示法)是一种轻量级的数据交换格式。人类易于阅读和书写。机器很容易解析和生成。它基于JavaScript编程语言标准ECMA-262第三版(1999年12月)的子集 。JsON是一种完全独立于语言的文本格式,但是使用C语言家族(包括C,C ++,C#,Java,JavaScript,Perl,Python等)的程序员熟悉的约定。这些属性使JsON成为理想的数据交换语言。

cJsON旨在成为您可以完成工作的最简单的解析器。它是资源只有一个C的头文件和C文件,所以方便移植。它可以为你各种需要的Json字符串处理,包括打包、解析、修改、删除、添加等。在这里将一探究竟。

在这里将着重叙述Json的打包和解析,更多处理玩法,见文章末尾链接。

开始cJsON

cJsON合并到您的项目

因为整个库只有一个C文件和一个头文件,所以您只需复制cJsON.h并复制cJsON.c到项目源并开始使用它。

cJsON用ANSI C(C89)编写,以便支持尽可能多的平台和编译器。

 

下载:

https://github.com/DaveGamble/cJSON/releases

 

CJson结构体

/* The cJsON structure: */typedef struct cJsON{    struct cJsON *next;    prev;    child;    int type;    char *valuestring;     valueint;    double valuedouble;    string;} cJsON;

结构体项解析:

next 和prev :CJson结构体作为一个双向连表的环,可以通过 next 和prev 指针进行连表遍历

child:可以是cJsON_Array、cJsON_Object类型数据

type:当前项的类型

valuestring:内容存储,当类型是cJsON_String和cJsON_Raw

valueint:内容存储,整型,可以是cJsON_False、cJsON_True数据

valuedouble:内容存储,浮点型,当类型是cJsON_Number

string:键名

数据类型

l  cJsON_InvalID表示一个不包含任何值的无效项目。如果将项目设置为全零字节,则将自动具有此类型。

l  cJsON_False表示一个false布尔值。您也可以使用来检查布尔值cJsON_IsBool

l  cJsON_True表示一个true布尔值。您也可以使用来检查布尔值cJsON_IsBool

l  cJsON_NulL表示一个null值

l  cJsON_Number 表示一个数字值。该值存储为double in valuedouble和in valueint。如果数字超出整数范围,INT_MAX或INT_MIN用于valueint

l  cJsON_String表示一个字符串值。它以零终止字符串的形式存储在中valuestring

l  cJsON_Array表示一个数组值。这是通过指向表示数组中值child的cJsON项目的链接列表来实现的。使用next和将元素链接在一起prev,其中第一个元素具有prev.next == NulL和最后一个元素next == NulL

l  cJsON_Object 表示一个对象值。对象的存储方式与数组相同,唯一的区别是对象中的项将其键存储在中string

l  cJsON_Raw表示以JsON字符存储的零终止形式的任何JsON valuestring。例如,可以使用它来避免一遍又一遍地打印相同的静态JsON以节省性能。解析时,cJsON永远不会创建此类型。另请注意,cJsON不会检查其是否为有效JsON。

类型

#define cJsON_InvalID (0)#define cJsON_False  (1 << 0)#define cJsON_True   (1 << 1)#define cJsON_NulL   (1 << 2)#define cJsON_Number (1 << 3)#define cJsON_String (1 << 4)#define cJsON_Array  (1 << 5)#define cJsON_Object (1 << 6)#define cJsON_Raw    (1 << 7) /* raw Json */

类型判断

cJsON_IsInvalID(const cJsON * const item);cJsON_IsFalse( item);cJsON_IsTrue( item);cJsON_IsBool( item);cJsON_IsNull( item);cJsON_IsNumber( item);cJsON_Isstring( item);cJsON_IsArray( item);cJsON_IsObject( item);cJsON_IsRaw(const item);

注意

创建cJson对象后,处理完需要进行内存释放:

如果是cJson里的对象,请使用cJsON_Delete()

如果不是对象:cJsON_free()或free()

 

零字符

cJsON不支持包含零字符'\0'或的字符串\u0000。对于当前的API,这是不可能的,因为字符串以零结尾。

 

字符编码

cJsON仅支持UTF-8编码的输入。但是在大多数情况下,它不会拒绝无效的UTF-8作为输入,而只是将其原样传播。只要输入不包含无效的UTF-8,输出将始终是有效的UTF-8。

 

C标准

cJsON用ANSI C(或C89,C90)编写。如果您的编译器或C库未遵循此标准,则不能保证正确的行为。

 

注意:ANSI C不是C ++,因此不应使用C ++编译器进行编译。您可以使用C编译器对其进行编译,然后将其与C ++代码链接。尽管可以使用C ++编译器进行编译,但是不能保证正确的行为。

 

浮点数字

double除IEEE754双精度浮点数外,cJsON不正式支持任何实现。它可能仍然可以与其他实现一起使用,但是这些实现的错误将被视为无效。

 

目前,cJsON支持的浮点文字的最大长度为63个字符。

 

数组和对象的深层嵌套

cJsON不支持嵌套太深的数组和对象,因为这会导致堆栈溢出。为了防止这种CJsON_nesTING_liMIT情况,默认情况下,cJsON将深度限制为1000,但是可以在编译时进行更改。

格式化输出

按标准的格式输出Json字符串,输出完后一定要记得释放内存

 代码

 1 #include <stdio.h> 2 #include "cJsON.h" 3 #include cJsON.c 4 voID main(){ 5     //待解析字符串  6     char *Json_str={\"key1\":\"dongxiaodong\",\"key2\":1998,\"key3\":55778}"; 7      8     输出原字符串 9     printf(原字符串:%s\r\n,Json_str); 10 11     解析成Json对象 12     cJsON * Json_obj = cJsON_Parse(Json_str); 13 14     格式输出15     char *Json_print_str=NulL;16     Json_print_str=cJsON_Print(Json_obj);17     printf(\r\n输出内容:\r\n\r\n%s\r\n18     19     释放资源 20     free(Json_print_str);21     22     23     cJsON_Delete(Json_obj);24 }
Json打包

cJsON_CreateObject函数可创建一个根数据项,在此之后就可以添加各种数据类型的子节点了,使用完成后需要通过cJsON_Delete()释放内存。

创建一层级的Json

 代码:

 5     cJsON *root_obj = NulL;根,Json对象 char *out_str = NulL; 输出结果  7     root_obj =cJsON_CreateObject();创建  8      添加一个字符串,参数(根对象,键,值)  9     cJsON_AddStringToObject(root_obj,key1",1)">dongxiaodong);10     添加一个整型,参数(根对象,键,值) 11     cJsON_AddNumberToObject(root_obj,1)">key2199812     添加一个浮点型,参数(根对象,键,值) 13     cJsON_AddNumberToObject(root_obj,1)">key322.33添加一个bool类型,参数(根对象,键,值) bool值可以是0/1或false/true 16     cJsON_AddBoolToObject(root_obj,1)">key4017     将Json对象打包成字符串 18     out_str = cJsON_PrintUnformatted(root_obj);销毁Json对象,释放内存 20     cJsON_Delete(root_obj); 21     输出值:{"key1":"dongxiaodong","key2":1998,"key3":22.33,"key4":false} 22     printf(%s23 }

类型创建函数还有:

cJsON_AddNullToObject(cJsON * const object,const char * const name);

cJsON_AddTruetoObject(cJsON * const object,const char * const name);

cJsON_AddFalsetoObject(cJsON * const object,const char * const name);

cJsON_AddBoolToObject(cJsON * const object,const char * const name,const cJsON_bool boolean);

cJsON_AddNumberToObject(cJsON * const object,const double number);

cJsON_AddStringToObject(cJsON * const object,const char * const string);

cJsON_AddRawToObject(cJsON * const object,const char * const raw);

cJsON_AddobjectToObject(cJsON * const object,const char * const name);

cJsON_AddArrayToObject(cJsON * const object,const char * const name);

创建多层级的Json

 代码:

 6     cJsON *item_obj = NulL;二级Json对象  7      8      9     root_obj =cJsON_CreateObject();10      11     cJsON_AddStringToObject(root_obj,1)">14     创建一个子Json对象16     item_obj= cJsON_AddobjectToObject(root_obj,1)">myson); 向孩子对象中添加内容18     cJsON_AddStringToObject(item_obj,1)">sonkey1东小东19     cJsON_AddNumberToObject(item_obj,1)">sonkey2202020       22     out_str =23     24 25     26     printf(27 }

创建多层Json(数组形式)

 

 代码

数组对象 创建一个子数组对象 16     item_obj= cJsON_AddArrayToObject(root_obj,1)">向数组对象中添加内容18     cJsON_AddItemToArray(item_obj,cJsON_CreateTrue()); 19     cJsON_AddItemToArray(item_obj,cJsON_CreateNumber(22));27 }

创建的对象还可以是下面这些

cJsON_CreateNull(voID);

cJsON_CreateTrue(voID);

cJsON_CreateFalse(voID);

cJsON_CreateBool(cJsON_bool boolean);

cJsON_CreateNumber(double num);

cJsON_CreateString(const char *string);

cJsON_Createraw(const char *raw);

cJsON_CreateArray(voID);

cJsON_CreateObject(voID);

创建混合Json

 代码

 6     cJsON *son_obj=NulL;  7     cJsON *item_obj = NulL;输出结果  9     根对象 11     root_obj =cJsON_CreateObject();13     cJsON_AddStringToObject(root_obj,1)">15     cJsON_AddNumberToObject(root_obj,1)">16     18     item_obj= cJsON_AddArrayToObject(root_obj,1)">21     cJsON_AddItemToArray(item_obj,1)">22     子对象 24     son_obj =cJsON_CreateObject();26     cJsON_AddStringToObject(son_obj,1)">son127     28     cJsON_AddNumberToObject(son_obj,1)">son229 30     31     32     out_str =33     34 35     36     printf(37 }
Json解析

解析一层级的Json

 

代码:

 8     cJsON * Json_obj =项存储 11     cJsON *item=12     13     14     printf(15     16     获取string类型 17     item=cJsON_GetobjectItem(Json_obj,1)">);  18     printf(\r\nkey1:%s\r\nvaluestring);19     cJsON_Delete(item);释放资源 20      获取数字 22     item=cJsON_GetobjectItem(Json_obj,1)">23     printf(\r\nkey2:%d\r\nvalueint);24     cJsON_Delete(item);25     26     27     item=cJsON_GetobjectItem(Json_obj,1)">28     printf(\r\nkey3:%f\r\nvaluedouble);29     cJsON_Delete(item);获取bool 32     item=cJsON_GetobjectItem(Json_obj,1)">33     printf(\r\nkey4:%d\r\n34     cJsON_Delete(item);35     36     是否资源 37 38 }

解析多层级的Json

 

代码

内部项存储13     cJsON * item_item=16     printf(17     18     19     item=cJsON_GetobjectItem(Json_obj,1)">20     printf(21     cJsON_Delete(item);22      24     item=cJsON_GetobjectItem(Json_obj,1)">25     printf(26     cJsON_Delete(item);27     28     子串29     item=cJsON_GetobjectItem(Json_obj,1)">30     item_item=cJsON_GetobjectItem(item,1)">31     printf(\r\nmyson(sonkey1):%s\r\n32     cJsON_Delete(item_item);33     34     item_item=cJsON_GetobjectItem(item,1)">35     printf(\r\nmyson(sonkey2):%d\r\n36     cJsON_Delete(item_item);37     38     cJsON_Delete(item);39     40     41 42 }

 解析多层Json(数组形式)

 

 

代码

获取子串 输出数组大小 32     printf(\r\n数组大小:%d\r\n34     输出项1内容 35     item_item=cJsON_GetArrayItem(item,1)">\r\nmyson(0):%d\r\n37     cJsON_Delete(item_item);38     39     输出项2内容 40     item_item=cJsON_GetArrayItem(item,1)">141     printf(\r\nmyson(1):%d\r\n42     cJsON_Delete(item_item);43     44     cJsON_Delete(item);45     46     47 48 }

  解析混合Json

代码

44     项3内容45     item_item=cJsON_GetArrayItem(item,1)">246     cJsON *item_item_son=47     48     item_item_son =cJsON_GetobjectItem(item_item,1)">49     printf(\r\nmyson(2)(son1):%s\r\n50     cJsON_Delete(item_item_son);51     52     item_item_son =cJsON_GetobjectItem(item_item,1)">53     printf(\r\nmyson(2)(son2):%d\r\n54     cJsON_Delete(item_item_son);释放资源55     cJsON_Delete(item_item);释放资源   56     57     cJsON_Delete(item);58     59     60 61 }

 附件:

cJsON.h

  1 /*  2   copyright (c) 2009-2017 Dave Gamble and cJsON contributors  3   4   Permission is hereby granted,free of charge,to any person obtaining a copy  5   of this software and associated documentation files (the "Software"),to deal  6   in the Software without restriction,including without limitation the rights  7   to use,copy,modify,merge,publish,distribute,sublicense,and/or sell  8   copIEs of the Software,and to permit persons to whom the Software is  9   furnished to do so,subject to the following conditions: 10  11   The above copyright notice and this permission notice shall be included in 12   all copIEs or substantial portions of the Software. 13  14   THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR 15   IMPLIED,INCLUDING BUT NOT liMITED TO THE WARRANTIES OF MERCHANTABIliTY, 16   fitness FOR A PARTIculaR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17   AUTHORS OR copYRIGHT HolDERS BE liABLE FOR ANY CLaim,damAGES OR OTHER 18   liABIliTY,WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE,ARISING FROM,1)"> 19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEAliNGS IN 20   THE SOFTWARE. 21 */ 22  23 #ifndef cJsON__h 24 #define cJsON__h 25  26 #ifdef __cplusplus 27 extern C 28 { 29 #endif 30  31 #if !defined(__windows__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) 32 #define __windows__ 33  34  35 #ifdef __windows__ 36  37  When compiling for windows,we specify a specific calling convention to avoID issues where we are being called from a project with a different default calling convention.  For windows you have 3 define options: 38  39 CJsON_HIDE_SYMBolS - define this in the case where you don't want to ever dllexport symbols 40 CJsON_EXPORT_SYMBolS - define this on library build when you want to dllexport symbols (default) 41 CJsON_import_SYMBolS - define this if you want to dllimport symbol 42  43 For *nix builds that support visibility attribute,you can define similar behavior by 44  45 setting default visibility to hIDden by adding 46 -fvisibility=hIDden (for gcc) 47 or 48 -xldscope=hIDden (for sun cc) 49 to CFLAGS 50  51 then using the CJsON_API_VISIBIliTY flag to "export" the same symbols the way CJsON_EXPORT_SYMBolS does 52  53  54  55 #define CJsON_CDECL __cdecl 56 #define CJsON_STDCALL __stdcall 57  58  export symbols by default,this is necessary for copy pasting the C and header file  59 #if !defined(CJsON_HIDE_SYMBolS) && !defined(CJsON_import_SYMBolS) && !defined(CJsON_EXPORT_SYMBolS) 60 #define CJsON_EXPORT_SYMBolS 61  62  63 #if defined(CJsON_HIDE_SYMBolS) 64 #define CJsON_PUBliC(type)   type CJsON_STDCALL 65 #elif defined(CJsON_EXPORT_SYMBolS) 66 #define CJsON_PUBliC(type)   __declspec(dllexport) type CJsON_STDCALL 67 #elif defined(CJsON_import_SYMBolS) 68 #define CJsON_PUBliC(type)   __declspec(dllimport) type CJsON_STDCALL 69  70 #else /* !__windows__ */ 71 #define CJsON_CDECL 72 #define CJsON_STDCALL 73  74 #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJsON_API_VISIBIliTY) 75 #define CJsON_PUBliC(type)   __attribute__((visibility("default"))) type 76 #else 77 #define CJsON_PUBliC(type) type 78  79  80  81  project version  82 #define CJsON_VERSION_MAJOR 1 83 #define CJsON_VERSION_MInor 7 84 #define CJsON_VERSION_PATCH 13 85  86 #include <stddef.h> 87  88  cJsON Types:  89  90  91  92  93  94  95  96  97 #define cJsON_Raw    (1 << 7) /* raw Json */ 98  99 #define cJsON_IsReference 256100 #define cJsON_StringIsConst 512101 102 103 typedef  cJsON104 105      next/prev allow you to walk array/object chains. Alternatively,use GetArraySize/GetArrayItem/GetobjectItem 106     next;107     prev;108      An array or object item will have a child pointer pointing to a chain of the items in the array/object. 109     child;110 111      The type of the item,as above. 112      type;113 114      The item's string,if type==cJsON_String  and type == cJsON_Raw 115     valuestring;116      writing to valueint is DEPRECATED,use cJsON_SetNumberValue instead 117      valueint;118      The item's number,if type==cJsON_Number 119      valuedouble;120 121      The item's name string,if this item is the child of,or is in the List of subitems of an object. 122     123 } cJsON;124 125 typedef  cJsON_Hooks126 127        malloc/free are CDECL on windows regardless of the default calling convention of the compiler,so ensure the hooks allow passing those functions directly. 128       voID *(CJsON_CDECL *malloc_fn)(size_t sz);129       voID (CJsON_CDECL *free_fn)(voID *ptr);130 } cJsON_Hooks;131 132 typedef  cJsON_bool;133 134  limits how deeply nested arrays/objects can be before cJsON rejects to parse them.135  * This is to prevent stack overflows. 136 #ifndef CJsON_nesTING_liMIT137 #define CJsON_nesTING_liMIT 1000138 139 140  returns the version of cJsON as a string 141 CJsON_PUBliC(const char*) cJsON_Version(142 143  Supply malloc,realloc and free functions to cJsON 144 CJsON_PUBliC(voID) cJsON_InitHooks(cJsON_Hooks* hooks);145 146  Memory Management: the caller is always responsible to free the results from all variants of cJsON_Parse (with cJsON_Delete) and cJsON_Print (with stdlib free,cJsON_Hooks.free_fn,or cJsON_free as appropriate). The exception is cJsON_PrintPreallocated,where the caller has full responsibility of the buffer. 147  Supply a block of JsON,and this returns a cJsON object you can interrogate. 148 CJsON_PUBliC(cJsON *) cJsON_Parse(value);149 CJsON_PUBliC(cJsON *) cJsON_ParseWithLength(value,size_t buffer_length);150  ParseWithOpts allows you to require (and check) that the JsON is null terminated,and to retrIEve the pointer to the final byte parsed. 151  If you supply a ptr in return_parse_end and parsing fails,then return_parse_end will contain a pointer to the error so will match cJsON_GetErrorPtr(). 152 CJsON_PUBliC(cJsON *) cJsON_ParseWithOpts(char *value,char **return_parse_end,cJsON_bool require_null_terminated);153 CJsON_PUBliC(cJsON *) cJsON_ParseWithLengthOpts(154 155  Render a cJsON entity to text for transfer/storage. 156 CJsON_PUBliC(char *) cJsON_Print(const cJsON *item);157  Render a cJsON entity to text for transfer/storage without any formatting. 158 CJsON_PUBliC(char *) cJsON_PrintUnformatted(159  Render a cJsON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted,=1 gives formatted 160 CJsON_PUBliC(char *) cJsON_PrintBuffered(const cJsON *item,1)"> prebuffer,cJsON_bool fmt);161  Render a cJsON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. 162  NOTE: cJsON is not always 100% accurate in estimating how much memory it will use,so to be safe allocate 5 bytes more than you actually need 163 CJsON_PUBliC(cJsON_bool) cJsON_PrintPreallocated(cJsON *item,1)">char *buffer,1)">int length,1)"> cJsON_bool format);164  Delete a cJsON entity and all subentitIEs. 165 CJsON_PUBliC(voID) cJsON_Delete(cJsON *166 167  Returns the number of items in an array (or object). 168 CJsON_PUBliC(int) cJsON_GetArraySize(array);169  RetrIEve item number "index" from array "array". Returns NulL if unsuccessful. 170 CJsON_PUBliC(cJsON *) cJsON_GetArrayItem(const cJsON *array,1)"> index);171  Get item "string" from object. Case insensitive. 172 CJsON_PUBliC(cJsON *) cJsON_GetobjectItem(object,1)">char * 173 CJsON_PUBliC(cJsON *) cJsON_GetobjectItemCaseSensitive(174 CJsON_PUBliC(cJsON_bool) cJsON_HasObjectItem(175  For analysing Failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. defined when cJsON_Parse() returns 0. 0 when cJsON_Parse() succeeds. 176 CJsON_PUBliC(char *) cJsON_GetErrorPtr(177 178  Check item type and return its value 179 CJsON_PUBliC(char *) cJsON_GetStringValue(cJsON *180 CJsON_PUBliC(double) cJsON_GetNumberValue(cJsON *181 182  These functions check the type of an item 183 CJsON_PUBliC(cJsON_bool) cJsON_IsInvalID( item);184 CJsON_PUBliC(cJsON_bool) cJsON_IsFalse(185 CJsON_PUBliC(cJsON_bool) cJsON_IsTrue(186 CJsON_PUBliC(cJsON_bool) cJsON_IsBool(187 CJsON_PUBliC(cJsON_bool) cJsON_IsNull(188 CJsON_PUBliC(cJsON_bool) cJsON_IsNumber(189 CJsON_PUBliC(cJsON_bool) cJsON_Isstring(190 CJsON_PUBliC(cJsON_bool) cJsON_IsArray(191 CJsON_PUBliC(cJsON_bool) cJsON_IsObject(192 CJsON_PUBliC(cJsON_bool) cJsON_IsRaw(193 194  These calls create a cJsON item of the appropriate type. 195 CJsON_PUBliC(cJsON *) cJsON_CreateNull(196 CJsON_PUBliC(cJsON *) cJsON_CreateTrue(197 CJsON_PUBliC(cJsON *) cJsON_CreateFalse(198 CJsON_PUBliC(cJsON *) cJsON_CreateBool(cJsON_bool boolean);199 CJsON_PUBliC(cJsON *) cJsON_CreateNumber( num);200 CJsON_PUBliC(cJsON *) cJsON_CreateString(201  raw Json 202 CJsON_PUBliC(cJsON *) cJsON_Createraw(raw);203 CJsON_PUBliC(cJsON *) cJsON_CreateArray(204 CJsON_PUBliC(cJsON *) cJsON_CreateObject(205 206  Create a string where valuestring references a string so207  * it will not be freed by cJsON_Delete 208 CJsON_PUBliC(cJsON *) cJsON_CreateStringReference(209  Create an object/array that only references it's elements so210  * they will not be freed by cJsON_Delete 211 CJsON_PUBliC(cJsON *) cJsON_CreateObjectReference(child);212 CJsON_PUBliC(cJsON *) cJsON_CreateArrayReference(213 214  These utilitIEs create an Array of count items.215  * The parameter count cannot be greater than the number of elements in the number array,otherwise array access will be out of bounds.216 CJsON_PUBliC(cJsON *) cJsON_CreateIntArray(int *numbers,1)"> count);217 CJsON_PUBliC(cJsON *) cJsON_CreatefloatArray(float *numbers,1)">218 CJsON_PUBliC(cJsON *) cJsON_CreateDoubleArray(double *numbers,1)">219 CJsON_PUBliC(cJsON *) cJsON_CreateStringArray(const *strings,1)">220 221  Append item to the specifIEd array/object. 222 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToArray(cJsON *array,cJsON *223 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObject(cJsON *string,1)">224  Use this when string is definitely const (i.e. a literal,or as good as),and will definitely survive the cJsON object.225  * WARNING: When this function was used,make sure to always check that (item->type & cJsON_StringIsConst) is zero before226  * writing to `item->string` 227 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObjectCS(cJsON *228  Append reference to item to the specifIEd array/object. Use this when you want to add an existing cJsON to a new cJsON,but don't want to corrupt your existing cJsON. 229 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoArray(cJsON *array,1)">230 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoObject(cJsON *231 232  Remove/Detach items from Arrays/Objects. 233 CJsON_PUBliC(cJsON *) cJsON_DetachItemViaPointer(cJsON *parent,cJsON * 234 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromArray(cJsON *array,1)"> which);235 CJsON_PUBliC(voID) cJsON_DeleteItemFromArray(cJsON *array,1)">236 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObject(cJsON *237 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObjectCaseSensitive(cJsON *238 CJsON_PUBliC(voID) cJsON_DeleteItemFromObject(cJsON *239 CJsON_PUBliC(voID) cJsON_DeleteItemFromObjectCaseSensitive(cJsON *240 241  Update array items. 242 CJsON_PUBliC(cJsON_bool) cJsON_InsertItemInArray(cJsON *array,1)">int which,cJsON *newitem);  Shifts pre-existing items to the right. 243 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemViaPointer(cJsON * const parent,1)">const item,1)"> replacement);244 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInArray(cJsON *array,1)">newitem);245 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObject(cJsON *246 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObjectCaseSensitive(cJsON *247 248  Duplicate a cJsON item 249 CJsON_PUBliC(cJsON *) cJsON_Duplicate(item,cJsON_bool recurse);250  Duplicate will create a new,IDentical cJsON item to the one you pass,in new memory that will251  * need to be released. With recurse!=0,it will duplicate any children connected to the item.252  * The item->next and ->prev pointers are always zero on return from Duplicate. 253  Recursively compare two cJsON items for equality. If either a or b is NulL or invalID,they will be consIDered unequal.254  * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) 255 CJsON_PUBliC(cJsON_bool) cJsON_Compare(const a,1)">const b,1)"> cJsON_bool case_sensitive);256 257  Minify a strings,remove blank characters(such as ' ','\t','\r','\n') from strings.258  * The input pointer Json cannot point to a read-only address area,such as a string constant,1)">259  * but should point to a readable and writable adress area. 260 CJsON_PUBliC(voID) cJsON_Minify(Json);261 262  Helper functions for creating and adding items to an object at the same time.263  * They return the added item or NulL on failure. 264 CJsON_PUBliC(cJsON*) cJsON_AddNullToObject(cJsON *  name);265 CJsON_PUBliC(cJsON*) cJsON_AddTruetoObject(cJsON * 266 CJsON_PUBliC(cJsON*) cJsON_AddFalsetoObject(cJsON * 267 CJsON_PUBliC(cJsON*) cJsON_AddBoolToObject(cJsON * const name,1)"> cJsON_bool boolean);268 CJsON_PUBliC(cJsON*) cJsON_AddNumberToObject(cJsON *  number);269 CJsON_PUBliC(cJsON*) cJsON_AddStringToObject(cJsON * 270 CJsON_PUBliC(cJsON*) cJsON_AddRawToObject(cJsON *  raw);271 CJsON_PUBliC(cJsON*) cJsON_AddobjectToObject(cJsON * 272 CJsON_PUBliC(cJsON*) cJsON_AddArrayToObject(cJsON * 273 274  When assigning an integer value,it needs to be propagated to valuedouble too. 275 #define cJsON_SetIntValue(object,number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))276  helper for the cJsON_SetNumberValue macro 277 CJsON_PUBliC(double) cJsON_SetNumberHelper(cJsON *278 #define cJsON_SetNumberValue(object,number) ((object != NulL) ? cJsON_SetNumberHelper(object,(double)number) : (number))279  Change the valuestring of a cJsON_String object,only takes effect when type of object is cJsON_String 280 CJsON_PUBliC(char*) cJsON_SetValuestring(cJsON *281 282  Macro for iterating over an array or object 283 #define cJsON_ArrayForEach(element,array) for(element = (array != NulL) ? (array)->child : NulL; element != NulL; element = element->next)284 285  malloc/free objects using the malloc/free functions that have been set with cJsON_InitHooks 286 CJsON_PUBliC() cJsON_malloc(size_t size);287 CJsON_PUBliC(voID) cJsON_free(object288 289 290 }291 292 293 #endif
VIEw Code

cJsON.c

   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23  cJsON   24  JsON parser in C.   25   26  disable warnings about old C89 functions in MSVC   27 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)  28 #define _CRT_SECURE_NO_DEPRECATE  29   30   31 #ifdef __GNUC__  32 #pragma GCC visibility push(default)  33   34 #if defined(_MSC_VER)  35 #pragma warning (push)  36  disable warning about single line comments in system headers   37 #pragma warning (disable : 4001)  38   39   40 #include <string.h>  41 #include <stdio.h>  42 #include <math.h>  43 #include <stdlib.h>  44 #include <limits.h>  45 #include <ctype.h>  46 #include <float.h>  47   48 #ifdef ENABLE_LOCALES  49 #include <locale.h>  50   51   52   53 #pragma warning (pop)  54   55   56 #pragma GCC visibility pop  57   58   59 #include   60   61  define our own boolean type   62 #ifdef true  63 #undef true  64   65 #define true ((cJsON_bool)1)  66   67 #ifdef false  68 #undef false  69   70 #define false ((cJsON_bool)0)  71   72  define isnan and isinf for ANSI C,if in C99 or above,isnan and isinf has been defined in math.h   73 #ifndef isinf  74 #define isinf(d) (isnan((d - d)) && !isnan(d))  75   76 #ifndef isnan  77 #define isnan(d) (d != d)  78   79   80 #ifndef NAN  81 #define NAN 0.0/0.0  82   83   84 typedef  {  85     const unsigned Json;  86     size_t position;  87 } error;  88 static error global_error = { NulL,1)"> };  89   90 CJsON_PUBliC()  91   92     return (char*) (global_error.Json + global_error.position);  93   94   95 CJsON_PUBliC(item)   96   97     if (!cJsON_Isstring(item))   98     {  99         return NulL; 100     } 101  102     return item-> 103  104  105 CJsON_PUBliC( 106  107     cJsON_IsNumber(item))  108  109          NAN; 110  111  112     valuedouble; 113  114  115  This is a safeguard to prevent copy-pasters from using incompatible C and header files  116 #if (CJsON_VERSION_MAJOR != 1) || (CJsON_VERSION_MInor != 7) || (CJsON_VERSION_PATCH != 13) 117     #error cJsON.h and cJsON.c have different versions. Make sure that both have the same. 118  119  120 CJsON_PUBliC( 121  122     static char version[15]; 123     sprintf(version,1)">%i.%i.%i 124  125      version; 126  127  128  Case insensitive string comparison,doesn't consIDer two NulL pointers equal though  129 int case_insensitive_strcmp(char *string1,1)">string2) 130  131     if ((string1 == NulL) || (string2 == NulL)) 132  133         return  134  135  136     if (string1 == string2) 137  138          139  140  141     for(; tolower(*string1) == tolower(*string2); (voID)string1++,string2++ 142  143         if (*string1 == '' 144        {  145 146                     }  147 148  149 return     string2); tolower(*string1) - tolower(* 150 151  152  internal_hooks typedef  153 154 allocate)(size_t size);      155voID     pointer); (CJsON_CDECL *deallocate)( 156voID     pointer,size_t size); *(CJsON_CDECL *reallocate)( 157} internal_hooks;  158 159  160  work around MSVC error C2322: '...' address of dllimport '...' is not static   161 CJsON_CDECL internal_malloc(size_t size)  162 163 return     malloc (size); 164 165 voID pointer) CJsON_CDECL internal_free( 166 167 (pointer);      168 169 voID  170 * CJsON_CDECL internal_realloc( 171 realloc     (pointer,size); 172 173  174 #define  175 internal_malloc malloc#define  176 internal_free free#define  177 internal_realloc realloc 178  179  strlen of character literals resolved at compile time   180#define  181 static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) 182 static  { internal_malloc,internal_free,internal_realloc }; internal_hooks global_hooks = 183 184 static char unsigned char* cJsON_strdup(const*  hooks) internal_hooks *  185 186  187     size_t length = char     unsigned  188 *copy = 189 if     string ( NulL) == 190 191  192          193  194 char     length = strlen((string*)sizeof) + ""( 195char     copy = (unsigned allocate(length);*)hooks-> 196if      197 (copy == 198  199          200  201     memcpy(copy,length); 202  copy;      203 204  205  206 CJsON_PUBliC( 207 if      208 (hooks == 209  reset hooks           210 211         global_hooks.allocate =  212         global_hooks.deallocate =  213         global_hooks.reallocate =  214          215  216  217     global_hooks.allocate = if      218 (hooks->malloc_fn != 219 malloc_fn;         global_hooks.allocate = hooks-> 220 221  222  223     global_hooks.deallocate = if      224 (hooks->free_fn != 225 free_fn;         global_hooks.deallocate = hooks-> 226 227  228  use realloc only if both free and malloc are used       229 230     global_hooks.reallocate =if     malloc ((global_hooks.allocate == ))) && (global_hooks.deallocate ==  231 232  233         global_hooks.reallocate =  234  235  236  Internal constructor.   237static  238 cJsON *cJsON_New_Item( 239 sizeof     cJsON* node = (cJsON*)hooks->allocate((cJsON)); 240if      (node) 241 242  244         memset(node,1)">',1)"> 243  245  node;      246 247  248  Delete a cJsON structure.   249item) CJsON_PUBliC( 250 251  252     cJsON *next =while      253 (item != 254  255         next = item->if          256 (!(item->type & cJsON_IsReference) && (item->child != 257  258             cJsON_Delete(item-> 259 if          260 (!(item->type & cJsON_IsReference) && (item->valuestring != 261  262             global_hooks.deallocate(item-> 263 if         string (!(item->type & cJsON_StringIsConst) && (item-> 264 != 265  266             global_hooks.deallocate(item-> 267         global_hooks.deallocate(item);  268 next;         item = 269 270  271  272  get the decimal point character of the current locale   273char  274 get_decimal_point( 275  276 struct      localeconv(); lconv *lconv = 277return     char (unsigned  278) lconv->decimal_point[ 279 .      280 281  282  283 struct typedef  284 285 content;      286    size_t length;  287    size_t offset;  288 How deeply nested (in arrays/objects) is the input at the current offset.      size_t depth;  289    internal_hooks hooks;  290} parse_buffer;  291 292  check if the given size is left to read in a given parse buffer (starting with 1)   293#define  294 can_read(buffer,size) ((buffer != NulL) && (((buffer)->offset + size) <= (buffer)->length)) check if the buffer can be accessed at the given index (starting with 0)   295#define  296 can_access_at_index(buffer,index) ((buffer != NulL) && (((buffer)->offset + index) < (buffer)->length))#define  297 cannot_access_at_index(buffer,index) (!can_access_at_index(buffer,index)) get a pointer to the buffer at the position   298#define  299 buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) 300  Parse the input text to generate a number,and populate the result into item.   301static  input_buffer) cJsON_bool parse_number(cJsON *  302 303 double      304 number = char     unsigned  305 *after_end =char     unsigned 64 number_c_string[ 306char     unsigned  get_decimal_point(); decimal_point = 307 308     size_t i =  309 if      310 ((input_buffer == NulL) || (input_buffer->content == 311 false          312 313  314  copy the number into a temporary buffer and replace '.' with the decimal point      315     * of the current locale (for strtod)  316     * This also takes care of ' 317' not necessarily being available for marking the end of the input  for0     sizeof (i = 1; (i < ( 318(number_c_string) -  319)) && can_access_at_index(input_buffer,i); i++switch  (buffer_at_offset(input_buffer)[i])          320 321case 0             :  3221 323             2 324             3 325             4 326             5 327             6 328             7 329             8 330             9 331             + 332             - 333             e 334             E 335              buffer_at_offset(input_buffer)[i]; 336                 number_c_string[i] =break 337                  338 339  decimal_point;              340                 number_c_string[i] = 341 342                 default  343             goto loop_end;                  344 345 346 loop_end:  347  348 349     number_c_string[i] = char char     number = strtod((after_end);*)number_c_string,( 350**)&if after_end)      351 (number_c_string == 352false  parse_error           353;  354 355  number;  356     item->valuedouble = 357 use saturation in case of overflow   358     if INT_MAX)      359 (number >= 360 INT_MAX;  361         item->valueint = 362else if     )INT_MIN)  363 (number <= ( 364 INT_MIN;  365         item->valueint = 366else  367      368)number;  369         item->valueint = ( 370 371  cJsON_Number;  372     item->type = 373 number_c_string);  374     input_buffer->offset += (size_t)(after_end -true 375      376 377  don't ask me,but the original cJsON_SetNumberValue returns an integer or double   378  number) 379 CJsON_PUBliC( 380 381  382     object  383          384->valueint = 385  386      387  388          389  390     object  391          392->valueint = ( 393 object  394      395->valuedouble = 396 valuestring)  397 CJsON_PUBliC( 398 399  if object's type is not cJsON_String or is cJsON_IsReference,it should not set valuestring       400     ifobject     object (!( cJsON_IsReference))->type & cJsON_String) || ( 401->type & 402 403  404         if object     valuestring)) (strlen(valuestring) <= strlen( 405-> 406valuestring,valuestring);  407         strcpy( 408 409         char char     copy = (global_hooks);*) cJsON_strdup(( 410*)valuestring,& 411 412      413  414         object  415      416->valuestring != 417  418         cJsON_free(object  419      420->valuestring = 421  422      423  424  425 typedef buffer;  426     unsigned  427 428  current nesting depth (for formatted printing)   429     size_t depth;     cJsON_bool noalloc; 430  is this print a formatted print  431     cJsON_bool format;  432} printbuffer;  433  434 realloc printbuffer if necessary to have at least "needed" bytes more   435 char p,size_t needed)  436* ensure(printbuffer *  437char  438     unsigned  439 *newbuffer = 440     size_t newsize = if  441      442 ((p == NulL) || (p->buffer == 443  444          445 if 0     length)) ((p->length >  446) && (p->offset >= p-> 447 make sure that offset is valID   448          449 450          451 if  452      453 (needed > sizes bigger than INT_MAX are currently not supported   454          455 456          457  458 if     needed += p->offset + length)      459 (needed <= p-> 460return offset;          461 p->buffer + p-> 462 463 if noalloc) {      464 (p-> 465 466          467  calculate new buffer size   468     if 469      470 (needed > (INT_MAX /  overflow of int,use INT_MAX if possible   471         if 472          473 (needed <= 474  475             newsize = 476  477          478  479              480  481  482      483  484         newsize = needed *  485 if  486      487 (p->hooks.reallocate != reallocate with realloc if available   488         charbuffer,newsize);         newbuffer = (unsigned  489*)p->hooks.reallocate(p->if 490          491 (newbuffer ==buffer);  492             p->hooks.deallocate(p-> 493 494             p->length =  495             p->buffer = 496  497              498  499  500      otherwise reallocate manually   501         charhooks.allocate(newsize);         newbuffer = (unsigned  502*)p->newbuffer) 503          504 505  506             p->hooks.deallocate(p-> 507             p->length =  508             p->buffer = 509  510              (newbuffer)  511          512 513  514             memcpy(newbuffer,p->buffer,p->offset +  515  516         p->hooks.deallocate(p-> newsize;  517     p->length = newbuffer; 518     p->buffer = 519return  520      521 newbuffer + p-> 522  calculate the new length of the string in a printbuffer and update the offset   523 voID buffer)  524 update_offset(printbuffer *  525char  526     if *buffer_pointer = 527      528 ((buffer == NulL) || (buffer->buffer == 529  530          531  532     buffer_pointer = buffer->buffer + buffer->char )buffer_pointer);     buffer->offset += strlen(( 533* 534 535  securely comparison of floating-point variables   536 staticdouble  537 cJsON_bool compare_double( 538 a,1)"> b)double  fabs(a) : fabs(b);      539 maxVal = fabs(a) > fabs(b) ?return DBL_EPSILON);      540 (fabs(a - b) <= maxVal * 541 542  Render the number nicely from the given item into a string.   543 static output_buffer)  544 cJsON_bool print_number( 545char  546     unsigned double *output_pointer = 547     int d = item-> 548      549 length = char     size_t i = 26     unsigned 0 number_buffer[ temporary buffer to print the number into ] = { 550};  551double     unsigned 0.0      552 test =  553if  554      555 (output_buffer == 556  557          558  This checks for NaN and Infinity   559     if isinf(d))      560 (isnan(d) || 561char  562         length = sprintf(( 563*)number_buffer,1)">null 564  565      Try 15 decimal places of precision to avoID nonsignificant nonzero digits   566         %1.15g 567         length = sprintf(( 568 Check whether the original double can be recovered   569         if%lg         1 ((sscanf(()test,d)) 570) || !compare_double(( 571 If not,print with 17 decimal places of precision   572             %1.17g 573             length = sprintf(( 574 575  576  sprintf Failed or buffer overrun occurred   577     if0     int ((length < sizeof) || (length > ())))( 578(number_buffer) -  579 580  581          582  reserve appropriate space in the output   583      584if     output_pointer = ensure(output_buffer,(size_t)length +  585      586 (output_pointer == 587  588          589  copy the printed number to the output and replace locale  590          * dependent decimal point with '.'  591 0 592      593; i < ((size_t)length); i++if  decimal_point)          594 (number_buffer[i] == 595 596 continue             output_pointer[i] =  597              598 599  number_buffer[i];  600         output_pointer[i] = 601 602  603     output_pointer[i] =  (size_t)length;  604     output_buffer->offset += 605 606  607      608  parse 4 digit hexadecimal number   609 static input)  610 unsigned parse_hex4( 611int  612     unsigned  613 h =  614     size_t i = 0 4      615; i <  616; i++ parse digit   617         if'          618 ((input[i] >=  619) && (input[i] <= int  620             h += (unsigned  621) input[i] - A F          622 623int 10             h += (unsigned  624)  625 + input[i] - a f          626 627 628  629             h += (unsigned  invalID   630          631 632  633              634 if 3          635 (i <  636 shift left to make place for the next nibble   637             4 638             h = h <<  639 640  641  h;  642      643 644  converts a UTF-16 literal to UTF-8  645  * A literal can be one or two sequences of the form \uXXXX  646 charconst output_pointer) utf16_literal_to_utf8( 647 input_pointer,1)">const input_end,unsigned  648long int      649 unsigned int codepoint =  650     unsigned char first_code =  input_pointer;      651 *first_sequence =char 652     unsigned char utf8_length =  653     unsigned char utf8_position =  654     unsigned char sequence_length =  655     unsigned  656 first_byte_mark = if 6      657 ((input_end - first_sequence) <  658 input ends unexpectedly   659          fail; 660          661 662  get the first utf16 sequence   663      664 665     first_code = parse_hex4(first_sequence +  check that the code is valID   666     if0xDC00     0xDFFF (((first_code >=  667) && (first_code <=  668 669  670          671  UTF16 surrogate pair   672     if0xD800     0xDBFF ((first_code >=  673) && (first_code <=  674char  675         int *second_sequence = first_sequence +  676         unsigned 12 second_code =  \uXXXX\uXXXX          sequence_length =  677;  678if  679          680 ((input_end - second_sequence) <  681  682              683              684 if 0         \ ((second_sequence['] != 1u) || (second_sequence[ 685] !=  686 missing second half of the surrogate pair   687              688 689              690  get the second utf16 sequence   691          692 693         second_code = parse_hex4(second_sequence + if         0xDC00          694 ((second_code <  695) || (second_code >  invalID second half of the surrogate pair   696              697 698              699  700  calculate the unicode codepoint from the surrogate pair   701         0x100000x3FF         codepoint = 10 + (((first_code & 0x3FF) <<  702) | (second_code &  703 704  705     6  \uXXXX          sequence_length =  706;  first_code; 707         codepoint = 708 709  encode as UTF-8  710          * takes at maximum 4 bytes to encode: 711      * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  712 if0x80      713 (codepoint <  714 normal ascii,enCoding 0xxxxxxx   715          716 717         utf8_length = 0x800  718      719 two bytes,enCoding 110xxxxx 10xxxxxx   720          7210xC0         utf8_length =  11000000          first_byte_mark =  722;  7230x10000  724      725 three bytes,enCoding 1110xxxx 10xxxxxx 10xxxxxx   726          7270xE0         utf8_length =  11100000          first_byte_mark =  728;  729if 0x10FFFF      730 (codepoint <=  731 four bytes,enCoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx   732          7330xF0         utf8_length =  11110000          first_byte_mark =  734;  735 736  737      invalID unicode codepoint   738          739 740          741  encode as utf8   742     forchar     1 (utf8_position = (unsigned 0)(utf8_length -  743); utf8_position >  744; utf8_position-- 10xxxxxx   745         char0x80         (*output_pointer)[utf8_position] = (unsigned 0xBF)((codepoint |  746) &  747 748         codepoint >>=  encode first byte   749     if 750      751 (utf8_length > 0 char         (*output_pointer)[0xFF] = (unsigned  752)((codepoint | first_byte_mark) &  753 754  755     char 0x7F         (*output_pointer)[ 756)(codepoint &  757 758  utf8_length;  759     *output_pointer += 760 sequence_length;  761      762fail:  763  764 765      766  Parse the input text into an unescaped cinput,and populate item.   767 static 768  769 cJsON_bool parse_string(cJsON * char  770     char *input_pointer = buffer_at_offset(input_buffer) +  771      772 *input_end = buffer_at_offset(input_buffer) + char     unsigned  773     unsigned  774 *output = not a string   775     if\"      776 (buffer_at_offset(input_buffer)[ 777 778  779          780  781  calculate approximate size of the output (overestimate)   782          783 784         size_t allocation_length = while         size_t skipped_bytes =  785          786 (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end !=  is escape sequence   787             if0              788 (input_end[            {] ==  789 if1                  790 ((size_t)(input_end +                 { - input_buffer->content) >= input_buffer-> 791  prevent buffer overflow when last input character is a backslash  792                      793                }                      794  795 796                 skipped_bytes++            }                 input_end++ 797  798 799             input_end++if  800          801 (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != goto  string ended unexpectedly               802 fail;  803 804  This is at most how much we need for the output   805          skipped_bytes; 806         allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) -char 807         output = (unsigned if*)input_buffer->hooks.allocate(allocation_length +  808          809 (output == allocation failure   810              811 812  813  output;  814     output_pointer = loop through the string literal  815     while input_end)      816 (input_pointer < 817if  818          819 (*input_pointer !=  820  821             *output_pointer++ = *input_pointer++ escape sequence   822          823 824          825 if             unsigned  826              827 ((input_end - input_pointer) <  828  829                  830 switch ])              831 (input_pointer[ 832b  833                 \b 834                     *output_pointer++ =  835 836                     \f                  837                     *output_pointer++ =  838n                      839                 \n 840                     *output_pointer++ =  841r                      842                 \r 843                     *output_pointer++ =  844t                      845                 \t 846                     *output_pointer++ =  847 848                      849                 /                  850                  851 852                     *output_pointer++ = input_pointer[ 853                      UTF-16 literal   854                  855 856                 if                     sequence_length = utf16_literal_to_utf8(input_pointer,input_end,1)">output_pointer); 857                                         { (sequence_length ==  858  Failed to convert UTF16-literal to UTF-8  859                          860                    }                          861  862 863                      864  865                  866                      867  868             input_pointer += 869  870  zero terminate the output   871      872 873     *output_pointer =  cJsON_String;  874     item->type =)output; 875     item->valuestring = ( 876content);  877     input_buffer->offset = (size_t) (input_end - input_buffer-> 878 879     input_buffer->offset++ 880  881      882 if  883      884 (output !=hooks.deallocate(output);  885         input_buffer-> 886 887 if  888      889 (input_pointer != 890  891         input_buffer->offset = (size_t)(input_pointer - input_buffer-> 892  893  894      895  Render the cstring provIDed to an escaped version that can be printed.   896 staticconst  898 cJsON_bool print_string_ptr(char input,1)"> 897  899      900 *input_pointer = 901     unsigned  902     unsigned  numbers of additional characters needed for escaPing      size_t output_length =  903      904 905     size_t escape_characters =  906  907      908  909          910  empty string   911     if 912      913 (input == 914  915         output = ensure(output_buffer,1)">\"\" 916          917  918             char  920         strcpy(( 921*)output,1)"> 919  922          923  set "flag" to 1 if something needs to be escaped   924     for 925      926 (input_pointer = input; *input_pointer; input_pointer++switch input_pointer)          927 (* 928 929  930              931              932              933              934              935              one character escape sequence               936                  937 938                 escape_characters++ 939                 if             32                  940 (*input_pointer <  941 UTF-16 escape sequence uXXXX   942                     5 943                     escape_characters +=  944 945  946                  947  escape_characters;  948     output_length = (size_t)(input_pointer - input) + 949 950  951     output = ensure(output_buffer,output_length +  952      953  954          955  no characters have to be escaped   956     if 957      958 (escape_characters == 0  959         output[ 960] = 1         memcpy(output +  961         output[output_length + 2] =  962         output[output_length +  963] =  964  965          966  967  968     output[ copy the string      output_pointer = output +  969     for'     voID (input_pointer = input; *input_pointer !=  970; ( 971)input_pointer++,output_pointer++if 31         ' ((*input_pointer >  972) && (*input_pointer !=  973) && (*input_pointer !=  normal character,copy   974             input_pointer; 975             *output_pointer = * 976 977  978          character needs to be escaped   979              980 981             *output_pointer++ =  982              983  984                  985                     *output_pointer =  986                      987                  988                     *output_pointer =  989                      990                  991                     *output_pointer =  992                      993                  994                     *output_pointer =  995                      996                  997                     *output_pointer =  998                      999                 1000                     *output_pointer = 1001                     1002                 1003                     *output_pointer = 1004                      escape and print as unicode codepoint                  1005                     charinput_pointer);                     sprintf((1006*)output_pointer,1)">u%04x10071008                     output_pointer += 1009                     1010 1011 1012 1013     output[output_length + 1014     output[output_length + 1015 1016     1017  Invoke print_string_ptr (which is useful) on an item.  1018 static p) 1019 cJsON_bool print_string(1020return char     1021 print_string_ptr((unsigned 1022*)item->1023  Predeclare these prototypes.  1024 static input_buffer); 1025 cJsON_bool parse_value(cJsON * static output_buffer); 1026 cJsON_bool print_value(static1027 static cJsON_bool parse_array(cJsON * 1028 static cJsON_bool print_array(1029 static cJsON_bool parse_object(cJsON * 1030 1031 cJsON_bool print_object( Utility to jump whitespace and cr/lf  1032 static1033 1034 parse_buffer *buffer_skip_whitespace(parse_buffer * if 1035     1036 ((buffer == NulL) || (buffer->content ==1037 1038         1039 if 1041      buffer; (cannot_access_at_index(buffer,1)">1040 1042         10431044 while 0     1045 (can_access_at_index(buffer,1)">0) && (buffer_at_offset(buffer)[1046] <= 1047 1048        buffer->offset++1049 if 1050     1051 (buffer->offset == buffer->1052 1053         buffer->offset--1054 1055 1056     1057  skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer  1058 static1059 1060 parse_buffer *skip_utf8_bom(parse_buffer * if 1061     1062 ((buffer == NulL) || (buffer->content == NulL) || (buffer->offset != 1063 1064         1065 if char     3 (can_access_at_index(buffer,1)">4) && (strncmp((1066*)buffer_at_offset(buffer),1)">\xEF\xBB\xBF1067) == 1068 1069         buffer->offset += 1070 1071 1072     1073 1074 1075 CJsON_PUBliC(cJsON *) cJsON_ParseWithOpts(    size_t buffer_length; 1076 1077if  value)     1078 (NulL ==10791080 1081         1082  Adding null character size due to require_null_terminated.  1083     10841085     buffer_length = strlen(value) +  cJsON_ParseWithLengthOpts(value,buffer_length,return_parse_end,require_null_terminated); 1086     10871088  Parse an object - create a new root,and populate.  1089 10901091 CJsON_PUBliC(cJsON *) cJsON_ParseWithLengthOpts(0  } };     parse_buffer buffer = { 1092,{ 10931094     cJsON *item = reset error position  1095     10961097     global_error.Json =1098     global_error.position = if 0      buffer_length) (value == NulL || 1099 ==11001101 1102         1103 )value; 1104     buffer.content = ( buffer_length; 1105     buffer.length =1106 global_hooks;     buffer.offset = 1107     buffer.hooks =11081109 if     item = cJsON_New_Item(& memory fail      1110 (item == NulL) 11111112 1113         1114 if buffer))))     1115 (!parse_value(item,buffer_skip_whitespace(skip_utf8_bom(&1116 parse failure. ep is set.  1117         11181119         1120  if we require null-terminated JsON without appended garbage,skip and then check for a null terminator  1121      (require_null_terminated)1122     11231124 if         buffer_skip_whitespace(&1125         1126 ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[1127 1128             1129  (return_parse_end) 1130     1131char 1132         *return_parse_end = (1133*)buffer_at_offset(&1134  item; 1135     11361137 if 1138     1139 (item !=        cJsON_Delete(item); 1140 11411142 if 1143     1144 (value !=        error local_error; 1145 11461147         local_error.Json = (1148         local_error.position = if  buffer.length)         1149 (buffer.offset <1150 buffer.offset; 1151             local_error.position =1152if 1153         1154 (buffer.length > 1155 1156             local_error.position = buffer.length - 1157 if 1158         1159 (return_parse_end !=char  local_error.position;             *return_parse_end = (1160*)local_error.Json +11611162  local_error; 1163         global_error =11641165 1166 1167     1168  Default options for cJsON_Parse  1169 value)1170 CJsON_PUBliC(cJsON *) cJsON_Parse(1171return 1173     1174 cJsON_ParseWithOpts(value,1)">1172 1175 1176 CJsON_PUBliC(cJsON *) cJsON_ParseWithLength(return 1178     1179 cJsON_ParseWithLengthOpts(value,1)">1177 #define 1180 1181 cJson_min(a,b) (((a) < (b)) ? (a) : (b))char 1182 1183 *print(const 256     1184 size_t default_buffer_size = 1185char     printbuffer buffer[1186     unsigned 1187 *printed =1188 1189     memset(buffer,1)">(buffer)); create buffer  1190     charallocate(default_buffer_size);     buffer->buffer = (unsigned 1191*) hooks-> default_buffer_size;1192     buffer->length = format;1193     buffer->format =hooks;1194     buffer->hooks = *if1195     1196 (buffer->buffer ==1197 1198         1199  print the value  1200     print_value(item,buffer))1201     12021203 1204             update_offset(buffer); 1205 1206 check if reallocate is available  1207     if1208     1209 (hooks->reallocate !=char 1210         printed = (unsigned if*) hooks->reallocate(buffer->buffer,buffer->offset +  NulL) {         1211 (printed ==12121213             1214 1215         buffer->buffer = otherwise copy the JsON over to a new buffer  1216     1217char 1218         printed = (unsigned 1219*) hooks->allocate(buffer->offset + 1220         1221 1222             '  just to be sure          memcpy(printed,buffer->buffer,cJson_min(buffer->length,1)">1223         printed[buffer->offset] = 1224; 1225 free the buffer  1226         12271228         hooks->deallocate(buffer->1229  printed; 1230     12311232 if 1233     1234 (buffer->buffer !=1235 1236         hooks->deallocate(buffer->1237 if 1238     1239 (printed !=deallocate(printed); 1240         hooks->12411242 1243 1244     1245  Render a cJsON item/entity/structure to text.  1246 12471248 CJsON_PUBliC(char 1250     1251*)print(item,1)">true,1)">1249 1252 1253 CJsON_PUBliC(false 1255     1256,1)">1254 1257 1258 CJsON_PUBliC(1259 1260     printbuffer p = { if 1261     1262 (prebuffer < 1263 1264         1265 )global_hooks.allocate((size_t)prebuffer); 1266     p.buffer = (unsigned p.buffer)1267     12681269 1270         1271  (size_t)prebuffer; 1272     p.length =12731274     p.offset =  fmt;     p.noalloc = 1275     p.format =12761277     p.hooks =if 1278     1279 (!print_value(item,1)">p))        global_hooks.deallocate(p.buffer); 1280 12811282         1283 )p.buffer; 1284     12851286 1287 1288 CJsON_PUBliC(cJsON_bool) cJsON_PrintPreallocated(cJsON *item,1)"> cJsON_bool format)1289 1290     printbuffer p = { 0 1291     1292) || (buffer ==1293 1294         1295 )buffer; 1296     p.buffer = (unsigned 12971298     p.length =1299     p.offset = 1300     p.noalloc = 1301     p.format =1302     p.hooks =return 1303     1304 print_value(item,1)">p);1305  Parser core - when encountering text,process appropriately.  1306 13071308 1309 1310      no input  1311         13121313  parse the different types of values  1314      null 1315     if1316     1317 (can_read(input_buffer,1)">char*)buffer_at_offset(input_buffer),1)">4) ==  cJsON_NulL; 1318         item->type =13191320         input_buffer->offset += 1321          false  1322     5false     5) && (strncmp((13231324) ==  cJsON_False; 1325         item->type =13261327         input_buffer->offset += 1328          true  1329     true1330     1331 cJsON_True; 1332         item->type =13331334         item->valueint = 1335         input_buffer->offset += 1336          string  1337     if1338     1339 (can_access_at_index(input_buffer,1)">0) && (buffer_at_offset(input_buffer)[ parse_string(item,input_buffer); 1340         1341 number  1342     0'     0) && ((buffer_at_offset(input_buffer)[') || ((buffer_at_offset(input_buffer)[))))] >= 1343) && (buffer_at_offset(input_buffer)[13441346  array           parse_number(item,1)">1345 1347     [1348     13491351  object           parse_array(item,1)">1350 1352     {1353     13541356 1357          parse_object(item,1)">1355 1358 1359     1360  Render a value to text.  1361 13621363 1364 1365     unsigned if 1366     1367 ((item == NulL) || (output_buffer ==1368 1369         1370 switch 1371     1372 ((item->type) & case  cJsON_NulL:         137313751376             output = ensure(output_buffer,1)">1374             1377 1378                 1379 1380             strcpy((1381              cJsON_False: 1382         13841385             output = ensure(output_buffer,1)">1383             1386 1387                 1388 1389             strcpy((1390              cJsON_True: 1391         13931394             output = ensure(output_buffer,1)">1392             1395 1396                 1397 1398             strcpy((1399              cJsON_Number: 1400          print_number(item,output_buffer);1401             1402 cJsON_Raw: 1403         14041405 if             size_t raw_length = 1406             1407 (item->valuestring ==1408 1409                 1410 1411  ensure(output_buffer,raw_length);             raw_length = strlen(item->valuestring) + 1412             output =14131414             1415 1416                 1418 1419             memcpy(output,1)">1417             1420  cJsON_String: 1421         1423 cJsON_Array:              print_string(item,1)">1422 1424         1426 cJsON_Object:              print_array(item,1)">1425 1427         14291430              print_object(item,1)">1428 1431         1432             1433 1434  Build an array from input text.  1435 14361437  head of the linked List  1438     cJsON *head = NulL; 14391440     cJsON *current_item =if  CJsON_nesTING_liMIT)     1441 (input_buffer->depth >=1442 to deeply nested  1443         14441445 1446     input_buffer->depth++1447 1448      not an array  1449         14501451         1452 1453     buffer_skip_whitespace(input_buffer);     input_buffer->offset++1454 ]1455     1456 empty array  1457          success;1458         14591460  check if we skipped to the end of the buffer  1461     if1463     1464 (cannot_access_at_index(input_buffer,1)">1462 1465         input_buffer->offset--1466         1467  step back to character in front of the first element  1468     1469 loop through the comma separated array elements      input_buffer->offset--1470     do1471     1472 allocate next item  1473         hooks));1474         cJsON *new_item = cJsON_New_Item(&(input_buffer->if1475         1476 (new_item ==1477 1478             1479  attach next item to List  1480         if1481         1482 (head == start the linked List  1483              new_item;1484             current_item = head =14851486 1487          add to the end and advance  1488             1489 current_item;             current_item->next =1490             new_item->prev =14911492             current_item =1493  parse next value  1494         1495        buffer_skip_whitespace(input_buffer);         input_buffer->offset++1496 parse_value(current_item,input_buffer))1497         1498 Failed to parse value  1499             15001501 1502 while 1503     1504 (can_access_at_index(input_buffer,0 1505     1506) || buffer_at_offset(input_buffer)[ expected end of array  1507         15081509 success: 1510 15111512     input_buffer->depth-- cJsON_Array; 1513     item->type = head;1514     item->child =15151516 1517     input_buffer->offset++1518 1519     1520 if 1521     1522 (head !=        cJsON_Delete(head); 1523 15241525 1526 1527     1528  Render an array to text  1529 15301531 1532 1533     unsigned 1534     size_t length = 1535     cJsON *current_element = item->1536 1537     1538 1539         1540  Compose the output array.  1541      opening square bracket 1542     15441545     output_pointer = ensure(output_buffer,1)">1543     1546 1547         1548 1549 1550     *output_pointer = 1551     output_buffer->offset++1552     output_buffer->depth++while 1553     1554 (current_element !=print_value(current_element,output_buffer)) 1555         15561557 1558                     update_offset(output_buffer); 1559 ifnext)         1560 (current_element->15612 1562             length = (size_t) (output_buffer->format ? 1563 : 1564             output_pointer = ensure(output_buffer,length + 1565             1566 1567                 1568 if             *output_pointer++ = format)             1569(output_buffer->1570' 1571                 *output_pointer++ = 1572 1573  length;             *output_pointer = 1574             output_buffer->offset +=15751576 1577         current_element = current_element->1578 1580 1581     output_pointer = ensure(output_buffer,1)">1579     1582 1583         1584 1585     *output_pointer++ = 1586     *output_pointer = 1587     output_buffer->depth--1588 1589     1590  Build an object from the text.  1591 15921593  linked List head  1594     cJsON *head = NulL; 15951596     cJsON *current_item =1597 1598     1599 1600         1601 1602     input_buffer->depth++0 1603     1604) || (buffer_at_offset(input_buffer)[ not an object  1605         16061607 1608 1609     input_buffer->offset++} 1610     1611goto  empty object          1612 success; 16131614 1615 1616     1617     1618 1619         input_buffer->offset--1620         1621 1622 1623     1624     input_buffer->offset--1625     1626     1627 1628         1629         cJsON *new_item = cJsON_New_Item(&(input_buffer->1630         1631 1632             1633 1634 1635         1636         1637 1638             1639             current_item = head =1640 1641         1642 1643             1644             current_item->next =1645             new_item->prev =1646             current_item =1647  parse the name of the child  1648         16491650         input_buffer->offset++1652  Failed to parse name          parse_string(current_item,1)">1651 1653             16541655 1656  swap valuestring and string,because we parsed the name  1657         string1658         current_item->1659 = current_item->1660         current_item->valuestring =: 1661         1662 invalID object  1663             16641665  parse the value  1666         16671668         input_buffer->offset++1669 1670         1671 1672             1673 1674 1675 1676     1677 1678      expected end of object  1679         16801681 1682 1683 1684     input_buffer->depth-- cJsON_Object; 1685     item->type =16861687     item->child =1688 1689     input_buffer->offset++1690     1691 1692 1693     1694 1695 1696 1697 1698     1699  Render an object to text.  1700 17011702 1703 1704     unsigned 1705     size_t length = 1706     cJsON *current_item = item->1707 1708     1709 1710         1711  Compose the output:  1712     1 fmt: {\n      length = (size_t) (output_buffer->format ? 1713); 17151716     output_pointer = ensure(output_buffer,1)">1714     1717 1718         1719 1720 1721     *output_pointer++ = if     output_buffer->depth++1722     1723 (output_buffer->1724 1725         *output_pointer++ = 1726 1727     output_buffer->offset +=while  (current_item)     172817291730 1731                     size_t i; 1732 depth);1733             output_pointer = ensure(output_buffer,output_buffer->17341735             1736 1737                 0 1738             1739; i < output_buffer->depth; i++1740 1741                 *output_pointer++ = depth; 1742             output_buffer->offset += output_buffer->17431744  print key  1745         ifchar         1746 (!print_string_ptr((unsigned 1747*)current_item->1748 1749             1750 1751 1752 1753         length = (size_t) (output_buffer->format ? 1754         output_pointer =1755         1756 1757             1758 1759         *output_pointer++ = 1760         1761 1762             *output_pointer++ = 1763 1764         output_buffer->offset += print value  1765         17671768         print_value(current_item,1)">1766 1769             1770 1771  print comma if not last  1772         10         length = ((size_t)(output_buffer->format ? 1773 : 1775) + (size_t)(current_item->next ? 1776         output_pointer = ensure(output_buffer,1)">1774         1777 1778             if 1779         1780 (current_item->1781 1782             *output_pointer++ = 1783 1784 1785         1786 1787             *output_pointer++ = 1788 1789         *output_pointer = 1790         output_buffer->offset +=1791 1792         current_item = current_item->1793 1 1794     output_pointer = ensure(output_buffer,output_buffer->format ? (output_buffer->depth + 1795) : 1796     1797 1798         1799 1800             size_t i; 1801 01         1802; i < (output_buffer->depth - 1803); i++1804 1805             *output_pointer++ = 1806 1807 1808     *output_pointer++ = 1809     *output_pointer = 1810     output_buffer->depth--1811 1812     1813  Get Array size/item / object item.  1814 array)1815 CJsON_PUBliC(18161817 1818     cJsON *child =1819     size_t size = if 1820     1821 (array ==1822 1823         1824 1825 1826     child = array->while 1827     1828(child !=1829 1830         size++1831         child = child->1832  FIXME: Can overflow here. Cannot be fixed without breaking the API  1833     1834)size; 1835     18361837 static array,size_t index) 1838 cJsON* get_array_item(18391840 1841     cJsON *current_child =1842 1843     1844 1845         1846 1847 while     current_child = array->1848     1849 ((current_child != NulL) && (index > 1850 1851         index--1852         current_child = current_child->1853  current_child; 1854     18551856  index) 1857 CJsON_PUBliC(cJsON *) cJsON_GetArrayItem(1858if 1859     1860 (index < 1861 1862         1863  get_array_item(array,(size_t)index); 1864     18651866 static  cJsON_bool case_sensitive) 1867 cJsON *get_object_item(18681869 1870     cJsON *current_element =if object     1871 ((1872 == NulL) || (name ==1873 1874         1875 1876  (case_sensitive)     current_element = 1877     1878while string         string ((current_element != NulL) && (current_element->1879 != NulL) && (strcmp(name,current_element->1880) != 1881 1882             current_element = current_element->1883 1884 1885     while char         string ((current_element != NulL) && (case_insensitive_strcmp((1886*)name,1)">char*)(current_element->1887)) != 1888 1889             current_element = current_element->1890 1891 if  NulL)) {     1892 ((current_element == NulL) || (current_element->18931894         1895  current_element; 1896     18971898 1899 1900 CJsON_PUBliC(cJsON *) cJsON_GetobjectItem(return 1901     1902 get_object_item(1903 1904 1905 CJsON_PUBliC(cJsON *) cJsON_GetobjectItemCaseSensitive(1906 1907     1908 1909 1910 CJsON_PUBliC(cJsON_bool) cJsON_HasObjectItem(return string     1911 cJsON_GetobjectItem(1912) ? 1913  Utility for array List handling.  1914 voID1916 1917 suffix_object(cJsON *prev,1)">1915  prev;     prev->next =1918     item->prev =19191920  Utility for handling references.  1921 static1922 1923 cJsON *create_reference(1924 if     cJsON *reference =1925     1926 (item ==1927 1928         1929  cJsON_New_Item(hooks); 1930     reference =if1931     1932 (reference ==1933 1934         1935 string 1937     memcpy(reference,item,1)">1936     reference-> cJsON_IsReference; =1938     reference->type |=1939 reference;     reference->next = reference->prev =1940     19411942 static 1944 1945 cJsON_bool add_item_to_array(cJsON *array,1)">1943 1946     cJsON *child =if  item))     1947 ((item == NulL) || (array == NulL) || (array ==19481949 1950         1951 1952 1953     child = array->     * To find the last item in array quickly,we use prev in array     1954 1955if      1956     1957 (child == List is empty,start new one  1958         19591960         array->child =1961         item->prev =1962         item->next =1963 1964      append to the end  1965         ifprev)         1966 (child->1967prev,item); 1968             suffix_object(child->19691970             array->child->prev =1971 1972         while 1973             1974 (child->1975 1976                 child = child->1978 1979             suffix_object(child,1)">1977             array->child->prev =1980 1981 1982 1983     1984  Add item to array/object.  1985 19871989 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToArray(cJsON *array,1)">1986 1990      add_item_to_array(array,1)">1988 #if 1991 #pragma defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MInor__ > 5))))1992     1993 GCC diagnostic push1994 #pragma 1995 1996 GCC diagnostic ignored "-Wcast-qual" helper function to cast away const  1997 voIDvoID 1998* cast_away_const(1999* voID 2000     2001*)2002 #pragma 2003     2004 GCC diagnostic pop2005 2006 static const 2007 cJsON_bool add_item_to_object(cJsON * 2008 hooks,1)"> cJsON_bool constant_key)char 2009     int *new_key = cJsON_InvalID;     2010 new_type =2011object string     object == NulL) || (2012 == NulL) || (item == NulL) || (2013 ==2014 2015         2016  (constant_key) 2017     2018char 2019         new_key = ( cJsON_StringIsConst;*)cast_away_const(2020         new_type = item->type |20212022 2023     char 2024         new_key = (if*)cJsON_strdup((2025         2026 (new_key ==2027 2028             2029 cJsON_StringIsConst; 2030         new_type = item->type & ~20312032 2033 2034     2035 2036         hooks->deallocate(item->2037  new_key; 2038     item-> new_type;2039     item->type =2040return 2041     2042 add_item_to_array(2043 2044 2045 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObject(cJsON *return 2046     2047 add_item_to_object(2048  Add an item to an object with constant string as key  2049 20502051 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObjectCS(cJsON *2052 2053     2054 2056 2057 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoArray(cJsON *array,1)">2055 2058     2059 2060         2061 return 2062     2063 add_item_to_array(array,create_reference(item,1)">global_hooks));2064 2065 2066 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoObject(cJsON *2067 2068     2069 2070         2071 2072 2073     2074  name) 2075 CJsON_PUBliC(cJsON*) cJsON_AddNullToObject(cJsON * 2076null  cJsON_CreateNull();     cJsON *2077 =ifnull     2079 (add_item_to_object(null,1)">2078 2080         20812082 2083 2084     cJsON_Delete(2085     2086 2087 2088 CJsON_PUBliC(cJsON*) cJsON_AddTruetoObject(cJsON *  cJsON_CreateTrue(); 2089     cJsON *true_item =20902091      true_item; 2092         20932094     cJsON_Delete(true_item); 2095 20962097     2098 2099 2100 CJsON_PUBliC(cJsON*) cJsON_AddFalsetoObject(cJsON *  cJsON_CreateFalse(); 2101     cJsON *false_item =21022103      false_item; 2104         21052106     cJsON_Delete(false_item); 2107 21082109     2110  cJsON_bool boolean) 2111 CJsON_PUBliC(cJsON*) cJsON_AddBoolToObject(cJsON * 2112 cJsON_CreateBool(boolean); 2113     cJsON *bool_item =21142115      bool_item; 2116         21172118     cJsON_Delete(bool_item); 2119 21202121     2122 2123 2124 CJsON_PUBliC(cJsON*) cJsON_AddNumberToObject(cJsON *  cJsON_CreateNumber(number); 2125     cJsON *number_item =21262127      number_item; 2128         21292130     cJsON_Delete(number_item); 2131 21322133     2134 2135 2136 CJsON_PUBliC(cJsON*) cJsON_AddStringToObject(cJsON * 2137 2138     cJsON *string_item = cJsON_CreateString(2139      string_item; 2140         21412142     cJsON_Delete(string_item); 2143 21442145     2146  raw) 2147 CJsON_PUBliC(cJsON*) cJsON_AddRawToObject(cJsON * 2148 cJsON_Createraw(raw); 2149     cJsON *raw_item =21502151      raw_item; 2152         21532154     cJsON_Delete(raw_item); 2155 21562157     2158 2159 2160 CJsON_PUBliC(cJsON*) cJsON_AddobjectToObject(cJsON *  cJsON_CreateObject(); 2161     cJsON *object_item =21622163      object_item; 2164         21652166     cJsON_Delete(object_item); 2167 21682169     2170 2171 2172 CJsON_PUBliC(cJsON*) cJsON_AddArrayToObject(cJsON *  cJsON_CreateArray(); 2173     cJsON *array =21742175      array; 2176         21772178     cJsON_Delete(array); 2179 21802181     2182 2183 2184 CJsON_PUBliC(cJsON *) cJsON_DetachItemViaPointer(cJsON *parent,1)"> item)if 2185     2186 ((parent == NulL) || (item ==2187 2188         2189 if child)     2190 (item != parent->2191 not the first element  2192         21932194         item->prev->next = item->if 2195     2196 (item->next != not the last element  2197         21982199         item->next->prev = item->2200 if 2201     2202 (item == parent-> first element  2203         22042205         parent->child = item-> make sure the detached item doesn't point anywhere anymore  2206     22072208     item->prev =2209     item->next =2210 2211     2212 2213 2214 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromArray(cJsON *array,1)"> which)if 2215     2216 (which < 2217 2218         2219  cJsON_DetachItemViaPointer(array,get_array_item(array,(size_t)which)); 2220     22212222 2223 2224 CJsON_PUBliC(    cJsON_Delete(cJsON_DetachItemFromArray(array,which)); 2225 22262227 2228 2229 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObject(cJsON *2230 2231     cJsON *to_detach = cJsON_GetobjectItem(return 2232     2233 cJsON_DetachItemViaPointer(2234 2235 2236 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObjectCaseSensitive(cJsON *2237 2238     cJsON *to_detach = cJsON_GetobjectItemCaseSensitive(2239 2240     2241 2242 2243 CJsON_PUBliC(2244 2245     cJsON_Delete(cJsON_DetachItemFromObject(2246 2247 2248 CJsON_PUBliC(2249 2250     cJsON_Delete(cJsON_DetachItemFromObjectCaseSensitive(2251  Replace array/object items with new ones.  2252 22532254 CJsON_PUBliC(cJsON_bool) cJsON_InsertItemInArray(cJsON *array,1)">newitem)2255 2256     cJsON *after_inserted =2257 2258     2259 2260         2261 2262 if     after_inserted =2263     2264 (after_inserted ==2265 2266         2267  after_inserted; 2268     newitem->next =2269 newitem;     newitem->prev = after_inserted->2270     after_inserted->prev =if2271     2272 (after_inserted == array->2273 2274         array->child =2275 2276     2277 2278         newitem->prev->next =2279 2280     2281  replacement) 2282 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemViaPointer(cJsON * 2283if 2284     2285 ((parent == NulL) || (replacement == NulL) || (item ==2286 2287         2288 if 2289     2290 (replacement ==2291 2292         2293 2294 2295     replacement->next = item->2296     replacement->prev = item->if 2297     2298 (replacement->next != replacement; 2299         replacement->next->prev =2300if 2301     2302 (parent->child ==2303 2304         parent->child =2305 2306              * To find the last item in array quickly,we use prev in array.     {   2307          * We can't modify the last item's next pointer where this item was the parent's child2308 2309if          2310         2311 (replacement->prev !=2312 2313             replacement->prev->next =2314 2315 2316 2317     item->next =    cJsON_Delete(item);     item->prev =2318 23192320 2321     2322 2324 2325 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInArray(cJsON *array,1)">2323 2326     2327 2328         2329 2331 2332      cJsON_ReplaceItemViaPointer(array,(size_t)which),1)">2330 static replacement,cJsON_bool case_sensitive) 2333 cJsON_bool replace_item_in_object(cJsON *2334if 2335     2336 ((replacement == NulL) || (2337 2338         2339  replace the name in the replacement  2340     if2341     2342 (!(replacement->type & cJsON_StringIsConst) && (replacement->2343 2344         cJsON_free(replacement->string 2345     replacement->2346 = (2347     replacement->type &= ~return 2348     2349 cJsON_ReplaceItemViaPointer(2350 2351 2352 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObject(cJsON *return 2353     2354 replace_item_in_object(2355 2356 2357 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObjectCaseSensitive(cJsON *2358 2359     2360  Create basic types:  2361 23622363 CJsON_PUBliC(cJsON *) cJsON_CreateNull(2364 (item)     cJsON *item = cJsON_New_Item(&2365     23662367 2368         item->type =2369 2370 2371     2372 2373 2374 CJsON_PUBliC(cJsON *) cJsON_CreateTrue(2375 2376     cJsON *item = cJsON_New_Item(&2377     2378 2379         item->type =2380 2381 2382     2383 2384 2385 CJsON_PUBliC(cJsON *) cJsON_CreateFalse(2386 2387     cJsON *item = cJsON_New_Item(&2388     2389 2390         item->type =2391 2392 2393     2394 ) cJsON_CreateBool(cJsON_bool boolean) 2395 CJsON_PUBliC(cJsON *23962397 2398     cJsON *item = cJsON_New_Item(&2399      cJsON_True : cJsON_False; 2400         item->type = boolean ?24012402 2403 2404     2405  num) 2406 CJsON_PUBliC(cJsON *) cJsON_CreateNumber(24072408 2409     cJsON *item = cJsON_New_Item(&2410     2411  num;         item->type =2412         item->valuedouble =24132414 if         2415         2416 (num >=2417 2418             item->valueint =if 2419         2420 (num <= (2421 2422             item->valueint =2423 2424         )num; 2425             item->valueint = (24262427 2428 2429 2430     2431 2432 2433 CJsON_PUBliC(cJsON *) cJsON_CreateString(2434 2435     cJsON *item = cJsON_New_Item(&2436     2437 2438         item->type =if         item->valuestring = (2439         2440(!item->            cJsON_Delete(item); 2441 24422443             2444 2445 2446 2447     2448 2449 2450 CJsON_PUBliC(cJsON *) cJsON_CreateStringReference(2451 2452     cJsON *item = cJsON_New_Item(&2453     2454 2455         item->type = cJsON_String |2456         item->valuestring = (2457 2458 2459     2460 2461 2462 CJsON_PUBliC(cJsON *) cJsON_CreateObjectReference(2463 2464     cJsON *item = cJsON_New_Item(&2465     )cast_away_const(child);         item->type = cJsON_Object |2466         item->child = (cJsON*24672468 2469 2470     2471 child) { 2472 CJsON_PUBliC(cJsON *) cJsON_CreateArrayReference(24732474     cJsON *item = cJsON_New_Item(&2475     2476         item->type = cJsON_Array |2477         item->child = (cJsON*2478 2479 2480     2481 raw) 2482 CJsON_PUBliC(cJsON *) cJsON_Createraw(24832484 2485     cJsON *item = cJsON_New_Item(&2486      cJsON_Raw; 2487         item->type =char2489         item->valuestring = (2490*)raw,1)">2488         2491 2492 2493             2494 2495 2496 2497     2498 2499 2500 CJsON_PUBliC(cJsON *) cJsON_CreateArray(2501 2502     cJsON *item = cJsON_New_Item(&2503     cJsON_Array; 2504         item->type=25052506 2507 2508     2509 2510 2511 CJsON_PUBliC(cJsON *) cJsON_CreateObject(2512  (item)     cJsON *item = cJsON_New_Item(&2513     25142515 2516         item->type =2517 2518 2519     2520  Create Arrays:  2521  count)2522 CJsON_PUBliC(cJsON *) cJsON_CreateIntArray(25232524 2525     size_t i = 2526     cJsON *n =2527     cJsON *p =2528     cJsON *a =if 0     2529 ((count < 2530) || (numbers ==2531 2532         2533 2534 for     a =0     2535(i = 2536; a && (i < (size_t)count); i++ cJsON_CreateNumber(numbers[i]); 2537         n =n)2538         2539            cJsON_Delete(a); 2540 25412542             if i)         2543(!2544 n; 2545             a->child =25462547 2548                     suffix_object(p,n); 2549 25502551 2552         p =2553  a; 2554     25552556 2557 2558 CJsON_PUBliC(cJsON *) cJsON_CreatefloatArray(2559 2560     size_t i = 2561     cJsON *n =2562     cJsON *p =2563     cJsON *a =2564 2565     2566 2567         2568 2569 2570     a =2571 2572     )numbers[i]); 2573         n = cJsON_CreateNumber((25742575         2576 2577 2578             2579 2580         2581 2582             a->child =2583 2584         2585 2586 2587 2588         p =2589 2590 2591     2592 2593 2594 CJsON_PUBliC(cJsON *) cJsON_CreateDoubleArray(2595 2596     size_t i = 2597     cJsON *n =2598     cJsON *p =2599     cJsON *a =2600 2601     2602 2603         2604 2605 2606     a =0 2607     2608;a && (i < (size_t)count); i++2609 2610         n =2611         2612 2613 2614             2615 2616         2617 2618             a->child =2619 2620         2621 2622 2623 2624         p =2625 2626 2627     2628 2629 2630 CJsON_PUBliC(cJsON *) cJsON_CreateStringArray(2631 2632     size_t i = 2633     cJsON *n =2634     cJsON *p =2635     cJsON *a =0 2636     2637) || (strings ==2638 2639         2640 2641 2642     a =2643 2644      cJsON_CreateString(strings[i]); 2645         n =26462647         2648 2649 2650             2651 2652         2653 2654             a->child =2655 2656         2657 2658 2659 2660         p =2661 2662 2663     2664  Duplication  2665 26662667 CJsON_PUBliC(cJsON *) cJsON_Duplicate(2668 2669     cJsON *newitem =2670     cJsON *child =2671     cJsON *next =2672     cJsON *newchild = Bail on bad ptr  2673     26742675     2676 2677          Create new item  2678     26792680     newitem = cJsON_New_Item(&2681     2682 2683          copy over all vars  2684     cJsON_IsReference);2685     newitem->type = item->type & (~valueint;2686     newitem->valueint = item->2687if     newitem->valuedouble = item->2688     2689 (item->char char         newitem->valuestring = (if*)cJsON_strdup((unsigned 2691*)item->valuestring,1)">2690         2692 (!newitem->2693 2694             2695 2696 2697     string string         newitem->2698 = (item->type&cJsON_StringIsConst) ? item->2699 : (2700         2701 2702             2703  If non-recursive,then we're done!  2704     recurse)2705     27062707 2708          Walk the ->next chain for the child.  2709     2710while     child = item->2711     2712 (child != Duplicate (with recurse) each item in the ->next chain  2713         newchild = cJsON_Duplicate(child,1)">true); newchild)2714         27152716 2717             if 2718         2719 (next != If newitem->child already set,then crosswire ->prev and ->next and move on  2720              newchild;2721             next->next =27222723             newchild->prev =2724             next =2725 2726          Set newitem->child and move to it  2727             27282729             newitem->child =2730             next =2731 2732         child = child->2733 2734 2735     2736 if 2737     2738 (newitem !=        cJsON_Delete(newitem); 2739 27402741 2742 2743     2744 voID input) 2745 skip_oneline_comment(2746// 2747     *input += static_strlen(2748for '     input)) (; (*input)[2749; ++(*2750if ) {         2751 ((*input)[27522753             *input += static_strlen(2754             2755 2756 2757 voID 2758 2759 skip_multiline_comment(/* 2760     *input += static_strlen(27612762 2763     if *         ' (((*input)[12764) && ((*input)[2765] == */ 2766             *input += static_strlen(27672768             2769 2770 2771 voID char 2772 Minify_string(0 **input,1)">output) {2773     (*output)[2774] = (*input)[2775     *input += static_strlen(2776     *output += static_strlen(2777 voID output)) {     2778)++(*input),++(*27792780         (*output)[2781 2782         2783             (*output)[2784             *input += static_strlen(2785             *output += static_strlen()) {             2786         } 12787             (*output)[2788] = (*input)[2789             *input += static_strlen(2790             *output += static_strlen(2791 2792 2793 Json) 2794 CJsON_PUBliC(2795char  Json;     2796 *into =2797if 2798     2799 (Json ==2800 2801         2802 while 2803     2804 (Json[switch 2805         2806 (Json[2807 2808             2809             2810             2811             2812                 Json++2813                 2814 if             2815                 2816 (Json[2817 2818                     skip_oneline_comment(&2819 2820                 2821 else                     skip_multiline_comment(&2822                 } 28232824                     Json++2825 2826                 2827 2828             2829                 Minify_string(&Json,1)">into);2830                 2831 0             2832                 into[2833] = Json[2834                 Json++2835                 into++2836 2837  and null-terminate.  2838     28392840     *into = 2841 2842 2843 CJsON_PUBliC(cJsON_bool) cJsON_IsInvalID(2844 2845     2846 2847         2848 return 0xFF     2849 (item->type & 2850) ==2851 2852 2853 CJsON_PUBliC(cJsON_bool) cJsON_IsFalse(2854 2855     2856 2857         2858 2859 2860     2861 2862 2863 CJsON_PUBliC(cJsON_bool) cJsON_IsTrue(2864 2865     2866 2867         2868 0xff 2869     2870) ==2871 2872 2873 2874 CJsON_PUBliC(cJsON_bool) cJsON_IsBool(2875 2876     2877 2878         2879 return 2880     2881 (item->type & (cJsON_True | cJsON_False)) != 2882 2883 CJsON_PUBliC(cJsON_bool) cJsON_IsNull(2884 2885     2886 2887         2888 2889 2890     2891 2892 2893 CJsON_PUBliC(cJsON_bool) cJsON_IsNumber(2894 2895     2896 2897         2898 2899 2900     2901 2902 2903 CJsON_PUBliC(cJsON_bool) cJsON_Isstring(2904 2905     2906 2907         2908 2909 2910     2911 2912 2913 CJsON_PUBliC(cJsON_bool) cJsON_IsArray(2914 2915     2916 2917         2918 2919 2920     2921 2922 2923 CJsON_PUBliC(cJsON_bool) cJsON_IsObject(2924 2925     2926 2927         2928 2929 2930     2931 2932 2933 CJsON_PUBliC(cJsON_bool) cJsON_IsRaw(2934 2935     2936 2937         2938 2939 2940     2941 2942 2943 CJsON_PUBliC(cJsON_bool) cJsON_Compare(if 0xFF     0xFF ((a == NulL) || (b == NulL) || ((a->type &  cJsON_IsInvalID(a))) != (b->type & 2944)) ||29452946 2947         2948  check if type is valID  2949     switch2950     2951 (a->type & 2952 2953         2954         2955         2956         2957         2958         2959         2960         2961             2962 2963         2964             2965  IDentical objects are equal  2966     if2967     2968 (a ==2969 2970         2971 2972 2973      in these cases and equal type is enough  2974         29752976         2977         2978         2979             2980 if         valuedouble))             2981 (compare_double(a->valuedouble,b->29822983 2984                 2985 2986             2987 2988         if         2989             2990 ((a->valuestring == NulL) || (b->valuestring ==2991 2992                 if 2993             2994 (strcmp(a->valuestring,b->valuestring) == 2995 2996                 2997 2998 2999             3000 3001         3002 3003             cJsON *a_element = a->3004             cJsON *b_element = b->for  NulL);)             3005 (; (a_element != NulL) && (b_element !=3006cJsON_Compare(a_element,b_element,case_sensitive)) 3007                 30083009 3010                     3011 3012 3013                 a_element = a_element->3014                 b_element = b_element->3015  one of the arrays is longer than the other  3016             if b_element) {             3017 (a_element !=30183019                 3020 3021 3022             3023 3024 3025         3026 3027             cJsON *a_element =            cJsON_ArrayForEach(a_element,a)             cJsON *b_element =3028 3029 Todo This has O(n^2) runtime,which is horrible!  3030                 3031if                 b_element = get_object_item(b,a_element->3032                 3033 (b_element ==3034 3035                     3036 3037 3038                 3039 3040                     3041 3042  doing this twice,once on a and b to prevent true comparison if a subset of b 3043                          * Todo: Do this the proper way,this is just a fix for Now 3044             cJsON_ArrayForEach(b_element,b)3045 30463047 if                 a_element = get_object_item(a,b_element->3048                 3049 (a_element ==3050 3051                     3052 3054 3055                 cJsON_Compare(b_element,a_element,1)">3053 3056                     3057 3058 3059 3060             3061 3062 3063         3064             3065 3066 ) cJsON_malloc(size_t size) 3067 CJsON_PUBliC(3068 global_hooks.allocate(size); 3069     30703071 3072 3073 CJsON_PUBliC(3074 VIEw Code     global_hooks.deallocate( }
[+++]

 

 参考:

https://blog.csdn.net/shizhe0123/article/details/94742514

https://blog.csdn.net/fengxinlinux/article/details/53121287

https://www.cnblogs.com/skullboyer/p/8152157.html

总结

以上是内存溢出为你收集整理的不可不知的JSON处理库(cJSON)全部内容,希望文章能够帮你解决不可不知的JSON处理库(cJSON)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
不可不知的JSON处理库(cJSON)_C_内存溢出

不可不知的JSON处理库(cJSON)

不可不知的JSON处理库(cJSON),第1张

概述ANSI C中的超轻量级JSON解析器 JSON(JavaScript对象表示法)是一种轻量级的数据交换格式。人类易于阅读和书写。机器很容易解析和生成。它基于JavaScript编程语言标准ECMA-

ANSI C中的超轻量级JsON解析器

JsON(JavaScript对象表示法)是一种轻量级的数据交换格式。人类易于阅读和书写。机器很容易解析和生成。它基于JavaScript编程语言标准ECMA-262第三版(1999年12月)的子集 。JsON是一种完全独立于语言的文本格式,但是使用C语言家族(包括C,C ++,C#,Java,JavaScript,Perl,Python等)的程序员熟悉的约定。这些属性使JsON成为理想的数据交换语言。

cJsON旨在成为您可以完成工作的最简单的解析器。它是资源只有一个C的头文件和C文件,所以方便移植。它可以为你各种需要的Json字符串处理,包括打包、解析、修改、删除、添加等。在这里将一探究竟。

在这里将着重叙述Json的打包和解析,更多处理玩法,见文章末尾链接。

开始cJsON

cJsON合并到您的项目

因为整个库只有一个C文件和一个头文件,所以您只需复制cJsON.h并复制cJsON.c到项目源并开始使用它。

cJsON用ANSI C(C89)编写,以便支持尽可能多的平台和编译器。

 

下载:

https://github.com/DaveGamble/cJSON/releases

 

CJson结构体

/* The cJsON structure: */typedef struct cJsON{    struct cJsON *next;    prev;    child;    int type;    char *valuestring;     valueint;    double valuedouble;    string;} cJsON;

结构体项解析:

next 和prev :CJson结构体作为一个双向连表的环,可以通过 next 和prev 指针进行连表遍历

child:可以是cJsON_Array、cJsON_Object类型数据

type:当前项的类型

valuestring:内容存储,当类型是cJsON_String和cJsON_Raw

valueint:内容存储,整型,可以是cJsON_False、cJsON_True数据

valuedouble:内容存储,浮点型,当类型是cJsON_Number

string:键名

数据类型

l  cJsON_InvalID表示一个不包含任何值的无效项目。如果将项目设置为全零字节,则将自动具有此类型。

l  cJsON_False表示一个false布尔值。您也可以使用来检查布尔值cJsON_IsBool

l  cJsON_True表示一个true布尔值。您也可以使用来检查布尔值cJsON_IsBool

l  cJsON_NulL表示一个null值

l  cJsON_Number 表示一个数字值。该值存储为double in valuedouble和in valueint。如果数字超出整数范围,INT_MAX或INT_MIN用于valueint

l  cJsON_String表示一个字符串值。它以零终止字符串的形式存储在中valuestring

l  cJsON_Array表示一个数组值。这是通过指向表示数组中值child的cJsON项目的链接列表来实现的。使用next和将元素链接在一起prev,其中第一个元素具有prev.next == NulL和最后一个元素next == NulL

l  cJsON_Object 表示一个对象值。对象的存储方式与数组相同,唯一的区别是对象中的项将其键存储在中string

l  cJsON_Raw表示以JsON字符存储的零终止形式的任何JsON valuestring。例如,可以使用它来避免一遍又一遍地打印相同的静态JsON以节省性能。解析时,cJsON永远不会创建此类型。另请注意,cJsON不会检查其是否为有效JsON。

类型

#define cJsON_InvalID (0)#define cJsON_False  (1 << 0)#define cJsON_True   (1 << 1)#define cJsON_NulL   (1 << 2)#define cJsON_Number (1 << 3)#define cJsON_String (1 << 4)#define cJsON_Array  (1 << 5)#define cJsON_Object (1 << 6)#define cJsON_Raw    (1 << 7) /* raw Json */

类型判断

cJsON_IsInvalID(const cJsON * const item);cJsON_IsFalse( item);cJsON_IsTrue( item);cJsON_IsBool( item);cJsON_IsNull( item);cJsON_IsNumber( item);cJsON_Isstring( item);cJsON_IsArray( item);cJsON_IsObject( item);cJsON_IsRaw(const item);

注意

创建cJson对象后,处理完需要进行内存释放:

如果是cJson里的对象,请使用cJsON_Delete()

如果不是对象:cJsON_free()或free()

 

零字符

cJsON不支持包含零字符'\0'或的字符串\u0000。对于当前的API,这是不可能的,因为字符串以零结尾。

 

字符编码

cJsON仅支持UTF-8编码的输入。但是在大多数情况下,它不会拒绝无效的UTF-8作为输入,而只是将其原样传播。只要输入不包含无效的UTF-8,输出将始终是有效的UTF-8。

 

C标准

cJsON用ANSI C(或C89,C90)编写。如果您的编译器或C库未遵循此标准,则不能保证正确的行为。

 

注意:ANSI C不是C ++,因此不应使用C ++编译器进行编译。您可以使用C编译器对其进行编译,然后将其与C ++代码链接。尽管可以使用C ++编译器进行编译,但是不能保证正确的行为。

 

浮点数字

double除IEEE754双精度浮点数外,cJsON不正式支持任何实现。它可能仍然可以与其他实现一起使用,但是这些实现的错误将被视为无效。

 

目前,cJsON支持的浮点文字的最大长度为63个字符。

 

数组和对象的深层嵌套

cJsON不支持嵌套太深的数组和对象,因为这会导致堆栈溢出。为了防止这种CJsON_nesTING_liMIT情况,默认情况下,cJsON将深度限制为1000,但是可以在编译时进行更改。

格式化输出

按标准的格式输出Json字符串,输出完后一定要记得释放内存

 代码

 1 #include <stdio.h> 2 #include "cJsON.h" 3 #include cJsON.c 4 voID main(){ 5     //待解析字符串  6     char *Json_str={\"key1\":\"dongxiaodong\",\"key2\":1998,\"key3\":55778}"; 7      8     输出原字符串 9     printf(原字符串:%s\r\n,Json_str); 10 11     解析成Json对象 12     cJsON * Json_obj = cJsON_Parse(Json_str); 13 14     格式输出15     char *Json_print_str=NulL;16     Json_print_str=cJsON_Print(Json_obj);17     printf(\r\n输出内容:\r\n\r\n%s\r\n18     19     释放资源 20     free(Json_print_str);21     22     23     cJsON_Delete(Json_obj);24 }
Json打包

cJsON_CreateObject函数可创建一个根数据项,在此之后就可以添加各种数据类型的子节点了,使用完成后需要通过cJsON_Delete()释放内存。

创建一层级的Json

 代码:

 5     cJsON *root_obj = NulL;根,Json对象 char *out_str = NulL; 输出结果  7     root_obj =cJsON_CreateObject();创建  8      添加一个字符串,参数(根对象,键,值)  9     cJsON_AddStringToObject(root_obj,key1",1)">dongxiaodong);10     添加一个整型,参数(根对象,键,值) 11     cJsON_AddNumberToObject(root_obj,1)">key2199812     添加一个浮点型,参数(根对象,键,值) 13     cJsON_AddNumberToObject(root_obj,1)">key322.33添加一个bool类型,参数(根对象,键,值) bool值可以是0/1或false/true 16     cJsON_AddBoolToObject(root_obj,1)">key4017     将Json对象打包成字符串 18     out_str = cJsON_PrintUnformatted(root_obj);销毁Json对象,释放内存 20     cJsON_Delete(root_obj); 21     输出值:{"key1":"dongxiaodong","key2":1998,"key3":22.33,"key4":false} 22     printf(%s23 }

类型创建函数还有:

cJsON_AddNullToObject(cJsON * const object,const char * const name);

cJsON_AddTruetoObject(cJsON * const object,const char * const name);

cJsON_AddFalsetoObject(cJsON * const object,const char * const name);

cJsON_AddBoolToObject(cJsON * const object,const char * const name,const cJsON_bool boolean);

cJsON_AddNumberToObject(cJsON * const object,const double number);

cJsON_AddStringToObject(cJsON * const object,const char * const string);

cJsON_AddRawToObject(cJsON * const object,const char * const raw);

cJsON_AddobjectToObject(cJsON * const object,const char * const name);

cJsON_AddArrayToObject(cJsON * const object,const char * const name);

创建多层级的Json

 代码:

 6     cJsON *item_obj = NulL;二级Json对象  7      8      9     root_obj =cJsON_CreateObject();10      11     cJsON_AddStringToObject(root_obj,1)">14     创建一个子Json对象16     item_obj= cJsON_AddobjectToObject(root_obj,1)">myson); 向孩子对象中添加内容18     cJsON_AddStringToObject(item_obj,1)">sonkey1东小东19     cJsON_AddNumberToObject(item_obj,1)">sonkey2202020       22     out_str =23     24 25     26     printf(27 }

创建多层Json(数组形式)

 

 代码

数组对象 创建一个子数组对象 16     item_obj= cJsON_AddArrayToObject(root_obj,1)">向数组对象中添加内容18     cJsON_AddItemToArray(item_obj,cJsON_CreateTrue()); 19     cJsON_AddItemToArray(item_obj,cJsON_CreateNumber(22));27 }

创建的对象还可以是下面这些

cJsON_CreateNull(voID);

cJsON_CreateTrue(voID);

cJsON_CreateFalse(voID);

cJsON_CreateBool(cJsON_bool boolean);

cJsON_CreateNumber(double num);

cJsON_CreateString(const char *string);

cJsON_Createraw(const char *raw);

cJsON_CreateArray(voID);

cJsON_CreateObject(voID);

创建混合Json

 代码

 6     cJsON *son_obj=NulL;  7     cJsON *item_obj = NulL;输出结果  9     根对象 11     root_obj =cJsON_CreateObject();13     cJsON_AddStringToObject(root_obj,1)">15     cJsON_AddNumberToObject(root_obj,1)">16     18     item_obj= cJsON_AddArrayToObject(root_obj,1)">21     cJsON_AddItemToArray(item_obj,1)">22     子对象 24     son_obj =cJsON_CreateObject();26     cJsON_AddStringToObject(son_obj,1)">son127     28     cJsON_AddNumberToObject(son_obj,1)">son229 30     31     32     out_str =33     34 35     36     printf(37 }
Json解析

解析一层级的Json

 

代码:

 8     cJsON * Json_obj =项存储 11     cJsON *item=12     13     14     printf(15     16     获取string类型 17     item=cJsON_GetobjectItem(Json_obj,1)">);  18     printf(\r\nkey1:%s\r\nvaluestring);19     cJsON_Delete(item);释放资源 20      获取数字 22     item=cJsON_GetobjectItem(Json_obj,1)">23     printf(\r\nkey2:%d\r\nvalueint);24     cJsON_Delete(item);25     26     27     item=cJsON_GetobjectItem(Json_obj,1)">28     printf(\r\nkey3:%f\r\nvaluedouble);29     cJsON_Delete(item);获取bool 32     item=cJsON_GetobjectItem(Json_obj,1)">33     printf(\r\nkey4:%d\r\n34     cJsON_Delete(item);35     36     是否资源 37 38 }

解析多层级的Json

 

代码

内部项存储13     cJsON * item_item=16     printf(17     18     19     item=cJsON_GetobjectItem(Json_obj,1)">20     printf(21     cJsON_Delete(item);22      24     item=cJsON_GetobjectItem(Json_obj,1)">25     printf(26     cJsON_Delete(item);27     28     子串29     item=cJsON_GetobjectItem(Json_obj,1)">30     item_item=cJsON_GetobjectItem(item,1)">31     printf(\r\nmyson(sonkey1):%s\r\n32     cJsON_Delete(item_item);33     34     item_item=cJsON_GetobjectItem(item,1)">35     printf(\r\nmyson(sonkey2):%d\r\n36     cJsON_Delete(item_item);37     38     cJsON_Delete(item);39     40     41 42 }

 解析多层Json(数组形式)

 

 

代码

获取子串 输出数组大小 32     printf(\r\n数组大小:%d\r\n34     输出项1内容 35     item_item=cJsON_GetArrayItem(item,1)">\r\nmyson(0):%d\r\n37     cJsON_Delete(item_item);38     39     输出项2内容 40     item_item=cJsON_GetArrayItem(item,1)">141     printf(\r\nmyson(1):%d\r\n42     cJsON_Delete(item_item);43     44     cJsON_Delete(item);45     46     47 48 }

  解析混合Json

代码

44     项3内容45     item_item=cJsON_GetArrayItem(item,1)">246     cJsON *item_item_son=47     48     item_item_son =cJsON_GetobjectItem(item_item,1)">49     printf(\r\nmyson(2)(son1):%s\r\n50     cJsON_Delete(item_item_son);51     52     item_item_son =cJsON_GetobjectItem(item_item,1)">53     printf(\r\nmyson(2)(son2):%d\r\n54     cJsON_Delete(item_item_son);释放资源55     cJsON_Delete(item_item);释放资源   56     57     cJsON_Delete(item);58     59     60 61 }

 附件:

cJsON.h

  1 /*  2   copyright (c) 2009-2017 Dave Gamble and cJsON contributors  3   4   Permission is hereby granted,free of charge,to any person obtaining a copy  5   of this software and associated documentation files (the "Software"),to deal  6   in the Software without restriction,including without limitation the rights  7   to use,copy,modify,merge,publish,distribute,sublicense,and/or sell  8   copIEs of the Software,and to permit persons to whom the Software is  9   furnished to do so,subject to the following conditions: 10  11   The above copyright notice and this permission notice shall be included in 12   all copIEs or substantial portions of the Software. 13  14   THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR 15   IMPLIED,INCLUDING BUT NOT liMITED TO THE WARRANTIES OF MERCHANTABIliTY, 16   fitness FOR A PARTIculaR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17   AUTHORS OR copYRIGHT HolDERS BE liABLE FOR ANY CLaim,damAGES OR OTHER 18   liABIliTY,WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE,ARISING FROM,1)"> 19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEAliNGS IN 20   THE SOFTWARE. 21 */ 22  23 #ifndef cJsON__h 24 #define cJsON__h 25  26 #ifdef __cplusplus 27 extern C 28 { 29 #endif 30  31 #if !defined(__windows__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) 32 #define __windows__ 33  34  35 #ifdef __windows__ 36  37  When compiling for windows,we specify a specific calling convention to avoID issues where we are being called from a project with a different default calling convention.  For windows you have 3 define options: 38  39 CJsON_HIDE_SYMBolS - define this in the case where you don't want to ever dllexport symbols 40 CJsON_EXPORT_SYMBolS - define this on library build when you want to dllexport symbols (default) 41 CJsON_import_SYMBolS - define this if you want to dllimport symbol 42  43 For *nix builds that support visibility attribute,you can define similar behavior by 44  45 setting default visibility to hIDden by adding 46 -fvisibility=hIDden (for gcc) 47 or 48 -xldscope=hIDden (for sun cc) 49 to CFLAGS 50  51 then using the CJsON_API_VISIBIliTY flag to "export" the same symbols the way CJsON_EXPORT_SYMBolS does 52  53  54  55 #define CJsON_CDECL __cdecl 56 #define CJsON_STDCALL __stdcall 57  58  export symbols by default,this is necessary for copy pasting the C and header file  59 #if !defined(CJsON_HIDE_SYMBolS) && !defined(CJsON_import_SYMBolS) && !defined(CJsON_EXPORT_SYMBolS) 60 #define CJsON_EXPORT_SYMBolS 61  62  63 #if defined(CJsON_HIDE_SYMBolS) 64 #define CJsON_PUBliC(type)   type CJsON_STDCALL 65 #elif defined(CJsON_EXPORT_SYMBolS) 66 #define CJsON_PUBliC(type)   __declspec(dllexport) type CJsON_STDCALL 67 #elif defined(CJsON_import_SYMBolS) 68 #define CJsON_PUBliC(type)   __declspec(dllimport) type CJsON_STDCALL 69  70 #else /* !__windows__ */ 71 #define CJsON_CDECL 72 #define CJsON_STDCALL 73  74 #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJsON_API_VISIBIliTY) 75 #define CJsON_PUBliC(type)   __attribute__((visibility("default"))) type 76 #else 77 #define CJsON_PUBliC(type) type 78  79  80  81  project version  82 #define CJsON_VERSION_MAJOR 1 83 #define CJsON_VERSION_MInor 7 84 #define CJsON_VERSION_PATCH 13 85  86 #include <stddef.h> 87  88  cJsON Types:  89  90  91  92  93  94  95  96  97 #define cJsON_Raw    (1 << 7) /* raw Json */ 98  99 #define cJsON_IsReference 256100 #define cJsON_StringIsConst 512101 102 103 typedef  cJsON104 105      next/prev allow you to walk array/object chains. Alternatively,use GetArraySize/GetArrayItem/GetobjectItem 106     next;107     prev;108      An array or object item will have a child pointer pointing to a chain of the items in the array/object. 109     child;110 111      The type of the item,as above. 112      type;113 114      The item's string,if type==cJsON_String  and type == cJsON_Raw 115     valuestring;116      writing to valueint is DEPRECATED,use cJsON_SetNumberValue instead 117      valueint;118      The item's number,if type==cJsON_Number 119      valuedouble;120 121      The item's name string,if this item is the child of,or is in the List of subitems of an object. 122     123 } cJsON;124 125 typedef  cJsON_Hooks126 127        malloc/free are CDECL on windows regardless of the default calling convention of the compiler,so ensure the hooks allow passing those functions directly. 128       voID *(CJsON_CDECL *malloc_fn)(size_t sz);129       voID (CJsON_CDECL *free_fn)(voID *ptr);130 } cJsON_Hooks;131 132 typedef  cJsON_bool;133 134  limits how deeply nested arrays/objects can be before cJsON rejects to parse them.135  * This is to prevent stack overflows. 136 #ifndef CJsON_nesTING_liMIT137 #define CJsON_nesTING_liMIT 1000138 139 140  returns the version of cJsON as a string 141 CJsON_PUBliC(const char*) cJsON_Version(142 143  Supply malloc,realloc and free functions to cJsON 144 CJsON_PUBliC(voID) cJsON_InitHooks(cJsON_Hooks* hooks);145 146  Memory Management: the caller is always responsible to free the results from all variants of cJsON_Parse (with cJsON_Delete) and cJsON_Print (with stdlib free,cJsON_Hooks.free_fn,or cJsON_free as appropriate). The exception is cJsON_PrintPreallocated,where the caller has full responsibility of the buffer. 147  Supply a block of JsON,and this returns a cJsON object you can interrogate. 148 CJsON_PUBliC(cJsON *) cJsON_Parse(value);149 CJsON_PUBliC(cJsON *) cJsON_ParseWithLength(value,size_t buffer_length);150  ParseWithOpts allows you to require (and check) that the JsON is null terminated,and to retrIEve the pointer to the final byte parsed. 151  If you supply a ptr in return_parse_end and parsing fails,then return_parse_end will contain a pointer to the error so will match cJsON_GetErrorPtr(). 152 CJsON_PUBliC(cJsON *) cJsON_ParseWithOpts(char *value,char **return_parse_end,cJsON_bool require_null_terminated);153 CJsON_PUBliC(cJsON *) cJsON_ParseWithLengthOpts(154 155  Render a cJsON entity to text for transfer/storage. 156 CJsON_PUBliC(char *) cJsON_Print(const cJsON *item);157  Render a cJsON entity to text for transfer/storage without any formatting. 158 CJsON_PUBliC(char *) cJsON_PrintUnformatted(159  Render a cJsON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted,=1 gives formatted 160 CJsON_PUBliC(char *) cJsON_PrintBuffered(const cJsON *item,1)"> prebuffer,cJsON_bool fmt);161  Render a cJsON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. 162  NOTE: cJsON is not always 100% accurate in estimating how much memory it will use,so to be safe allocate 5 bytes more than you actually need 163 CJsON_PUBliC(cJsON_bool) cJsON_PrintPreallocated(cJsON *item,1)">char *buffer,1)">int length,1)"> cJsON_bool format);164  Delete a cJsON entity and all subentitIEs. 165 CJsON_PUBliC(voID) cJsON_Delete(cJsON *166 167  Returns the number of items in an array (or object). 168 CJsON_PUBliC(int) cJsON_GetArraySize(array);169  RetrIEve item number "index" from array "array". Returns NulL if unsuccessful. 170 CJsON_PUBliC(cJsON *) cJsON_GetArrayItem(const cJsON *array,1)"> index);171  Get item "string" from object. Case insensitive. 172 CJsON_PUBliC(cJsON *) cJsON_GetobjectItem(object,1)">char * 173 CJsON_PUBliC(cJsON *) cJsON_GetobjectItemCaseSensitive(174 CJsON_PUBliC(cJsON_bool) cJsON_HasObjectItem(175  For analysing Failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. defined when cJsON_Parse() returns 0. 0 when cJsON_Parse() succeeds. 176 CJsON_PUBliC(char *) cJsON_GetErrorPtr(177 178  Check item type and return its value 179 CJsON_PUBliC(char *) cJsON_GetStringValue(cJsON *180 CJsON_PUBliC(double) cJsON_GetNumberValue(cJsON *181 182  These functions check the type of an item 183 CJsON_PUBliC(cJsON_bool) cJsON_IsInvalID( item);184 CJsON_PUBliC(cJsON_bool) cJsON_IsFalse(185 CJsON_PUBliC(cJsON_bool) cJsON_IsTrue(186 CJsON_PUBliC(cJsON_bool) cJsON_IsBool(187 CJsON_PUBliC(cJsON_bool) cJsON_IsNull(188 CJsON_PUBliC(cJsON_bool) cJsON_IsNumber(189 CJsON_PUBliC(cJsON_bool) cJsON_Isstring(190 CJsON_PUBliC(cJsON_bool) cJsON_IsArray(191 CJsON_PUBliC(cJsON_bool) cJsON_IsObject(192 CJsON_PUBliC(cJsON_bool) cJsON_IsRaw(193 194  These calls create a cJsON item of the appropriate type. 195 CJsON_PUBliC(cJsON *) cJsON_CreateNull(196 CJsON_PUBliC(cJsON *) cJsON_CreateTrue(197 CJsON_PUBliC(cJsON *) cJsON_CreateFalse(198 CJsON_PUBliC(cJsON *) cJsON_CreateBool(cJsON_bool boolean);199 CJsON_PUBliC(cJsON *) cJsON_CreateNumber( num);200 CJsON_PUBliC(cJsON *) cJsON_CreateString(201  raw Json 202 CJsON_PUBliC(cJsON *) cJsON_Createraw(raw);203 CJsON_PUBliC(cJsON *) cJsON_CreateArray(204 CJsON_PUBliC(cJsON *) cJsON_CreateObject(205 206  Create a string where valuestring references a string so207  * it will not be freed by cJsON_Delete 208 CJsON_PUBliC(cJsON *) cJsON_CreateStringReference(209  Create an object/array that only references it's elements so210  * they will not be freed by cJsON_Delete 211 CJsON_PUBliC(cJsON *) cJsON_CreateObjectReference(child);212 CJsON_PUBliC(cJsON *) cJsON_CreateArrayReference(213 214  These utilitIEs create an Array of count items.215  * The parameter count cannot be greater than the number of elements in the number array,otherwise array access will be out of bounds.216 CJsON_PUBliC(cJsON *) cJsON_CreateIntArray(int *numbers,1)"> count);217 CJsON_PUBliC(cJsON *) cJsON_CreatefloatArray(float *numbers,1)">218 CJsON_PUBliC(cJsON *) cJsON_CreateDoubleArray(double *numbers,1)">219 CJsON_PUBliC(cJsON *) cJsON_CreateStringArray(const *strings,1)">220 221  Append item to the specifIEd array/object. 222 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToArray(cJsON *array,cJsON *223 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObject(cJsON *string,1)">224  Use this when string is definitely const (i.e. a literal,or as good as),and will definitely survive the cJsON object.225  * WARNING: When this function was used,make sure to always check that (item->type & cJsON_StringIsConst) is zero before226  * writing to `item->string` 227 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObjectCS(cJsON *228  Append reference to item to the specifIEd array/object. Use this when you want to add an existing cJsON to a new cJsON,but don't want to corrupt your existing cJsON. 229 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoArray(cJsON *array,1)">230 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoObject(cJsON *231 232  Remove/Detach items from Arrays/Objects. 233 CJsON_PUBliC(cJsON *) cJsON_DetachItemViaPointer(cJsON *parent,cJsON * 234 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromArray(cJsON *array,1)"> which);235 CJsON_PUBliC(voID) cJsON_DeleteItemFromArray(cJsON *array,1)">236 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObject(cJsON *237 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObjectCaseSensitive(cJsON *238 CJsON_PUBliC(voID) cJsON_DeleteItemFromObject(cJsON *239 CJsON_PUBliC(voID) cJsON_DeleteItemFromObjectCaseSensitive(cJsON *240 241  Update array items. 242 CJsON_PUBliC(cJsON_bool) cJsON_InsertItemInArray(cJsON *array,1)">int which,cJsON *newitem);  Shifts pre-existing items to the right. 243 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemViaPointer(cJsON * const parent,1)">const item,1)"> replacement);244 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInArray(cJsON *array,1)">newitem);245 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObject(cJsON *246 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObjectCaseSensitive(cJsON *247 248  Duplicate a cJsON item 249 CJsON_PUBliC(cJsON *) cJsON_Duplicate(item,cJsON_bool recurse);250  Duplicate will create a new,IDentical cJsON item to the one you pass,in new memory that will251  * need to be released. With recurse!=0,it will duplicate any children connected to the item.252  * The item->next and ->prev pointers are always zero on return from Duplicate. 253  Recursively compare two cJsON items for equality. If either a or b is NulL or invalID,they will be consIDered unequal.254  * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) 255 CJsON_PUBliC(cJsON_bool) cJsON_Compare(const a,1)">const b,1)"> cJsON_bool case_sensitive);256 257  Minify a strings,remove blank characters(such as ' ','\t','\r','\n') from strings.258  * The input pointer Json cannot point to a read-only address area,such as a string constant,1)">259  * but should point to a readable and writable adress area. 260 CJsON_PUBliC(voID) cJsON_Minify(Json);261 262  Helper functions for creating and adding items to an object at the same time.263  * They return the added item or NulL on failure. 264 CJsON_PUBliC(cJsON*) cJsON_AddNullToObject(cJsON *  name);265 CJsON_PUBliC(cJsON*) cJsON_AddTruetoObject(cJsON * 266 CJsON_PUBliC(cJsON*) cJsON_AddFalsetoObject(cJsON * 267 CJsON_PUBliC(cJsON*) cJsON_AddBoolToObject(cJsON * const name,1)"> cJsON_bool boolean);268 CJsON_PUBliC(cJsON*) cJsON_AddNumberToObject(cJsON *  number);269 CJsON_PUBliC(cJsON*) cJsON_AddStringToObject(cJsON * 270 CJsON_PUBliC(cJsON*) cJsON_AddRawToObject(cJsON *  raw);271 CJsON_PUBliC(cJsON*) cJsON_AddobjectToObject(cJsON * 272 CJsON_PUBliC(cJsON*) cJsON_AddArrayToObject(cJsON * 273 274  When assigning an integer value,it needs to be propagated to valuedouble too. 275 #define cJsON_SetIntValue(object,number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))276  helper for the cJsON_SetNumberValue macro 277 CJsON_PUBliC(double) cJsON_SetNumberHelper(cJsON *278 #define cJsON_SetNumberValue(object,number) ((object != NulL) ? cJsON_SetNumberHelper(object,(double)number) : (number))279  Change the valuestring of a cJsON_String object,only takes effect when type of object is cJsON_String 280 CJsON_PUBliC(char*) cJsON_SetValuestring(cJsON *281 282  Macro for iterating over an array or object 283 #define cJsON_ArrayForEach(element,array) for(element = (array != NulL) ? (array)->child : NulL; element != NulL; element = element->next)284 285  malloc/free objects using the malloc/free functions that have been set with cJsON_InitHooks 286 CJsON_PUBliC() cJsON_malloc(size_t size);287 CJsON_PUBliC(voID) cJsON_free(object288 289 290 }291 292 293 #endif
VIEw Code

cJsON.c

   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23  cJsON   24  JsON parser in C.   25   26  disable warnings about old C89 functions in MSVC   27 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)  28 #define _CRT_SECURE_NO_DEPRECATE  29   30   31 #ifdef __GNUC__  32 #pragma GCC visibility push(default)  33   34 #if defined(_MSC_VER)  35 #pragma warning (push)  36  disable warning about single line comments in system headers   37 #pragma warning (disable : 4001)  38   39   40 #include <string.h>  41 #include <stdio.h>  42 #include <math.h>  43 #include <stdlib.h>  44 #include <limits.h>  45 #include <ctype.h>  46 #include <float.h>  47   48 #ifdef ENABLE_LOCALES  49 #include <locale.h>  50   51   52   53 #pragma warning (pop)  54   55   56 #pragma GCC visibility pop  57   58   59 #include   60   61  define our own boolean type   62 #ifdef true  63 #undef true  64   65 #define true ((cJsON_bool)1)  66   67 #ifdef false  68 #undef false  69   70 #define false ((cJsON_bool)0)  71   72  define isnan and isinf for ANSI C,if in C99 or above,isnan and isinf has been defined in math.h   73 #ifndef isinf  74 #define isinf(d) (isnan((d - d)) && !isnan(d))  75   76 #ifndef isnan  77 #define isnan(d) (d != d)  78   79   80 #ifndef NAN  81 #define NAN 0.0/0.0  82   83   84 typedef  {  85     const unsigned Json;  86     size_t position;  87 } error;  88 static error global_error = { NulL,1)"> };  89   90 CJsON_PUBliC()  91   92     return (char*) (global_error.Json + global_error.position);  93   94   95 CJsON_PUBliC(item)   96   97     if (!cJsON_Isstring(item))   98     {  99         return NulL; 100     } 101  102     return item-> 103  104  105 CJsON_PUBliC( 106  107     cJsON_IsNumber(item))  108  109          NAN; 110  111  112     valuedouble; 113  114  115  This is a safeguard to prevent copy-pasters from using incompatible C and header files  116 #if (CJsON_VERSION_MAJOR != 1) || (CJsON_VERSION_MInor != 7) || (CJsON_VERSION_PATCH != 13) 117     #error cJsON.h and cJsON.c have different versions. Make sure that both have the same. 118  119  120 CJsON_PUBliC( 121  122     static char version[15]; 123     sprintf(version,1)">%i.%i.%i 124  125      version; 126  127  128  Case insensitive string comparison,doesn't consIDer two NulL pointers equal though  129 int case_insensitive_strcmp(char *string1,1)">string2) 130  131     if ((string1 == NulL) || (string2 == NulL)) 132  133         return  134  135  136     if (string1 == string2) 137  138          139  140  141     for(; tolower(*string1) == tolower(*string2); (voID)string1++,string2++ 142  143         if (*string1 == '' 144        {  145 146                     }  147 148  149 return     string2); tolower(*string1) - tolower(* 150 151  152  internal_hooks typedef  153 154 allocate)(size_t size);      155voID     pointer); (CJsON_CDECL *deallocate)( 156voID     pointer,size_t size); *(CJsON_CDECL *reallocate)( 157} internal_hooks;  158 159  160  work around MSVC error C2322: '...' address of dllimport '...' is not static   161 CJsON_CDECL internal_malloc(size_t size)  162 163 return     malloc (size); 164 165 voID pointer) CJsON_CDECL internal_free( 166 167 (pointer);      168 169 voID  170 * CJsON_CDECL internal_realloc( 171 realloc     (pointer,size); 172 173  174 #define  175 internal_malloc malloc#define  176 internal_free free#define  177 internal_realloc realloc 178  179  strlen of character literals resolved at compile time   180#define  181 static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) 182 static  { internal_malloc,internal_free,internal_realloc }; internal_hooks global_hooks = 183 184 static char unsigned char* cJsON_strdup(const*  hooks) internal_hooks *  185 186  187     size_t length = char     unsigned  188 *copy = 189 if     string ( NulL) == 190 191  192          193  194 char     length = strlen((string*)sizeof) + ""( 195char     copy = (unsigned allocate(length);*)hooks-> 196if      197 (copy == 198  199          200  201     memcpy(copy,length); 202  copy;      203 204  205  206 CJsON_PUBliC( 207 if      208 (hooks == 209  reset hooks           210 211         global_hooks.allocate =  212         global_hooks.deallocate =  213         global_hooks.reallocate =  214          215  216  217     global_hooks.allocate = if      218 (hooks->malloc_fn != 219 malloc_fn;         global_hooks.allocate = hooks-> 220 221  222  223     global_hooks.deallocate = if      224 (hooks->free_fn != 225 free_fn;         global_hooks.deallocate = hooks-> 226 227  228  use realloc only if both free and malloc are used       229 230     global_hooks.reallocate =if     malloc ((global_hooks.allocate == ))) && (global_hooks.deallocate ==  231 232  233         global_hooks.reallocate =  234  235  236  Internal constructor.   237static  238 cJsON *cJsON_New_Item( 239 sizeof     cJsON* node = (cJsON*)hooks->allocate((cJsON)); 240if      (node) 241 242  244         memset(node,1)">',1)"> 243  245  node;      246 247  248  Delete a cJsON structure.   249item) CJsON_PUBliC( 250 251  252     cJsON *next =while      253 (item != 254  255         next = item->if          256 (!(item->type & cJsON_IsReference) && (item->child != 257  258             cJsON_Delete(item-> 259 if          260 (!(item->type & cJsON_IsReference) && (item->valuestring != 261  262             global_hooks.deallocate(item-> 263 if         string (!(item->type & cJsON_StringIsConst) && (item-> 264 != 265  266             global_hooks.deallocate(item-> 267         global_hooks.deallocate(item);  268 next;         item = 269 270  271  272  get the decimal point character of the current locale   273char  274 get_decimal_point( 275  276 struct      localeconv(); lconv *lconv = 277return     char (unsigned  278) lconv->decimal_point[ 279 .      280 281  282  283 struct typedef  284 285 content;      286    size_t length;  287    size_t offset;  288 How deeply nested (in arrays/objects) is the input at the current offset.      size_t depth;  289    internal_hooks hooks;  290} parse_buffer;  291 292  check if the given size is left to read in a given parse buffer (starting with 1)   293#define  294 can_read(buffer,size) ((buffer != NulL) && (((buffer)->offset + size) <= (buffer)->length)) check if the buffer can be accessed at the given index (starting with 0)   295#define  296 can_access_at_index(buffer,index) ((buffer != NulL) && (((buffer)->offset + index) < (buffer)->length))#define  297 cannot_access_at_index(buffer,index) (!can_access_at_index(buffer,index)) get a pointer to the buffer at the position   298#define  299 buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) 300  Parse the input text to generate a number,and populate the result into item.   301static  input_buffer) cJsON_bool parse_number(cJsON *  302 303 double      304 number = char     unsigned  305 *after_end =char     unsigned 64 number_c_string[ 306char     unsigned  get_decimal_point(); decimal_point = 307 308     size_t i =  309 if      310 ((input_buffer == NulL) || (input_buffer->content == 311 false          312 313  314  copy the number into a temporary buffer and replace '.' with the decimal point      315     * of the current locale (for strtod)  316     * This also takes care of ' 317' not necessarily being available for marking the end of the input  for0     sizeof (i = 1; (i < ( 318(number_c_string) -  319)) && can_access_at_index(input_buffer,i); i++switch  (buffer_at_offset(input_buffer)[i])          320 321case 0             :  3221 323             2 324             3 325             4 326             5 327             6 328             7 329             8 330             9 331             + 332             - 333             e 334             E 335              buffer_at_offset(input_buffer)[i]; 336                 number_c_string[i] =break 337                  338 339  decimal_point;              340                 number_c_string[i] = 341 342                 default  343             goto loop_end;                  344 345 346 loop_end:  347  348 349     number_c_string[i] = char char     number = strtod((after_end);*)number_c_string,( 350**)&if after_end)      351 (number_c_string == 352false  parse_error           353;  354 355  number;  356     item->valuedouble = 357 use saturation in case of overflow   358     if INT_MAX)      359 (number >= 360 INT_MAX;  361         item->valueint = 362else if     )INT_MIN)  363 (number <= ( 364 INT_MIN;  365         item->valueint = 366else  367      368)number;  369         item->valueint = ( 370 371  cJsON_Number;  372     item->type = 373 number_c_string);  374     input_buffer->offset += (size_t)(after_end -true 375      376 377  don't ask me,but the original cJsON_SetNumberValue returns an integer or double   378  number) 379 CJsON_PUBliC( 380 381  382     object  383          384->valueint = 385  386      387  388          389  390     object  391          392->valueint = ( 393 object  394      395->valuedouble = 396 valuestring)  397 CJsON_PUBliC( 398 399  if object's type is not cJsON_String or is cJsON_IsReference,it should not set valuestring       400     ifobject     object (!( cJsON_IsReference))->type & cJsON_String) || ( 401->type & 402 403  404         if object     valuestring)) (strlen(valuestring) <= strlen( 405-> 406valuestring,valuestring);  407         strcpy( 408 409         char char     copy = (global_hooks);*) cJsON_strdup(( 410*)valuestring,& 411 412      413  414         object  415      416->valuestring != 417  418         cJsON_free(object  419      420->valuestring = 421  422      423  424  425 typedef buffer;  426     unsigned  427 428  current nesting depth (for formatted printing)   429     size_t depth;     cJsON_bool noalloc; 430  is this print a formatted print  431     cJsON_bool format;  432} printbuffer;  433  434 realloc printbuffer if necessary to have at least "needed" bytes more   435 char p,size_t needed)  436* ensure(printbuffer *  437char  438     unsigned  439 *newbuffer = 440     size_t newsize = if  441      442 ((p == NulL) || (p->buffer == 443  444          445 if 0     length)) ((p->length >  446) && (p->offset >= p-> 447 make sure that offset is valID   448          449 450          451 if  452      453 (needed > sizes bigger than INT_MAX are currently not supported   454          455 456          457  458 if     needed += p->offset + length)      459 (needed <= p-> 460return offset;          461 p->buffer + p-> 462 463 if noalloc) {      464 (p-> 465 466          467  calculate new buffer size   468     if 469      470 (needed > (INT_MAX /  overflow of int,use INT_MAX if possible   471         if 472          473 (needed <= 474  475             newsize = 476  477          478  479              480  481  482      483  484         newsize = needed *  485 if  486      487 (p->hooks.reallocate != reallocate with realloc if available   488         charbuffer,newsize);         newbuffer = (unsigned  489*)p->hooks.reallocate(p->if 490          491 (newbuffer ==buffer);  492             p->hooks.deallocate(p-> 493 494             p->length =  495             p->buffer = 496  497              498  499  500      otherwise reallocate manually   501         charhooks.allocate(newsize);         newbuffer = (unsigned  502*)p->newbuffer) 503          504 505  506             p->hooks.deallocate(p-> 507             p->length =  508             p->buffer = 509  510              (newbuffer)  511          512 513  514             memcpy(newbuffer,p->buffer,p->offset +  515  516         p->hooks.deallocate(p-> newsize;  517     p->length = newbuffer; 518     p->buffer = 519return  520      521 newbuffer + p-> 522  calculate the new length of the string in a printbuffer and update the offset   523 voID buffer)  524 update_offset(printbuffer *  525char  526     if *buffer_pointer = 527      528 ((buffer == NulL) || (buffer->buffer == 529  530          531  532     buffer_pointer = buffer->buffer + buffer->char )buffer_pointer);     buffer->offset += strlen(( 533* 534 535  securely comparison of floating-point variables   536 staticdouble  537 cJsON_bool compare_double( 538 a,1)"> b)double  fabs(a) : fabs(b);      539 maxVal = fabs(a) > fabs(b) ?return DBL_EPSILON);      540 (fabs(a - b) <= maxVal * 541 542  Render the number nicely from the given item into a string.   543 static output_buffer)  544 cJsON_bool print_number( 545char  546     unsigned double *output_pointer = 547     int d = item-> 548      549 length = char     size_t i = 26     unsigned 0 number_buffer[ temporary buffer to print the number into ] = { 550};  551double     unsigned 0.0      552 test =  553if  554      555 (output_buffer == 556  557          558  This checks for NaN and Infinity   559     if isinf(d))      560 (isnan(d) || 561char  562         length = sprintf(( 563*)number_buffer,1)">null 564  565      Try 15 decimal places of precision to avoID nonsignificant nonzero digits   566         %1.15g 567         length = sprintf(( 568 Check whether the original double can be recovered   569         if%lg         1 ((sscanf(()test,d)) 570) || !compare_double(( 571 If not,print with 17 decimal places of precision   572             %1.17g 573             length = sprintf(( 574 575  576  sprintf Failed or buffer overrun occurred   577     if0     int ((length < sizeof) || (length > ())))( 578(number_buffer) -  579 580  581          582  reserve appropriate space in the output   583      584if     output_pointer = ensure(output_buffer,(size_t)length +  585      586 (output_pointer == 587  588          589  copy the printed number to the output and replace locale  590          * dependent decimal point with '.'  591 0 592      593; i < ((size_t)length); i++if  decimal_point)          594 (number_buffer[i] == 595 596 continue             output_pointer[i] =  597              598 599  number_buffer[i];  600         output_pointer[i] = 601 602  603     output_pointer[i] =  (size_t)length;  604     output_buffer->offset += 605 606  607      608  parse 4 digit hexadecimal number   609 static input)  610 unsigned parse_hex4( 611int  612     unsigned  613 h =  614     size_t i = 0 4      615; i <  616; i++ parse digit   617         if'          618 ((input[i] >=  619) && (input[i] <= int  620             h += (unsigned  621) input[i] - A F          622 623int 10             h += (unsigned  624)  625 + input[i] - a f          626 627 628  629             h += (unsigned  invalID   630          631 632  633              634 if 3          635 (i <  636 shift left to make place for the next nibble   637             4 638             h = h <<  639 640  641  h;  642      643 644  converts a UTF-16 literal to UTF-8  645  * A literal can be one or two sequences of the form \uXXXX  646 charconst output_pointer) utf16_literal_to_utf8( 647 input_pointer,1)">const input_end,unsigned  648long int      649 unsigned int codepoint =  650     unsigned char first_code =  input_pointer;      651 *first_sequence =char 652     unsigned char utf8_length =  653     unsigned char utf8_position =  654     unsigned char sequence_length =  655     unsigned  656 first_byte_mark = if 6      657 ((input_end - first_sequence) <  658 input ends unexpectedly   659          fail; 660          661 662  get the first utf16 sequence   663      664 665     first_code = parse_hex4(first_sequence +  check that the code is valID   666     if0xDC00     0xDFFF (((first_code >=  667) && (first_code <=  668 669  670          671  UTF16 surrogate pair   672     if0xD800     0xDBFF ((first_code >=  673) && (first_code <=  674char  675         int *second_sequence = first_sequence +  676         unsigned 12 second_code =  \uXXXX\uXXXX          sequence_length =  677;  678if  679          680 ((input_end - second_sequence) <  681  682              683              684 if 0         \ ((second_sequence['] != 1u) || (second_sequence[ 685] !=  686 missing second half of the surrogate pair   687              688 689              690  get the second utf16 sequence   691          692 693         second_code = parse_hex4(second_sequence + if         0xDC00          694 ((second_code <  695) || (second_code >  invalID second half of the surrogate pair   696              697 698              699  700  calculate the unicode codepoint from the surrogate pair   701         0x100000x3FF         codepoint = 10 + (((first_code & 0x3FF) <<  702) | (second_code &  703 704  705     6  \uXXXX          sequence_length =  706;  first_code; 707         codepoint = 708 709  encode as UTF-8  710          * takes at maximum 4 bytes to encode: 711      * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  712 if0x80      713 (codepoint <  714 normal ascii,enCoding 0xxxxxxx   715          716 717         utf8_length = 0x800  718      719 two bytes,enCoding 110xxxxx 10xxxxxx   720          7210xC0         utf8_length =  11000000          first_byte_mark =  722;  7230x10000  724      725 three bytes,enCoding 1110xxxx 10xxxxxx 10xxxxxx   726          7270xE0         utf8_length =  11100000          first_byte_mark =  728;  729if 0x10FFFF      730 (codepoint <=  731 four bytes,enCoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx   732          7330xF0         utf8_length =  11110000          first_byte_mark =  734;  735 736  737      invalID unicode codepoint   738          739 740          741  encode as utf8   742     forchar     1 (utf8_position = (unsigned 0)(utf8_length -  743); utf8_position >  744; utf8_position-- 10xxxxxx   745         char0x80         (*output_pointer)[utf8_position] = (unsigned 0xBF)((codepoint |  746) &  747 748         codepoint >>=  encode first byte   749     if 750      751 (utf8_length > 0 char         (*output_pointer)[0xFF] = (unsigned  752)((codepoint | first_byte_mark) &  753 754  755     char 0x7F         (*output_pointer)[ 756)(codepoint &  757 758  utf8_length;  759     *output_pointer += 760 sequence_length;  761      762fail:  763  764 765      766  Parse the input text into an unescaped cinput,and populate item.   767 static 768  769 cJsON_bool parse_string(cJsON * char  770     char *input_pointer = buffer_at_offset(input_buffer) +  771      772 *input_end = buffer_at_offset(input_buffer) + char     unsigned  773     unsigned  774 *output = not a string   775     if\"      776 (buffer_at_offset(input_buffer)[ 777 778  779          780  781  calculate approximate size of the output (overestimate)   782          783 784         size_t allocation_length = while         size_t skipped_bytes =  785          786 (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end !=  is escape sequence   787             if0              788 (input_end[            {] ==  789 if1                  790 ((size_t)(input_end +                 { - input_buffer->content) >= input_buffer-> 791  prevent buffer overflow when last input character is a backslash  792                      793                }                      794  795 796                 skipped_bytes++            }                 input_end++ 797  798 799             input_end++if  800          801 (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != goto  string ended unexpectedly               802 fail;  803 804  This is at most how much we need for the output   805          skipped_bytes; 806         allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) -char 807         output = (unsigned if*)input_buffer->hooks.allocate(allocation_length +  808          809 (output == allocation failure   810              811 812  813  output;  814     output_pointer = loop through the string literal  815     while input_end)      816 (input_pointer < 817if  818          819 (*input_pointer !=  820  821             *output_pointer++ = *input_pointer++ escape sequence   822          823 824          825 if             unsigned  826              827 ((input_end - input_pointer) <  828  829                  830 switch ])              831 (input_pointer[ 832b  833                 \b 834                     *output_pointer++ =  835 836                     \f                  837                     *output_pointer++ =  838n                      839                 \n 840                     *output_pointer++ =  841r                      842                 \r 843                     *output_pointer++ =  844t                      845                 \t 846                     *output_pointer++ =  847 848                      849                 /                  850                  851 852                     *output_pointer++ = input_pointer[ 853                      UTF-16 literal   854                  855 856                 if                     sequence_length = utf16_literal_to_utf8(input_pointer,input_end,1)">output_pointer); 857                                         { (sequence_length ==  858  Failed to convert UTF16-literal to UTF-8  859                          860                    }                          861  862 863                      864  865                  866                      867  868             input_pointer += 869  870  zero terminate the output   871      872 873     *output_pointer =  cJsON_String;  874     item->type =)output; 875     item->valuestring = ( 876content);  877     input_buffer->offset = (size_t) (input_end - input_buffer-> 878 879     input_buffer->offset++ 880  881      882 if  883      884 (output !=hooks.deallocate(output);  885         input_buffer-> 886 887 if  888      889 (input_pointer != 890  891         input_buffer->offset = (size_t)(input_pointer - input_buffer-> 892  893  894      895  Render the cstring provIDed to an escaped version that can be printed.   896 staticconst  898 cJsON_bool print_string_ptr(char input,1)"> 897  899      900 *input_pointer = 901     unsigned  902     unsigned  numbers of additional characters needed for escaPing      size_t output_length =  903      904 905     size_t escape_characters =  906  907      908  909          910  empty string   911     if 912      913 (input == 914  915         output = ensure(output_buffer,1)">\"\" 916          917  918             char  920         strcpy(( 921*)output,1)"> 919  922          923  set "flag" to 1 if something needs to be escaped   924     for 925      926 (input_pointer = input; *input_pointer; input_pointer++switch input_pointer)          927 (* 928 929  930              931              932              933              934              935              one character escape sequence               936                  937 938                 escape_characters++ 939                 if             32                  940 (*input_pointer <  941 UTF-16 escape sequence uXXXX   942                     5 943                     escape_characters +=  944 945  946                  947  escape_characters;  948     output_length = (size_t)(input_pointer - input) + 949 950  951     output = ensure(output_buffer,output_length +  952      953  954          955  no characters have to be escaped   956     if 957      958 (escape_characters == 0  959         output[ 960] = 1         memcpy(output +  961         output[output_length + 2] =  962         output[output_length +  963] =  964  965          966  967  968     output[ copy the string      output_pointer = output +  969     for'     voID (input_pointer = input; *input_pointer !=  970; ( 971)input_pointer++,output_pointer++if 31         ' ((*input_pointer >  972) && (*input_pointer !=  973) && (*input_pointer !=  normal character,copy   974             input_pointer; 975             *output_pointer = * 976 977  978          character needs to be escaped   979              980 981             *output_pointer++ =  982              983  984                  985                     *output_pointer =  986                      987                  988                     *output_pointer =  989                      990                  991                     *output_pointer =  992                      993                  994                     *output_pointer =  995                      996                  997                     *output_pointer =  998                      999                 1000                     *output_pointer = 1001                     1002                 1003                     *output_pointer = 1004                      escape and print as unicode codepoint                  1005                     charinput_pointer);                     sprintf((1006*)output_pointer,1)">u%04x10071008                     output_pointer += 1009                     1010 1011 1012 1013     output[output_length + 1014     output[output_length + 1015 1016     1017  Invoke print_string_ptr (which is useful) on an item.  1018 static p) 1019 cJsON_bool print_string(1020return char     1021 print_string_ptr((unsigned 1022*)item->1023  Predeclare these prototypes.  1024 static input_buffer); 1025 cJsON_bool parse_value(cJsON * static output_buffer); 1026 cJsON_bool print_value(static1027 static cJsON_bool parse_array(cJsON * 1028 static cJsON_bool print_array(1029 static cJsON_bool parse_object(cJsON * 1030 1031 cJsON_bool print_object( Utility to jump whitespace and cr/lf  1032 static1033 1034 parse_buffer *buffer_skip_whitespace(parse_buffer * if 1035     1036 ((buffer == NulL) || (buffer->content ==1037 1038         1039 if 1041      buffer; (cannot_access_at_index(buffer,1)">1040 1042         10431044 while 0     1045 (can_access_at_index(buffer,1)">0) && (buffer_at_offset(buffer)[1046] <= 1047 1048        buffer->offset++1049 if 1050     1051 (buffer->offset == buffer->1052 1053         buffer->offset--1054 1055 1056     1057  skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer  1058 static1059 1060 parse_buffer *skip_utf8_bom(parse_buffer * if 1061     1062 ((buffer == NulL) || (buffer->content == NulL) || (buffer->offset != 1063 1064         1065 if char     3 (can_access_at_index(buffer,1)">4) && (strncmp((1066*)buffer_at_offset(buffer),1)">\xEF\xBB\xBF1067) == 1068 1069         buffer->offset += 1070 1071 1072     1073 1074 1075 CJsON_PUBliC(cJsON *) cJsON_ParseWithOpts(    size_t buffer_length; 1076 1077if  value)     1078 (NulL ==10791080 1081         1082  Adding null character size due to require_null_terminated.  1083     10841085     buffer_length = strlen(value) +  cJsON_ParseWithLengthOpts(value,buffer_length,return_parse_end,require_null_terminated); 1086     10871088  Parse an object - create a new root,and populate.  1089 10901091 CJsON_PUBliC(cJsON *) cJsON_ParseWithLengthOpts(0  } };     parse_buffer buffer = { 1092,{ 10931094     cJsON *item = reset error position  1095     10961097     global_error.Json =1098     global_error.position = if 0      buffer_length) (value == NulL || 1099 ==11001101 1102         1103 )value; 1104     buffer.content = ( buffer_length; 1105     buffer.length =1106 global_hooks;     buffer.offset = 1107     buffer.hooks =11081109 if     item = cJsON_New_Item(& memory fail      1110 (item == NulL) 11111112 1113         1114 if buffer))))     1115 (!parse_value(item,buffer_skip_whitespace(skip_utf8_bom(&1116 parse failure. ep is set.  1117         11181119         1120  if we require null-terminated JsON without appended garbage,skip and then check for a null terminator  1121      (require_null_terminated)1122     11231124 if         buffer_skip_whitespace(&1125         1126 ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[1127 1128             1129  (return_parse_end) 1130     1131char 1132         *return_parse_end = (1133*)buffer_at_offset(&1134  item; 1135     11361137 if 1138     1139 (item !=        cJsON_Delete(item); 1140 11411142 if 1143     1144 (value !=        error local_error; 1145 11461147         local_error.Json = (1148         local_error.position = if  buffer.length)         1149 (buffer.offset <1150 buffer.offset; 1151             local_error.position =1152if 1153         1154 (buffer.length > 1155 1156             local_error.position = buffer.length - 1157 if 1158         1159 (return_parse_end !=char  local_error.position;             *return_parse_end = (1160*)local_error.Json +11611162  local_error; 1163         global_error =11641165 1166 1167     1168  Default options for cJsON_Parse  1169 value)1170 CJsON_PUBliC(cJsON *) cJsON_Parse(1171return 1173     1174 cJsON_ParseWithOpts(value,1)">1172 1175 1176 CJsON_PUBliC(cJsON *) cJsON_ParseWithLength(return 1178     1179 cJsON_ParseWithLengthOpts(value,1)">1177 #define 1180 1181 cJson_min(a,b) (((a) < (b)) ? (a) : (b))char 1182 1183 *print(const 256     1184 size_t default_buffer_size = 1185char     printbuffer buffer[1186     unsigned 1187 *printed =1188 1189     memset(buffer,1)">(buffer)); create buffer  1190     charallocate(default_buffer_size);     buffer->buffer = (unsigned 1191*) hooks-> default_buffer_size;1192     buffer->length = format;1193     buffer->format =hooks;1194     buffer->hooks = *if1195     1196 (buffer->buffer ==1197 1198         1199  print the value  1200     print_value(item,buffer))1201     12021203 1204             update_offset(buffer); 1205 1206 check if reallocate is available  1207     if1208     1209 (hooks->reallocate !=char 1210         printed = (unsigned if*) hooks->reallocate(buffer->buffer,buffer->offset +  NulL) {         1211 (printed ==12121213             1214 1215         buffer->buffer = otherwise copy the JsON over to a new buffer  1216     1217char 1218         printed = (unsigned 1219*) hooks->allocate(buffer->offset + 1220         1221 1222             '  just to be sure          memcpy(printed,buffer->buffer,cJson_min(buffer->length,1)">1223         printed[buffer->offset] = 1224; 1225 free the buffer  1226         12271228         hooks->deallocate(buffer->1229  printed; 1230     12311232 if 1233     1234 (buffer->buffer !=1235 1236         hooks->deallocate(buffer->1237 if 1238     1239 (printed !=deallocate(printed); 1240         hooks->12411242 1243 1244     1245  Render a cJsON item/entity/structure to text.  1246 12471248 CJsON_PUBliC(char 1250     1251*)print(item,1)">true,1)">1249 1252 1253 CJsON_PUBliC(false 1255     1256,1)">1254 1257 1258 CJsON_PUBliC(1259 1260     printbuffer p = { if 1261     1262 (prebuffer < 1263 1264         1265 )global_hooks.allocate((size_t)prebuffer); 1266     p.buffer = (unsigned p.buffer)1267     12681269 1270         1271  (size_t)prebuffer; 1272     p.length =12731274     p.offset =  fmt;     p.noalloc = 1275     p.format =12761277     p.hooks =if 1278     1279 (!print_value(item,1)">p))        global_hooks.deallocate(p.buffer); 1280 12811282         1283 )p.buffer; 1284     12851286 1287 1288 CJsON_PUBliC(cJsON_bool) cJsON_PrintPreallocated(cJsON *item,1)"> cJsON_bool format)1289 1290     printbuffer p = { 0 1291     1292) || (buffer ==1293 1294         1295 )buffer; 1296     p.buffer = (unsigned 12971298     p.length =1299     p.offset = 1300     p.noalloc = 1301     p.format =1302     p.hooks =return 1303     1304 print_value(item,1)">p);1305  Parser core - when encountering text,process appropriately.  1306 13071308 1309 1310      no input  1311         13121313  parse the different types of values  1314      null 1315     if1316     1317 (can_read(input_buffer,1)">char*)buffer_at_offset(input_buffer),1)">4) ==  cJsON_NulL; 1318         item->type =13191320         input_buffer->offset += 1321          false  1322     5false     5) && (strncmp((13231324) ==  cJsON_False; 1325         item->type =13261327         input_buffer->offset += 1328          true  1329     true1330     1331 cJsON_True; 1332         item->type =13331334         item->valueint = 1335         input_buffer->offset += 1336          string  1337     if1338     1339 (can_access_at_index(input_buffer,1)">0) && (buffer_at_offset(input_buffer)[ parse_string(item,input_buffer); 1340         1341 number  1342     0'     0) && ((buffer_at_offset(input_buffer)[') || ((buffer_at_offset(input_buffer)[))))] >= 1343) && (buffer_at_offset(input_buffer)[13441346  array           parse_number(item,1)">1345 1347     [1348     13491351  object           parse_array(item,1)">1350 1352     {1353     13541356 1357          parse_object(item,1)">1355 1358 1359     1360  Render a value to text.  1361 13621363 1364 1365     unsigned if 1366     1367 ((item == NulL) || (output_buffer ==1368 1369         1370 switch 1371     1372 ((item->type) & case  cJsON_NulL:         137313751376             output = ensure(output_buffer,1)">1374             1377 1378                 1379 1380             strcpy((1381              cJsON_False: 1382         13841385             output = ensure(output_buffer,1)">1383             1386 1387                 1388 1389             strcpy((1390              cJsON_True: 1391         13931394             output = ensure(output_buffer,1)">1392             1395 1396                 1397 1398             strcpy((1399              cJsON_Number: 1400          print_number(item,output_buffer);1401             1402 cJsON_Raw: 1403         14041405 if             size_t raw_length = 1406             1407 (item->valuestring ==1408 1409                 1410 1411  ensure(output_buffer,raw_length);             raw_length = strlen(item->valuestring) + 1412             output =14131414             1415 1416                 1418 1419             memcpy(output,1)">1417             1420  cJsON_String: 1421         1423 cJsON_Array:              print_string(item,1)">1422 1424         1426 cJsON_Object:              print_array(item,1)">1425 1427         14291430              print_object(item,1)">1428 1431         1432             1433 1434  Build an array from input text.  1435 14361437  head of the linked List  1438     cJsON *head = NulL; 14391440     cJsON *current_item =if  CJsON_nesTING_liMIT)     1441 (input_buffer->depth >=1442 to deeply nested  1443         14441445 1446     input_buffer->depth++1447 1448      not an array  1449         14501451         1452 1453     buffer_skip_whitespace(input_buffer);     input_buffer->offset++1454 ]1455     1456 empty array  1457          success;1458         14591460  check if we skipped to the end of the buffer  1461     if1463     1464 (cannot_access_at_index(input_buffer,1)">1462 1465         input_buffer->offset--1466         1467  step back to character in front of the first element  1468     1469 loop through the comma separated array elements      input_buffer->offset--1470     do1471     1472 allocate next item  1473         hooks));1474         cJsON *new_item = cJsON_New_Item(&(input_buffer->if1475         1476 (new_item ==1477 1478             1479  attach next item to List  1480         if1481         1482 (head == start the linked List  1483              new_item;1484             current_item = head =14851486 1487          add to the end and advance  1488             1489 current_item;             current_item->next =1490             new_item->prev =14911492             current_item =1493  parse next value  1494         1495        buffer_skip_whitespace(input_buffer);         input_buffer->offset++1496 parse_value(current_item,input_buffer))1497         1498 Failed to parse value  1499             15001501 1502 while 1503     1504 (can_access_at_index(input_buffer,0 1505     1506) || buffer_at_offset(input_buffer)[ expected end of array  1507         15081509 success: 1510 15111512     input_buffer->depth-- cJsON_Array; 1513     item->type = head;1514     item->child =15151516 1517     input_buffer->offset++1518 1519     1520 if 1521     1522 (head !=        cJsON_Delete(head); 1523 15241525 1526 1527     1528  Render an array to text  1529 15301531 1532 1533     unsigned 1534     size_t length = 1535     cJsON *current_element = item->1536 1537     1538 1539         1540  Compose the output array.  1541      opening square bracket 1542     15441545     output_pointer = ensure(output_buffer,1)">1543     1546 1547         1548 1549 1550     *output_pointer = 1551     output_buffer->offset++1552     output_buffer->depth++while 1553     1554 (current_element !=print_value(current_element,output_buffer)) 1555         15561557 1558                     update_offset(output_buffer); 1559 ifnext)         1560 (current_element->15612 1562             length = (size_t) (output_buffer->format ? 1563 : 1564             output_pointer = ensure(output_buffer,length + 1565             1566 1567                 1568 if             *output_pointer++ = format)             1569(output_buffer->1570' 1571                 *output_pointer++ = 1572 1573  length;             *output_pointer = 1574             output_buffer->offset +=15751576 1577         current_element = current_element->1578 1580 1581     output_pointer = ensure(output_buffer,1)">1579     1582 1583         1584 1585     *output_pointer++ = 1586     *output_pointer = 1587     output_buffer->depth--1588 1589     1590  Build an object from the text.  1591 15921593  linked List head  1594     cJsON *head = NulL; 15951596     cJsON *current_item =1597 1598     1599 1600         1601 1602     input_buffer->depth++0 1603     1604) || (buffer_at_offset(input_buffer)[ not an object  1605         16061607 1608 1609     input_buffer->offset++} 1610     1611goto  empty object          1612 success; 16131614 1615 1616     1617     1618 1619         input_buffer->offset--1620         1621 1622 1623     1624     input_buffer->offset--1625     1626     1627 1628         1629         cJsON *new_item = cJsON_New_Item(&(input_buffer->1630         1631 1632             1633 1634 1635         1636         1637 1638             1639             current_item = head =1640 1641         1642 1643             1644             current_item->next =1645             new_item->prev =1646             current_item =1647  parse the name of the child  1648         16491650         input_buffer->offset++1652  Failed to parse name          parse_string(current_item,1)">1651 1653             16541655 1656  swap valuestring and string,because we parsed the name  1657         string1658         current_item->1659 = current_item->1660         current_item->valuestring =: 1661         1662 invalID object  1663             16641665  parse the value  1666         16671668         input_buffer->offset++1669 1670         1671 1672             1673 1674 1675 1676     1677 1678      expected end of object  1679         16801681 1682 1683 1684     input_buffer->depth-- cJsON_Object; 1685     item->type =16861687     item->child =1688 1689     input_buffer->offset++1690     1691 1692 1693     1694 1695 1696 1697 1698     1699  Render an object to text.  1700 17011702 1703 1704     unsigned 1705     size_t length = 1706     cJsON *current_item = item->1707 1708     1709 1710         1711  Compose the output:  1712     1 fmt: {\n      length = (size_t) (output_buffer->format ? 1713); 17151716     output_pointer = ensure(output_buffer,1)">1714     1717 1718         1719 1720 1721     *output_pointer++ = if     output_buffer->depth++1722     1723 (output_buffer->1724 1725         *output_pointer++ = 1726 1727     output_buffer->offset +=while  (current_item)     172817291730 1731                     size_t i; 1732 depth);1733             output_pointer = ensure(output_buffer,output_buffer->17341735             1736 1737                 0 1738             1739; i < output_buffer->depth; i++1740 1741                 *output_pointer++ = depth; 1742             output_buffer->offset += output_buffer->17431744  print key  1745         ifchar         1746 (!print_string_ptr((unsigned 1747*)current_item->1748 1749             1750 1751 1752 1753         length = (size_t) (output_buffer->format ? 1754         output_pointer =1755         1756 1757             1758 1759         *output_pointer++ = 1760         1761 1762             *output_pointer++ = 1763 1764         output_buffer->offset += print value  1765         17671768         print_value(current_item,1)">1766 1769             1770 1771  print comma if not last  1772         10         length = ((size_t)(output_buffer->format ? 1773 : 1775) + (size_t)(current_item->next ? 1776         output_pointer = ensure(output_buffer,1)">1774         1777 1778             if 1779         1780 (current_item->1781 1782             *output_pointer++ = 1783 1784 1785         1786 1787             *output_pointer++ = 1788 1789         *output_pointer = 1790         output_buffer->offset +=1791 1792         current_item = current_item->1793 1 1794     output_pointer = ensure(output_buffer,output_buffer->format ? (output_buffer->depth + 1795) : 1796     1797 1798         1799 1800             size_t i; 1801 01         1802; i < (output_buffer->depth - 1803); i++1804 1805             *output_pointer++ = 1806 1807 1808     *output_pointer++ = 1809     *output_pointer = 1810     output_buffer->depth--1811 1812     1813  Get Array size/item / object item.  1814 array)1815 CJsON_PUBliC(18161817 1818     cJsON *child =1819     size_t size = if 1820     1821 (array ==1822 1823         1824 1825 1826     child = array->while 1827     1828(child !=1829 1830         size++1831         child = child->1832  FIXME: Can overflow here. Cannot be fixed without breaking the API  1833     1834)size; 1835     18361837 static array,size_t index) 1838 cJsON* get_array_item(18391840 1841     cJsON *current_child =1842 1843     1844 1845         1846 1847 while     current_child = array->1848     1849 ((current_child != NulL) && (index > 1850 1851         index--1852         current_child = current_child->1853  current_child; 1854     18551856  index) 1857 CJsON_PUBliC(cJsON *) cJsON_GetArrayItem(1858if 1859     1860 (index < 1861 1862         1863  get_array_item(array,(size_t)index); 1864     18651866 static  cJsON_bool case_sensitive) 1867 cJsON *get_object_item(18681869 1870     cJsON *current_element =if object     1871 ((1872 == NulL) || (name ==1873 1874         1875 1876  (case_sensitive)     current_element = 1877     1878while string         string ((current_element != NulL) && (current_element->1879 != NulL) && (strcmp(name,current_element->1880) != 1881 1882             current_element = current_element->1883 1884 1885     while char         string ((current_element != NulL) && (case_insensitive_strcmp((1886*)name,1)">char*)(current_element->1887)) != 1888 1889             current_element = current_element->1890 1891 if  NulL)) {     1892 ((current_element == NulL) || (current_element->18931894         1895  current_element; 1896     18971898 1899 1900 CJsON_PUBliC(cJsON *) cJsON_GetobjectItem(return 1901     1902 get_object_item(1903 1904 1905 CJsON_PUBliC(cJsON *) cJsON_GetobjectItemCaseSensitive(1906 1907     1908 1909 1910 CJsON_PUBliC(cJsON_bool) cJsON_HasObjectItem(return string     1911 cJsON_GetobjectItem(1912) ? 1913  Utility for array List handling.  1914 voID1916 1917 suffix_object(cJsON *prev,1)">1915  prev;     prev->next =1918     item->prev =19191920  Utility for handling references.  1921 static1922 1923 cJsON *create_reference(1924 if     cJsON *reference =1925     1926 (item ==1927 1928         1929  cJsON_New_Item(hooks); 1930     reference =if1931     1932 (reference ==1933 1934         1935 string 1937     memcpy(reference,item,1)">1936     reference-> cJsON_IsReference; =1938     reference->type |=1939 reference;     reference->next = reference->prev =1940     19411942 static 1944 1945 cJsON_bool add_item_to_array(cJsON *array,1)">1943 1946     cJsON *child =if  item))     1947 ((item == NulL) || (array == NulL) || (array ==19481949 1950         1951 1952 1953     child = array->     * To find the last item in array quickly,we use prev in array     1954 1955if      1956     1957 (child == List is empty,start new one  1958         19591960         array->child =1961         item->prev =1962         item->next =1963 1964      append to the end  1965         ifprev)         1966 (child->1967prev,item); 1968             suffix_object(child->19691970             array->child->prev =1971 1972         while 1973             1974 (child->1975 1976                 child = child->1978 1979             suffix_object(child,1)">1977             array->child->prev =1980 1981 1982 1983     1984  Add item to array/object.  1985 19871989 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToArray(cJsON *array,1)">1986 1990      add_item_to_array(array,1)">1988 #if 1991 #pragma defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MInor__ > 5))))1992     1993 GCC diagnostic push1994 #pragma 1995 1996 GCC diagnostic ignored "-Wcast-qual" helper function to cast away const  1997 voIDvoID 1998* cast_away_const(1999* voID 2000     2001*)2002 #pragma 2003     2004 GCC diagnostic pop2005 2006 static const 2007 cJsON_bool add_item_to_object(cJsON * 2008 hooks,1)"> cJsON_bool constant_key)char 2009     int *new_key = cJsON_InvalID;     2010 new_type =2011object string     object == NulL) || (2012 == NulL) || (item == NulL) || (2013 ==2014 2015         2016  (constant_key) 2017     2018char 2019         new_key = ( cJsON_StringIsConst;*)cast_away_const(2020         new_type = item->type |20212022 2023     char 2024         new_key = (if*)cJsON_strdup((2025         2026 (new_key ==2027 2028             2029 cJsON_StringIsConst; 2030         new_type = item->type & ~20312032 2033 2034     2035 2036         hooks->deallocate(item->2037  new_key; 2038     item-> new_type;2039     item->type =2040return 2041     2042 add_item_to_array(2043 2044 2045 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObject(cJsON *return 2046     2047 add_item_to_object(2048  Add an item to an object with constant string as key  2049 20502051 CJsON_PUBliC(cJsON_bool) cJsON_AddItemToObjectCS(cJsON *2052 2053     2054 2056 2057 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoArray(cJsON *array,1)">2055 2058     2059 2060         2061 return 2062     2063 add_item_to_array(array,create_reference(item,1)">global_hooks));2064 2065 2066 CJsON_PUBliC(cJsON_bool) cJsON_AddItemReferencetoObject(cJsON *2067 2068     2069 2070         2071 2072 2073     2074  name) 2075 CJsON_PUBliC(cJsON*) cJsON_AddNullToObject(cJsON * 2076null  cJsON_CreateNull();     cJsON *2077 =ifnull     2079 (add_item_to_object(null,1)">2078 2080         20812082 2083 2084     cJsON_Delete(2085     2086 2087 2088 CJsON_PUBliC(cJsON*) cJsON_AddTruetoObject(cJsON *  cJsON_CreateTrue(); 2089     cJsON *true_item =20902091      true_item; 2092         20932094     cJsON_Delete(true_item); 2095 20962097     2098 2099 2100 CJsON_PUBliC(cJsON*) cJsON_AddFalsetoObject(cJsON *  cJsON_CreateFalse(); 2101     cJsON *false_item =21022103      false_item; 2104         21052106     cJsON_Delete(false_item); 2107 21082109     2110  cJsON_bool boolean) 2111 CJsON_PUBliC(cJsON*) cJsON_AddBoolToObject(cJsON * 2112 cJsON_CreateBool(boolean); 2113     cJsON *bool_item =21142115      bool_item; 2116         21172118     cJsON_Delete(bool_item); 2119 21202121     2122 2123 2124 CJsON_PUBliC(cJsON*) cJsON_AddNumberToObject(cJsON *  cJsON_CreateNumber(number); 2125     cJsON *number_item =21262127      number_item; 2128         21292130     cJsON_Delete(number_item); 2131 21322133     2134 2135 2136 CJsON_PUBliC(cJsON*) cJsON_AddStringToObject(cJsON * 2137 2138     cJsON *string_item = cJsON_CreateString(2139      string_item; 2140         21412142     cJsON_Delete(string_item); 2143 21442145     2146  raw) 2147 CJsON_PUBliC(cJsON*) cJsON_AddRawToObject(cJsON * 2148 cJsON_Createraw(raw); 2149     cJsON *raw_item =21502151      raw_item; 2152         21532154     cJsON_Delete(raw_item); 2155 21562157     2158 2159 2160 CJsON_PUBliC(cJsON*) cJsON_AddobjectToObject(cJsON *  cJsON_CreateObject(); 2161     cJsON *object_item =21622163      object_item; 2164         21652166     cJsON_Delete(object_item); 2167 21682169     2170 2171 2172 CJsON_PUBliC(cJsON*) cJsON_AddArrayToObject(cJsON *  cJsON_CreateArray(); 2173     cJsON *array =21742175      array; 2176         21772178     cJsON_Delete(array); 2179 21802181     2182 2183 2184 CJsON_PUBliC(cJsON *) cJsON_DetachItemViaPointer(cJsON *parent,1)"> item)if 2185     2186 ((parent == NulL) || (item ==2187 2188         2189 if child)     2190 (item != parent->2191 not the first element  2192         21932194         item->prev->next = item->if 2195     2196 (item->next != not the last element  2197         21982199         item->next->prev = item->2200 if 2201     2202 (item == parent-> first element  2203         22042205         parent->child = item-> make sure the detached item doesn't point anywhere anymore  2206     22072208     item->prev =2209     item->next =2210 2211     2212 2213 2214 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromArray(cJsON *array,1)"> which)if 2215     2216 (which < 2217 2218         2219  cJsON_DetachItemViaPointer(array,get_array_item(array,(size_t)which)); 2220     22212222 2223 2224 CJsON_PUBliC(    cJsON_Delete(cJsON_DetachItemFromArray(array,which)); 2225 22262227 2228 2229 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObject(cJsON *2230 2231     cJsON *to_detach = cJsON_GetobjectItem(return 2232     2233 cJsON_DetachItemViaPointer(2234 2235 2236 CJsON_PUBliC(cJsON *) cJsON_DetachItemFromObjectCaseSensitive(cJsON *2237 2238     cJsON *to_detach = cJsON_GetobjectItemCaseSensitive(2239 2240     2241 2242 2243 CJsON_PUBliC(2244 2245     cJsON_Delete(cJsON_DetachItemFromObject(2246 2247 2248 CJsON_PUBliC(2249 2250     cJsON_Delete(cJsON_DetachItemFromObjectCaseSensitive(2251  Replace array/object items with new ones.  2252 22532254 CJsON_PUBliC(cJsON_bool) cJsON_InsertItemInArray(cJsON *array,1)">newitem)2255 2256     cJsON *after_inserted =2257 2258     2259 2260         2261 2262 if     after_inserted =2263     2264 (after_inserted ==2265 2266         2267  after_inserted; 2268     newitem->next =2269 newitem;     newitem->prev = after_inserted->2270     after_inserted->prev =if2271     2272 (after_inserted == array->2273 2274         array->child =2275 2276     2277 2278         newitem->prev->next =2279 2280     2281  replacement) 2282 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemViaPointer(cJsON * 2283if 2284     2285 ((parent == NulL) || (replacement == NulL) || (item ==2286 2287         2288 if 2289     2290 (replacement ==2291 2292         2293 2294 2295     replacement->next = item->2296     replacement->prev = item->if 2297     2298 (replacement->next != replacement; 2299         replacement->next->prev =2300if 2301     2302 (parent->child ==2303 2304         parent->child =2305 2306              * To find the last item in array quickly,we use prev in array.     {   2307          * We can't modify the last item's next pointer where this item was the parent's child2308 2309if          2310         2311 (replacement->prev !=2312 2313             replacement->prev->next =2314 2315 2316 2317     item->next =    cJsON_Delete(item);     item->prev =2318 23192320 2321     2322 2324 2325 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInArray(cJsON *array,1)">2323 2326     2327 2328         2329 2331 2332      cJsON_ReplaceItemViaPointer(array,(size_t)which),1)">2330 static replacement,cJsON_bool case_sensitive) 2333 cJsON_bool replace_item_in_object(cJsON *2334if 2335     2336 ((replacement == NulL) || (2337 2338         2339  replace the name in the replacement  2340     if2341     2342 (!(replacement->type & cJsON_StringIsConst) && (replacement->2343 2344         cJsON_free(replacement->string 2345     replacement->2346 = (2347     replacement->type &= ~return 2348     2349 cJsON_ReplaceItemViaPointer(2350 2351 2352 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObject(cJsON *return 2353     2354 replace_item_in_object(2355 2356 2357 CJsON_PUBliC(cJsON_bool) cJsON_ReplaceItemInObjectCaseSensitive(cJsON *2358 2359     2360  Create basic types:  2361 23622363 CJsON_PUBliC(cJsON *) cJsON_CreateNull(2364 (item)     cJsON *item = cJsON_New_Item(&2365     23662367 2368         item->type =2369 2370 2371     2372 2373 2374 CJsON_PUBliC(cJsON *) cJsON_CreateTrue(2375 2376     cJsON *item = cJsON_New_Item(&2377     2378 2379         item->type =2380 2381 2382     2383 2384 2385 CJsON_PUBliC(cJsON *) cJsON_CreateFalse(2386 2387     cJsON *item = cJsON_New_Item(&2388     2389 2390         item->type =2391 2392 2393     2394 ) cJsON_CreateBool(cJsON_bool boolean) 2395 CJsON_PUBliC(cJsON *23962397 2398     cJsON *item = cJsON_New_Item(&2399      cJsON_True : cJsON_False; 2400         item->type = boolean ?24012402 2403 2404     2405  num) 2406 CJsON_PUBliC(cJsON *) cJsON_CreateNumber(24072408 2409     cJsON *item = cJsON_New_Item(&2410     2411  num;         item->type =2412         item->valuedouble =24132414 if         2415         2416 (num >=2417 2418             item->valueint =if 2419         2420 (num <= (2421 2422             item->valueint =2423 2424         )num; 2425             item->valueint = (24262427 2428 2429 2430     2431 2432 2433 CJsON_PUBliC(cJsON *) cJsON_CreateString(2434 2435     cJsON *item = cJsON_New_Item(&2436     2437 2438         item->type =if         item->valuestring = (2439         2440(!item->            cJsON_Delete(item); 2441 24422443             2444 2445 2446 2447     2448 2449 2450 CJsON_PUBliC(cJsON *) cJsON_CreateStringReference(2451 2452     cJsON *item = cJsON_New_Item(&2453     2454 2455         item->type = cJsON_String |2456         item->valuestring = (2457 2458 2459     2460 2461 2462 CJsON_PUBliC(cJsON *) cJsON_CreateObjectReference(2463 2464     cJsON *item = cJsON_New_Item(&2465     )cast_away_const(child);         item->type = cJsON_Object |2466         item->child = (cJsON*24672468 2469 2470     2471 child) { 2472 CJsON_PUBliC(cJsON *) cJsON_CreateArrayReference(24732474     cJsON *item = cJsON_New_Item(&2475     2476         item->type = cJsON_Array |2477         item->child = (cJsON*2478 2479 2480     2481 raw) 2482 CJsON_PUBliC(cJsON *) cJsON_Createraw(24832484 2485     cJsON *item = cJsON_New_Item(&2486      cJsON_Raw; 2487         item->type =char2489         item->valuestring = (2490*)raw,1)">2488         2491 2492 2493             2494 2495 2496 2497     2498 2499 2500 CJsON_PUBliC(cJsON *) cJsON_CreateArray(2501 2502     cJsON *item = cJsON_New_Item(&2503     cJsON_Array; 2504         item->type=25052506 2507 2508     2509 2510 2511 CJsON_PUBliC(cJsON *) cJsON_CreateObject(2512  (item)     cJsON *item = cJsON_New_Item(&2513     25142515 2516         item->type =2517 2518 2519     2520  Create Arrays:  2521  count)2522 CJsON_PUBliC(cJsON *) cJsON_CreateIntArray(25232524 2525     size_t i = 2526     cJsON *n =2527     cJsON *p =2528     cJsON *a =if 0     2529 ((count < 2530) || (numbers ==2531 2532         2533 2534 for     a =0     2535(i = 2536; a && (i < (size_t)count); i++ cJsON_CreateNumber(numbers[i]); 2537         n =n)2538         2539            cJsON_Delete(a); 2540 25412542             if i)         2543(!2544 n; 2545             a->child =25462547 2548                     suffix_object(p,n); 2549 25502551 2552         p =2553  a; 2554     25552556 2557 2558 CJsON_PUBliC(cJsON *) cJsON_CreatefloatArray(2559 2560     size_t i = 2561     cJsON *n =2562     cJsON *p =2563     cJsON *a =2564 2565     2566 2567         2568 2569 2570     a =2571 2572     )numbers[i]); 2573         n = cJsON_CreateNumber((25742575         2576 2577 2578             2579 2580         2581 2582             a->child =2583 2584         2585 2586 2587 2588         p =2589 2590 2591     2592 2593 2594 CJsON_PUBliC(cJsON *) cJsON_CreateDoubleArray(2595 2596     size_t i = 2597     cJsON *n =2598     cJsON *p =2599     cJsON *a =2600 2601     2602 2603         2604 2605 2606     a =0 2607     2608;a && (i < (size_t)count); i++2609 2610         n =2611         2612 2613 2614             2615 2616         2617 2618             a->child =2619 2620         2621 2622 2623 2624         p =2625 2626 2627     2628 2629 2630 CJsON_PUBliC(cJsON *) cJsON_CreateStringArray(2631 2632     size_t i = 2633     cJsON *n =2634     cJsON *p =2635     cJsON *a =0 2636     2637) || (strings ==2638 2639         2640 2641 2642     a =2643 2644      cJsON_CreateString(strings[i]); 2645         n =26462647         2648 2649 2650             2651 2652         2653 2654             a->child =2655 2656         2657 2658 2659 2660         p =2661 2662 2663     2664  Duplication  2665 26662667 CJsON_PUBliC(cJsON *) cJsON_Duplicate(2668 2669     cJsON *newitem =2670     cJsON *child =2671     cJsON *next =2672     cJsON *newchild = Bail on bad ptr  2673     26742675     2676 2677          Create new item  2678     26792680     newitem = cJsON_New_Item(&2681     2682 2683          copy over all vars  2684     cJsON_IsReference);2685     newitem->type = item->type & (~valueint;2686     newitem->valueint = item->2687if     newitem->valuedouble = item->2688     2689 (item->char char         newitem->valuestring = (if*)cJsON_strdup((unsigned 2691*)item->valuestring,1)">2690         2692 (!newitem->2693 2694             2695 2696 2697     string string         newitem->2698 = (item->type&cJsON_StringIsConst) ? item->2699 : (2700         2701 2702             2703  If non-recursive,then we're done!  2704     recurse)2705     27062707 2708          Walk the ->next chain for the child.  2709     2710while     child = item->2711     2712 (child != Duplicate (with recurse) each item in the ->next chain  2713         newchild = cJsON_Duplicate(child,1)">true); newchild)2714         27152716 2717             if 2718         2719 (next != If newitem->child already set,then crosswire ->prev and ->next and move on  2720              newchild;2721             next->next =27222723             newchild->prev =2724             next =2725 2726          Set newitem->child and move to it  2727             27282729             newitem->child =2730             next =2731 2732         child = child->2733 2734 2735     2736 if 2737     2738 (newitem !=        cJsON_Delete(newitem); 2739 27402741 2742 2743     2744 voID input) 2745 skip_oneline_comment(2746// 2747     *input += static_strlen(2748for '     input)) (; (*input)[2749; ++(*2750if ) {         2751 ((*input)[27522753             *input += static_strlen(2754             2755 2756 2757 voID 2758 2759 skip_multiline_comment(/* 2760     *input += static_strlen(27612762 2763     if *         ' (((*input)[12764) && ((*input)[2765] == */ 2766             *input += static_strlen(27672768             2769 2770 2771 voID char 2772 Minify_string(0 **input,1)">output) {2773     (*output)[2774] = (*input)[2775     *input += static_strlen(2776     *output += static_strlen(2777 voID output)) {     2778)++(*input),++(*27792780         (*output)[2781 2782         2783             (*output)[2784             *input += static_strlen(2785             *output += static_strlen()) {             2786         } 12787             (*output)[2788] = (*input)[2789             *input += static_strlen(2790             *output += static_strlen(2791 2792 2793 Json) 2794 CJsON_PUBliC(2795char  Json;     2796 *into =2797if 2798     2799 (Json ==2800 2801         2802 while 2803     2804 (Json[switch 2805         2806 (Json[2807 2808             2809             2810             2811             2812                 Json++2813                 2814 if             2815                 2816 (Json[2817 2818                     skip_oneline_comment(&2819 2820                 2821 else                     skip_multiline_comment(&2822                 } 28232824                     Json++2825 2826                 2827 2828             2829                 Minify_string(&Json,1)">into);2830                 2831 0             2832                 into[2833] = Json[2834                 Json++2835                 into++2836 2837  and null-terminate.  2838     28392840     *into = 2841 2842 2843 CJsON_PUBliC(cJsON_bool) cJsON_IsInvalID(2844 2845     2846 2847         2848 return 0xFF     2849 (item->type & 2850) ==2851 2852 2853 CJsON_PUBliC(cJsON_bool) cJsON_IsFalse(2854 2855     2856 2857         2858 2859 2860     2861 2862 2863 CJsON_PUBliC(cJsON_bool) cJsON_IsTrue(2864 2865     2866 2867         2868 0xff 2869     2870) ==2871 2872 2873 2874 CJsON_PUBliC(cJsON_bool) cJsON_IsBool(2875 2876     2877 2878         2879 return 2880     2881 (item->type & (cJsON_True | cJsON_False)) != 2882 2883 CJsON_PUBliC(cJsON_bool) cJsON_IsNull(2884 2885     2886 2887         2888 2889 2890     2891 2892 2893 CJsON_PUBliC(cJsON_bool) cJsON_IsNumber(2894 2895     2896 2897         2898 2899 2900     2901 2902 2903 CJsON_PUBliC(cJsON_bool) cJsON_Isstring(2904 2905     2906 2907         2908 2909 2910     2911 2912 2913 CJsON_PUBliC(cJsON_bool) cJsON_IsArray(2914 2915     2916 2917         2918 2919 2920     2921 2922 2923 CJsON_PUBliC(cJsON_bool) cJsON_IsObject(2924 2925     2926 2927         2928 2929 2930     2931 2932 2933 CJsON_PUBliC(cJsON_bool) cJsON_IsRaw(2934 2935     2936 2937         2938 2939 2940     2941 2942 2943 CJsON_PUBliC(cJsON_bool) cJsON_Compare(if 0xFF     0xFF ((a == NulL) || (b == NulL) || ((a->type &  cJsON_IsInvalID(a))) != (b->type & 2944)) ||29452946 2947         2948  check if type is valID  2949     switch2950     2951 (a->type & 2952 2953         2954         2955         2956         2957         2958         2959         2960         2961             2962 2963         2964             2965  IDentical objects are equal  2966     if2967     2968 (a ==2969 2970         2971 2972 2973      in these cases and equal type is enough  2974         29752976         2977         2978         2979             2980 if         valuedouble))             2981 (compare_double(a->valuedouble,b->29822983 2984                 2985 2986             2987 2988         if         2989             2990 ((a->valuestring == NulL) || (b->valuestring ==2991 2992                 if 2993             2994 (strcmp(a->valuestring,b->valuestring) == 2995 2996                 2997 2998 2999             3000 3001         3002 3003             cJsON *a_element = a->3004             cJsON *b_element = b->for  NulL);)             3005 (; (a_element != NulL) && (b_element !=3006cJsON_Compare(a_element,b_element,case_sensitive)) 3007                 30083009 3010                     3011 3012 3013                 a_element = a_element->3014                 b_element = b_element->3015  one of the arrays is longer than the other  3016             if b_element) {             3017 (a_element !=30183019                 3020 3021 3022             3023 3024 3025         3026 3027             cJsON *a_element =            cJsON_ArrayForEach(a_element,a)             cJsON *b_element =3028 3029 Todo This has O(n^2) runtime,which is horrible!  3030                 3031if                 b_element = get_object_item(b,a_element->3032                 3033 (b_element ==3034 3035                     3036 3037 3038                 3039 3040                     3041 3042  doing this twice,once on a and b to prevent true comparison if a subset of b 3043                          * Todo: Do this the proper way,this is just a fix for Now 3044             cJsON_ArrayForEach(b_element,b)3045 30463047 if                 a_element = get_object_item(a,b_element->3048                 3049 (a_element ==3050 3051                     3052 3054 3055                 cJsON_Compare(b_element,a_element,1)">3053 3056                     3057 3058 3059 3060             3061 3062 3063         3064             3065 3066 ) cJsON_malloc(size_t size) 3067 CJsON_PUBliC(3068 global_hooks.allocate(size); 3069     30703071 3072 3073 CJsON_PUBliC(3074 VIEw Code     global_hooks.deallocate( }

 

 参考:

https://blog.csdn.net/shizhe0123/article/details/94742514

https://blog.csdn.net/fengxinlinux/article/details/53121287

https://www.cnblogs.com/skullboyer/p/8152157.html

总结

以上是内存溢出为你收集整理的不可不知的JSON处理库(cJSON)全部内容,希望文章能够帮你解决不可不知的JSON处理库(cJSON)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1158246.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存