STM32-cJSON库的打包和解析

这几天使用了一下JSON在STM32103平台上的使用,还是很好用的,在此记录下。

JSON是啥我也不总结了,就是直观的看起来是一个有格式的字符串,看起来非常清楚明白,有点像Python中的dicitionary的意思,键值对,详细的可以看此链接http://www.cnblogs.com/catgatp/p/6380030.html。实际使用的过程中主要就是“打包”和“解析”。下面直接来代码。

 

 1 char * Status_to_cJSON( char * cJSONROOM, ROBOStatus_TypeDef status)//传入一个变量的指针,这里cJSONROOM是一个全局变量(一个提前规定大小的字符数组),用来存放转换之后的JSON字符串
 2 
 3 {
 4 
 5       char *result;
 6 
 7       cJSON *root,*subroot;//新建两个cJSON的对象指针
 8 
 9       root=cJSON_CreateObject();//创建一个机器人状态的JSON对象
10 
11       subroot=cJSON_CreateObject();//subroot是下面的一个嵌入对象
12 
13       cJSON_AddStringToObject(subroot,"RunStatus",status.RunStatus);//将status.RunStatus的值赋值到subroot下面一个叫RunStatus的变量。
14 
15       cJSON_AddStringToObject(subroot,"CurrentTime",status.CurrentTime);
16 
17 //同上
18 
19   cJSON_AddNumberToObject(subroot,"CurrentPosition",status.CurrentPositiont);
20 
21 //将位置信息赋值到subroot下面一个叫CurrentPosition的变量,注意此处为Number类型
22 
23       cJSON_AddNumberToObject(subroot,"CurrentSpeed",status.CurrentSpeed);
24 
25       cJSON_AddNumberToObject(subroot,"RunningCount",status.RunningCount);      
26 
27       cJSON_AddNumberToObject(subroot,"CurrentTemp",status.CurrentTemp);
28 
29      cJSON_AddNumberToObject(subroot,"CurrentVoltage",status.CurrentVoltage);      
30 
31       cJSON_AddNumberToObject(subroot,"CurrentAmp",status.CurrentAmp);
32 
33       cJSON_AddNumberToObject(subroot,"CurrentDir",status.CurrentDir);   
34 
35 cJSON_AddNumberToObject(subroot,"ControlSystemEnergy",status.ControlSystemEnergy);
36 
37 cJSON_AddNumberToObject(subroot,"DynamicSystemEnergy",status.DynamicSystemEnergy);
38 
39    cJSON_AddItemToObject(root, "RobotStatus", subroot);
40 
41       result=cJSON_PrintUnformatted(root);//生成JSONC字符串,注意可以用cJSON_Print()格式的,就是人眼看着好看一点,就是有点占用存储空间
42 
43       strcpy(cJSONROOM,result);//将转换的结果字符串赋值给传入的全局变量
44 
45       cJSON_Delete(root);//最后将root根节点删除
46 
47       myfree(result);//释放result的空间,必须要有,要不然内存里会失去一段空间,最后系统崩溃
48 
49       return cJSONROOM;//不要指望着返回一个局部变量的地址,这是非常危险的,因为函数调用完毕后这个地址指向的内容就消失了。所以这个函数在设计的时候返回了一个全局变量的地址。
50 
51 }   

 

注意:malloc在STM32平台上使用的时候需要改动一下,关于内存操作的改动见下面的代码。使用字符数组会提高程序的可靠性,之前一直用字符指针,可能没有用好,中途会挂掉,后来发现提前建立一个数组,在这段空间进行数据的操作还是比较稳定的。

  1 #include "malloc.h"
  2 
  3 //内存池(4字节对齐)
  4 __align(4) u8 membase[MEM_MAX_SIZE];                                                    //内部SRAM内存池
  5 //内存管理表
  6 u16 memmapbase[MEM_ALLOC_TABLE_SIZE];                                                    //内部SRAM内存池MAP
  7 //内存管理参数       
  8 const u32 memtblsize = MEM_ALLOC_TABLE_SIZE;        //内存表大小
  9 const u32 memblksize = MEM_BLOCK_SIZE;                    //内存分块大小
 10 const u32 memsize    = MEM_MAX_SIZE;                            //内存总大小
 11 
 12 
 13 //内存管理控制器
 14 struct _m_mallco_dev mallco_dev=
 15 {
 16     mem_init,                //内存初始化
 17     mem_perused,      //内存使用率
 18     membase,            //内存池
 19     memmapbase,     //内存管理状态表
 20     0,                        //内存管理未就绪
 21 };
 22 
 23 //复制内存
 24 //*des:目的地址
 25 //*src:源地址
 26 //n:需要复制的内存长度(字节为单位)
 27 void mymemcpy(void *des,void *src,u32 n)  
 28 {  
 29   u8 *xdes=des;
 30     u8 *xsrc=src; 
 31   while(n--)*xdes++=*xsrc++;  
 32 }  
 33 
 34 //设置内存
 35 //*s:内存首地址
 36 //c :要设置的值
 37 //count:需要设置的内存大小(字节为单位)
 38 void mymemset(void *s,u8 c,u32 count)  
 39 {  
 40     u8 *xs = s;  
 41     while(count--)*xs++=c;  
 42 }    
 43 
 44 //内存管理初始化  
 45 //memx:所属内存块
 46 void mem_init(void)  
 47 {  
 48   mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零  
 49     mymemset(mallco_dev.membase, 0,memsize);    //内存池所有数据清零  
 50     mallco_dev.memrdy=1;                                //内存管理初始化OK  
 51 } 
 52  
 53 //获取内存使用率
 54 //memx:所属内存块
 55 //返回值:使用率(0~100)
 56 u8 mem_perused(void)  
 57 {  
 58     u32 used=0;  
 59     u32 i;  
 60     for(i=0;i<memtblsize;i++)  
 61     {  
 62         if(mallco_dev.memmap[i])used++; 
 63     } 
 64     return (used*100)/(memtblsize);  
 65 }  
 66 
 67 //内存分配(内部调用)
 68 //memx:所属内存块
 69 //size:要分配的内存大小(字节)
 70 //返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址 
 71 u32 mem_malloc(u32 size)  
 72 {  
 73     signed long offset=0;  
 74     u16 nmemb;    //需要的内存块数  
 75     u16 cmemb=0;//连续空内存块数
 76     u32 i;  
 77     if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化 
 78     if(size==0)return 0XFFFFFFFF;//不需要分配
 79 
 80     nmemb=size/memblksize;      //获取需要分配的连续内存块数
 81     if(size%memblksize)nmemb++;  
 82     for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区  
 83     {     
 84         if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
 85         else cmemb=0;                                //连续内存块清零
 86         if(cmemb==nmemb)                            //找到了连续nmemb个空内存块
 87         {
 88             for(i=0;i<nmemb;i++)                      //标注内存块非空 
 89             {  
 90                 mallco_dev.memmap[offset+i]=nmemb;  
 91             }  
 92             return (offset*memblksize);//返回偏移地址  
 93         }
 94     }  
 95     return 0XFFFFFFFF;//未找到符合分配条件的内存块  
 96 }  
 97 
 98 //释放内存(内部调用) 
 99 //memx:所属内存块
