Axeda demo software for u-blox C027 (GSM)

Dependencies:   mbed

Committer:
AxedaCorp
Date:
Mon Aug 11 19:02:42 2014 +0000
Revision:
0:a725e8eab383
1st commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AxedaCorp 0:a725e8eab383 1 /*
AxedaCorp 0:a725e8eab383 2 Copyright (c) 2009 Dave Gamble
AxedaCorp 0:a725e8eab383 3
AxedaCorp 0:a725e8eab383 4 Permission is hereby granted, free of charge, to any person obtaining a copy
AxedaCorp 0:a725e8eab383 5 of this software and associated documentation files (the "Software"), to deal
AxedaCorp 0:a725e8eab383 6 in the Software without restriction, including without limitation the rights
AxedaCorp 0:a725e8eab383 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
AxedaCorp 0:a725e8eab383 8 copies of the Software, and to permit persons to whom the Software is
AxedaCorp 0:a725e8eab383 9 furnished to do so, subject to the following conditions:
AxedaCorp 0:a725e8eab383 10
AxedaCorp 0:a725e8eab383 11 The above copyright notice and this permission notice shall be included in
AxedaCorp 0:a725e8eab383 12 all copies or substantial portions of the Software.
AxedaCorp 0:a725e8eab383 13
AxedaCorp 0:a725e8eab383 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
AxedaCorp 0:a725e8eab383 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
AxedaCorp 0:a725e8eab383 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AxedaCorp 0:a725e8eab383 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
AxedaCorp 0:a725e8eab383 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
AxedaCorp 0:a725e8eab383 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
AxedaCorp 0:a725e8eab383 20 THE SOFTWARE.
AxedaCorp 0:a725e8eab383 21 */
AxedaCorp 0:a725e8eab383 22
AxedaCorp 0:a725e8eab383 23 /* cJSON */
AxedaCorp 0:a725e8eab383 24 /* JSON parser in C. */
AxedaCorp 0:a725e8eab383 25
AxedaCorp 0:a725e8eab383 26 #include <string.h>
AxedaCorp 0:a725e8eab383 27 #include <stdio.h>
AxedaCorp 0:a725e8eab383 28 #include <math.h>
AxedaCorp 0:a725e8eab383 29 #include <stdlib.h>
AxedaCorp 0:a725e8eab383 30 #include <float.h>
AxedaCorp 0:a725e8eab383 31 #include <limits.h>
AxedaCorp 0:a725e8eab383 32 #include <ctype.h>
AxedaCorp 0:a725e8eab383 33 #include "cJSON.h"
AxedaCorp 0:a725e8eab383 34
AxedaCorp 0:a725e8eab383 35 static const char *ep;
AxedaCorp 0:a725e8eab383 36
AxedaCorp 0:a725e8eab383 37 const char *cJSON_GetErrorPtr()
AxedaCorp 0:a725e8eab383 38 {
AxedaCorp 0:a725e8eab383 39 return ep;
AxedaCorp 0:a725e8eab383 40 }
AxedaCorp 0:a725e8eab383 41
AxedaCorp 0:a725e8eab383 42 static int cJSON_strcasecmp(const char *s1,const char *s2)
AxedaCorp 0:a725e8eab383 43 {
AxedaCorp 0:a725e8eab383 44 if (!s1) return (s1==s2)?0:1;
AxedaCorp 0:a725e8eab383 45 if (!s2) return 1;
AxedaCorp 0:a725e8eab383 46 for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
AxedaCorp 0:a725e8eab383 47 return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
AxedaCorp 0:a725e8eab383 48 }
AxedaCorp 0:a725e8eab383 49
AxedaCorp 0:a725e8eab383 50 static void *(*cJSON_malloc)(size_t sz) = malloc;
AxedaCorp 0:a725e8eab383 51 static void (*cJSON_free)(void *ptr) = free;
AxedaCorp 0:a725e8eab383 52
AxedaCorp 0:a725e8eab383 53 static char* cJSON_strdup(const char* str)
AxedaCorp 0:a725e8eab383 54 {
AxedaCorp 0:a725e8eab383 55 size_t len;
AxedaCorp 0:a725e8eab383 56 char* copy;
AxedaCorp 0:a725e8eab383 57
AxedaCorp 0:a725e8eab383 58 len = strlen(str) + 1;
AxedaCorp 0:a725e8eab383 59 if (!(copy = (char*)cJSON_malloc(len))) return 0;
AxedaCorp 0:a725e8eab383 60 memcpy(copy,str,len);
AxedaCorp 0:a725e8eab383 61 return copy;
AxedaCorp 0:a725e8eab383 62 }
AxedaCorp 0:a725e8eab383 63
AxedaCorp 0:a725e8eab383 64 void cJSON_InitHooks(cJSON_Hooks* hooks)
AxedaCorp 0:a725e8eab383 65 {
AxedaCorp 0:a725e8eab383 66 if (!hooks) { /* Reset hooks */
AxedaCorp 0:a725e8eab383 67 cJSON_malloc = malloc;
AxedaCorp 0:a725e8eab383 68 cJSON_free = free;
AxedaCorp 0:a725e8eab383 69 return;
AxedaCorp 0:a725e8eab383 70 }
AxedaCorp 0:a725e8eab383 71
AxedaCorp 0:a725e8eab383 72 cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
AxedaCorp 0:a725e8eab383 73 cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
AxedaCorp 0:a725e8eab383 74 }
AxedaCorp 0:a725e8eab383 75
AxedaCorp 0:a725e8eab383 76 /* Internal constructor. */
AxedaCorp 0:a725e8eab383 77 static cJSON *cJSON_New_Item()
AxedaCorp 0:a725e8eab383 78 {
AxedaCorp 0:a725e8eab383 79 cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
AxedaCorp 0:a725e8eab383 80 if (node) memset(node,0,sizeof(cJSON));
AxedaCorp 0:a725e8eab383 81 return node;
AxedaCorp 0:a725e8eab383 82 }
AxedaCorp 0:a725e8eab383 83
AxedaCorp 0:a725e8eab383 84 /* Delete a cJSON structure. */
AxedaCorp 0:a725e8eab383 85 void cJSON_Delete(cJSON *c)
AxedaCorp 0:a725e8eab383 86 {
AxedaCorp 0:a725e8eab383 87 cJSON *next;
AxedaCorp 0:a725e8eab383 88 while (c) {
AxedaCorp 0:a725e8eab383 89 next=c->next;
AxedaCorp 0:a725e8eab383 90 if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
AxedaCorp 0:a725e8eab383 91 if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
AxedaCorp 0:a725e8eab383 92 if (c->string) cJSON_free(c->string);
AxedaCorp 0:a725e8eab383 93 cJSON_free(c);
AxedaCorp 0:a725e8eab383 94 c=next;
AxedaCorp 0:a725e8eab383 95 }
AxedaCorp 0:a725e8eab383 96 }
AxedaCorp 0:a725e8eab383 97
AxedaCorp 0:a725e8eab383 98 /* Parse the input text to generate a number, and populate the result into item. */
AxedaCorp 0:a725e8eab383 99 static const char *parse_number(cJSON *item,const char *num)
AxedaCorp 0:a725e8eab383 100 {
AxedaCorp 0:a725e8eab383 101 double n=0,sign=1,scale=0;
AxedaCorp 0:a725e8eab383 102 int subscale=0,signsubscale=1;
AxedaCorp 0:a725e8eab383 103
AxedaCorp 0:a725e8eab383 104 /* Could use sscanf for this? */
AxedaCorp 0:a725e8eab383 105 if (*num=='-') sign=-1,num++; /* Has sign? */
AxedaCorp 0:a725e8eab383 106 if (*num=='0') num++; /* is zero */
AxedaCorp 0:a725e8eab383 107 if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0');
AxedaCorp 0:a725e8eab383 108 while (*num>='0' && *num<='9'); /* Number? */
AxedaCorp 0:a725e8eab383 109 if (*num=='.' && num[1]>='0' && num[1]<='9') {
AxedaCorp 0:a725e8eab383 110 num++; /* Fractional part? */
AxedaCorp 0:a725e8eab383 111 do n=(n*10.0)+(*num++ -'0'),scale--;
AxedaCorp 0:a725e8eab383 112 while (*num>='0' && *num<='9');
AxedaCorp 0:a725e8eab383 113 }
AxedaCorp 0:a725e8eab383 114 if (*num=='e' || *num=='E') { /* Exponent? */
AxedaCorp 0:a725e8eab383 115 num++;
AxedaCorp 0:a725e8eab383 116 if (*num=='+') num++;
AxedaCorp 0:a725e8eab383 117 else if (*num=='-') signsubscale=-1,num++; /* With sign? */
AxedaCorp 0:a725e8eab383 118 while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
AxedaCorp 0:a725e8eab383 119 }
AxedaCorp 0:a725e8eab383 120
AxedaCorp 0:a725e8eab383 121 n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
AxedaCorp 0:a725e8eab383 122
AxedaCorp 0:a725e8eab383 123 item->valuedouble=n;
AxedaCorp 0:a725e8eab383 124 item->valueint=(int)n;
AxedaCorp 0:a725e8eab383 125 item->type=cJSON_Number;
AxedaCorp 0:a725e8eab383 126 return num;
AxedaCorp 0:a725e8eab383 127 }
AxedaCorp 0:a725e8eab383 128
AxedaCorp 0:a725e8eab383 129 /* Render the number nicely from the given item into a string. */
AxedaCorp 0:a725e8eab383 130 static char *print_number(cJSON *item)
AxedaCorp 0:a725e8eab383 131 {
AxedaCorp 0:a725e8eab383 132 char *str;
AxedaCorp 0:a725e8eab383 133 double d=item->valuedouble;
AxedaCorp 0:a725e8eab383 134 if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) {
AxedaCorp 0:a725e8eab383 135 str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
AxedaCorp 0:a725e8eab383 136 if (str) sprintf(str,"%d",item->valueint);
AxedaCorp 0:a725e8eab383 137 } else {
AxedaCorp 0:a725e8eab383 138 str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
AxedaCorp 0:a725e8eab383 139 if (str) {
AxedaCorp 0:a725e8eab383 140 if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d);
AxedaCorp 0:a725e8eab383 141 else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
AxedaCorp 0:a725e8eab383 142 else sprintf(str,"%f",d);
AxedaCorp 0:a725e8eab383 143 }
AxedaCorp 0:a725e8eab383 144 }
AxedaCorp 0:a725e8eab383 145 return str;
AxedaCorp 0:a725e8eab383 146 }
AxedaCorp 0:a725e8eab383 147
AxedaCorp 0:a725e8eab383 148 /* Parse the input text into an unescaped cstring, and populate item. */
AxedaCorp 0:a725e8eab383 149 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
AxedaCorp 0:a725e8eab383 150 static const char *parse_string(cJSON *item,const char *str)
AxedaCorp 0:a725e8eab383 151 {
AxedaCorp 0:a725e8eab383 152 const char *ptr=str+1;
AxedaCorp 0:a725e8eab383 153 char *ptr2;
AxedaCorp 0:a725e8eab383 154 char *out;
AxedaCorp 0:a725e8eab383 155 int len=0;
AxedaCorp 0:a725e8eab383 156 unsigned uc,uc2;
AxedaCorp 0:a725e8eab383 157 if (*str!='\"') {
AxedaCorp 0:a725e8eab383 158 ep=str; /* not a string! */
AxedaCorp 0:a725e8eab383 159 return 0;
AxedaCorp 0:a725e8eab383 160 }
AxedaCorp 0:a725e8eab383 161
AxedaCorp 0:a725e8eab383 162 while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
AxedaCorp 0:a725e8eab383 163
AxedaCorp 0:a725e8eab383 164 out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
AxedaCorp 0:a725e8eab383 165 if (!out) return 0;
AxedaCorp 0:a725e8eab383 166
AxedaCorp 0:a725e8eab383 167 ptr=str+1;
AxedaCorp 0:a725e8eab383 168 ptr2=out;
AxedaCorp 0:a725e8eab383 169 while (*ptr!='\"' && *ptr) {
AxedaCorp 0:a725e8eab383 170 if (*ptr!='\\') *ptr2++=*ptr++;
AxedaCorp 0:a725e8eab383 171 else {
AxedaCorp 0:a725e8eab383 172 ptr++;
AxedaCorp 0:a725e8eab383 173 switch (*ptr) {
AxedaCorp 0:a725e8eab383 174 case 'b':
AxedaCorp 0:a725e8eab383 175 *ptr2++='\b';
AxedaCorp 0:a725e8eab383 176 break;
AxedaCorp 0:a725e8eab383 177 case 'f':
AxedaCorp 0:a725e8eab383 178 *ptr2++='\f';
AxedaCorp 0:a725e8eab383 179 break;
AxedaCorp 0:a725e8eab383 180 case 'n':
AxedaCorp 0:a725e8eab383 181 *ptr2++='\n';
AxedaCorp 0:a725e8eab383 182 break;
AxedaCorp 0:a725e8eab383 183 case 'r':
AxedaCorp 0:a725e8eab383 184 *ptr2++='\r';
AxedaCorp 0:a725e8eab383 185 break;
AxedaCorp 0:a725e8eab383 186 case 't':
AxedaCorp 0:a725e8eab383 187 *ptr2++='\t';
AxedaCorp 0:a725e8eab383 188 break;
AxedaCorp 0:a725e8eab383 189 case 'u': /* transcode utf16 to utf8. */
AxedaCorp 0:a725e8eab383 190 sscanf(ptr+1,"%4x",&uc);
AxedaCorp 0:a725e8eab383 191 ptr+=4; /* get the unicode char. */
AxedaCorp 0:a725e8eab383 192
AxedaCorp 0:a725e8eab383 193 if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid.
AxedaCorp 0:a725e8eab383 194
AxedaCorp 0:a725e8eab383 195 if (uc>=0xD800 && uc<=0xDBFF) { // UTF16 surrogate pairs.
AxedaCorp 0:a725e8eab383 196 if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate.
AxedaCorp 0:a725e8eab383 197 sscanf(ptr+3,"%4x",&uc2);
AxedaCorp 0:a725e8eab383 198 ptr+=6;
AxedaCorp 0:a725e8eab383 199 if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate.
AxedaCorp 0:a725e8eab383 200 uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
AxedaCorp 0:a725e8eab383 201 }
AxedaCorp 0:a725e8eab383 202
AxedaCorp 0:a725e8eab383 203 len=4;
AxedaCorp 0:a725e8eab383 204 if (uc<0x80) len=1;
AxedaCorp 0:a725e8eab383 205 else if (uc<0x800) len=2;
AxedaCorp 0:a725e8eab383 206 else if (uc<0x10000) len=3;
AxedaCorp 0:a725e8eab383 207 ptr2+=len;
AxedaCorp 0:a725e8eab383 208
AxedaCorp 0:a725e8eab383 209 switch (len) {
AxedaCorp 0:a725e8eab383 210 case 4:
AxedaCorp 0:a725e8eab383 211 *--ptr2 =((uc | 0x80) & 0xBF);
AxedaCorp 0:a725e8eab383 212 uc >>= 6;
AxedaCorp 0:a725e8eab383 213 case 3:
AxedaCorp 0:a725e8eab383 214 *--ptr2 =((uc | 0x80) & 0xBF);
AxedaCorp 0:a725e8eab383 215 uc >>= 6;
AxedaCorp 0:a725e8eab383 216 case 2:
AxedaCorp 0:a725e8eab383 217 *--ptr2 =((uc | 0x80) & 0xBF);
AxedaCorp 0:a725e8eab383 218 uc >>= 6;
AxedaCorp 0:a725e8eab383 219 case 1:
AxedaCorp 0:a725e8eab383 220 *--ptr2 =(uc | firstByteMark[len]);
AxedaCorp 0:a725e8eab383 221 }
AxedaCorp 0:a725e8eab383 222 ptr2+=len;
AxedaCorp 0:a725e8eab383 223 break;
AxedaCorp 0:a725e8eab383 224 default:
AxedaCorp 0:a725e8eab383 225 *ptr2++=*ptr;
AxedaCorp 0:a725e8eab383 226 break;
AxedaCorp 0:a725e8eab383 227 }
AxedaCorp 0:a725e8eab383 228 ptr++;
AxedaCorp 0:a725e8eab383 229 }
AxedaCorp 0:a725e8eab383 230 }
AxedaCorp 0:a725e8eab383 231 *ptr2=0;
AxedaCorp 0:a725e8eab383 232 if (*ptr=='\"') ptr++;
AxedaCorp 0:a725e8eab383 233 item->valuestring=out;
AxedaCorp 0:a725e8eab383 234 item->type=cJSON_String;
AxedaCorp 0:a725e8eab383 235 return ptr;
AxedaCorp 0:a725e8eab383 236 }
AxedaCorp 0:a725e8eab383 237
AxedaCorp 0:a725e8eab383 238 /* Render the cstring provided to an escaped version that can be printed. */
AxedaCorp 0:a725e8eab383 239 static char *print_string_ptr(const char *str)
AxedaCorp 0:a725e8eab383 240 {
AxedaCorp 0:a725e8eab383 241 const char *ptr;
AxedaCorp 0:a725e8eab383 242 char *ptr2,*out;
AxedaCorp 0:a725e8eab383 243 int len=0;
AxedaCorp 0:a725e8eab383 244 unsigned char token;
AxedaCorp 0:a725e8eab383 245
AxedaCorp 0:a725e8eab383 246 if (!str) return cJSON_strdup("");
AxedaCorp 0:a725e8eab383 247 ptr=str;
AxedaCorp 0:a725e8eab383 248 while ((token=*ptr) && ++len) {
AxedaCorp 0:a725e8eab383 249 if (strchr("\"\\\b\f\n\r\t",token)) len++;
AxedaCorp 0:a725e8eab383 250 else if (token<32) len+=5;
AxedaCorp 0:a725e8eab383 251 ptr++;
AxedaCorp 0:a725e8eab383 252 }
AxedaCorp 0:a725e8eab383 253
AxedaCorp 0:a725e8eab383 254 out=(char*)cJSON_malloc(len+3);
AxedaCorp 0:a725e8eab383 255 if (!out) return 0;
AxedaCorp 0:a725e8eab383 256
AxedaCorp 0:a725e8eab383 257 ptr2=out;
AxedaCorp 0:a725e8eab383 258 ptr=str;
AxedaCorp 0:a725e8eab383 259 *ptr2++='\"';
AxedaCorp 0:a725e8eab383 260 while (*ptr) {
AxedaCorp 0:a725e8eab383 261 if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
AxedaCorp 0:a725e8eab383 262 else {
AxedaCorp 0:a725e8eab383 263 *ptr2++='\\';
AxedaCorp 0:a725e8eab383 264 switch (token=*ptr++) {
AxedaCorp 0:a725e8eab383 265 case '\\':
AxedaCorp 0:a725e8eab383 266 *ptr2++='\\';
AxedaCorp 0:a725e8eab383 267 break;
AxedaCorp 0:a725e8eab383 268 case '\"':
AxedaCorp 0:a725e8eab383 269 *ptr2++='\"';
AxedaCorp 0:a725e8eab383 270 break;
AxedaCorp 0:a725e8eab383 271 case '\b':
AxedaCorp 0:a725e8eab383 272 *ptr2++='b';
AxedaCorp 0:a725e8eab383 273 break;
AxedaCorp 0:a725e8eab383 274 case '\f':
AxedaCorp 0:a725e8eab383 275 *ptr2++='f';
AxedaCorp 0:a725e8eab383 276 break;
AxedaCorp 0:a725e8eab383 277 case '\n':
AxedaCorp 0:a725e8eab383 278 *ptr2++='n';
AxedaCorp 0:a725e8eab383 279 break;
AxedaCorp 0:a725e8eab383 280 case '\r':
AxedaCorp 0:a725e8eab383 281 *ptr2++='r';
AxedaCorp 0:a725e8eab383 282 break;
AxedaCorp 0:a725e8eab383 283 case '\t':
AxedaCorp 0:a725e8eab383 284 *ptr2++='t';
AxedaCorp 0:a725e8eab383 285 break;
AxedaCorp 0:a725e8eab383 286 default:
AxedaCorp 0:a725e8eab383 287 sprintf(ptr2,"u%04x",token);
AxedaCorp 0:a725e8eab383 288 ptr2+=5;
AxedaCorp 0:a725e8eab383 289 break; /* escape and print */
AxedaCorp 0:a725e8eab383 290 }
AxedaCorp 0:a725e8eab383 291 }
AxedaCorp 0:a725e8eab383 292 }
AxedaCorp 0:a725e8eab383 293 *ptr2++='\"';
AxedaCorp 0:a725e8eab383 294 *ptr2++=0;
AxedaCorp 0:a725e8eab383 295 return out;
AxedaCorp 0:a725e8eab383 296 }
AxedaCorp 0:a725e8eab383 297 /* Invote print_string_ptr (which is useful) on an item. */
AxedaCorp 0:a725e8eab383 298 static char *print_string(cJSON *item)
AxedaCorp 0:a725e8eab383 299 {
AxedaCorp 0:a725e8eab383 300 return print_string_ptr(item->valuestring);
AxedaCorp 0:a725e8eab383 301 }
AxedaCorp 0:a725e8eab383 302
AxedaCorp 0:a725e8eab383 303 /* Predeclare these prototypes. */
AxedaCorp 0:a725e8eab383 304 static const char *parse_value(cJSON *item,const char *value);
AxedaCorp 0:a725e8eab383 305 static char *print_value(cJSON *item,int depth,int fmt);
AxedaCorp 0:a725e8eab383 306 static const char *parse_array(cJSON *item,const char *value);
AxedaCorp 0:a725e8eab383 307 static char *print_array(cJSON *item,int depth,int fmt);
AxedaCorp 0:a725e8eab383 308 static const char *parse_object(cJSON *item,const char *value);
AxedaCorp 0:a725e8eab383 309 static char *print_object(cJSON *item,int depth,int fmt);
AxedaCorp 0:a725e8eab383 310
AxedaCorp 0:a725e8eab383 311 /* Utility to jump whitespace and cr/lf */
AxedaCorp 0:a725e8eab383 312 static const char *skip(const char *in)
AxedaCorp 0:a725e8eab383 313 {
AxedaCorp 0:a725e8eab383 314 while (in && *in && (unsigned char)*in<=32) in++;
AxedaCorp 0:a725e8eab383 315 return in;
AxedaCorp 0:a725e8eab383 316 }
AxedaCorp 0:a725e8eab383 317
AxedaCorp 0:a725e8eab383 318 /* Parse an object - create a new root, and populate. */
AxedaCorp 0:a725e8eab383 319 cJSON *cJSON_Parse(const char *value)
AxedaCorp 0:a725e8eab383 320 {
AxedaCorp 0:a725e8eab383 321 cJSON *c=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 322 ep=0;
AxedaCorp 0:a725e8eab383 323 if (!c) return 0; /* memory fail */
AxedaCorp 0:a725e8eab383 324
AxedaCorp 0:a725e8eab383 325 if (!parse_value(c,skip(value))) {
AxedaCorp 0:a725e8eab383 326 cJSON_Delete(c);
AxedaCorp 0:a725e8eab383 327 return 0;
AxedaCorp 0:a725e8eab383 328 }
AxedaCorp 0:a725e8eab383 329 return c;
AxedaCorp 0:a725e8eab383 330 }
AxedaCorp 0:a725e8eab383 331
AxedaCorp 0:a725e8eab383 332 /* Render a cJSON item/entity/structure to text. */
AxedaCorp 0:a725e8eab383 333 char *cJSON_Print(cJSON *item)
AxedaCorp 0:a725e8eab383 334 {
AxedaCorp 0:a725e8eab383 335 return print_value(item,0,1);
AxedaCorp 0:a725e8eab383 336 }
AxedaCorp 0:a725e8eab383 337 char *cJSON_PrintUnformatted(cJSON *item)
AxedaCorp 0:a725e8eab383 338 {
AxedaCorp 0:a725e8eab383 339 return print_value(item,0,0);
AxedaCorp 0:a725e8eab383 340 }
AxedaCorp 0:a725e8eab383 341
AxedaCorp 0:a725e8eab383 342 /* Parser core - when encountering text, process appropriately. */
AxedaCorp 0:a725e8eab383 343 static const char *parse_value(cJSON *item,const char *value)
AxedaCorp 0:a725e8eab383 344 {
AxedaCorp 0:a725e8eab383 345 if (!value) return 0; /* Fail on null. */
AxedaCorp 0:a725e8eab383 346 if (!strncmp(value,"null",4)) {
AxedaCorp 0:a725e8eab383 347 item->type=cJSON_NULL;
AxedaCorp 0:a725e8eab383 348 return value+4;
AxedaCorp 0:a725e8eab383 349 }
AxedaCorp 0:a725e8eab383 350 if (!strncmp(value,"false",5)) {
AxedaCorp 0:a725e8eab383 351 item->type=cJSON_False;
AxedaCorp 0:a725e8eab383 352 return value+5;
AxedaCorp 0:a725e8eab383 353 }
AxedaCorp 0:a725e8eab383 354 if (!strncmp(value,"true",4)) {
AxedaCorp 0:a725e8eab383 355 item->type=cJSON_True;
AxedaCorp 0:a725e8eab383 356 item->valueint=1;
AxedaCorp 0:a725e8eab383 357 return value+4;
AxedaCorp 0:a725e8eab383 358 }
AxedaCorp 0:a725e8eab383 359 if (*value=='\"') {
AxedaCorp 0:a725e8eab383 360 return parse_string(item,value);
AxedaCorp 0:a725e8eab383 361 }
AxedaCorp 0:a725e8eab383 362 if (*value=='-' || (*value>='0' && *value<='9')) {
AxedaCorp 0:a725e8eab383 363 return parse_number(item,value);
AxedaCorp 0:a725e8eab383 364 }
AxedaCorp 0:a725e8eab383 365 if (*value=='[') {
AxedaCorp 0:a725e8eab383 366 return parse_array(item,value);
AxedaCorp 0:a725e8eab383 367 }
AxedaCorp 0:a725e8eab383 368 if (*value=='{') {
AxedaCorp 0:a725e8eab383 369 return parse_object(item,value);
AxedaCorp 0:a725e8eab383 370 }
AxedaCorp 0:a725e8eab383 371
AxedaCorp 0:a725e8eab383 372 ep=value;
AxedaCorp 0:a725e8eab383 373 return 0; /* failure. */
AxedaCorp 0:a725e8eab383 374 }
AxedaCorp 0:a725e8eab383 375
AxedaCorp 0:a725e8eab383 376 /* Render a value to text. */
AxedaCorp 0:a725e8eab383 377 static char *print_value(cJSON *item,int depth,int fmt)
AxedaCorp 0:a725e8eab383 378 {
AxedaCorp 0:a725e8eab383 379 char *out=0;
AxedaCorp 0:a725e8eab383 380 if (!item) return 0;
AxedaCorp 0:a725e8eab383 381 switch ((item->type)&255) {
AxedaCorp 0:a725e8eab383 382 case cJSON_NULL:
AxedaCorp 0:a725e8eab383 383 out=cJSON_strdup("null");
AxedaCorp 0:a725e8eab383 384 break;
AxedaCorp 0:a725e8eab383 385 case cJSON_False:
AxedaCorp 0:a725e8eab383 386 out=cJSON_strdup("false");
AxedaCorp 0:a725e8eab383 387 break;
AxedaCorp 0:a725e8eab383 388 case cJSON_True:
AxedaCorp 0:a725e8eab383 389 out=cJSON_strdup("true");
AxedaCorp 0:a725e8eab383 390 break;
AxedaCorp 0:a725e8eab383 391 case cJSON_Number:
AxedaCorp 0:a725e8eab383 392 out=print_number(item);
AxedaCorp 0:a725e8eab383 393 break;
AxedaCorp 0:a725e8eab383 394 case cJSON_String:
AxedaCorp 0:a725e8eab383 395 out=print_string(item);
AxedaCorp 0:a725e8eab383 396 break;
AxedaCorp 0:a725e8eab383 397 case cJSON_Array:
AxedaCorp 0:a725e8eab383 398 out=print_array(item,depth,fmt);
AxedaCorp 0:a725e8eab383 399 break;
AxedaCorp 0:a725e8eab383 400 case cJSON_Object:
AxedaCorp 0:a725e8eab383 401 out=print_object(item,depth,fmt);
AxedaCorp 0:a725e8eab383 402 break;
AxedaCorp 0:a725e8eab383 403 }
AxedaCorp 0:a725e8eab383 404 return out;
AxedaCorp 0:a725e8eab383 405 }
AxedaCorp 0:a725e8eab383 406
AxedaCorp 0:a725e8eab383 407 /* Build an array from input text. */
AxedaCorp 0:a725e8eab383 408 static const char *parse_array(cJSON *item,const char *value)
AxedaCorp 0:a725e8eab383 409 {
AxedaCorp 0:a725e8eab383 410 cJSON *child;
AxedaCorp 0:a725e8eab383 411 if (*value!='[') {
AxedaCorp 0:a725e8eab383 412 ep=value; /* not an array! */
AxedaCorp 0:a725e8eab383 413 return 0;
AxedaCorp 0:a725e8eab383 414 }
AxedaCorp 0:a725e8eab383 415
AxedaCorp 0:a725e8eab383 416 item->type=cJSON_Array;
AxedaCorp 0:a725e8eab383 417 value=skip(value+1);
AxedaCorp 0:a725e8eab383 418 if (*value==']') return value+1; /* empty array. */
AxedaCorp 0:a725e8eab383 419
AxedaCorp 0:a725e8eab383 420 item->child=child=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 421 if (!item->child) return 0; /* memory fail */
AxedaCorp 0:a725e8eab383 422 value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
AxedaCorp 0:a725e8eab383 423 if (!value) return 0;
AxedaCorp 0:a725e8eab383 424
AxedaCorp 0:a725e8eab383 425 while (*value==',') {
AxedaCorp 0:a725e8eab383 426 cJSON *new_item;
AxedaCorp 0:a725e8eab383 427 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
AxedaCorp 0:a725e8eab383 428 child->next=new_item;
AxedaCorp 0:a725e8eab383 429 new_item->prev=child;
AxedaCorp 0:a725e8eab383 430 child=new_item;
AxedaCorp 0:a725e8eab383 431 value=skip(parse_value(child,skip(value+1)));
AxedaCorp 0:a725e8eab383 432 if (!value) return 0; /* memory fail */
AxedaCorp 0:a725e8eab383 433 }
AxedaCorp 0:a725e8eab383 434
AxedaCorp 0:a725e8eab383 435 if (*value==']') return value+1; /* end of array */
AxedaCorp 0:a725e8eab383 436 ep=value;
AxedaCorp 0:a725e8eab383 437 return 0; /* malformed. */
AxedaCorp 0:a725e8eab383 438 }
AxedaCorp 0:a725e8eab383 439
AxedaCorp 0:a725e8eab383 440 /* Render an array to text */
AxedaCorp 0:a725e8eab383 441 static char *print_array(cJSON *item,int depth,int fmt)
AxedaCorp 0:a725e8eab383 442 {
AxedaCorp 0:a725e8eab383 443 char **entries;
AxedaCorp 0:a725e8eab383 444 char *out=0,*ptr,*ret;
AxedaCorp 0:a725e8eab383 445 int len=5;
AxedaCorp 0:a725e8eab383 446 cJSON *child=item->child;
AxedaCorp 0:a725e8eab383 447 int numentries=0,i=0,fail=0;
AxedaCorp 0:a725e8eab383 448
AxedaCorp 0:a725e8eab383 449 /* How many entries in the array? */
AxedaCorp 0:a725e8eab383 450 while (child) numentries++,child=child->next;
AxedaCorp 0:a725e8eab383 451 /* Allocate an array to hold the values for each */
AxedaCorp 0:a725e8eab383 452 entries=(char**)cJSON_malloc(numentries*sizeof(char*));
AxedaCorp 0:a725e8eab383 453 if (!entries) return 0;
AxedaCorp 0:a725e8eab383 454 memset(entries,0,numentries*sizeof(char*));
AxedaCorp 0:a725e8eab383 455 /* Retrieve all the results: */
AxedaCorp 0:a725e8eab383 456 child=item->child;
AxedaCorp 0:a725e8eab383 457 while (child && !fail) {
AxedaCorp 0:a725e8eab383 458 ret=print_value(child,depth+1,fmt);
AxedaCorp 0:a725e8eab383 459 entries[i++]=ret;
AxedaCorp 0:a725e8eab383 460 if (ret) len+=strlen(ret)+2+(fmt?1:0);
AxedaCorp 0:a725e8eab383 461 else fail=1;
AxedaCorp 0:a725e8eab383 462 child=child->next;
AxedaCorp 0:a725e8eab383 463 }
AxedaCorp 0:a725e8eab383 464
AxedaCorp 0:a725e8eab383 465 /* If we didn't fail, try to malloc the output string */
AxedaCorp 0:a725e8eab383 466 if (!fail) out=(char*)cJSON_malloc(len);
AxedaCorp 0:a725e8eab383 467 /* If that fails, we fail. */
AxedaCorp 0:a725e8eab383 468 if (!out) fail=1;
AxedaCorp 0:a725e8eab383 469
AxedaCorp 0:a725e8eab383 470 /* Handle failure. */
AxedaCorp 0:a725e8eab383 471 if (fail) {
AxedaCorp 0:a725e8eab383 472 for (i=0; i<numentries; i++) if (entries[i]) cJSON_free(entries[i]);
AxedaCorp 0:a725e8eab383 473 cJSON_free(entries);
AxedaCorp 0:a725e8eab383 474 return 0;
AxedaCorp 0:a725e8eab383 475 }
AxedaCorp 0:a725e8eab383 476
AxedaCorp 0:a725e8eab383 477 /* Compose the output array. */
AxedaCorp 0:a725e8eab383 478 *out='[';
AxedaCorp 0:a725e8eab383 479 ptr=out+1;
AxedaCorp 0:a725e8eab383 480 *ptr=0;
AxedaCorp 0:a725e8eab383 481 for (i=0; i<numentries; i++) {
AxedaCorp 0:a725e8eab383 482 strcpy(ptr,entries[i]);
AxedaCorp 0:a725e8eab383 483 ptr+=strlen(entries[i]);
AxedaCorp 0:a725e8eab383 484 if (i!=numentries-1) {
AxedaCorp 0:a725e8eab383 485 *ptr++=',';
AxedaCorp 0:a725e8eab383 486 if(fmt)*ptr++=' ';
AxedaCorp 0:a725e8eab383 487 *ptr=0;
AxedaCorp 0:a725e8eab383 488 }
AxedaCorp 0:a725e8eab383 489 cJSON_free(entries[i]);
AxedaCorp 0:a725e8eab383 490 }
AxedaCorp 0:a725e8eab383 491 cJSON_free(entries);
AxedaCorp 0:a725e8eab383 492 *ptr++=']';
AxedaCorp 0:a725e8eab383 493 *ptr++=0;
AxedaCorp 0:a725e8eab383 494 return out;
AxedaCorp 0:a725e8eab383 495 }
AxedaCorp 0:a725e8eab383 496
AxedaCorp 0:a725e8eab383 497 /* Build an object from the text. */
AxedaCorp 0:a725e8eab383 498 static const char *parse_object(cJSON *item,const char *value)
AxedaCorp 0:a725e8eab383 499 {
AxedaCorp 0:a725e8eab383 500 cJSON *child;
AxedaCorp 0:a725e8eab383 501 if (*value!='{') {
AxedaCorp 0:a725e8eab383 502 ep=value; /* not an object! */
AxedaCorp 0:a725e8eab383 503 return 0;
AxedaCorp 0:a725e8eab383 504 }
AxedaCorp 0:a725e8eab383 505
AxedaCorp 0:a725e8eab383 506 item->type=cJSON_Object;
AxedaCorp 0:a725e8eab383 507 value=skip(value+1);
AxedaCorp 0:a725e8eab383 508 if (*value=='}') return value+1; /* empty array. */
AxedaCorp 0:a725e8eab383 509
AxedaCorp 0:a725e8eab383 510 item->child=child=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 511 if (!item->child) return 0;
AxedaCorp 0:a725e8eab383 512 value=skip(parse_string(child,skip(value)));
AxedaCorp 0:a725e8eab383 513 if (!value) return 0;
AxedaCorp 0:a725e8eab383 514 child->string=child->valuestring;
AxedaCorp 0:a725e8eab383 515 child->valuestring=0;
AxedaCorp 0:a725e8eab383 516 if (*value!=':') {
AxedaCorp 0:a725e8eab383 517 ep=value; /* fail! */
AxedaCorp 0:a725e8eab383 518 return 0;
AxedaCorp 0:a725e8eab383 519 }
AxedaCorp 0:a725e8eab383 520 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
AxedaCorp 0:a725e8eab383 521 if (!value) return 0;
AxedaCorp 0:a725e8eab383 522
AxedaCorp 0:a725e8eab383 523 while (*value==',') {
AxedaCorp 0:a725e8eab383 524 cJSON *new_item;
AxedaCorp 0:a725e8eab383 525 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
AxedaCorp 0:a725e8eab383 526 child->next=new_item;
AxedaCorp 0:a725e8eab383 527 new_item->prev=child;
AxedaCorp 0:a725e8eab383 528 child=new_item;
AxedaCorp 0:a725e8eab383 529 value=skip(parse_string(child,skip(value+1)));
AxedaCorp 0:a725e8eab383 530 if (!value) return 0;
AxedaCorp 0:a725e8eab383 531 child->string=child->valuestring;
AxedaCorp 0:a725e8eab383 532 child->valuestring=0;
AxedaCorp 0:a725e8eab383 533 if (*value!=':') {
AxedaCorp 0:a725e8eab383 534 ep=value; /* fail! */
AxedaCorp 0:a725e8eab383 535 return 0;
AxedaCorp 0:a725e8eab383 536 }
AxedaCorp 0:a725e8eab383 537 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
AxedaCorp 0:a725e8eab383 538 if (!value) return 0;
AxedaCorp 0:a725e8eab383 539 }
AxedaCorp 0:a725e8eab383 540
AxedaCorp 0:a725e8eab383 541 if (*value=='}') return value+1; /* end of array */
AxedaCorp 0:a725e8eab383 542 ep=value;
AxedaCorp 0:a725e8eab383 543 return 0; /* malformed. */
AxedaCorp 0:a725e8eab383 544 }
AxedaCorp 0:a725e8eab383 545
AxedaCorp 0:a725e8eab383 546 /* Render an object to text. */
AxedaCorp 0:a725e8eab383 547 static char *print_object(cJSON *item,int depth,int fmt)
AxedaCorp 0:a725e8eab383 548 {
AxedaCorp 0:a725e8eab383 549 char **entries=0,**names=0;
AxedaCorp 0:a725e8eab383 550 char *out=0,*ptr,*ret,*str;
AxedaCorp 0:a725e8eab383 551 int len=7,i=0,j;
AxedaCorp 0:a725e8eab383 552 cJSON *child=item->child;
AxedaCorp 0:a725e8eab383 553 int numentries=0,fail=0;
AxedaCorp 0:a725e8eab383 554 /* Count the number of entries. */
AxedaCorp 0:a725e8eab383 555 while (child) numentries++,child=child->next;
AxedaCorp 0:a725e8eab383 556 /* Allocate space for the names and the objects */
AxedaCorp 0:a725e8eab383 557 entries=(char**)cJSON_malloc(numentries*sizeof(char*));
AxedaCorp 0:a725e8eab383 558 if (!entries) return 0;
AxedaCorp 0:a725e8eab383 559 names=(char**)cJSON_malloc(numentries*sizeof(char*));
AxedaCorp 0:a725e8eab383 560 if (!names) {
AxedaCorp 0:a725e8eab383 561 cJSON_free(entries);
AxedaCorp 0:a725e8eab383 562 return 0;
AxedaCorp 0:a725e8eab383 563 }
AxedaCorp 0:a725e8eab383 564 memset(entries,0,sizeof(char*)*numentries);
AxedaCorp 0:a725e8eab383 565 memset(names,0,sizeof(char*)*numentries);
AxedaCorp 0:a725e8eab383 566
AxedaCorp 0:a725e8eab383 567 /* Collect all the results into our arrays: */
AxedaCorp 0:a725e8eab383 568 child=item->child;
AxedaCorp 0:a725e8eab383 569 depth++;
AxedaCorp 0:a725e8eab383 570 if (fmt) len+=depth;
AxedaCorp 0:a725e8eab383 571 while (child) {
AxedaCorp 0:a725e8eab383 572 names[i]=str=print_string_ptr(child->string);
AxedaCorp 0:a725e8eab383 573 entries[i++]=ret=print_value(child,depth,fmt);
AxedaCorp 0:a725e8eab383 574 if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0);
AxedaCorp 0:a725e8eab383 575 else fail=1;
AxedaCorp 0:a725e8eab383 576 child=child->next;
AxedaCorp 0:a725e8eab383 577 }
AxedaCorp 0:a725e8eab383 578
AxedaCorp 0:a725e8eab383 579 /* Try to allocate the output string */
AxedaCorp 0:a725e8eab383 580 if (!fail) out=(char*)cJSON_malloc(len);
AxedaCorp 0:a725e8eab383 581 if (!out) fail=1;
AxedaCorp 0:a725e8eab383 582
AxedaCorp 0:a725e8eab383 583 /* Handle failure */
AxedaCorp 0:a725e8eab383 584 if (fail) {
AxedaCorp 0:a725e8eab383 585 for (i=0; i<numentries; i++) {
AxedaCorp 0:a725e8eab383 586 if (names[i]) cJSON_free(names[i]);
AxedaCorp 0:a725e8eab383 587 if (entries[i]) cJSON_free(entries[i]);
AxedaCorp 0:a725e8eab383 588 }
AxedaCorp 0:a725e8eab383 589 cJSON_free(names);
AxedaCorp 0:a725e8eab383 590 cJSON_free(entries);
AxedaCorp 0:a725e8eab383 591 return 0;
AxedaCorp 0:a725e8eab383 592 }
AxedaCorp 0:a725e8eab383 593
AxedaCorp 0:a725e8eab383 594 /* Compose the output: */
AxedaCorp 0:a725e8eab383 595 *out='{';
AxedaCorp 0:a725e8eab383 596 ptr=out+1;
AxedaCorp 0:a725e8eab383 597 if (fmt)*ptr++='\n';
AxedaCorp 0:a725e8eab383 598 *ptr=0;
AxedaCorp 0:a725e8eab383 599 for (i=0; i<numentries; i++) {
AxedaCorp 0:a725e8eab383 600 if (fmt) for (j=0; j<depth; j++) *ptr++='\t';
AxedaCorp 0:a725e8eab383 601 strcpy(ptr,names[i]);
AxedaCorp 0:a725e8eab383 602 ptr+=strlen(names[i]);
AxedaCorp 0:a725e8eab383 603 *ptr++=':';
AxedaCorp 0:a725e8eab383 604 if (fmt) *ptr++='\t';
AxedaCorp 0:a725e8eab383 605 strcpy(ptr,entries[i]);
AxedaCorp 0:a725e8eab383 606 ptr+=strlen(entries[i]);
AxedaCorp 0:a725e8eab383 607 if (i!=numentries-1) *ptr++=',';
AxedaCorp 0:a725e8eab383 608 if (fmt) *ptr++='\n';
AxedaCorp 0:a725e8eab383 609 *ptr=0;
AxedaCorp 0:a725e8eab383 610 cJSON_free(names[i]);
AxedaCorp 0:a725e8eab383 611 cJSON_free(entries[i]);
AxedaCorp 0:a725e8eab383 612 }
AxedaCorp 0:a725e8eab383 613
AxedaCorp 0:a725e8eab383 614 cJSON_free(names);
AxedaCorp 0:a725e8eab383 615 cJSON_free(entries);
AxedaCorp 0:a725e8eab383 616 if (fmt) for (i=0; i<depth-1; i++) *ptr++='\t';
AxedaCorp 0:a725e8eab383 617 *ptr++='}';
AxedaCorp 0:a725e8eab383 618 *ptr++=0;
AxedaCorp 0:a725e8eab383 619 return out;
AxedaCorp 0:a725e8eab383 620 }
AxedaCorp 0:a725e8eab383 621
AxedaCorp 0:a725e8eab383 622 /* Get Array size/item / object item. */
AxedaCorp 0:a725e8eab383 623 int cJSON_GetArraySize(cJSON *array)
AxedaCorp 0:a725e8eab383 624 {
AxedaCorp 0:a725e8eab383 625 cJSON *c=array->child;
AxedaCorp 0:a725e8eab383 626 int i=0;
AxedaCorp 0:a725e8eab383 627 while(c)i++,c=c->next;
AxedaCorp 0:a725e8eab383 628 return i;
AxedaCorp 0:a725e8eab383 629 }
AxedaCorp 0:a725e8eab383 630 cJSON *cJSON_GetArrayItem(cJSON *array,int item)
AxedaCorp 0:a725e8eab383 631 {
AxedaCorp 0:a725e8eab383 632 cJSON *c=array->child;
AxedaCorp 0:a725e8eab383 633 while (c && item>0) item--,c=c->next;
AxedaCorp 0:a725e8eab383 634 return c;
AxedaCorp 0:a725e8eab383 635 }
AxedaCorp 0:a725e8eab383 636 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)
AxedaCorp 0:a725e8eab383 637 {
AxedaCorp 0:a725e8eab383 638 cJSON *c=object->child;
AxedaCorp 0:a725e8eab383 639 while (c && cJSON_strcasecmp(c->string,string)) c=c->next;
AxedaCorp 0:a725e8eab383 640 return c;
AxedaCorp 0:a725e8eab383 641 }
AxedaCorp 0:a725e8eab383 642
AxedaCorp 0:a725e8eab383 643 /* Utility for array list handling. */
AxedaCorp 0:a725e8eab383 644 static void suffix_object(cJSON *prev,cJSON *item)
AxedaCorp 0:a725e8eab383 645 {
AxedaCorp 0:a725e8eab383 646 prev->next=item;
AxedaCorp 0:a725e8eab383 647 item->prev=prev;
AxedaCorp 0:a725e8eab383 648 }
AxedaCorp 0:a725e8eab383 649 /* Utility for handling references. */
AxedaCorp 0:a725e8eab383 650 static cJSON *create_reference(cJSON *item)
AxedaCorp 0:a725e8eab383 651 {
AxedaCorp 0:a725e8eab383 652 cJSON *ref=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 653 if (!ref) return 0;
AxedaCorp 0:a725e8eab383 654 memcpy(ref,item,sizeof(cJSON));
AxedaCorp 0:a725e8eab383 655 ref->string=0;
AxedaCorp 0:a725e8eab383 656 ref->type|=cJSON_IsReference;
AxedaCorp 0:a725e8eab383 657 ref->next=ref->prev=0;
AxedaCorp 0:a725e8eab383 658 return ref;
AxedaCorp 0:a725e8eab383 659 }
AxedaCorp 0:a725e8eab383 660
AxedaCorp 0:a725e8eab383 661 /* Add item to array/object. */
AxedaCorp 0:a725e8eab383 662 void cJSON_AddItemToArray(cJSON *array, cJSON *item)
AxedaCorp 0:a725e8eab383 663 {
AxedaCorp 0:a725e8eab383 664 cJSON *c=array->child;
AxedaCorp 0:a725e8eab383 665 if (!item) return;
AxedaCorp 0:a725e8eab383 666 if (!c) {
AxedaCorp 0:a725e8eab383 667 array->child=item;
AxedaCorp 0:a725e8eab383 668 } else {
AxedaCorp 0:a725e8eab383 669 while (c && c->next) c=c->next;
AxedaCorp 0:a725e8eab383 670 suffix_object(c,item);
AxedaCorp 0:a725e8eab383 671 }
AxedaCorp 0:a725e8eab383 672 }
AxedaCorp 0:a725e8eab383 673 void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)
AxedaCorp 0:a725e8eab383 674 {
AxedaCorp 0:a725e8eab383 675 if (!item) return;
AxedaCorp 0:a725e8eab383 676 if (item->string) cJSON_free(item->string);
AxedaCorp 0:a725e8eab383 677 item->string=cJSON_strdup(string);
AxedaCorp 0:a725e8eab383 678 cJSON_AddItemToArray(object,item);
AxedaCorp 0:a725e8eab383 679 }
AxedaCorp 0:a725e8eab383 680 void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
AxedaCorp 0:a725e8eab383 681 {
AxedaCorp 0:a725e8eab383 682 cJSON_AddItemToArray(array,create_reference(item));
AxedaCorp 0:a725e8eab383 683 }
AxedaCorp 0:a725e8eab383 684 void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)
AxedaCorp 0:a725e8eab383 685 {
AxedaCorp 0:a725e8eab383 686 cJSON_AddItemToObject(object,string,create_reference(item));
AxedaCorp 0:a725e8eab383 687 }
AxedaCorp 0:a725e8eab383 688
AxedaCorp 0:a725e8eab383 689 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)
AxedaCorp 0:a725e8eab383 690 {
AxedaCorp 0:a725e8eab383 691 cJSON *c=array->child;
AxedaCorp 0:a725e8eab383 692 while (c && which>0) c=c->next,which--;
AxedaCorp 0:a725e8eab383 693 if (!c) return 0;
AxedaCorp 0:a725e8eab383 694 if (c->prev) c->prev->next=c->next;
AxedaCorp 0:a725e8eab383 695 if (c->next) c->next->prev=c->prev;
AxedaCorp 0:a725e8eab383 696 if (c==array->child) array->child=c->next;
AxedaCorp 0:a725e8eab383 697 c->prev=c->next=0;
AxedaCorp 0:a725e8eab383 698 return c;
AxedaCorp 0:a725e8eab383 699 }
AxedaCorp 0:a725e8eab383 700 void cJSON_DeleteItemFromArray(cJSON *array,int which)
AxedaCorp 0:a725e8eab383 701 {
AxedaCorp 0:a725e8eab383 702 cJSON_Delete(cJSON_DetachItemFromArray(array,which));
AxedaCorp 0:a725e8eab383 703 }
AxedaCorp 0:a725e8eab383 704 cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string)
AxedaCorp 0:a725e8eab383 705 {
AxedaCorp 0:a725e8eab383 706 int i=0;
AxedaCorp 0:a725e8eab383 707 cJSON *c=object->child;
AxedaCorp 0:a725e8eab383 708 while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;
AxedaCorp 0:a725e8eab383 709 if (c) return cJSON_DetachItemFromArray(object,i);
AxedaCorp 0:a725e8eab383 710 return 0;
AxedaCorp 0:a725e8eab383 711 }
AxedaCorp 0:a725e8eab383 712 void cJSON_DeleteItemFromObject(cJSON *object,const char *string)
AxedaCorp 0:a725e8eab383 713 {
AxedaCorp 0:a725e8eab383 714 cJSON_Delete(cJSON_DetachItemFromObject(object,string));
AxedaCorp 0:a725e8eab383 715 }
AxedaCorp 0:a725e8eab383 716
AxedaCorp 0:a725e8eab383 717 /* Replace array/object items with new ones. */
AxedaCorp 0:a725e8eab383 718 void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)
AxedaCorp 0:a725e8eab383 719 {
AxedaCorp 0:a725e8eab383 720 cJSON *c=array->child;
AxedaCorp 0:a725e8eab383 721 while (c && which>0) c=c->next,which--;
AxedaCorp 0:a725e8eab383 722 if (!c) return;
AxedaCorp 0:a725e8eab383 723 newitem->next=c->next;
AxedaCorp 0:a725e8eab383 724 newitem->prev=c->prev;
AxedaCorp 0:a725e8eab383 725 if (newitem->next) newitem->next->prev=newitem;
AxedaCorp 0:a725e8eab383 726 if (c==array->child) array->child=newitem;
AxedaCorp 0:a725e8eab383 727 else newitem->prev->next=newitem;
AxedaCorp 0:a725e8eab383 728 c->next=c->prev=0;
AxedaCorp 0:a725e8eab383 729 cJSON_Delete(c);
AxedaCorp 0:a725e8eab383 730 }
AxedaCorp 0:a725e8eab383 731 void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem)
AxedaCorp 0:a725e8eab383 732 {
AxedaCorp 0:a725e8eab383 733 int i=0;
AxedaCorp 0:a725e8eab383 734 cJSON *c=object->child;
AxedaCorp 0:a725e8eab383 735 while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;
AxedaCorp 0:a725e8eab383 736 if(c) {
AxedaCorp 0:a725e8eab383 737 newitem->string=cJSON_strdup(string);
AxedaCorp 0:a725e8eab383 738 cJSON_ReplaceItemInArray(object,i,newitem);
AxedaCorp 0:a725e8eab383 739 }
AxedaCorp 0:a725e8eab383 740 }
AxedaCorp 0:a725e8eab383 741
AxedaCorp 0:a725e8eab383 742 /* Create basic types: */
AxedaCorp 0:a725e8eab383 743 cJSON *cJSON_CreateNull()
AxedaCorp 0:a725e8eab383 744 {
AxedaCorp 0:a725e8eab383 745 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 746 if(item)item->type=cJSON_NULL;
AxedaCorp 0:a725e8eab383 747 return item;
AxedaCorp 0:a725e8eab383 748 }
AxedaCorp 0:a725e8eab383 749 cJSON *cJSON_CreateTrue()
AxedaCorp 0:a725e8eab383 750 {
AxedaCorp 0:a725e8eab383 751 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 752 if(item)item->type=cJSON_True;
AxedaCorp 0:a725e8eab383 753 return item;
AxedaCorp 0:a725e8eab383 754 }
AxedaCorp 0:a725e8eab383 755 cJSON *cJSON_CreateFalse()
AxedaCorp 0:a725e8eab383 756 {
AxedaCorp 0:a725e8eab383 757 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 758 if(item)item->type=cJSON_False;
AxedaCorp 0:a725e8eab383 759 return item;
AxedaCorp 0:a725e8eab383 760 }
AxedaCorp 0:a725e8eab383 761 cJSON *cJSON_CreateBool(int b)
AxedaCorp 0:a725e8eab383 762 {
AxedaCorp 0:a725e8eab383 763 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 764 if(item)item->type=b?cJSON_True:cJSON_False;
AxedaCorp 0:a725e8eab383 765 return item;
AxedaCorp 0:a725e8eab383 766 }
AxedaCorp 0:a725e8eab383 767 cJSON *cJSON_CreateNumber(double num)
AxedaCorp 0:a725e8eab383 768 {
AxedaCorp 0:a725e8eab383 769 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 770 if(item) {
AxedaCorp 0:a725e8eab383 771 item->type=cJSON_Number;
AxedaCorp 0:a725e8eab383 772 item->valuedouble=num;
AxedaCorp 0:a725e8eab383 773 item->valueint=(int)num;
AxedaCorp 0:a725e8eab383 774 }
AxedaCorp 0:a725e8eab383 775 return item;
AxedaCorp 0:a725e8eab383 776 }
AxedaCorp 0:a725e8eab383 777 cJSON *cJSON_CreateString(const char *string)
AxedaCorp 0:a725e8eab383 778 {
AxedaCorp 0:a725e8eab383 779 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 780 if(item) {
AxedaCorp 0:a725e8eab383 781 item->type=cJSON_String;
AxedaCorp 0:a725e8eab383 782 item->valuestring=cJSON_strdup(string);
AxedaCorp 0:a725e8eab383 783 }
AxedaCorp 0:a725e8eab383 784 return item;
AxedaCorp 0:a725e8eab383 785 }
AxedaCorp 0:a725e8eab383 786 cJSON *cJSON_CreateArray()
AxedaCorp 0:a725e8eab383 787 {
AxedaCorp 0:a725e8eab383 788 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 789 if(item)item->type=cJSON_Array;
AxedaCorp 0:a725e8eab383 790 return item;
AxedaCorp 0:a725e8eab383 791 }
AxedaCorp 0:a725e8eab383 792 cJSON *cJSON_CreateObject()
AxedaCorp 0:a725e8eab383 793 {
AxedaCorp 0:a725e8eab383 794 cJSON *item=cJSON_New_Item();
AxedaCorp 0:a725e8eab383 795 if(item)item->type=cJSON_Object;
AxedaCorp 0:a725e8eab383 796 return item;
AxedaCorp 0:a725e8eab383 797 }
AxedaCorp 0:a725e8eab383 798
AxedaCorp 0:a725e8eab383 799 /* Create Arrays: */
AxedaCorp 0:a725e8eab383 800 cJSON *cJSON_CreateIntArray(int *numbers,int count)
AxedaCorp 0:a725e8eab383 801 {
AxedaCorp 0:a725e8eab383 802 int i;
AxedaCorp 0:a725e8eab383 803 cJSON *n=0,*p=0,*a=cJSON_CreateArray();
AxedaCorp 0:a725e8eab383 804 for(i=0; a && i<count; i++) {
AxedaCorp 0:a725e8eab383 805 n=cJSON_CreateNumber(numbers[i]);
AxedaCorp 0:a725e8eab383 806 if(!i)a->child=n;
AxedaCorp 0:a725e8eab383 807 else suffix_object(p,n);
AxedaCorp 0:a725e8eab383 808 p=n;
AxedaCorp 0:a725e8eab383 809 }
AxedaCorp 0:a725e8eab383 810 return a;
AxedaCorp 0:a725e8eab383 811 }
AxedaCorp 0:a725e8eab383 812 cJSON *cJSON_CreateFloatArray(float *numbers,int count)
AxedaCorp 0:a725e8eab383 813 {
AxedaCorp 0:a725e8eab383 814 int i;
AxedaCorp 0:a725e8eab383 815 cJSON *n=0,*p=0,*a=cJSON_CreateArray();
AxedaCorp 0:a725e8eab383 816 for(i=0; a && i<count; i++) {
AxedaCorp 0:a725e8eab383 817 n=cJSON_CreateNumber(numbers[i]);
AxedaCorp 0:a725e8eab383 818 if(!i)a->child=n;
AxedaCorp 0:a725e8eab383 819 else suffix_object(p,n);
AxedaCorp 0:a725e8eab383 820 p=n;
AxedaCorp 0:a725e8eab383 821 }
AxedaCorp 0:a725e8eab383 822 return a;
AxedaCorp 0:a725e8eab383 823 }
AxedaCorp 0:a725e8eab383 824 cJSON *cJSON_CreateDoubleArray(double *numbers,int count)
AxedaCorp 0:a725e8eab383 825 {
AxedaCorp 0:a725e8eab383 826 int i;
AxedaCorp 0:a725e8eab383 827 cJSON *n=0,*p=0,*a=cJSON_CreateArray();
AxedaCorp 0:a725e8eab383 828 for(i=0; a && i<count; i++) {
AxedaCorp 0:a725e8eab383 829 n=cJSON_CreateNumber(numbers[i]);
AxedaCorp 0:a725e8eab383 830 if(!i)a->child=n;
AxedaCorp 0:a725e8eab383 831 else suffix_object(p,n);
AxedaCorp 0:a725e8eab383 832 p=n;
AxedaCorp 0:a725e8eab383 833 }
AxedaCorp 0:a725e8eab383 834 return a;
AxedaCorp 0:a725e8eab383 835 }
AxedaCorp 0:a725e8eab383 836 cJSON *cJSON_CreateStringArray(const char **strings,int count)
AxedaCorp 0:a725e8eab383 837 {
AxedaCorp 0:a725e8eab383 838 int i;
AxedaCorp 0:a725e8eab383 839 cJSON *n=0,*p=0,*a=cJSON_CreateArray();
AxedaCorp 0:a725e8eab383 840 for(i=0; a && i<count; i++) {
AxedaCorp 0:a725e8eab383 841 n=cJSON_CreateString(strings[i]);
AxedaCorp 0:a725e8eab383 842 if(!i)a->child=n;
AxedaCorp 0:a725e8eab383 843 else suffix_object(p,n);
AxedaCorp 0:a725e8eab383 844 p=n;
AxedaCorp 0:a725e8eab383 845 }
AxedaCorp 0:a725e8eab383 846 return a;
AxedaCorp 0:a725e8eab383 847 }