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