100 //offset:内存地址偏移
101 //返回值:0,释放成功;1,释放失败;  
102 u8 mem_free(u32 offset)  
103 {  
104     int i;  
105     if(!mallco_dev.memrdy)//未初始化,先执行初始化
106     {
107         mallco_dev.init();    
108         return 1;//未初始化  
109     }  
110     if(offset<memsize)//偏移在内存池内. 
111     {  
112         int index=offset/memblksize;            //偏移所在内存块号码  
113         int nmemb=mallco_dev.memmap[index];    //内存块数量
114         for(i=0;i<nmemb;i++)                          //内存块清零
115         {  
116             mallco_dev.memmap[index+i]=0;  
117         }  
118         return 0;  
119     }else return 2;//偏移超区了.  
120 }  
121 
122 //释放内存(外部调用) 
123 //memx:所属内存块
124 //ptr:内存首地址 
125 void myfree(void *ptr)  
126 {  
127     u32 offset;  
128     if(ptr==NULL)return;//地址为0.  
129      offset=(u32)ptr-(u32)mallco_dev.membase;  
130     mem_free(offset);//释放内存     
131 }
132 
133 //分配内存(外部调用)
134 //memx:所属内存块
135 //size:内存大小(字节)
136 //返回值:分配到的内存首地址.
137 void *mymalloc(u32 size)  
138 {  
139     u32 offset;                                            
140     offset=mem_malloc(size);                            
141     if(offset==0XFFFFFFFF)return NULL;  
142     else return (void*)((u32)mallco_dev.membase+offset);  
143 }  
144 
145 //重新分配内存(外部调用)
146 //memx:所属内存块
147 //*ptr:旧内存首地址
148 //size:要分配的内存大小(字节)
149 //返回值:新分配到的内存首地址.
150 void *myrealloc(void *ptr,u32 size)  
151 {  
152     u32 offset;  
153     offset=mem_malloc(size);  
154     if(offset==0XFFFFFFFF)return NULL;     
155     else  
156     {                                         
157         mymemcpy((void*)((u32)mallco_dev.membase+offset),ptr,size);    //拷贝旧内存内容到新内存   
158         myfree(ptr);                                                        //释放旧内存
159         return (void*)((u32)mallco_dev.membase+offset);                  //返回新内存首地址
160     }  
161 } 

malloc.h内容如下:

 1 #ifndef __MALLOC_H
 2 #define __MALLOC_H
 3 #include "stm32f10x.h"
 4   
 5 #ifndef NULL
 6 #define NULL 0
 7 #endif
 8 
 9 #define MEM_BLOCK_SIZE              32                                      //内存块大小为32字节
10 #define MEM_MAX_SIZE                16*1024                                  //最大管理内存 2K
11 #define MEM_ALLOC_TABLE_SIZE    MEM_MAX_SIZE/MEM_BLOCK_SIZE //内存表大小
12          
13 //内存管理控制器
14 struct _m_mallco_dev
15 {
16     void (*init)(void);                    //初始化
17     u8   (*perused)(void);                      //内存使用率
18     u8       *membase;                    //内存池
19     u16   *memmap;                     //内存管理状态表
20     u8     memrdy;                         //内存管理是否就绪
21 };
22 
23 extern struct _m_mallco_dev mallco_dev;     //在mallco.c里面定义
24 
25 void mymemset(void *s,u8 c,u32 count);     //设置内存
26 void mymemcpy(void *des,void *src,u32 n);//复制内存 
27 
28 void mem_init(void);                     //内存管理初始化函数
29 u32 mem_malloc(u32 size);         //内存分配
30 u8 mem_free(u32 offset);         //内存释放
31 u8 mem_perused(void);                 //获得内存使用率 
32 ////////////////////////////////////////////////////////////////////////////////
33 //用户调用函数
34 void myfree(void *ptr);              //内存释放
35 void *mymalloc(u32 size);            //内存分配
36 void *myrealloc(void *ptr,u32 size);//重新分配内存
37 #endif

