source: rtos_arduino/trunk/arduino_lib/libraries/Milkcocoa_Arduino_SDK/aJSON.cpp@ 144

Last change on this file since 144 was 144, checked in by ertl-honda, 8 years ago

Milkcocoa用のMQTTライブラリの追加と,ESP8266用ライブラリの名称変更.

File size: 26.4 KB
Line 
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
59bool
60aJsonStream::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
77int
78aJsonStream::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
95void
96aJsonStream::ungetch(char ch)
97{
98 bucket = ch;
99}
100
101size_t
102aJsonStream::write(uint8_t ch)
103{
104 return stream()->write(ch);
105}
106
107size_t
108aJsonStream::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
123int
124aJsonClientStream::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
141bool
142aJsonStringStream::available()
143{
144 if (bucket != EOF)
145 return true;
146 return inbuf_len > 0;
147}
148
149int
150aJsonStringStream::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
167size_t
168aJsonStringStream::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.
181aJsonObject*
182aJsonClass::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.
191void
192aJsonClass::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.
216int
217aJsonStream::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.
300int
301aJsonStream::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
311int
312aJsonStream::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.
348int
349aJsonStream::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.
434int
435aJsonStream::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.
489int
490aJsonStream::printString(aJsonObject *item)
491{
492 return this->printStringPtr(item->valuestring);
493}
494
495// Utility to jump whitespace and cr/lf
496int
497aJsonStream::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.
515int
516aJsonStream::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.
528aJsonObject*
529aJsonClass::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.
537aJsonObject*
538aJsonClass::parse(aJsonStream* stream)
539{
540 return parse(stream, NULL);
541}
542
543// Parse an object - create a new root, and populate.
544aJsonObject*
545aJsonClass::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.
565int
566aJsonClass::print(aJsonObject* item, aJsonStream* stream)
567{
568 return stream->printValue(item);
569}
570
571char*
572aJsonClass::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.
585int
586aJsonStream::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.
672int
673aJsonStream::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.
714int
715aJsonStream::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
772int
773aJsonStream::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.
808int
809aJsonStream::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.
883int
884aJsonStream::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.
927unsigned char
928aJsonClass::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}
936aJsonObject*
937aJsonClass::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}
944aJsonObject*
945aJsonClass::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.
954void
955aJsonClass::suffixObject(aJsonObject *prev, aJsonObject *item)
956{
957 prev->next = item;
958 item->prev = prev;
959}
960// Utility for handling references.
961aJsonObject*
962aJsonClass::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.
975void
976aJsonClass::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}
992void
993aJsonClass::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}
1003void
1004aJsonClass::addItemReferenceToArray(aJsonObject *array, aJsonObject *item)
1005{
1006 addItemToArray(array, createReference(item));
1007}
1008void
1009aJsonClass::addItemReferenceToObject(aJsonObject *object, const char *string,
1010 aJsonObject *item)
1011{
1012 addItemToObject(object, string, createReference(item));
1013}
1014
1015aJsonObject*
1016aJsonClass::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}
1032void
1033aJsonClass::deleteItemFromArray(aJsonObject *array, unsigned char which)
1034{
1035 deleteItem(detachItemFromArray(array, which));
1036}
1037aJsonObject*
1038aJsonClass::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}
1048void
1049aJsonClass::deleteItemFromObject(aJsonObject *object, const char *string)
1050{
1051 deleteItem(detachItemFromObject(object, string));
1052}
1053
1054// Replace array/object items with new ones.
1055void
1056aJsonClass::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}
1075void
1076aJsonClass::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:
1091aJsonObject*
1092aJsonClass::createNull()
1093{
1094 aJsonObject *item = newItem();
1095 if (item)
1096 item->type = aJson_NULL;
1097 return item;
1098}
1099
1100aJsonObject*
1101aJsonClass::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
1112aJsonObject*
1113aJsonClass::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
1124aJsonObject*
1125aJsonClass::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
1136aJsonObject*
1137aJsonClass::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
1148aJsonObject*
1149aJsonClass::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
1160aJsonObject*
1161aJsonClass::createArray()
1162{
1163 aJsonObject *item = newItem();
1164 if (item)
1165 item->type = aJson_Array;
1166 return item;
1167}
1168aJsonObject*
1169aJsonClass::createObject()
1170{
1171 aJsonObject *item = newItem();
1172 if (item)
1173 item->type = aJson_Object;
1174 return item;
1175}
1176
1177// Create Arrays:
1178aJsonObject*
1179aJsonClass::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
1195aJsonObject*
1196aJsonClass::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
1212aJsonObject*
1213aJsonClass::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
1229aJsonObject*
1230aJsonClass::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
1246void
1247aJsonClass::addNullToObject(aJsonObject* object, const char* name)
1248{
1249 addItemToObject(object, name, createNull());
1250}
1251
1252void
1253aJsonClass::addBooleanToObject(aJsonObject* object, const char* name, bool b)
1254{
1255 addItemToObject(object, name, createItem(b));
1256}
1257
1258void
1259aJsonClass::addNumberToObject(aJsonObject* object, const char* name, int n)
1260{
1261 addItemToObject(object, name, createItem(n));
1262}
1263
1264void
1265aJsonClass::addNumberToObject(aJsonObject* object, const char* name, double n)
1266{
1267 addItemToObject(object, name, createItem(n));
1268}
1269
1270void
1271aJsonClass::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
1279aJsonClass aJson;
Note: See TracBrowser for help on using the repository browser.