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