cJSON.c的内容也全在下面

  1 /*
  2   Copyright (c) 2009 Dave Gamble
  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,
 19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 20   THE SOFTWARE.
 21 */
 22 
 23 /* cJSON */
 24 /* JSON parser in C. */
 25 
 26 #include <string.h>
 27 #include <stdio.h>
 28 #include <math.h>
 29 #include <stdlib.h>
 30 #include <float.h>
 31 #include <limits.h>
 32 #include <ctype.h>
 33 #include "cJSON.h"
 34 
 35 #include "malloc.h"
 36 
 37 static const char *ep;
 38 
 39 const char *cJSON_GetErrorPtr(void) {return ep;}
 40 
 41 static int cJSON_strcasecmp(const char *s1,const char *s2)
 42 {
 43     if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
 44     for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)    if(*s1 == 0)    return 0;
 45     return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
 46 }
 47 
 48 static void *(*cJSON_malloc)(size_t sz) = mymalloc;
 49 static void (*cJSON_free)(void *ptr) = myfree;
 50 
 51 static char* cJSON_strdup(const char* str)
 52 {
 53       size_t len;
 54       char* copy;
 55 
 56       len = strlen(str) + 1;
 57       if (!(copy = (char*)cJSON_malloc(len))) return 0;
 58       memcpy(copy,str,len);
 59       return copy;
 60 }
 61 
 62 void cJSON_InitHooks(cJSON_Hooks* hooks)
 63 {
 64     if (!hooks) { /* Reset hooks */
 65         cJSON_malloc = malloc;
 66         cJSON_free = free;
 67         return;
 68     }
 69 
 70     cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
 71     cJSON_free     = (hooks->free_fn)?hooks->free_fn:free;
 72 }
 73 
 74 /* Internal constructor. */
 75 static cJSON *cJSON_New_Item(void)
 76 {
 77     cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
 78     if (node) memset(node,0,sizeof(cJSON));
 79     return node;
 80 }
 81 
 82 /* Delete a cJSON structure. */
 83 void cJSON_Delete(cJSON *c)
 84 {
 85     cJSON *next;
 86     while (c)
 87     {
 88         next=c->next;
 89         if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
 90         if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
 91         if (c->string) cJSON_free(c->string);
 92         cJSON_free(c);
 93         c=next;
 94     }
 95 }
 96 
 97 /* Parse the input text to generate a number, and populate the result into item. */
 98 static const char *parse_number(cJSON *item,const char *num)
 99 {
100     double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
101 
102     if (*num=='-') sign=-1,num++;    /* Has sign? */
103     if (*num=='0') num++;            /* is zero */
104     if (*num>='1' && *num<='9')    do    n=(n*10.0)+(*num++ -'0');    while (*num>='0' && *num<='9');    /* Number? */
105     if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;        do    n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}    /* Fractional part? */
106     if (*num=='e' || *num=='E')        /* Exponent? */
107     {    num++;if (*num=='+') num++;    else if (*num=='-') signsubscale=-1,num++;        /* With sign? */
108         while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');    /* Number? */
109     }
110 
111     n=sign*n*pow(10.0,(scale+subscale*signsubscale));    /* number = +/- number.fraction * 10^+/- exponent */
112     
113     item->valuedouble=n;
114     item->valueint=(int)n;
115     item->type=cJSON_Number;
116     return num;
117 }
118 
119 /* Render the number nicely from the given item into a string. */
120 static char *print_number(cJSON *item)
121 {
122     char *str;
123     double d=item->valuedouble;
124     if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
125     {
126         str=(char*)cJSON_malloc(21);    /* 2^64+1 can be represented in 21 chars. */
127         if (str) sprintf(str,"%d",item->valueint);
128     }
129     else
130     {
131         str=(char*)cJSON_malloc(64);    /* This is a nice tradeoff. */
132         if (str)
133         {
134             if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
135             else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)            sprintf(str,"%e",d);
136             else                                                sprintf(str,"%f",d);
137         }
138     }
139     return str;
140 }
141 
142 static unsigned parse_hex4(const char *str)
143 {
144     unsigned h=0;
145     if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
146     h=h<<4;str++;
147     if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
148     h=h<<4;str++;
149     if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
150     h=h<<4;str++;
151     if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
152     return h;
153 }
154 
155 /* Parse the input text into an unescaped cstring, and populate item. */
156 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
157 static const char *parse_string(cJSON *item,const char *str)
158 {
159     const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
160     if (*str!='\"') {ep=str;return 0;}    /* not a string! */
161     
162     while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;    /* Skip escaped quotes. */
163     
164     out=(char*)cJSON_malloc(len+1);    /* This is how long we need for the string, roughly. */
165     if (!out) return 0;
166     
167     ptr=str+1;ptr2=out;
168     while (*ptr!='\"' && *ptr)
169     {
170         if (*ptr!='\\') *ptr2++=*ptr++;
171         else
172         {
173             ptr++;
174             switch (*ptr)
175             {
176                 case 'b': *ptr2++='\b';    break;
177                 case 'f': *ptr2++='\f';    break;
178                 case 'n': *ptr2++='\n';    break;
179                 case 'r': *ptr2++='\r';    break;
180                 case 't': *ptr2++='\t';    break;
181                 case 'u':     /* transcode utf16 to utf8. */
182                     uc=parse_hex4(ptr+1);ptr+=4;    /* get the unicode char. */
183 
184                     if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)    break;    /* check for invalid.    */
185 
186                     if (uc>=0xD800 && uc<=0xDBFF)    /* UTF16 surrogate pairs.    */
187                     {
188                         if (ptr[1]!='\\' || ptr[2]!='u')    break;    /* missing second-half of surrogate.    */
189                         uc2=parse_hex4(ptr+3);ptr+=6;
190                         if (uc2<0xDC00 || uc2>0xDFFF)        break;    /* invalid second-half of surrogate.    */
191                         uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
192                     }
193 
194                     len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
195                     
196                     switch (len) {
197                         case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
198                         case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
199                         case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
200                         case 1: *--ptr2 =(uc | firstByteMark[len]);
201                     }
202                     ptr2+=len;
203                     break;
204                 default:  *ptr2++=*ptr; break;
205             }
206             ptr++;
207         }
208     }
209     *ptr2=0;
210     if (*ptr=='\"') ptr++;
211     item->valuestring=out;
212     item->type=cJSON_String;
213     return ptr;
214 }
215 
216 /* Render the cstring provided to an escaped version that can be printed. */
217 static char *print_string_ptr(const char *str)
218 {
219     const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
220     
221     if (!str) return cJSON_strdup("");
222     ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
223     
224     out=(char*)cJSON_malloc(len+3);
225     if (!out) return 0;
226 
227     ptr2=out;ptr=str;
228     *ptr2++='\"';
229     while (*ptr)
230     {
231         if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
232         else
233         {
234             *ptr2++='\\';
235             switch (token=*ptr++)
236             {
237                 case '\\':    *ptr2++='\\';    break;
238                 case '\"':    *ptr2++='\"';    break;
239                 case '\b':    *ptr2++='b';    break;
240                 case '\f':    *ptr2++='f';    break;
241                 case '\n':    *ptr2++='n';    break;
242                 case '\r':    *ptr2++='r';    break;
243                 case '\t':    *ptr2++='t';    break;
244                 default: sprintf(ptr2,"u%04x",token);ptr2+=5;    break;    /* escape and print */
245             }
246         }
247     }
248     *ptr2++='\"';*ptr2++=0;
249     return out;
250 }
251 /* Invote print_string_ptr (which is useful) on an item. */
252 static char *print_string(cJSON *item)    {return print_string_ptr(item->valuestring);}
253 
254 /* Predeclare these prototypes. */
255 static const char *parse_value(cJSON *item,const char *value);
256 static char *print_value(cJSON *item,int depth,int fmt);
257 static const char *parse_array(cJSON *item,const char *value);
258 static char *print_array(cJSON *item,int depth,int fmt);
259 static const char *parse_object(cJSON *item,const char *value);
260 static char *print_object(cJSON *item,int depth,int fmt);
261 
262 /* Utility to jump whitespace and cr/lf */
263 static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
264 
265 /* Parse an object - create a new root, and populate. */
266 cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
267 {
268     const char *end=0;
269     cJSON *c=cJSON_New_Item();
270     ep=0;
271     if (!c) return 0;       /* memory fail */
272 
273     end=parse_value(c,skip(value));
274     if (!end)    {cJSON_Delete(c);return 0;}    /* parse failure. ep is set. */
275 
276     /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
277     if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
278     if (return_parse_end) *return_parse_end=end;
279     return c;
280 }
281 /* Default options for cJSON_Parse */
282 cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
283 
284 /* Render a cJSON item/entity/structure to text. */
285 char *cJSON_Print(cJSON *item)                {return print_value(item,0,1);}
286 char *cJSON_PrintUnformatted(cJSON *item)    {return print_value(item,0,0);}
287 
288 /* Parser core - when encountering text, process appropriately. */
289 static const char *parse_value(cJSON *item,const char *value)
290 {
291     if (!value)                        return 0;    /* Fail on null. */
292     if (!strncmp(value,"null",4))    { item->type=cJSON_NULL;  return value+4; }
293     if (!strncmp(value,"false",5))    { item->type=cJSON_False; return value+5; }
294     if (!strncmp(value,"true",4))    { item->type=cJSON_True; item->valueint=1;    return value+4; }
295     if (*value=='\"')                { return parse_string(item,value); }
296     if (*value=='-' || (*value>='0' && *value<='9'))    { return parse_number(item,value); }
297     if (*value=='[')                { return parse_array(item,value); }
298     if (*value=='{')                { return parse_object(item,value); }
299 
300     ep=value;return 0;    /* failure. */
301 }
302 
303 /* Render a value to text. */
304 static char *print_value(cJSON *item,int depth,int fmt)
305 {
306     char *out=0;
307     if (!item) return 0;
308     switch ((item->type)&255)
309     {
310         case cJSON_NULL:    out=cJSON_strdup("null");    break;
311         case cJSON_False:    out=cJSON_strdup("false");break;
312         case cJSON_True:    out=cJSON_strdup("true"); break;
313         case cJSON_Number:    out=print_number(item);break;
314         case cJSON_String:    out=print_string(item);break;
315         case cJSON_Array:    out=print_array(item,depth,fmt);break;
316         case cJSON_Object:    out=print_object(item,depth,fmt);break;
317     }
318     return out;
319 }
320 
321 /* Build an array from input text. */
322 static const char *parse_array(cJSON *item,const char *value)
323 {
324     cJSON *child;
325     if (*value!='[')    {ep=value;return 0;}    /* not an array! */
326 
327     item->type=cJSON_Array;
328     value=skip(value+1);
329     if (*value==']') return value+1;    /* empty array. */
330 
331     item->child=child=cJSON_New_Item();
332     if (!item->child) return 0;         /* memory fail */
333     value=skip(parse_value(child,skip(value)));    /* skip any spacing, get the value. */
334     if (!value) return 0;
335 
336     while (*value==',')
337     {
338         cJSON *new_item;
339         if (!(new_item=cJSON_New_Item())) return 0;     /* memory fail */
340         child->next=new_item;new_item->prev=child;child=new_item;
341         value=skip(parse_value(child,skip(value+1)));
342         if (!value) return 0;    /* memory fail */
343     }
344 
345     if (*value==']') return value+1;    /* end of array */
346     ep=value;return 0;    /* malformed. */
347 }
348 
349 /* Render an array to text */
350 static char *print_array(cJSON *item,int depth,int fmt)
351 {
352     char **entries;
353     char *out=0,*ptr,*ret;int len=5;
354     cJSON *child=item->child;
355     int numentries=0,i=0,fail=0;
356     
357     /* How many entries in the array? */
358     while (child) numentries++,child=child->next;
359     /* Explicitly handle numentries==0 */
360     if (!numentries)
361     {
362         out=(char*)cJSON_malloc(3);
363         if (out) strcpy(out,"[]");
364         return out;
365     }
366     /* Allocate an array to hold the values for each */
367     entries=(char**)cJSON_malloc(numentries*sizeof(char*));
368     if (!entries) return 0;
369     memset(entries,0,numentries*sizeof(char*));
370     /* Retrieve all the results: */
371     child=item->child;
372     while (child && !fail)
373     {
374         ret=print_value(child,depth+1,fmt);
375         entries[i++]=ret;
376         if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
377         child=child->next;
378     }
379     
380     /* If we didn't fail, try to malloc the output string */
381     if (!fail) out=(char*)cJSON_malloc(len);
382     /* If that fails, we fail. */
383     if (!out) fail=1;
384 
385     /* Handle failure. */
386     if (fail)
387     {
388         for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
389         cJSON_free(entries);
390         return 0;
391     }
392     
393     /* Compose the output array. */
394     *out='[';
395     ptr=out+1;*ptr=0;
396     for (i=0;i<numentries;i++)
397     {
398         strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
399         if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
400         cJSON_free(entries[i]);
401     }
402     cJSON_free(entries);
403     *ptr++=']';*ptr++=0;
404     return out;    
405 }
406 
407 /* Build an object from the text. */
408 static const char *parse_object(cJSON *item,const char *value)
409 {
410     cJSON *child;
411     if (*value!='{')    {ep=value;return 0;}    /* not an object! */
412     
413     item->type=cJSON_Object;
414     value=skip(value+1);
415     if (*value=='}') return value+1;    /* empty array. */
416     
417     item->child=child=cJSON_New_Item();
418     if (!item->child) return 0;
419     value=skip(parse_string(child,skip(value)));
420     if (!value) return 0;
421     child->string=child->valuestring;child->valuestring=0;
422     if (*value!=':') {ep=value;return 0;}    /* fail! */
423     value=skip(parse_value(child,skip(value+1)));    /* skip any spacing, get the value. */
424     if (!value) return 0;
425     
426     while (*value==',')
427     {
428         cJSON *new_item;
429         if (!(new_item=cJSON_New_Item()))    return 0; /* memory fail */
430         child->next=new_item;new_item->prev=child;child=new_item;
431         value=skip(parse_string(child,skip(value+1)));
432         if (!value) return 0;
433         child->string=child->valuestring;child->valuestring=0;
434         if (*value!=':') {ep=value;return 0;}    /* fail! */
435         value=skip(parse_value(child,skip(value+1)));    /* skip any spacing, get the value. */
436         if (!value) return 0;
437     }
438     
439     if (*value=='}') return value+1;    /* end of array */
440     ep=value;return 0;    /* malformed. */
441 }
442 
443 /* Render an object to text. */
444 static char *print_object(cJSON *item,int depth,int fmt)
445 {
446     char **entries=0,**names=0;
447     char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
448     cJSON *child=item->child;
449     int numentries=0,fail=0;
450     /* Count the number of entries. */
451     while (child) numentries++,child=child->next;
452     /* Explicitly handle empty object case */
453     if (!numentries)
454     {
455         out=(char*)cJSON_malloc(fmt?depth+4:3);
456         if (!out)    return 0;
457         ptr=out;*ptr++='{';
458         if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
459         *ptr++='}';*ptr++=0;
460         return out;
461     }
462     /* Allocate space for the names and the objects */
463     entries=(char**)cJSON_malloc(numentries*sizeof(char*));
464     if (!entries) return 0;
465     names=(char**)cJSON_malloc(numentries*sizeof(char*));
466     if (!names) {cJSON_free(entries);return 0;}
467     memset(entries,0,sizeof(char*)*numentries);
468     memset(names,0,sizeof(char*)*numentries);
469 
470     /* Collect all the results into our arrays: */
471     child=item->child;depth++;if (fmt) len+=depth;
472     while (child)
473     {
474         names[i]=str=print_string_ptr(child->string);
475         entries[i++]=ret=print_value(child,depth,fmt);
476         if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
477         child=child->next;
478     }
479     
480     /* Try to allocate the output string */
481     if (!fail) out=(char*)cJSON_malloc(len);
482     if (!out) fail=1;
483 
484     /* Handle failure */
485     if (fail)
486     {
487         for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
488         cJSON_free(names);cJSON_free(entries);
489         return 0;
490     }
491     
492     /* Compose the output: */
493     *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
494     for (i=0;i<numentries;i++)
495     {
496         if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
497         strcpy(ptr,names[i]);ptr+=strlen(names[i]);
498         *ptr++=':';if (fmt) *ptr++='\t';
499         strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
500         if (i!=numentries-1) *ptr++=',';
501         if (fmt) *ptr++='\n';*ptr=0;
502         cJSON_free(names[i]);cJSON_free(entries[i]);
503     }
504     
505     cJSON_free(names);cJSON_free(entries);
506     if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
507     *ptr++='}';*ptr++=0;
508     return out;    
509 }
510 
511 /* Get Array size/item / object item. */
512 int    cJSON_GetArraySize(cJSON *array)                            {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
513 cJSON *cJSON_GetArrayItem(cJSON *array,int item)                {cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
514 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)    {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
515 
516 /* Utility for array list handling. */
517 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
518 /* Utility for handling references. */
519 static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;mymemcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
520 
521 /* Add item to array/object. */
522 void   cJSON_AddItemToArray(cJSON *array, cJSON *item)                        {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
523 void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)    {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
524 void    cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)                        {cJSON_AddItemToArray(array,create_reference(item));}
525 void    cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)    {cJSON_AddItemToObject(object,string,create_reference(item));}
526 
527 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)            {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
528     if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
529 void   cJSON_DeleteItemFromArray(cJSON *array,int which)            {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
530 cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
531 void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
532 
533 /* Replace array/object items with new ones. */
534 void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)        {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
535     newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
536     if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
537 void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
538 
539 /* Create basic types: */
540 cJSON *cJSON_CreateNull(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
541 cJSON *cJSON_CreateTrue(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
542 cJSON *cJSON_CreateFalse(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
543 cJSON *cJSON_CreateBool(int b)                    {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
544 cJSON *cJSON_CreateNumber(double num)            {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
545 cJSON *cJSON_CreateString(const char *string)    {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
546 cJSON *cJSON_CreateArray(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
547 cJSON *cJSON_CreateObject(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
548 
549 /* Create Arrays: */
550 cJSON *cJSON_CreateIntArray(const int *numbers,int count)        {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
551 cJSON *cJSON_CreateFloatArray(const float *numbers,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
552 cJSON *cJSON_CreateDoubleArray(const double *numbers,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
553 cJSON *cJSON_CreateStringArray(const char **strings,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
554 
555 /* Duplication */
556 cJSON *cJSON_Duplicate(cJSON *item,int recurse)
557 {
558     cJSON *newitem,*cptr,*nptr=0,*newchild;
559     /* Bail on bad ptr */
560     if (!item) return 0;
561     /* Create new item */
562     newitem=cJSON_New_Item();
563     if (!newitem) return 0;
564     /* Copy over all vars */
565     newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
566     if (item->valuestring)    {newitem->valuestring=cJSON_strdup(item->valuestring);    if (!newitem->valuestring)    {cJSON_Delete(newitem);return 0;}}
567     if (item->string)        {newitem->string=cJSON_strdup(item->string);            if (!newitem->string)        {cJSON_Delete(newitem);return 0;}}
568     /* If non-recursive, then we're done! */
569     if (!recurse) return newitem;
570     /* Walk the ->next chain for the child. */
571     cptr=item->child;
572     while (cptr)
573     {
574         newchild=cJSON_Duplicate(cptr,1);        /* Duplicate (with recurse) each item in the ->next chain */
575         if (!newchild) {cJSON_Delete(newitem);return 0;}
576         if (nptr)    {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}    /* If newitem->child already set, then crosswire ->prev and ->next and move on */
577         else        {newitem->child=newchild;nptr=newchild;}                    /* Set newitem->child and move to it */
578         cptr=cptr->next;
579     }
580     return newitem;
581 }
582 
583 void cJSON_Minify(char *json)
584 {
585     char *into=json;
586     while (*json)
587     {
588         if (*json==' ') json++;
589         else if (*json=='\t') json++;    // Whitespace characters.
590         else if (*json=='\r') json++;
591         else if (*json=='\n') json++;
592         else if (*json=='/' && json[1]=='/')  while (*json && *json!='\n') json++;    // double-slash comments, to end of line.
593         else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;}    // multiline comments.
594         else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
595         else *into++=*json++;            // All other characters.
596     }
597     *into=0;    // and null-terminate.
598 }

cJSON.h内容如下
  1 /*
  2   Copyright (c) 2009 Dave Gamble
  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,
 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 #include <stddef.h>
 27 
 28 #ifdef __cplusplus
 29 extern "C"
 30 {
 31 #endif
 32 
 33 /* cJSON Types: */
 34 #define cJSON_False 0
 35 #define cJSON_True 1
 36 #define cJSON_NULL 2
 37 #define cJSON_Number 3
 38 #define cJSON_String 4
 39 #define cJSON_Array 5
 40 #define cJSON_Object 6
 41     
 42 #define cJSON_IsReference 256
 43 
 44 /* The cJSON structure: */
 45 typedef struct cJSON {
 46     struct cJSON *next,*prev;    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
 47     struct cJSON *child;        /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
 48 
 49     int type;                    /* The type of the item, as above. */
 50 
 51     char *valuestring;            /* The item's string, if type==cJSON_String */
 52     int valueint;                /* The item's number, if type==cJSON_Number */
 53     double valuedouble;            /* The item's number, if type==cJSON_Number */
 54 
 55     char *string;                /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
 56 } cJSON;
 57 
 58 
 59 
 60 typedef struct cJSON_Hooks {
 61       void *(*malloc_fn)(size_t sz);
 62       void (*free_fn)(void *ptr);
 63 } cJSON_Hooks;
 64 
 65 /* Supply malloc, realloc and free functions to cJSON */
 66 extern void cJSON_InitHooks(cJSON_Hooks* hooks);
 67 
 68 
 69 /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
 70 extern cJSON *cJSON_Parse(const char *value);
 71 /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
 72 extern char  *cJSON_Print(cJSON *item);
 73 /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
 74 extern char  *cJSON_PrintUnformatted(cJSON *item);
 75 /* Delete a cJSON entity and all subentities. */
 76 extern void   cJSON_Delete(cJSON *c);
 77 
 78 /* Returns the number of items in an array (or object). */
 79 extern int      cJSON_GetArraySize(cJSON *array);
 80 /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
 81 extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
 82 /* Get item "string" from object. Case insensitive. */
 83 extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
 84 
 85 /* 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. */
 86 extern const char *cJSON_GetErrorPtr(void);
 87     
 88 /* These calls create a cJSON item of the appropriate type. */
 89 extern cJSON *cJSON_CreateNull(void);
 90 extern cJSON *cJSON_CreateTrue(void);
 91 extern cJSON *cJSON_CreateFalse(void);
 92 extern cJSON *cJSON_CreateBool(int b);
 93 extern cJSON *cJSON_CreateNumber(double num);
 94 extern cJSON *cJSON_CreateString(const char *string);
 95 extern cJSON *cJSON_CreateArray(void);
 96 extern cJSON *cJSON_CreateObject(void);
 97 
 98 /* These utilities create an Array of count items. */
 99 extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
100 extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
101 extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
102 extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
103 
104 /* Append item to the specified array/object. */
105 extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
106 extern void    cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
107 /* 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. */
108 extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
109 extern void    cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
110 
111 /* Remove/Detatch items from Arrays/Objects. */
112 extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
113 extern void   cJSON_DeleteItemFromArray(cJSON *array,int which);
114 extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
115 extern void   cJSON_DeleteItemFromObject(cJSON *object,const char *string);
116     
117 /* Update array items. */
118 extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
119 extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
120 
121 /* Duplicate a cJSON item */
122 extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
123 /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
124 need to be released. With recurse!=0, it will duplicate any children connected to the item.
125 The item->next and ->prev pointers are always zero on return from Duplicate. */
126 
127 /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
128 extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
129 
130 extern void cJSON_Minify(char *json);
131 
132 /* Macros for creating things quickly. */
133 #define cJSON_AddNullToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateNull())
134 #define cJSON_AddTrueToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
135 #define cJSON_AddFalseToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
136 #define cJSON_AddBoolToObject(object,name,b)    cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
137 #define cJSON_AddNumberToObject(object,name,n)    cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
138 #define cJSON_AddStringToObject(object,name,s)    cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
139 
140 /* When assigning an integer value, it needs to be propagated to valuedouble too. */
141 #define cJSON_SetIntValue(object,val)            ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
142 
143 #ifdef __cplusplus
144 }
145 #endif
146 
147 #endif

 





 

 

下面是JSON数据的解析部分,简单说来就是对号入座。

  1 /**************************************************************************
  2 函数功能:JSON字符串解析,按照命令格式,解析出上位机发送的命令
  3 入口参数:JSON格式的字符串,
  4 返回  值:指令类型
  5 注    意:从服务器的socket得到的字符串是加密了的字符串,需要首先解密后才能放入此函数
  6 **************************************************************************/
  7 CommandType GetCommandFromServer(char * JsonDataFromSocket)
  8 {
  9     
 10 //  ROBOCmd_TypeDef cmd;//使用的时候用全部结构体代替
 11     
 12 //    Hello_Ack_TypeDef hello_ack;//使用的时候用全局接头体代替
 13     CommandType cmdtype;
 14   RobotJSON_CMD_TypeDef json_cmd;    
 15     HelloJSON_Ack_TypeDef json_ack;
 16     
 17   cJSON *root,*command_root;
 18 
 19   root =     cJSON_Parse(JsonDataFromSocket); //实例化JSON对象(静态对象)    
 20     if(!root) 
 21             {
 22                  //printf("get cJSON  faild !\n");
 23                 cmdtype=NOCOMMAND;//如果没有,就直接返回0
 24              } 
 25             else
 26                 {
 27                  command_root = cJSON_GetObjectItem(root, "RobotCommand"); //取RobotCommand键值对
 28                     if(!command_root) 
 29                         { 
 30                                 //printf("No RobotCommand !\n"); 
 31                             
 32                                 command_root = cJSON_GetObjectItem(root, "HelloACK"); //取hellACK键值对
 33                                     if(!command_root)
 34                                     {
 35                                          //将函数的返回值改下 既不是RobotCommand也不是HelloACK的情况就返回0
 36                                              cmdtype=NOCOMMAND;//如果没有,就直接返回0
 37                                     }
 38                                     else{
 39                                                 
 40                                     
 41                                             json_ack.ID = cJSON_GetObjectItem(command_root,"ID");
 42                                             if(!json_ack.ID)
 43                                                 {
 44                                                     cmdtype=NOCOMMAND;//如果没有,就直接返回0
 45                                                 }
 46                                             else
 47                                                 {
 48                                                          strcpy(Ack_From_Server.ID,json_ack.ID->valuestring);
 49                                                 }
 50                                             json_ack.Time = cJSON_GetObjectItem(command_root,"Time");
 51                                             if(!json_ack.Time)
 52                                                 {
 53                                                     cmdtype=NOCOMMAND;//如果没有,就直接返回0
 54                                                 }
 55                                             else
 56                                                 {
 57                                                          strcpy(Ack_From_Server.Time,json_ack.Time->valuestring);                    
 58                                                 }
 59 
 60                                                 cmdtype=HELLO_ACK;//如果没有,就直接返回0
 61                                     }
 62                         }
 63                     else
 64                         {
 65                             
 66                             //运动命令
 67                               json_cmd.Command =cJSON_GetObjectItem(command_root,"Command");
 68                             if(!json_cmd.Command) 
 69                                 { 
 70                                     //printf("no Command!\n");
 71                                         //cmdtype=NOCOMMAND;//如果没有,就直接返回0    
 72                                 } 
 73                             else
 74                                 {
 75                                                 //printf("Command is %s\r\n", robocmd.Command->valuestring);
 76                                                  strcpy(Cmd_From_Server.Command,json_cmd.Command->valuestring);
 77                                     //此时应该发送对应命令的OK程序,Set或者Auto或者。。。具体见协议
 78                                     
 79                                 }
 80                             //速度指令
 81                             json_cmd.Speed=cJSON_GetObjectItem(command_root,"Speed");
 82                             if(!json_cmd.Speed) 
 83                                 { 
 84                                     //printf("no Speed!\n");     
 85 //                                    cmdtype=NOCOMMAND;//如果没有,就直接返回0
 86                                 } 
 87                             else
 88                                 {
 89                                                 //printf("Speed is %d\r\n", json_cmd.Speed->valueint);
 90                                                 Cmd_From_Server.Speed=json_cmd.Speed->valueint;
 91                                 }
 92                             
 93                                 //运行次数
 94                                 json_cmd.RunCount = cJSON_GetObjectItem(command_root,"RunCount");
 95                             if(!json_cmd.RunCount) 
 96                                 { 
 97                                     //printf("no RunCount!\n"); 
 98 //                                        cmdtype=NOCOMMAND;//如果没有,就直接返回0
 99                                 } 
100                             else
101                                 {
102                                             //printf("RunCount is %d\r\n",json_cmd.RunCount->valueint);
103                                             Cmd_From_Server.RunCount=json_cmd.RunCount->valueint;
104                                 }
105                                 //开始位置
106                                     json_cmd.StartPosition = cJSON_GetObjectItem(command_root,"StartPosition");
107                             if(!json_cmd.StartPosition) 
108                                 { 
109                                     //printf("no StartPosition!\n"); 
110 //                                        cmdtype=NOCOMMAND;//如果没有,就直接返回0
111                                 } 
112                             else
113                                 {
114                                             //printf("StartPosition is %d\r\n",json_cmd.StartPosition->valueint);
115                                             Cmd_From_Server.StartPosition=json_cmd.StartPosition->valueint;
116                                 }
117                                 //结束位置
118                                             json_cmd.EndPosition = cJSON_GetObjectItem(command_root,"EndPosition");
119                             if(!json_cmd.EndPosition) 
120                                 { 
121                                     //printf("no EndPosition!\n"); 
122 //                                        cmdtype=NOCOMMAND;//如果没有,就直接返回0
123                                 } 
124                             else
125                                 {
126                                             //printf("EndPosition is %d\r\n",json_cmd.EndPosition->valueint);
127                                             Cmd_From_Server.EndPosition=json_cmd.EndPosition->valueint;
128                                 }
129                                 //目标位置TargetPosition
130                                                         json_cmd.TargetPosition = cJSON_GetObjectItem(command_root,"TargetPosition");
131                             if(!json_cmd.TargetPosition) 
132                                 { 
133                                     //printf("no TargetPosition!\n"); 
134 //                                        cmdtype=NOCOMMAND;//如果没有,就直接返回0
135                                 } 
136                             else
137                                 {
138                                             //printf("TargetPosition is %d\r\n",json_cmd.TargetPosition->valueint);
139                                             Cmd_From_Server.TargetPosition=json_cmd.TargetPosition->valueint;
140                                 }
141                             
142                                 //*工作模式WorkMode;
143                                  json_cmd.WorkMode= cJSON_GetObjectItem(command_root,"WorkMode");
144                                 if(!json_cmd.WorkMode) 
145                                 { 
146                                     //printf("no WorkMode!\n"); 
147 //                                        cmdtype=NOCOMMAND;//如果没有,就直接返回0
148                                 } 
149                             else
150                                 {
151                                             //printf("WorkMode is %s\r\n",json_cmd.WorkMode->valuestring);
152                                              strcpy(Cmd_From_Server.WorkMode,json_cmd.WorkMode->valuestring);
153                                 }
154                                 //step
155                                      json_cmd.Step= cJSON_GetObjectItem(command_root,"Step");
156                                 if(!json_cmd.Step) 
157                                 { 
158                                     //printf("no Step!\n"); 
159 //                                        cmdtype=NOCOMMAND;//如果没有,就直接返回0
160                                 } 
161                             else
162                                 {
163                                             //printf("Step is %d\r\n",json_cmd.Step->valueint);
164                                             Cmd_From_Server.Step=json_cmd.Step->valueint;
165                                 }
166                                 
167                                 
168                                 cmdtype= COMMAND;
169                                 
170                         } 
171              }
172 
173 cJSON_Delete(root);
174 
175 return cmdtype;
176 }

 

posted on 2018-05-26 21:02  克拉波隆方程  阅读(10518)  评论(0编辑  收藏  举报

导航