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