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 }
厚积薄发,开物成务。
德才兼备、知行合一。
自强不息,厚德载物。