這幾天使用了一下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 }