cJSON.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /* cJSON */
  2. /* JSON parser in C. */
  3. #include "main.h"
  4. //#include <string.h>
  5. //#include <stdio.h>
  6. //#include <math.h>
  7. //#include <stdlib.h>
  8. //#include <float.h>
  9. //#include <limits.h>
  10. //#include <ctype.h>
  11. //#include <stddef.h>
  12. //#include "cJSON.h"
  13. //#include "myMalloc.h"
  14. static const char *ep;
  15. static int cJSON_strcasecmp(const char *s1,const char *s2)
  16. {
  17. if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
  18. for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
  19. return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
  20. }
  21. // Óû§µÄÄÚ´æ¹ÜÀíº¯Êý
  22. static void *(*cJSON_malloc)(size_t sz) = mymalloc;
  23. static void (*cJSON_free)(void *ptr) = myfree;
  24. /* Internal constructor. */
  25. static cJSON *cJSON_New_Item(void)
  26. {
  27. cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
  28. if (node) memset(node,0,sizeof(cJSON));
  29. return node;
  30. }
  31. /* Delete a cJSON structure. */
  32. void cJSON_Delete(cJSON *c)
  33. {
  34. cJSON *next;
  35. while (c)
  36. {
  37. next=c->next;
  38. if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
  39. if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
  40. if (c->string) cJSON_free(c->string);
  41. cJSON_free(c);
  42. c=next;
  43. }
  44. }
  45. /* Parse the input text to generate a number, and populate the result into item. */
  46. static const char *parse_number(cJSON *item,const char *num)
  47. {
  48. double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
  49. if (*num=='-') sign=-1,num++; /* Has sign? */
  50. if (*num=='0') num++; /* is zero */
  51. if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
  52. if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
  53. if (*num=='e' || *num=='E') /* Exponent? */
  54. { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
  55. while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
  56. }
  57. n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
  58. item->valuedouble=n;
  59. item->valueint=(int)n;
  60. item->type=cJSON_Number;
  61. return num;
  62. }
  63. /* Render the number nicely from the given item into a string. */
  64. static char *print_number(cJSON *item)
  65. {
  66. char *str;
  67. double d=item->valuedouble;
  68. if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
  69. {
  70. str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
  71. if (str) sprintf(str,"%d",item->valueint);
  72. }
  73. else
  74. {
  75. str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
  76. if (str)
  77. {
  78. if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
  79. else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
  80. else sprintf(str,"%f",d);
  81. }
  82. }
  83. return str;
  84. }
  85. static unsigned parse_hex4(const char *str)
  86. {
  87. unsigned h=0;
  88. 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;
  89. h=h<<4;str++;
  90. 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;
  91. h=h<<4;str++;
  92. 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;
  93. h=h<<4;str++;
  94. 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;
  95. return h;
  96. }
  97. /* Parse the input text into an unescaped cstring, and populate item. */
  98. static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  99. static const char *parse_string(cJSON *item,const char *str)
  100. {
  101. const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
  102. if (*str!='\"') {ep=str;return 0;} /* not a string! */
  103. while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
  104. out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
  105. if (!out) return 0;
  106. ptr=str+1;ptr2=out;
  107. while (*ptr!='\"' && *ptr)
  108. {
  109. if (*ptr!='\\') *ptr2++=*ptr++;
  110. else
  111. {
  112. ptr++;
  113. switch (*ptr)
  114. {
  115. case 'b': *ptr2++='\b'; break;
  116. case 'f': *ptr2++='\f'; break;
  117. case 'n': *ptr2++='\n'; break;
  118. case 'r': *ptr2++='\r'; break;
  119. case 't': *ptr2++='\t'; break;
  120. case 'u': /* transcode utf16 to utf8. */
  121. uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
  122. if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
  123. if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
  124. {
  125. if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
  126. uc2=parse_hex4(ptr+3);ptr+=6;
  127. if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
  128. uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
  129. }
  130. len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
  131. switch (len) {
  132. case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
  133. case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
  134. case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
  135. case 1: *--ptr2 =(uc | firstByteMark[len]);
  136. }
  137. ptr2+=len;
  138. break;
  139. default: *ptr2++=*ptr; break;
  140. }
  141. ptr++;
  142. }
  143. }
  144. *ptr2=0;
  145. if (*ptr=='\"') ptr++;
  146. item->valuestring=out;
  147. item->type=cJSON_String;
  148. return ptr;
  149. }
  150. ///* Predeclare these prototypes. */
  151. static const char *parse_value(cJSON *item,const char *value);
  152. //static char *print_value(cJSON *item,int depth,int fmt);
  153. static const char *parse_array(cJSON *item,const char *value);
  154. //static char *print_array(cJSON *item,int depth,int fmt);
  155. static const char *parse_object(cJSON *item,const char *value);
  156. //static char *print_object(cJSON *item,int depth,int fmt);
  157. /* Utility to jump whitespace and cr/lf */
  158. static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
  159. /* Parse an object - create a new root, and populate. */
  160. cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
  161. {
  162. const char *end=0;
  163. cJSON *c=cJSON_New_Item();
  164. ep=0;
  165. if (!c) return 0; /* memory fail */
  166. end=parse_value(c,skip(value));
  167. if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
  168. /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
  169. if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
  170. if (return_parse_end) *return_parse_end=end;
  171. return c;
  172. }
  173. /* Default options for cJSON_Parse */
  174. cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
  175. /* Parser core - when encountering text, process appropriately. */
  176. static const char *parse_value(cJSON *item,const char *value)
  177. {
  178. if (!value) return 0; /* Fail on null. */
  179. if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
  180. if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
  181. if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
  182. if (*value=='\"') { return parse_string(item,value); }
  183. if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
  184. if (*value=='[') { return parse_array(item,value); }
  185. if (*value=='{') { return parse_object(item,value); }
  186. ep=value;return 0; /* failure. */
  187. }
  188. /* Build an array from input text. */
  189. static const char *parse_array(cJSON *item,const char *value)
  190. {
  191. cJSON *child;
  192. if (*value!='[') {ep=value;return 0;} /* not an array! */
  193. item->type=cJSON_Array;
  194. value=skip(value+1);
  195. if (*value==']') return value+1; /* empty array. */
  196. item->child=child=cJSON_New_Item();
  197. if (!item->child) return 0; /* memory fail */
  198. value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
  199. if (!value) return 0;
  200. while (*value==',')
  201. {
  202. cJSON *new_item;
  203. if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
  204. child->next=new_item;new_item->prev=child;child=new_item;
  205. value=skip(parse_value(child,skip(value+1)));
  206. if (!value) return 0; /* memory fail */
  207. }
  208. if (*value==']') return value+1; /* end of array */
  209. ep=value;return 0; /* malformed. */
  210. }
  211. /* Build an object from the text. */
  212. static const char *parse_object(cJSON *item,const char *value)
  213. {
  214. cJSON *child;
  215. if (*value!='{') {ep=value;return 0;} /* not an object! */
  216. item->type=cJSON_Object;
  217. value=skip(value+1);
  218. if (*value=='}') return value+1; /* empty array. */
  219. item->child=child=cJSON_New_Item();
  220. if (!item->child) return 0;
  221. value=skip(parse_string(child,skip(value)));
  222. if (!value) return 0;
  223. child->string=child->valuestring;child->valuestring=0;
  224. if (*value!=':') {ep=value;return 0;} /* fail! */
  225. value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
  226. if (!value) return 0;
  227. while (*value==',')
  228. {
  229. cJSON *new_item;
  230. if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
  231. child->next=new_item;new_item->prev=child;child=new_item;
  232. value=skip(parse_string(child,skip(value+1)));
  233. if (!value) return 0;
  234. child->string=child->valuestring;child->valuestring=0;
  235. if (*value!=':') {ep=value;return 0;} /* fail! */
  236. value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
  237. if (!value) return 0;
  238. }
  239. if (*value=='}') return value+1; /* end of array */
  240. ep=value;return 0; /* malformed. */
  241. }
  242. cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}