aJson is the attempt to port a complete JSON implementation to Arduino. It is based on the cJSON implementation, reduced in size and removing one or two feature. The current mbed implementation only supports FILE* as input so you will have to use a temporary file for parsing your json input. https://github.com/interactive-matter/aJson

Dependents:   WIZwikiREST20

Committer:
mimil
Date:
Mon Aug 27 15:15:45 2012 +0000
Revision:
0:428cf9a51873
Child:
1:6df1d1f1b372
[mbed] converted /Trash/aJSON

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mimil 0:428cf9a51873 1 /*
mimil 0:428cf9a51873 2 Copyright (c) 2001, Interactive Matter, Marcus Nowotny
mimil 0:428cf9a51873 3
mimil 0:428cf9a51873 4 Based on the cJSON Library, Copyright (C) 2009 Dave Gamble
mimil 0:428cf9a51873 5
mimil 0:428cf9a51873 6 Permission is hereby granted, free of charge, to any person obtaining a copy
mimil 0:428cf9a51873 7 of this software and associated documentation files (the "Software"), to deal
mimil 0:428cf9a51873 8 in the Software without restriction, including without limitation the rights
mimil 0:428cf9a51873 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
mimil 0:428cf9a51873 10 copies of the Software, and to permit persons to whom the Software is
mimil 0:428cf9a51873 11 furnished to do so, subject to the following conditions:
mimil 0:428cf9a51873 12
mimil 0:428cf9a51873 13 The above copyright notice and this permission notice shall be included in
mimil 0:428cf9a51873 14 all copies or substantial portions of the Software.
mimil 0:428cf9a51873 15
mimil 0:428cf9a51873 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
mimil 0:428cf9a51873 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
mimil 0:428cf9a51873 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
mimil 0:428cf9a51873 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
mimil 0:428cf9a51873 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mimil 0:428cf9a51873 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
mimil 0:428cf9a51873 22 THE SOFTWARE.
mimil 0:428cf9a51873 23 */
mimil 0:428cf9a51873 24
mimil 0:428cf9a51873 25 // aJSON
mimil 0:428cf9a51873 26 // aJson Library for Arduino.
mimil 0:428cf9a51873 27 // This library is suited for Atmega328 based Arduinos.
mimil 0:428cf9a51873 28 // The RAM on ATmega168 based Arduinos is too limited
mimil 0:428cf9a51873 29
mimil 0:428cf9a51873 30 /******************************************************************************
mimil 0:428cf9a51873 31 * Includes
mimil 0:428cf9a51873 32 ******************************************************************************/
mimil 0:428cf9a51873 33
mimil 0:428cf9a51873 34 #include <string.h>
mimil 0:428cf9a51873 35 #include <math.h>
mimil 0:428cf9a51873 36 #include <stdlib.h>
mimil 0:428cf9a51873 37 #include <float.h>
mimil 0:428cf9a51873 38 #include <ctype.h>
mimil 0:428cf9a51873 39 //#include <avr/pgmspace.h>
mimil 0:428cf9a51873 40 #include "aJSON.h"
mimil 0:428cf9a51873 41 #include "utility/streamhelper.h"
mimil 0:428cf9a51873 42 #include "utility/stringbuffer.h"
mimil 0:428cf9a51873 43
mimil 0:428cf9a51873 44 #include "compatibility.h"
mimil 0:428cf9a51873 45 #include "stdio.h"
mimil 0:428cf9a51873 46
mimil 0:428cf9a51873 47 /******************************************************************************
mimil 0:428cf9a51873 48 * Definitions
mimil 0:428cf9a51873 49 ******************************************************************************/
mimil 0:428cf9a51873 50 //Default buffer sizes - buffers get initialized and grow acc to that size
mimil 0:428cf9a51873 51 #define BUFFER_DEFAULT_SIZE 4
mimil 0:428cf9a51873 52
mimil 0:428cf9a51873 53 //how much digits after . for float
mimil 0:428cf9a51873 54 #define FLOAT_PRECISION 5
mimil 0:428cf9a51873 55
mimil 0:428cf9a51873 56
mimil 0:428cf9a51873 57
mimil 0:428cf9a51873 58
mimil 0:428cf9a51873 59
mimil 0:428cf9a51873 60
mimil 0:428cf9a51873 61 // Internal constructor.
mimil 0:428cf9a51873 62 aJsonObject*
mimil 0:428cf9a51873 63 aJsonClass::newItem()
mimil 0:428cf9a51873 64 {
mimil 0:428cf9a51873 65 aJsonObject* node = (aJsonObject*) malloc(sizeof(aJsonObject));
mimil 0:428cf9a51873 66 if (node)
mimil 0:428cf9a51873 67 memset(node, 0, sizeof(aJsonObject));
mimil 0:428cf9a51873 68 return node;
mimil 0:428cf9a51873 69 }
mimil 0:428cf9a51873 70
mimil 0:428cf9a51873 71 // Delete a aJsonObject structure.
mimil 0:428cf9a51873 72 void
mimil 0:428cf9a51873 73 aJsonClass::deleteItem(aJsonObject *c)
mimil 0:428cf9a51873 74 {
mimil 0:428cf9a51873 75 aJsonObject *next;
mimil 0:428cf9a51873 76 while (c)
mimil 0:428cf9a51873 77 {
mimil 0:428cf9a51873 78 next = c->next;
mimil 0:428cf9a51873 79 if (!(c->type & aJson_IsReference) && c->child)
mimil 0:428cf9a51873 80 {
mimil 0:428cf9a51873 81 deleteItem(c->child);
mimil 0:428cf9a51873 82 }
mimil 0:428cf9a51873 83 if ((c->type == aJson_String) && c->valuestring)
mimil 0:428cf9a51873 84 {
mimil 0:428cf9a51873 85 free(c->valuestring);
mimil 0:428cf9a51873 86 }
mimil 0:428cf9a51873 87 if (c->name)
mimil 0:428cf9a51873 88 {
mimil 0:428cf9a51873 89 free(c->name);
mimil 0:428cf9a51873 90 }
mimil 0:428cf9a51873 91 free(c);
mimil 0:428cf9a51873 92 c = next;
mimil 0:428cf9a51873 93 }
mimil 0:428cf9a51873 94 }
mimil 0:428cf9a51873 95
mimil 0:428cf9a51873 96 // Parse the input text to generate a number, and populate the result into item.
mimil 0:428cf9a51873 97 int
mimil 0:428cf9a51873 98 aJsonClass::parseNumber(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 99 {
mimil 0:428cf9a51873 100 int i = 0;
mimil 0:428cf9a51873 101 char sign = 1;
mimil 0:428cf9a51873 102
mimil 0:428cf9a51873 103 int in = fgetc(stream);
mimil 0:428cf9a51873 104 if (in == EOF)
mimil 0:428cf9a51873 105 {
mimil 0:428cf9a51873 106 return EOF;
mimil 0:428cf9a51873 107 }
mimil 0:428cf9a51873 108 // It is easier to decode ourselves than to use sscnaf,
mimil 0:428cf9a51873 109 // since so we can easier decide between int & double
mimil 0:428cf9a51873 110 if (in == '-')
mimil 0:428cf9a51873 111 {
mimil 0:428cf9a51873 112 //it is a negative number
mimil 0:428cf9a51873 113 sign = -1;
mimil 0:428cf9a51873 114 in = fgetc(stream);
mimil 0:428cf9a51873 115 if (in == EOF)
mimil 0:428cf9a51873 116 {
mimil 0:428cf9a51873 117 return EOF;
mimil 0:428cf9a51873 118 }
mimil 0:428cf9a51873 119 }
mimil 0:428cf9a51873 120 if (in >= '0' && in <= '9')
mimil 0:428cf9a51873 121 do
mimil 0:428cf9a51873 122 {
mimil 0:428cf9a51873 123 i = (i * 10) + (in - '0');
mimil 0:428cf9a51873 124 in = fgetc(stream);
mimil 0:428cf9a51873 125 }
mimil 0:428cf9a51873 126 while (in >= '0' && in <= '9'); // Number?
mimil 0:428cf9a51873 127 //end of integer part &#65533; or isn't it?
mimil 0:428cf9a51873 128 if (!(in == '.' || in == 'e' || in == 'E'))
mimil 0:428cf9a51873 129 {
mimil 0:428cf9a51873 130 item->valueint = i * (int) sign;
mimil 0:428cf9a51873 131 item->type = aJson_Int;
mimil 0:428cf9a51873 132 }
mimil 0:428cf9a51873 133 //ok it seems to be a double
mimil 0:428cf9a51873 134 else
mimil 0:428cf9a51873 135 {
mimil 0:428cf9a51873 136 double n = (double) i;
mimil 0:428cf9a51873 137 int scale = 0;
mimil 0:428cf9a51873 138 int subscale = 0;
mimil 0:428cf9a51873 139 char signsubscale = 1;
mimil 0:428cf9a51873 140 if (in == '.')
mimil 0:428cf9a51873 141 {
mimil 0:428cf9a51873 142 in = fgetc(stream);
mimil 0:428cf9a51873 143 do
mimil 0:428cf9a51873 144 {
mimil 0:428cf9a51873 145 n = (n * 10.0) + (in - '0'), scale--;
mimil 0:428cf9a51873 146 in = fgetc(stream);
mimil 0:428cf9a51873 147 }
mimil 0:428cf9a51873 148 while (in >= '0' && in <= '9');
mimil 0:428cf9a51873 149 } // Fractional part?
mimil 0:428cf9a51873 150 if (in == 'e' || in == 'E') // Exponent?
mimil 0:428cf9a51873 151 {
mimil 0:428cf9a51873 152 in = fgetc(stream);
mimil 0:428cf9a51873 153 if (in == '+')
mimil 0:428cf9a51873 154 {
mimil 0:428cf9a51873 155 in = fgetc(stream);
mimil 0:428cf9a51873 156 }
mimil 0:428cf9a51873 157 else if (in == '-')
mimil 0:428cf9a51873 158 {
mimil 0:428cf9a51873 159 signsubscale = -1;
mimil 0:428cf9a51873 160 in = fgetc(stream);
mimil 0:428cf9a51873 161 }
mimil 0:428cf9a51873 162 while (in >= '0' && in <= '9')
mimil 0:428cf9a51873 163 {
mimil 0:428cf9a51873 164 subscale = (subscale * 10) + (in - '0'); // Number?
mimil 0:428cf9a51873 165 in = fgetc(stream);
mimil 0:428cf9a51873 166 }
mimil 0:428cf9a51873 167 }
mimil 0:428cf9a51873 168
mimil 0:428cf9a51873 169 n = sign * n * pow(10.0, ((double) scale + (double) subscale
mimil 0:428cf9a51873 170 * (double) signsubscale)); // number = +/- number.fraction * 10^+/- exponent
mimil 0:428cf9a51873 171
mimil 0:428cf9a51873 172 item->valuefloat = n;
mimil 0:428cf9a51873 173 item->type = aJson_Float;
mimil 0:428cf9a51873 174 }
mimil 0:428cf9a51873 175 //preserve the last character for the next routine
mimil 0:428cf9a51873 176 ungetc(in, stream);
mimil 0:428cf9a51873 177 return 0;
mimil 0:428cf9a51873 178 }
mimil 0:428cf9a51873 179
mimil 0:428cf9a51873 180 // Render the number nicely from the given item into a string.
mimil 0:428cf9a51873 181 int
mimil 0:428cf9a51873 182 aJsonClass::printInt(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 183 {
mimil 0:428cf9a51873 184 if (item != NULL)
mimil 0:428cf9a51873 185 {
mimil 0:428cf9a51873 186 return fprintf_P(stream, PSTR("%d"), item->valueint);
mimil 0:428cf9a51873 187 }
mimil 0:428cf9a51873 188 //printing nothing is ok
mimil 0:428cf9a51873 189 return 0;
mimil 0:428cf9a51873 190 }
mimil 0:428cf9a51873 191
mimil 0:428cf9a51873 192 int
mimil 0:428cf9a51873 193 aJsonClass::printFloat(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 194 {
mimil 0:428cf9a51873 195 if (item != NULL)
mimil 0:428cf9a51873 196 {
mimil 0:428cf9a51873 197 double d = item->valuefloat;
mimil 0:428cf9a51873 198 if (d<0.0) {
mimil 0:428cf9a51873 199 fprintf_P(stream,PSTR("-"));
mimil 0:428cf9a51873 200 d=-d;
mimil 0:428cf9a51873 201 }
mimil 0:428cf9a51873 202 //print the integer part
mimil 0:428cf9a51873 203 unsigned long integer_number = (unsigned long)d;
mimil 0:428cf9a51873 204 fprintf_P(stream,PSTR("%u."),integer_number);
mimil 0:428cf9a51873 205 //print the fractional part
mimil 0:428cf9a51873 206 double fractional_part = d - ((double)integer_number);
mimil 0:428cf9a51873 207 //we do a do-while since we want to print at least one zero
mimil 0:428cf9a51873 208 //we just support a certain number of digits after the '.'
mimil 0:428cf9a51873 209 int n = FLOAT_PRECISION;
mimil 0:428cf9a51873 210 fractional_part += 0.5/pow(10.0, FLOAT_PRECISION);
mimil 0:428cf9a51873 211 do {
mimil 0:428cf9a51873 212 //make the first digit non fractional(shift it before the '.'
mimil 0:428cf9a51873 213 fractional_part *= 10.0;
mimil 0:428cf9a51873 214 //create an int out of it
mimil 0:428cf9a51873 215 unsigned int digit = (unsigned int) fractional_part;
mimil 0:428cf9a51873 216 //print it
mimil 0:428cf9a51873 217 fprintf_P(stream,PSTR("%u"),digit);
mimil 0:428cf9a51873 218 //remove it from the number
mimil 0:428cf9a51873 219 fractional_part -= (double)digit;
mimil 0:428cf9a51873 220 n--;
mimil 0:428cf9a51873 221 } while ((fractional_part!=0) && (n>0));
mimil 0:428cf9a51873 222 }
mimil 0:428cf9a51873 223 //printing nothing is ok
mimil 0:428cf9a51873 224 return 0;
mimil 0:428cf9a51873 225 }
mimil 0:428cf9a51873 226
mimil 0:428cf9a51873 227 // Parse the input text into an unescaped cstring, and populate item.
mimil 0:428cf9a51873 228 int
mimil 0:428cf9a51873 229 aJsonClass::parseString(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 230 {
mimil 0:428cf9a51873 231 //we do not need to skip here since the first byte should be '\"'
mimil 0:428cf9a51873 232 int in = fgetc(stream);
mimil 0:428cf9a51873 233 if (in != '\"')
mimil 0:428cf9a51873 234 {
mimil 0:428cf9a51873 235 return EOF; // not a string!
mimil 0:428cf9a51873 236 }
mimil 0:428cf9a51873 237 item->type = aJson_String;
mimil 0:428cf9a51873 238 //allocate a buffer & track how long it is and how much we have read
mimil 0:428cf9a51873 239 string_buffer* buffer = stringBufferCreate();
mimil 0:428cf9a51873 240 if (buffer == NULL)
mimil 0:428cf9a51873 241 {
mimil 0:428cf9a51873 242 //unable to allocate the string
mimil 0:428cf9a51873 243 return EOF;
mimil 0:428cf9a51873 244 }
mimil 0:428cf9a51873 245 in = fgetc(stream);
mimil 0:428cf9a51873 246 if (in == EOF)
mimil 0:428cf9a51873 247 {
mimil 0:428cf9a51873 248 stringBufferFree(buffer);
mimil 0:428cf9a51873 249 return EOF;
mimil 0:428cf9a51873 250 }
mimil 0:428cf9a51873 251 while (in != EOF)
mimil 0:428cf9a51873 252 {
mimil 0:428cf9a51873 253 while (in != '\"' && in >= 32)
mimil 0:428cf9a51873 254 {
mimil 0:428cf9a51873 255 if (in != '\\')
mimil 0:428cf9a51873 256 {
mimil 0:428cf9a51873 257 stringBufferAdd((char) in, buffer);
mimil 0:428cf9a51873 258 }
mimil 0:428cf9a51873 259 else
mimil 0:428cf9a51873 260 {
mimil 0:428cf9a51873 261 in = fgetc(stream);
mimil 0:428cf9a51873 262 if (in == EOF)
mimil 0:428cf9a51873 263 {
mimil 0:428cf9a51873 264 stringBufferFree(buffer);
mimil 0:428cf9a51873 265 return EOF;
mimil 0:428cf9a51873 266 }
mimil 0:428cf9a51873 267 switch (in)
mimil 0:428cf9a51873 268 {
mimil 0:428cf9a51873 269 case '\\':
mimil 0:428cf9a51873 270 stringBufferAdd('\\', buffer);
mimil 0:428cf9a51873 271 break;
mimil 0:428cf9a51873 272 case '\"':
mimil 0:428cf9a51873 273 stringBufferAdd('\"', buffer);
mimil 0:428cf9a51873 274 break;
mimil 0:428cf9a51873 275 case 'b':
mimil 0:428cf9a51873 276 stringBufferAdd('\b', buffer);
mimil 0:428cf9a51873 277 break;
mimil 0:428cf9a51873 278 case 'f':
mimil 0:428cf9a51873 279 stringBufferAdd('\f', buffer);
mimil 0:428cf9a51873 280 break;
mimil 0:428cf9a51873 281 case 'n':
mimil 0:428cf9a51873 282 stringBufferAdd('\n', buffer);
mimil 0:428cf9a51873 283 break;
mimil 0:428cf9a51873 284 case 'r':
mimil 0:428cf9a51873 285 stringBufferAdd('\r', buffer);
mimil 0:428cf9a51873 286 break;
mimil 0:428cf9a51873 287 case 't':
mimil 0:428cf9a51873 288 stringBufferAdd('\t', buffer);
mimil 0:428cf9a51873 289 break;
mimil 0:428cf9a51873 290 default:
mimil 0:428cf9a51873 291 //we do not understand it so we skip it
mimil 0:428cf9a51873 292 break;
mimil 0:428cf9a51873 293 }
mimil 0:428cf9a51873 294 }
mimil 0:428cf9a51873 295 in = fgetc(stream);
mimil 0:428cf9a51873 296 if (in == EOF)
mimil 0:428cf9a51873 297 {
mimil 0:428cf9a51873 298 stringBufferFree(buffer);
mimil 0:428cf9a51873 299 return EOF;
mimil 0:428cf9a51873 300 }
mimil 0:428cf9a51873 301 }
mimil 0:428cf9a51873 302 //the string ends here
mimil 0:428cf9a51873 303 item->valuestring = stringBufferToString(buffer);
mimil 0:428cf9a51873 304 return 0;
mimil 0:428cf9a51873 305 }
mimil 0:428cf9a51873 306 //we should not be here but it is ok
mimil 0:428cf9a51873 307 return 0;
mimil 0:428cf9a51873 308 }
mimil 0:428cf9a51873 309
mimil 0:428cf9a51873 310 // Render the cstring provided to an escaped version that can be printed.
mimil 0:428cf9a51873 311 int
mimil 0:428cf9a51873 312 aJsonClass::printStringPtr(const char *str, FILE* stream)
mimil 0:428cf9a51873 313 {
mimil 0:428cf9a51873 314 if (fputc('\"', stream) == EOF)
mimil 0:428cf9a51873 315 {
mimil 0:428cf9a51873 316 return EOF;
mimil 0:428cf9a51873 317 }
mimil 0:428cf9a51873 318 char* ptr = (char*) str;
mimil 0:428cf9a51873 319 if (ptr != NULL)
mimil 0:428cf9a51873 320 {
mimil 0:428cf9a51873 321 while (*ptr != 0)
mimil 0:428cf9a51873 322 {
mimil 0:428cf9a51873 323 if ((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\')
mimil 0:428cf9a51873 324 {
mimil 0:428cf9a51873 325 if (fputc(*ptr, stream) == EOF)
mimil 0:428cf9a51873 326 {
mimil 0:428cf9a51873 327 return EOF;
mimil 0:428cf9a51873 328 }
mimil 0:428cf9a51873 329 ptr++;
mimil 0:428cf9a51873 330 }
mimil 0:428cf9a51873 331 else
mimil 0:428cf9a51873 332 {
mimil 0:428cf9a51873 333 if (fputc('\\', stream) == EOF)
mimil 0:428cf9a51873 334 {
mimil 0:428cf9a51873 335 return EOF;
mimil 0:428cf9a51873 336 }
mimil 0:428cf9a51873 337 switch (*ptr++)
mimil 0:428cf9a51873 338 {
mimil 0:428cf9a51873 339 case '\\':
mimil 0:428cf9a51873 340 if (fputc('\\', stream) == EOF)
mimil 0:428cf9a51873 341 {
mimil 0:428cf9a51873 342 return EOF;
mimil 0:428cf9a51873 343 }
mimil 0:428cf9a51873 344 break;
mimil 0:428cf9a51873 345 case '\"':
mimil 0:428cf9a51873 346 if (fputc('\"', stream) == EOF)
mimil 0:428cf9a51873 347 {
mimil 0:428cf9a51873 348 return EOF;
mimil 0:428cf9a51873 349 }
mimil 0:428cf9a51873 350 break;
mimil 0:428cf9a51873 351 case '\b':
mimil 0:428cf9a51873 352 if (fputc('b', stream) == EOF)
mimil 0:428cf9a51873 353 {
mimil 0:428cf9a51873 354 return EOF;
mimil 0:428cf9a51873 355 }
mimil 0:428cf9a51873 356 break;
mimil 0:428cf9a51873 357 case '\f':
mimil 0:428cf9a51873 358 if (fputc('f', stream) == EOF)
mimil 0:428cf9a51873 359 {
mimil 0:428cf9a51873 360 return EOF;
mimil 0:428cf9a51873 361 }
mimil 0:428cf9a51873 362 break;
mimil 0:428cf9a51873 363 case '\n':
mimil 0:428cf9a51873 364 if (fputc('n', stream) == EOF)
mimil 0:428cf9a51873 365 {
mimil 0:428cf9a51873 366 return EOF;
mimil 0:428cf9a51873 367 }
mimil 0:428cf9a51873 368 break;
mimil 0:428cf9a51873 369 case '\r':
mimil 0:428cf9a51873 370 if (fputc('r', stream) == EOF)
mimil 0:428cf9a51873 371 {
mimil 0:428cf9a51873 372 return EOF;
mimil 0:428cf9a51873 373 }
mimil 0:428cf9a51873 374 break;
mimil 0:428cf9a51873 375 case '\t':
mimil 0:428cf9a51873 376 if (fputc('t', stream) == EOF)
mimil 0:428cf9a51873 377 {
mimil 0:428cf9a51873 378 return EOF;
mimil 0:428cf9a51873 379 }
mimil 0:428cf9a51873 380 break;
mimil 0:428cf9a51873 381 default:
mimil 0:428cf9a51873 382 break; // eviscerate with prejudice.
mimil 0:428cf9a51873 383 }
mimil 0:428cf9a51873 384 }
mimil 0:428cf9a51873 385
mimil 0:428cf9a51873 386 }
mimil 0:428cf9a51873 387 }
mimil 0:428cf9a51873 388 if (fputc('\"', stream) == EOF)
mimil 0:428cf9a51873 389 {
mimil 0:428cf9a51873 390 return EOF;
mimil 0:428cf9a51873 391 }
mimil 0:428cf9a51873 392 return 0;
mimil 0:428cf9a51873 393 }
mimil 0:428cf9a51873 394
mimil 0:428cf9a51873 395 // Invote print_string_ptr (which is useful) on an item.
mimil 0:428cf9a51873 396 int
mimil 0:428cf9a51873 397 aJsonClass::printString(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 398 {
mimil 0:428cf9a51873 399 return printStringPtr(item->valuestring, stream);
mimil 0:428cf9a51873 400 }
mimil 0:428cf9a51873 401
mimil 0:428cf9a51873 402 // Utility to jump whitespace and cr/lf
mimil 0:428cf9a51873 403 int
mimil 0:428cf9a51873 404 aJsonClass::skip(FILE* stream)
mimil 0:428cf9a51873 405 {
mimil 0:428cf9a51873 406 if (stream == NULL)
mimil 0:428cf9a51873 407 {
mimil 0:428cf9a51873 408 return EOF;
mimil 0:428cf9a51873 409 }
mimil 0:428cf9a51873 410 int in = fgetc(stream);
mimil 0:428cf9a51873 411 while (in != EOF && (in <= 32))
mimil 0:428cf9a51873 412 {
mimil 0:428cf9a51873 413 in = fgetc(stream);
mimil 0:428cf9a51873 414 }
mimil 0:428cf9a51873 415 if (in != EOF)
mimil 0:428cf9a51873 416 {
mimil 0:428cf9a51873 417 if (ungetc(in, stream) == EOF)
mimil 0:428cf9a51873 418 {
mimil 0:428cf9a51873 419 return EOF;
mimil 0:428cf9a51873 420 }
mimil 0:428cf9a51873 421 return 0;
mimil 0:428cf9a51873 422 }
mimil 0:428cf9a51873 423 return EOF;
mimil 0:428cf9a51873 424 }
mimil 0:428cf9a51873 425
mimil 0:428cf9a51873 426 // Parse an object - create a new root, and populate.
mimil 0:428cf9a51873 427 /*aJsonObject*
mimil 0:428cf9a51873 428 aJsonClass::parse(char *value)
mimil 0:428cf9a51873 429 {
mimil 0:428cf9a51873 430 FILE* string_input_stream = openStringInputStream(value);
mimil 0:428cf9a51873 431 aJsonObject* result = parse(string_input_stream, NULL);
mimil 0:428cf9a51873 432 closeStringInputStream(string_input_stream);
mimil 0:428cf9a51873 433 return result;
mimil 0:428cf9a51873 434 }*/
mimil 0:428cf9a51873 435
mimil 0:428cf9a51873 436 // Parse an object - create a new root, and populate.
mimil 0:428cf9a51873 437 aJsonObject*
mimil 0:428cf9a51873 438 aJsonClass::parse(FILE* stream)
mimil 0:428cf9a51873 439 {
mimil 0:428cf9a51873 440 return parse(stream, NULL);
mimil 0:428cf9a51873 441 }
mimil 0:428cf9a51873 442
mimil 0:428cf9a51873 443 // Parse an object - create a new root, and populate.
mimil 0:428cf9a51873 444 aJsonObject*
mimil 0:428cf9a51873 445 aJsonClass::parse(FILE* stream, char** filter)
mimil 0:428cf9a51873 446 {
mimil 0:428cf9a51873 447 if (stream == NULL)
mimil 0:428cf9a51873 448 {
mimil 0:428cf9a51873 449 return NULL;
mimil 0:428cf9a51873 450 }
mimil 0:428cf9a51873 451 aJsonObject *c = newItem();
mimil 0:428cf9a51873 452 if (!c)
mimil 0:428cf9a51873 453 return NULL; /* memory fail */
mimil 0:428cf9a51873 454
mimil 0:428cf9a51873 455 skip(stream);
mimil 0:428cf9a51873 456 if (parseValue(c, stream, filter) == EOF)
mimil 0:428cf9a51873 457 {
mimil 0:428cf9a51873 458 deleteItem(c);
mimil 0:428cf9a51873 459 return NULL;
mimil 0:428cf9a51873 460 }
mimil 0:428cf9a51873 461 return c;
mimil 0:428cf9a51873 462 }
mimil 0:428cf9a51873 463
mimil 0:428cf9a51873 464 // Render a aJsonObject item/entity/structure to text.
mimil 0:428cf9a51873 465 int
mimil 0:428cf9a51873 466 aJsonClass::print(aJsonObject* item, FILE* stream)
mimil 0:428cf9a51873 467 {
mimil 0:428cf9a51873 468 return printValue(item, stream);
mimil 0:428cf9a51873 469 }
mimil 0:428cf9a51873 470
mimil 0:428cf9a51873 471 /*char*
mimil 0:428cf9a51873 472 aJsonClass::print(aJsonObject* item)
mimil 0:428cf9a51873 473 {
mimil 0:428cf9a51873 474 FILE* stream = openStringOutputStream();
mimil 0:428cf9a51873 475 if (stream == NULL)
mimil 0:428cf9a51873 476 {
mimil 0:428cf9a51873 477 return NULL;
mimil 0:428cf9a51873 478 }
mimil 0:428cf9a51873 479 print(item, stream);
mimil 0:428cf9a51873 480 return closeStringOutputStream(stream);
mimil 0:428cf9a51873 481 }*/
mimil 0:428cf9a51873 482
mimil 0:428cf9a51873 483 // Parser core - when encountering text, process appropriately.
mimil 0:428cf9a51873 484 int
mimil 0:428cf9a51873 485 aJsonClass::parseValue(aJsonObject *item, FILE* stream, char** filter)
mimil 0:428cf9a51873 486 {
mimil 0:428cf9a51873 487 if (stream == NULL)
mimil 0:428cf9a51873 488 {
mimil 0:428cf9a51873 489 return EOF; // Fail on null.
mimil 0:428cf9a51873 490 }
mimil 0:428cf9a51873 491 if (skip(stream) == EOF)
mimil 0:428cf9a51873 492 {
mimil 0:428cf9a51873 493 return EOF;
mimil 0:428cf9a51873 494 }
mimil 0:428cf9a51873 495 //read the first byte from the stream
mimil 0:428cf9a51873 496 int in = fgetc(stream);
mimil 0:428cf9a51873 497 if (in == EOF)
mimil 0:428cf9a51873 498 {
mimil 0:428cf9a51873 499 return EOF;
mimil 0:428cf9a51873 500 }
mimil 0:428cf9a51873 501 if (ungetc(in, stream) == EOF)
mimil 0:428cf9a51873 502 {
mimil 0:428cf9a51873 503 return EOF;
mimil 0:428cf9a51873 504 }
mimil 0:428cf9a51873 505 if (in == '\"')
mimil 0:428cf9a51873 506 {
mimil 0:428cf9a51873 507 return parseString(item, stream);
mimil 0:428cf9a51873 508 }
mimil 0:428cf9a51873 509 else if (in == '-' || (in >= '0' && in <= '9'))
mimil 0:428cf9a51873 510 {
mimil 0:428cf9a51873 511 return parseNumber(item, stream);
mimil 0:428cf9a51873 512 }
mimil 0:428cf9a51873 513 else if (in == '[')
mimil 0:428cf9a51873 514 {
mimil 0:428cf9a51873 515 return parseArray(item, stream, filter);
mimil 0:428cf9a51873 516 }
mimil 0:428cf9a51873 517 else if (in == '{')
mimil 0:428cf9a51873 518 {
mimil 0:428cf9a51873 519 return parseObject(item, stream, filter);
mimil 0:428cf9a51873 520 }
mimil 0:428cf9a51873 521 //it can only be null, false or true
mimil 0:428cf9a51873 522 else if (in == 'n')
mimil 0:428cf9a51873 523 {
mimil 0:428cf9a51873 524 //a buffer to read the value
mimil 0:428cf9a51873 525 char buffer[] =
mimil 0:428cf9a51873 526 { 0, 0, 0, 0 };
mimil 0:428cf9a51873 527 if (fread(buffer, sizeof(char), 4, stream) != 4)
mimil 0:428cf9a51873 528 {
mimil 0:428cf9a51873 529 return EOF;
mimil 0:428cf9a51873 530 }
mimil 0:428cf9a51873 531 if (!strncmp(buffer, "null", 4))
mimil 0:428cf9a51873 532 {
mimil 0:428cf9a51873 533 item->type = aJson_NULL;
mimil 0:428cf9a51873 534 return 0;
mimil 0:428cf9a51873 535 }
mimil 0:428cf9a51873 536 else
mimil 0:428cf9a51873 537 {
mimil 0:428cf9a51873 538 return EOF;
mimil 0:428cf9a51873 539 }
mimil 0:428cf9a51873 540 }
mimil 0:428cf9a51873 541 else if (in == 'f')
mimil 0:428cf9a51873 542 {
mimil 0:428cf9a51873 543 //a buffer to read the value
mimil 0:428cf9a51873 544 char buffer[] =
mimil 0:428cf9a51873 545 { 0, 0, 0, 0, 0 };
mimil 0:428cf9a51873 546 if (fread(buffer, sizeof(char), 5, stream) != 5)
mimil 0:428cf9a51873 547 {
mimil 0:428cf9a51873 548 return EOF;
mimil 0:428cf9a51873 549 }
mimil 0:428cf9a51873 550 if (!strncmp(buffer, "false", 5))
mimil 0:428cf9a51873 551 {
mimil 0:428cf9a51873 552 item->type = aJson_False;
mimil 0:428cf9a51873 553 item->valuebool = 0;
mimil 0:428cf9a51873 554 return 0;
mimil 0:428cf9a51873 555 }
mimil 0:428cf9a51873 556 }
mimil 0:428cf9a51873 557 else if (in == 't')
mimil 0:428cf9a51873 558 {
mimil 0:428cf9a51873 559 //a buffer to read the value
mimil 0:428cf9a51873 560 char buffer[] =
mimil 0:428cf9a51873 561 { 0, 0, 0, 0 };
mimil 0:428cf9a51873 562 if (fread(buffer, sizeof(char), 4, stream) != 4)
mimil 0:428cf9a51873 563 {
mimil 0:428cf9a51873 564 return EOF;
mimil 0:428cf9a51873 565 }
mimil 0:428cf9a51873 566 if (!strncmp(buffer, "true", 4))
mimil 0:428cf9a51873 567 {
mimil 0:428cf9a51873 568 item->type = aJson_True;
mimil 0:428cf9a51873 569 item->valuebool = -1;
mimil 0:428cf9a51873 570 return 0;
mimil 0:428cf9a51873 571 }
mimil 0:428cf9a51873 572 }
mimil 0:428cf9a51873 573
mimil 0:428cf9a51873 574 return EOF; // failure.
mimil 0:428cf9a51873 575 }
mimil 0:428cf9a51873 576
mimil 0:428cf9a51873 577 // Render a value to text.
mimil 0:428cf9a51873 578 int
mimil 0:428cf9a51873 579 aJsonClass::printValue(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 580 {
mimil 0:428cf9a51873 581 int result = 0;
mimil 0:428cf9a51873 582 if (item == NULL)
mimil 0:428cf9a51873 583 {
mimil 0:428cf9a51873 584 //nothing to do
mimil 0:428cf9a51873 585 return 0;
mimil 0:428cf9a51873 586 }
mimil 0:428cf9a51873 587 switch (item->type)
mimil 0:428cf9a51873 588 {
mimil 0:428cf9a51873 589 case aJson_NULL:
mimil 0:428cf9a51873 590 result = fprintf_P(stream, PSTR("null"));
mimil 0:428cf9a51873 591 break;
mimil 0:428cf9a51873 592 case aJson_False:
mimil 0:428cf9a51873 593 result = fprintf_P(stream, PSTR("false"));
mimil 0:428cf9a51873 594 break;
mimil 0:428cf9a51873 595 case aJson_True:
mimil 0:428cf9a51873 596 result = fprintf_P(stream, PSTR("true"));
mimil 0:428cf9a51873 597 break;
mimil 0:428cf9a51873 598 case aJson_Int:
mimil 0:428cf9a51873 599 result = printInt(item, stream);
mimil 0:428cf9a51873 600 break;
mimil 0:428cf9a51873 601 case aJson_Float:
mimil 0:428cf9a51873 602 result = printFloat(item, stream);
mimil 0:428cf9a51873 603 break;
mimil 0:428cf9a51873 604 case aJson_String:
mimil 0:428cf9a51873 605 result = printString(item, stream);
mimil 0:428cf9a51873 606 break;
mimil 0:428cf9a51873 607 case aJson_Array:
mimil 0:428cf9a51873 608 result = printArray(item, stream);
mimil 0:428cf9a51873 609 break;
mimil 0:428cf9a51873 610 case aJson_Object:
mimil 0:428cf9a51873 611 result = printObject(item, stream);
mimil 0:428cf9a51873 612 break;
mimil 0:428cf9a51873 613 }
mimil 0:428cf9a51873 614 //good time to flush the stream
mimil 0:428cf9a51873 615 fflush(stream);
mimil 0:428cf9a51873 616 return result;
mimil 0:428cf9a51873 617 }
mimil 0:428cf9a51873 618
mimil 0:428cf9a51873 619 // Build an array from input text.
mimil 0:428cf9a51873 620 int
mimil 0:428cf9a51873 621 aJsonClass::parseArray(aJsonObject *item, FILE* stream, char** filter)
mimil 0:428cf9a51873 622 {
mimil 0:428cf9a51873 623 int in = fgetc(stream);
mimil 0:428cf9a51873 624 if (in != '[')
mimil 0:428cf9a51873 625 {
mimil 0:428cf9a51873 626 return EOF; // not an array!
mimil 0:428cf9a51873 627 }
mimil 0:428cf9a51873 628
mimil 0:428cf9a51873 629 item->type = aJson_Array;
mimil 0:428cf9a51873 630 skip(stream);
mimil 0:428cf9a51873 631 in = fgetc(stream);
mimil 0:428cf9a51873 632 //check for empty array
mimil 0:428cf9a51873 633 if (in == ']')
mimil 0:428cf9a51873 634 {
mimil 0:428cf9a51873 635 return 0; // empty array.
mimil 0:428cf9a51873 636 }
mimil 0:428cf9a51873 637 //now put back the last character
mimil 0:428cf9a51873 638 ungetc(in, stream);
mimil 0:428cf9a51873 639 aJsonObject *child;
mimil 0:428cf9a51873 640 char first = -1;
mimil 0:428cf9a51873 641 while ((first) || (in == ','))
mimil 0:428cf9a51873 642 {
mimil 0:428cf9a51873 643 aJsonObject *new_item = newItem();
mimil 0:428cf9a51873 644 if (new_item == NULL)
mimil 0:428cf9a51873 645 {
mimil 0:428cf9a51873 646 return EOF; // memory fail
mimil 0:428cf9a51873 647 }
mimil 0:428cf9a51873 648 if (first)
mimil 0:428cf9a51873 649 {
mimil 0:428cf9a51873 650 item->child = new_item;
mimil 0:428cf9a51873 651 first = 0;
mimil 0:428cf9a51873 652 }
mimil 0:428cf9a51873 653 else
mimil 0:428cf9a51873 654 {
mimil 0:428cf9a51873 655 child->next = new_item;
mimil 0:428cf9a51873 656 new_item->prev = child;
mimil 0:428cf9a51873 657 }
mimil 0:428cf9a51873 658 child = new_item;
mimil 0:428cf9a51873 659 skip(stream);
mimil 0:428cf9a51873 660 if (parseValue(child, stream, filter))
mimil 0:428cf9a51873 661 {
mimil 0:428cf9a51873 662 return EOF;
mimil 0:428cf9a51873 663 }
mimil 0:428cf9a51873 664 skip(stream);
mimil 0:428cf9a51873 665 in = fgetc(stream);
mimil 0:428cf9a51873 666 }
mimil 0:428cf9a51873 667 if (in == ']')
mimil 0:428cf9a51873 668 {
mimil 0:428cf9a51873 669 return 0; // end of array
mimil 0:428cf9a51873 670 }
mimil 0:428cf9a51873 671 else
mimil 0:428cf9a51873 672 {
mimil 0:428cf9a51873 673 return EOF; // malformed.
mimil 0:428cf9a51873 674 }
mimil 0:428cf9a51873 675 }
mimil 0:428cf9a51873 676
mimil 0:428cf9a51873 677 // Render an array to text
mimil 0:428cf9a51873 678 int
mimil 0:428cf9a51873 679 aJsonClass::printArray(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 680 {
mimil 0:428cf9a51873 681 if (item == NULL)
mimil 0:428cf9a51873 682 {
mimil 0:428cf9a51873 683 //nothing to do
mimil 0:428cf9a51873 684 return 0;
mimil 0:428cf9a51873 685 }
mimil 0:428cf9a51873 686 aJsonObject *child = item->child;
mimil 0:428cf9a51873 687 if (fputc('[', stream) == EOF)
mimil 0:428cf9a51873 688 {
mimil 0:428cf9a51873 689 return EOF;
mimil 0:428cf9a51873 690 }
mimil 0:428cf9a51873 691 while (child)
mimil 0:428cf9a51873 692 {
mimil 0:428cf9a51873 693 if (printValue(child, stream) == EOF)
mimil 0:428cf9a51873 694 {
mimil 0:428cf9a51873 695 return EOF;
mimil 0:428cf9a51873 696 }
mimil 0:428cf9a51873 697 child = child->next;
mimil 0:428cf9a51873 698 if (child)
mimil 0:428cf9a51873 699 {
mimil 0:428cf9a51873 700 if (fputc(',', stream) == EOF)
mimil 0:428cf9a51873 701 {
mimil 0:428cf9a51873 702 return EOF;
mimil 0:428cf9a51873 703 }
mimil 0:428cf9a51873 704 }
mimil 0:428cf9a51873 705 }
mimil 0:428cf9a51873 706 if (fputc(']', stream) == EOF)
mimil 0:428cf9a51873 707 {
mimil 0:428cf9a51873 708 return EOF;
mimil 0:428cf9a51873 709 }
mimil 0:428cf9a51873 710 return 0;
mimil 0:428cf9a51873 711 }
mimil 0:428cf9a51873 712
mimil 0:428cf9a51873 713 // Build an object from the text.
mimil 0:428cf9a51873 714 int
mimil 0:428cf9a51873 715 aJsonClass::parseObject(aJsonObject *item, FILE* stream, char** filter)
mimil 0:428cf9a51873 716 {
mimil 0:428cf9a51873 717 int in = fgetc(stream);
mimil 0:428cf9a51873 718 if (in != '{')
mimil 0:428cf9a51873 719 {
mimil 0:428cf9a51873 720 return EOF; // not an object!
mimil 0:428cf9a51873 721 }
mimil 0:428cf9a51873 722
mimil 0:428cf9a51873 723 item->type = aJson_Object;
mimil 0:428cf9a51873 724 skip(stream);
mimil 0:428cf9a51873 725 //check for an empty object
mimil 0:428cf9a51873 726 in = fgetc(stream);
mimil 0:428cf9a51873 727 if (in == '}')
mimil 0:428cf9a51873 728 {
mimil 0:428cf9a51873 729 return 0; // empty object.
mimil 0:428cf9a51873 730 }
mimil 0:428cf9a51873 731 //preserve the char for the next parser
mimil 0:428cf9a51873 732 ungetc(in, stream);
mimil 0:428cf9a51873 733
mimil 0:428cf9a51873 734 aJsonObject* child;
mimil 0:428cf9a51873 735 char first = -1;
mimil 0:428cf9a51873 736 while ((first) || (in == ','))
mimil 0:428cf9a51873 737 {
mimil 0:428cf9a51873 738 //in = fgetc(stream);
mimil 0:428cf9a51873 739 aJsonObject* new_item = newItem();
mimil 0:428cf9a51873 740 if (new_item == NULL)
mimil 0:428cf9a51873 741 {
mimil 0:428cf9a51873 742 return EOF; // memory fail
mimil 0:428cf9a51873 743 }
mimil 0:428cf9a51873 744 if (first)
mimil 0:428cf9a51873 745 {
mimil 0:428cf9a51873 746 first = 0;
mimil 0:428cf9a51873 747 item->child = new_item;
mimil 0:428cf9a51873 748 }
mimil 0:428cf9a51873 749 else
mimil 0:428cf9a51873 750 {
mimil 0:428cf9a51873 751 child->next = new_item;
mimil 0:428cf9a51873 752 new_item->prev = child;
mimil 0:428cf9a51873 753 }
mimil 0:428cf9a51873 754 child = new_item;
mimil 0:428cf9a51873 755 skip(stream);
mimil 0:428cf9a51873 756 if (parseString(child, stream) == EOF)
mimil 0:428cf9a51873 757 {
mimil 0:428cf9a51873 758 return EOF;
mimil 0:428cf9a51873 759 }
mimil 0:428cf9a51873 760 skip(stream);
mimil 0:428cf9a51873 761 child->name = child->valuestring;
mimil 0:428cf9a51873 762 child->valuestring = NULL;
mimil 0:428cf9a51873 763
mimil 0:428cf9a51873 764 in = fgetc(stream);
mimil 0:428cf9a51873 765 if (in != ':')
mimil 0:428cf9a51873 766 {
mimil 0:428cf9a51873 767 return EOF; // fail!
mimil 0:428cf9a51873 768 }
mimil 0:428cf9a51873 769 // skip any spacing, get the value.
mimil 0:428cf9a51873 770 skip(stream);
mimil 0:428cf9a51873 771 if (parseValue(child, stream, filter) == EOF)
mimil 0:428cf9a51873 772 {
mimil 0:428cf9a51873 773 return EOF;
mimil 0:428cf9a51873 774 }
mimil 0:428cf9a51873 775 in = fgetc(stream);
mimil 0:428cf9a51873 776 }
mimil 0:428cf9a51873 777
mimil 0:428cf9a51873 778 if (in == '}')
mimil 0:428cf9a51873 779 {
mimil 0:428cf9a51873 780 return 0; // end of array
mimil 0:428cf9a51873 781 }
mimil 0:428cf9a51873 782 else
mimil 0:428cf9a51873 783 {
mimil 0:428cf9a51873 784 return EOF; // malformed.
mimil 0:428cf9a51873 785 }
mimil 0:428cf9a51873 786 }
mimil 0:428cf9a51873 787
mimil 0:428cf9a51873 788 // Render an object to text.
mimil 0:428cf9a51873 789 int
mimil 0:428cf9a51873 790 aJsonClass::printObject(aJsonObject *item, FILE* stream)
mimil 0:428cf9a51873 791 {
mimil 0:428cf9a51873 792 if (item == NULL)
mimil 0:428cf9a51873 793 {
mimil 0:428cf9a51873 794 //nothing to do
mimil 0:428cf9a51873 795 return 0;
mimil 0:428cf9a51873 796 }
mimil 0:428cf9a51873 797 aJsonObject *child = item->child;
mimil 0:428cf9a51873 798 if (fputc('{', stream) == EOF)
mimil 0:428cf9a51873 799 {
mimil 0:428cf9a51873 800 return EOF;
mimil 0:428cf9a51873 801 }
mimil 0:428cf9a51873 802 while (child)
mimil 0:428cf9a51873 803 {
mimil 0:428cf9a51873 804 if (printStringPtr(child->name, stream) == EOF)
mimil 0:428cf9a51873 805 {
mimil 0:428cf9a51873 806 return EOF;
mimil 0:428cf9a51873 807 }
mimil 0:428cf9a51873 808 if (fputc(':', stream) == EOF)
mimil 0:428cf9a51873 809 {
mimil 0:428cf9a51873 810 return EOF;
mimil 0:428cf9a51873 811 }
mimil 0:428cf9a51873 812 if (printValue(child, stream) == EOF)
mimil 0:428cf9a51873 813 {
mimil 0:428cf9a51873 814 return EOF;
mimil 0:428cf9a51873 815 }
mimil 0:428cf9a51873 816 child = child->next;
mimil 0:428cf9a51873 817 if (child)
mimil 0:428cf9a51873 818 {
mimil 0:428cf9a51873 819 if (fputc(',', stream) == EOF)
mimil 0:428cf9a51873 820 {
mimil 0:428cf9a51873 821 return EOF;
mimil 0:428cf9a51873 822 }
mimil 0:428cf9a51873 823 }
mimil 0:428cf9a51873 824 }
mimil 0:428cf9a51873 825 if (fputc('}', stream) == EOF)
mimil 0:428cf9a51873 826 {
mimil 0:428cf9a51873 827 return EOF;
mimil 0:428cf9a51873 828 }
mimil 0:428cf9a51873 829 return 0;
mimil 0:428cf9a51873 830 }
mimil 0:428cf9a51873 831
mimil 0:428cf9a51873 832 // Get Array size/item / object item.
mimil 0:428cf9a51873 833 unsigned char
mimil 0:428cf9a51873 834 aJsonClass::getArraySize(aJsonObject *array)
mimil 0:428cf9a51873 835 {
mimil 0:428cf9a51873 836 aJsonObject *c = array->child;
mimil 0:428cf9a51873 837 unsigned char i = 0;
mimil 0:428cf9a51873 838 while (c)
mimil 0:428cf9a51873 839 i++, c = c->next;
mimil 0:428cf9a51873 840 return i;
mimil 0:428cf9a51873 841 }
mimil 0:428cf9a51873 842 aJsonObject*
mimil 0:428cf9a51873 843 aJsonClass::getArrayItem(aJsonObject *array, unsigned char item)
mimil 0:428cf9a51873 844 {
mimil 0:428cf9a51873 845 aJsonObject *c = array->child;
mimil 0:428cf9a51873 846 while (c && item > 0)
mimil 0:428cf9a51873 847 item--, c = c->next;
mimil 0:428cf9a51873 848 return c;
mimil 0:428cf9a51873 849 }
mimil 0:428cf9a51873 850 aJsonObject*
mimil 0:428cf9a51873 851 aJsonClass::getObjectItem(aJsonObject *object, const char *string)
mimil 0:428cf9a51873 852 {
mimil 0:428cf9a51873 853 aJsonObject *c = object->child;
mimil 0:428cf9a51873 854 while (c && strcasecmp(c->name, string))
mimil 0:428cf9a51873 855 c = c->next;
mimil 0:428cf9a51873 856 return c;
mimil 0:428cf9a51873 857 }
mimil 0:428cf9a51873 858
mimil 0:428cf9a51873 859 // Utility for array list handling.
mimil 0:428cf9a51873 860 void
mimil 0:428cf9a51873 861 aJsonClass::suffixObject(aJsonObject *prev, aJsonObject *item)
mimil 0:428cf9a51873 862 {
mimil 0:428cf9a51873 863 prev->next = item;
mimil 0:428cf9a51873 864 item->prev = prev;
mimil 0:428cf9a51873 865 }
mimil 0:428cf9a51873 866 // Utility for handling references.
mimil 0:428cf9a51873 867 aJsonObject*
mimil 0:428cf9a51873 868 aJsonClass::createReference(aJsonObject *item)
mimil 0:428cf9a51873 869 {
mimil 0:428cf9a51873 870 aJsonObject *ref = newItem();
mimil 0:428cf9a51873 871 if (!ref)
mimil 0:428cf9a51873 872 return 0;
mimil 0:428cf9a51873 873 memcpy(ref, item, sizeof(aJsonObject));
mimil 0:428cf9a51873 874 ref->name = 0;
mimil 0:428cf9a51873 875 ref->type |= aJson_IsReference;
mimil 0:428cf9a51873 876 ref->next = ref->prev = 0;
mimil 0:428cf9a51873 877 return ref;
mimil 0:428cf9a51873 878 }
mimil 0:428cf9a51873 879
mimil 0:428cf9a51873 880 // Add item to array/object.
mimil 0:428cf9a51873 881 void
mimil 0:428cf9a51873 882 aJsonClass::addItemToArray(aJsonObject *array, aJsonObject *item)
mimil 0:428cf9a51873 883 {
mimil 0:428cf9a51873 884 aJsonObject *c = array->child;
mimil 0:428cf9a51873 885 if (!item)
mimil 0:428cf9a51873 886 return;
mimil 0:428cf9a51873 887 if (!c)
mimil 0:428cf9a51873 888 {
mimil 0:428cf9a51873 889 array->child = item;
mimil 0:428cf9a51873 890 }
mimil 0:428cf9a51873 891 else
mimil 0:428cf9a51873 892 {
mimil 0:428cf9a51873 893 while (c && c->next)
mimil 0:428cf9a51873 894 c = c->next;
mimil 0:428cf9a51873 895 suffixObject(c, item);
mimil 0:428cf9a51873 896 }
mimil 0:428cf9a51873 897 }
mimil 0:428cf9a51873 898 void
mimil 0:428cf9a51873 899 aJsonClass::addItemToObject(aJsonObject *object, const char *string,
mimil 0:428cf9a51873 900 aJsonObject *item)
mimil 0:428cf9a51873 901 {
mimil 0:428cf9a51873 902 if (!item)
mimil 0:428cf9a51873 903 return;
mimil 0:428cf9a51873 904 if (item->name)
mimil 0:428cf9a51873 905 free(item->name);
mimil 0:428cf9a51873 906 item->name = strdup(string);
mimil 0:428cf9a51873 907 addItemToArray(object, item);
mimil 0:428cf9a51873 908 }
mimil 0:428cf9a51873 909 void
mimil 0:428cf9a51873 910 aJsonClass::addItemReferenceToArray(aJsonObject *array, aJsonObject *item)
mimil 0:428cf9a51873 911 {
mimil 0:428cf9a51873 912 addItemToArray(array, createReference(item));
mimil 0:428cf9a51873 913 }
mimil 0:428cf9a51873 914 void
mimil 0:428cf9a51873 915 aJsonClass::addItemReferenceToObject(aJsonObject *object, const char *string,
mimil 0:428cf9a51873 916 aJsonObject *item)
mimil 0:428cf9a51873 917 {
mimil 0:428cf9a51873 918 addItemToObject(object, string, createReference(item));
mimil 0:428cf9a51873 919 }
mimil 0:428cf9a51873 920
mimil 0:428cf9a51873 921 aJsonObject*
mimil 0:428cf9a51873 922 aJsonClass::detachItemFromArray(aJsonObject *array, unsigned char which)
mimil 0:428cf9a51873 923 {
mimil 0:428cf9a51873 924 aJsonObject *c = array->child;
mimil 0:428cf9a51873 925 while (c && which > 0)
mimil 0:428cf9a51873 926 c = c->next, which--;
mimil 0:428cf9a51873 927 if (!c)
mimil 0:428cf9a51873 928 return 0;
mimil 0:428cf9a51873 929 if (c->prev)
mimil 0:428cf9a51873 930 c->prev->next = c->next;
mimil 0:428cf9a51873 931 if (c->next)
mimil 0:428cf9a51873 932 c->next->prev = c->prev;
mimil 0:428cf9a51873 933 if (c == array->child)
mimil 0:428cf9a51873 934 array->child = c->next;
mimil 0:428cf9a51873 935 c->prev = c->next = 0;
mimil 0:428cf9a51873 936 return c;
mimil 0:428cf9a51873 937 }
mimil 0:428cf9a51873 938 void
mimil 0:428cf9a51873 939 aJsonClass::deleteItemFromArray(aJsonObject *array, unsigned char which)
mimil 0:428cf9a51873 940 {
mimil 0:428cf9a51873 941 deleteItem(detachItemFromArray(array, which));
mimil 0:428cf9a51873 942 }
mimil 0:428cf9a51873 943 aJsonObject*
mimil 0:428cf9a51873 944 aJsonClass::detachItemFromObject(aJsonObject *object, const char *string)
mimil 0:428cf9a51873 945 {
mimil 0:428cf9a51873 946 unsigned char i = 0;
mimil 0:428cf9a51873 947 aJsonObject *c = object->child;
mimil 0:428cf9a51873 948 while (c && strcasecmp(c->name, string))
mimil 0:428cf9a51873 949 i++, c = c->next;
mimil 0:428cf9a51873 950 if (c)
mimil 0:428cf9a51873 951 return detachItemFromArray(object, i);
mimil 0:428cf9a51873 952 return 0;
mimil 0:428cf9a51873 953 }
mimil 0:428cf9a51873 954 void
mimil 0:428cf9a51873 955 aJsonClass::deleteItemFromObject(aJsonObject *object, const char *string)
mimil 0:428cf9a51873 956 {
mimil 0:428cf9a51873 957 deleteItem(detachItemFromObject(object, string));
mimil 0:428cf9a51873 958 }
mimil 0:428cf9a51873 959
mimil 0:428cf9a51873 960 // Replace array/object items with new ones.
mimil 0:428cf9a51873 961 void
mimil 0:428cf9a51873 962 aJsonClass::replaceItemInArray(aJsonObject *array, unsigned char which,
mimil 0:428cf9a51873 963 aJsonObject *newitem)
mimil 0:428cf9a51873 964 {
mimil 0:428cf9a51873 965 aJsonObject *c = array->child;
mimil 0:428cf9a51873 966 while (c && which > 0)
mimil 0:428cf9a51873 967 c = c->next, which--;
mimil 0:428cf9a51873 968 if (!c)
mimil 0:428cf9a51873 969 return;
mimil 0:428cf9a51873 970 newitem->next = c->next;
mimil 0:428cf9a51873 971 newitem->prev = c->prev;
mimil 0:428cf9a51873 972 if (newitem->next)
mimil 0:428cf9a51873 973 newitem->next->prev = newitem;
mimil 0:428cf9a51873 974 if (c == array->child)
mimil 0:428cf9a51873 975 array->child = newitem;
mimil 0:428cf9a51873 976 else
mimil 0:428cf9a51873 977 newitem->prev->next = newitem;
mimil 0:428cf9a51873 978 c->next = c->prev = 0;
mimil 0:428cf9a51873 979 deleteItem(c);
mimil 0:428cf9a51873 980 }
mimil 0:428cf9a51873 981 void
mimil 0:428cf9a51873 982 aJsonClass::replaceItemInObject(aJsonObject *object, const char *string,
mimil 0:428cf9a51873 983 aJsonObject *newitem)
mimil 0:428cf9a51873 984 {
mimil 0:428cf9a51873 985 unsigned char i = 0;
mimil 0:428cf9a51873 986 aJsonObject *c = object->child;
mimil 0:428cf9a51873 987 while (c && strcasecmp(c->name, string))
mimil 0:428cf9a51873 988 i++, c = c->next;
mimil 0:428cf9a51873 989 if (c)
mimil 0:428cf9a51873 990 {
mimil 0:428cf9a51873 991 newitem->name = strdup(string);
mimil 0:428cf9a51873 992 replaceItemInArray(object, i, newitem);
mimil 0:428cf9a51873 993 }
mimil 0:428cf9a51873 994 }
mimil 0:428cf9a51873 995
mimil 0:428cf9a51873 996 // Create basic types:
mimil 0:428cf9a51873 997 aJsonObject*
mimil 0:428cf9a51873 998 aJsonClass::createNull()
mimil 0:428cf9a51873 999 {
mimil 0:428cf9a51873 1000 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1001 if (item)
mimil 0:428cf9a51873 1002 item->type = aJson_NULL;
mimil 0:428cf9a51873 1003 return item;
mimil 0:428cf9a51873 1004 }
mimil 0:428cf9a51873 1005
mimil 0:428cf9a51873 1006 aJsonObject*
mimil 0:428cf9a51873 1007 aJsonClass::createTrue()
mimil 0:428cf9a51873 1008 {
mimil 0:428cf9a51873 1009 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1010 if (item)
mimil 0:428cf9a51873 1011 {
mimil 0:428cf9a51873 1012 item->type = aJson_True;
mimil 0:428cf9a51873 1013 item->valuebool = -1;
mimil 0:428cf9a51873 1014 }
mimil 0:428cf9a51873 1015 return item;
mimil 0:428cf9a51873 1016 }
mimil 0:428cf9a51873 1017 aJsonObject*
mimil 0:428cf9a51873 1018 aJsonClass::createFalse()
mimil 0:428cf9a51873 1019 {
mimil 0:428cf9a51873 1020 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1021 if (item)
mimil 0:428cf9a51873 1022 {
mimil 0:428cf9a51873 1023 item->type = aJson_False;
mimil 0:428cf9a51873 1024 item->valuebool = 0;
mimil 0:428cf9a51873 1025 }
mimil 0:428cf9a51873 1026 return item;
mimil 0:428cf9a51873 1027 }
mimil 0:428cf9a51873 1028 aJsonObject*
mimil 0:428cf9a51873 1029 aJsonClass::createItem(char b)
mimil 0:428cf9a51873 1030 {
mimil 0:428cf9a51873 1031 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1032 if (item)
mimil 0:428cf9a51873 1033 {
mimil 0:428cf9a51873 1034 item->type = b ? aJson_True : aJson_False;
mimil 0:428cf9a51873 1035 item->valuebool = b ? -1 : 0;
mimil 0:428cf9a51873 1036 }
mimil 0:428cf9a51873 1037 return item;
mimil 0:428cf9a51873 1038 }
mimil 0:428cf9a51873 1039
mimil 0:428cf9a51873 1040 aJsonObject*
mimil 0:428cf9a51873 1041 aJsonClass::createItem(int num)
mimil 0:428cf9a51873 1042 {
mimil 0:428cf9a51873 1043 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1044 if (item)
mimil 0:428cf9a51873 1045 {
mimil 0:428cf9a51873 1046 item->type = aJson_Int;
mimil 0:428cf9a51873 1047 item->valueint = (int) num;
mimil 0:428cf9a51873 1048 }
mimil 0:428cf9a51873 1049 return item;
mimil 0:428cf9a51873 1050 }
mimil 0:428cf9a51873 1051
mimil 0:428cf9a51873 1052 aJsonObject*
mimil 0:428cf9a51873 1053 aJsonClass::createItem(double num)
mimil 0:428cf9a51873 1054 {
mimil 0:428cf9a51873 1055 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1056 if (item)
mimil 0:428cf9a51873 1057 {
mimil 0:428cf9a51873 1058 item->type = aJson_Float;
mimil 0:428cf9a51873 1059 item->valuefloat = num;
mimil 0:428cf9a51873 1060 }
mimil 0:428cf9a51873 1061 return item;
mimil 0:428cf9a51873 1062 }
mimil 0:428cf9a51873 1063
mimil 0:428cf9a51873 1064 aJsonObject*
mimil 0:428cf9a51873 1065 aJsonClass::createItem(const char *string)
mimil 0:428cf9a51873 1066 {
mimil 0:428cf9a51873 1067 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1068 if (item)
mimil 0:428cf9a51873 1069 {
mimil 0:428cf9a51873 1070 item->type = aJson_String;
mimil 0:428cf9a51873 1071 item->valuestring = strdup(string);
mimil 0:428cf9a51873 1072 }
mimil 0:428cf9a51873 1073 return item;
mimil 0:428cf9a51873 1074 }
mimil 0:428cf9a51873 1075
mimil 0:428cf9a51873 1076 aJsonObject*
mimil 0:428cf9a51873 1077 aJsonClass::createArray()
mimil 0:428cf9a51873 1078 {
mimil 0:428cf9a51873 1079 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1080 if (item)
mimil 0:428cf9a51873 1081 item->type = aJson_Array;
mimil 0:428cf9a51873 1082 return item;
mimil 0:428cf9a51873 1083 }
mimil 0:428cf9a51873 1084 aJsonObject*
mimil 0:428cf9a51873 1085 aJsonClass::createObject()
mimil 0:428cf9a51873 1086 {
mimil 0:428cf9a51873 1087 aJsonObject *item = newItem();
mimil 0:428cf9a51873 1088 if (item)
mimil 0:428cf9a51873 1089 item->type = aJson_Object;
mimil 0:428cf9a51873 1090 return item;
mimil 0:428cf9a51873 1091 }
mimil 0:428cf9a51873 1092
mimil 0:428cf9a51873 1093 // Create Arrays:
mimil 0:428cf9a51873 1094 aJsonObject*
mimil 0:428cf9a51873 1095 aJsonClass::createIntArray(int *numbers, unsigned char count)
mimil 0:428cf9a51873 1096 {
mimil 0:428cf9a51873 1097 unsigned char i;
mimil 0:428cf9a51873 1098 aJsonObject *n = 0, *p = 0, *a = createArray();
mimil 0:428cf9a51873 1099 for (i = 0; a && i < count; i++)
mimil 0:428cf9a51873 1100 {
mimil 0:428cf9a51873 1101 n = createItem(numbers[i]);
mimil 0:428cf9a51873 1102 if (!i)
mimil 0:428cf9a51873 1103 a->child = n;
mimil 0:428cf9a51873 1104 else
mimil 0:428cf9a51873 1105 suffixObject(p, n);
mimil 0:428cf9a51873 1106 p = n;
mimil 0:428cf9a51873 1107 }
mimil 0:428cf9a51873 1108 return a;
mimil 0:428cf9a51873 1109 }
mimil 0:428cf9a51873 1110
mimil 0:428cf9a51873 1111 aJsonObject*
mimil 0:428cf9a51873 1112 aJsonClass::createFloatArray(double *numbers, unsigned char count)
mimil 0:428cf9a51873 1113 {
mimil 0:428cf9a51873 1114 unsigned char i;
mimil 0:428cf9a51873 1115 aJsonObject *n = 0, *p = 0, *a = createArray();
mimil 0:428cf9a51873 1116 for (i = 0; a && i < count; i++)
mimil 0:428cf9a51873 1117 {
mimil 0:428cf9a51873 1118 n = createItem(numbers[i]);
mimil 0:428cf9a51873 1119 if (!i)
mimil 0:428cf9a51873 1120 a->child = n;
mimil 0:428cf9a51873 1121 else
mimil 0:428cf9a51873 1122 suffixObject(p, n);
mimil 0:428cf9a51873 1123 p = n;
mimil 0:428cf9a51873 1124 }
mimil 0:428cf9a51873 1125 return a;
mimil 0:428cf9a51873 1126 }
mimil 0:428cf9a51873 1127
mimil 0:428cf9a51873 1128 aJsonObject*
mimil 0:428cf9a51873 1129 aJsonClass::createDoubleArray(double *numbers, unsigned char count)
mimil 0:428cf9a51873 1130 {
mimil 0:428cf9a51873 1131 unsigned char i;
mimil 0:428cf9a51873 1132 aJsonObject *n = 0, *p = 0, *a = createArray();
mimil 0:428cf9a51873 1133 for (i = 0; a && i < count; i++)
mimil 0:428cf9a51873 1134 {
mimil 0:428cf9a51873 1135 n = createItem(numbers[i]);
mimil 0:428cf9a51873 1136 if (!i)
mimil 0:428cf9a51873 1137 a->child = n;
mimil 0:428cf9a51873 1138 else
mimil 0:428cf9a51873 1139 suffixObject(p, n);
mimil 0:428cf9a51873 1140 p = n;
mimil 0:428cf9a51873 1141 }
mimil 0:428cf9a51873 1142 return a;
mimil 0:428cf9a51873 1143 }
mimil 0:428cf9a51873 1144
mimil 0:428cf9a51873 1145 aJsonObject*
mimil 0:428cf9a51873 1146 aJsonClass::createStringArray(const char **strings, unsigned char count)
mimil 0:428cf9a51873 1147 {
mimil 0:428cf9a51873 1148 unsigned char i;
mimil 0:428cf9a51873 1149 aJsonObject *n = 0, *p = 0, *a = createArray();
mimil 0:428cf9a51873 1150 for (i = 0; a && i < count; i++)
mimil 0:428cf9a51873 1151 {
mimil 0:428cf9a51873 1152 n = createItem(strings[i]);
mimil 0:428cf9a51873 1153 if (!i)
mimil 0:428cf9a51873 1154 a->child = n;
mimil 0:428cf9a51873 1155 else
mimil 0:428cf9a51873 1156 suffixObject(p, n);
mimil 0:428cf9a51873 1157 p = n;
mimil 0:428cf9a51873 1158 }
mimil 0:428cf9a51873 1159 return a;
mimil 0:428cf9a51873 1160 }
mimil 0:428cf9a51873 1161
mimil 0:428cf9a51873 1162 void
mimil 0:428cf9a51873 1163 aJsonClass::addNullToObject(aJsonObject* object, const char* name)
mimil 0:428cf9a51873 1164 {
mimil 0:428cf9a51873 1165 addItemToObject(object, name, createNull());
mimil 0:428cf9a51873 1166 }
mimil 0:428cf9a51873 1167
mimil 0:428cf9a51873 1168 void
mimil 0:428cf9a51873 1169 aJsonClass::addTrueToObject(aJsonObject* object, const char* name)
mimil 0:428cf9a51873 1170 {
mimil 0:428cf9a51873 1171 addItemToObject(object, name, createTrue());
mimil 0:428cf9a51873 1172 }
mimil 0:428cf9a51873 1173
mimil 0:428cf9a51873 1174 void
mimil 0:428cf9a51873 1175 aJsonClass::addFalseToObject(aJsonObject* object, const char* name)
mimil 0:428cf9a51873 1176 {
mimil 0:428cf9a51873 1177 addItemToObject(object, name, createFalse());
mimil 0:428cf9a51873 1178 }
mimil 0:428cf9a51873 1179
mimil 0:428cf9a51873 1180 void
mimil 0:428cf9a51873 1181 aJsonClass::addNumberToObject(aJsonObject* object, const char* name, int n)
mimil 0:428cf9a51873 1182 {
mimil 0:428cf9a51873 1183 addItemToObject(object, name, createItem(n));
mimil 0:428cf9a51873 1184 }
mimil 0:428cf9a51873 1185
mimil 0:428cf9a51873 1186 void
mimil 0:428cf9a51873 1187 aJsonClass::addNumberToObject(aJsonObject* object, const char* name, double n)
mimil 0:428cf9a51873 1188 {
mimil 0:428cf9a51873 1189 addItemToObject(object, name, createItem(n));
mimil 0:428cf9a51873 1190 }
mimil 0:428cf9a51873 1191
mimil 0:428cf9a51873 1192 void
mimil 0:428cf9a51873 1193 aJsonClass::addStringToObject(aJsonObject* object, const char* name,
mimil 0:428cf9a51873 1194 const char* s)
mimil 0:428cf9a51873 1195 {
mimil 0:428cf9a51873 1196 addItemToObject(object, name, createItem(s));
mimil 0:428cf9a51873 1197 }
mimil 0:428cf9a51873 1198
mimil 0:428cf9a51873 1199 //TODO conversion routines btw. float & int types?
mimil 0:428cf9a51873 1200
mimil 0:428cf9a51873 1201 aJsonClass aJson;