Everything Example

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of TCPEthernet by Artur Lachowicz

Committer:
lachu
Date:
Tue Jan 24 22:17:00 2017 +0000
Revision:
9:b08a28f659eb
Working Program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lachu 9:b08a28f659eb 1 /*
lachu 9:b08a28f659eb 2 * (c) Copyright 2012 EVRYTHNG Ltd London / Zurich
lachu 9:b08a28f659eb 3 * www.evrythng.com
lachu 9:b08a28f659eb 4 *
lachu 9:b08a28f659eb 5 * --- DISCLAIMER ---
lachu 9:b08a28f659eb 6 *
lachu 9:b08a28f659eb 7 * EVRYTHNG provides this source code "as is" and without warranty of any kind,
lachu 9:b08a28f659eb 8 * and hereby disclaims all express or implied warranties, including without
lachu 9:b08a28f659eb 9 * limitation warranties of merchantability, fitness for a particular purpose,
lachu 9:b08a28f659eb 10 * performance, accuracy, reliability, and non-infringement.
lachu 9:b08a28f659eb 11 *
lachu 9:b08a28f659eb 12 * Author: Michel Yerly
lachu 9:b08a28f659eb 13 *
lachu 9:b08a28f659eb 14 */
lachu 9:b08a28f659eb 15 #include "JsonParser.h"
lachu 9:b08a28f659eb 16 #include "string.h"
lachu 9:b08a28f659eb 17 #include "stdlib.h"
lachu 9:b08a28f659eb 18 #include "errno.h"
lachu 9:b08a28f659eb 19 #include "util.h"
lachu 9:b08a28f659eb 20
lachu 9:b08a28f659eb 21 //#define DEBUG_JSONTOKENIZER
lachu 9:b08a28f659eb 22 //#define DEBUG_JSONPARSER
lachu 9:b08a28f659eb 23 //#define DEBUG_JSONGET
lachu 9:b08a28f659eb 24
lachu 9:b08a28f659eb 25 using namespace std;
lachu 9:b08a28f659eb 26
lachu 9:b08a28f659eb 27 bool isDigit(char c)
lachu 9:b08a28f659eb 28 {
lachu 9:b08a28f659eb 29 return c >= '0' && c <= '9';
lachu 9:b08a28f659eb 30 }
lachu 9:b08a28f659eb 31
lachu 9:b08a28f659eb 32 JsonParser::JsonParser()
lachu 9:b08a28f659eb 33 {
lachu 9:b08a28f659eb 34 this->pDocument = NULL;
lachu 9:b08a28f659eb 35 }
lachu 9:b08a28f659eb 36
lachu 9:b08a28f659eb 37 JsonParser::~JsonParser()
lachu 9:b08a28f659eb 38 {
lachu 9:b08a28f659eb 39 if (this->pDocument) {
lachu 9:b08a28f659eb 40 delete this->pDocument;
lachu 9:b08a28f659eb 41 }
lachu 9:b08a28f659eb 42 }
lachu 9:b08a28f659eb 43
lachu 9:b08a28f659eb 44 int JsonParser::parse(const char* json)
lachu 9:b08a28f659eb 45 {
lachu 9:b08a28f659eb 46 this->json = json;
lachu 9:b08a28f659eb 47 this->json_len = strlen(json);
lachu 9:b08a28f659eb 48
lachu 9:b08a28f659eb 49 if (this->pDocument) {
lachu 9:b08a28f659eb 50 delete this->pDocument;
lachu 9:b08a28f659eb 51 this->pDocument = NULL;
lachu 9:b08a28f659eb 52 }
lachu 9:b08a28f659eb 53
lachu 9:b08a28f659eb 54 ctPos = 0;
lachu 9:b08a28f659eb 55 ctLen = 0;
lachu 9:b08a28f659eb 56 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 57 bool ok = true;
lachu 9:b08a28f659eb 58 if (json[ctPos] == '{') {
lachu 9:b08a28f659eb 59 if (parseObject(&pDocument) != 0) {
lachu 9:b08a28f659eb 60 ok = false;
lachu 9:b08a28f659eb 61 }
lachu 9:b08a28f659eb 62 } else {
lachu 9:b08a28f659eb 63 if (parseArray(&pDocument) != 0) ok = false;
lachu 9:b08a28f659eb 64 }
lachu 9:b08a28f659eb 65 if (ct != TOKEN_EOS) {
lachu 9:b08a28f659eb 66 ok = false;
lachu 9:b08a28f659eb 67 }
lachu 9:b08a28f659eb 68
lachu 9:b08a28f659eb 69 if (!ok) {
lachu 9:b08a28f659eb 70 delete pDocument;
lachu 9:b08a28f659eb 71 pDocument = NULL;
lachu 9:b08a28f659eb 72 return -1;
lachu 9:b08a28f659eb 73 }
lachu 9:b08a28f659eb 74
lachu 9:b08a28f659eb 75 return 0;
lachu 9:b08a28f659eb 76 }
lachu 9:b08a28f659eb 77
lachu 9:b08a28f659eb 78 JsonValue* JsonParser::getDocument()
lachu 9:b08a28f659eb 79 {
lachu 9:b08a28f659eb 80 return pDocument;
lachu 9:b08a28f659eb 81 }
lachu 9:b08a28f659eb 82
lachu 9:b08a28f659eb 83 int JsonParser::goToNextToken()
lachu 9:b08a28f659eb 84 {
lachu 9:b08a28f659eb 85
lachu 9:b08a28f659eb 86 #ifdef DEBUG_JSONTOKENIZER
lachu 9:b08a28f659eb 87
lachu 9:b08a28f659eb 88 dbg.printf("Token: ");
lachu 9:b08a28f659eb 89
lachu 9:b08a28f659eb 90 #endif
lachu 9:b08a28f659eb 91
lachu 9:b08a28f659eb 92 ctPos += ctLen;
lachu 9:b08a28f659eb 93
lachu 9:b08a28f659eb 94 // Skip whitespaces
lachu 9:b08a28f659eb 95 while (ctPos < json_len &&
lachu 9:b08a28f659eb 96 (json[ctPos] == ' ' || json[ctPos] == '\t' ||
lachu 9:b08a28f659eb 97 json[ctPos] == '\r' || json[ctPos] == '\n'))
lachu 9:b08a28f659eb 98 ++ctPos;
lachu 9:b08a28f659eb 99
lachu 9:b08a28f659eb 100 if (ctPos < json_len) {
lachu 9:b08a28f659eb 101 if (json[ctPos] == '"') {
lachu 9:b08a28f659eb 102 ct = TOKEN_STRING;
lachu 9:b08a28f659eb 103 int i = ctPos+1;
lachu 9:b08a28f659eb 104 while (i < json_len && json[i] != '"') {
lachu 9:b08a28f659eb 105 if (json[i] == '\\') {
lachu 9:b08a28f659eb 106 if (i+1 < json_len) {
lachu 9:b08a28f659eb 107 switch (json[i+1]) {
lachu 9:b08a28f659eb 108 case '\\':
lachu 9:b08a28f659eb 109 case '"':
lachu 9:b08a28f659eb 110 case '/':
lachu 9:b08a28f659eb 111 case 'b':
lachu 9:b08a28f659eb 112 case 'f':
lachu 9:b08a28f659eb 113 case 'n':
lachu 9:b08a28f659eb 114 case 'r':
lachu 9:b08a28f659eb 115 case 't':
lachu 9:b08a28f659eb 116 ++i;
lachu 9:b08a28f659eb 117 break;
lachu 9:b08a28f659eb 118 case 'u':
lachu 9:b08a28f659eb 119 i+= 5;
lachu 9:b08a28f659eb 120 break;
lachu 9:b08a28f659eb 121 default:
lachu 9:b08a28f659eb 122 return -1;
lachu 9:b08a28f659eb 123 }
lachu 9:b08a28f659eb 124 } else {
lachu 9:b08a28f659eb 125 return -1;
lachu 9:b08a28f659eb 126 }
lachu 9:b08a28f659eb 127 }
lachu 9:b08a28f659eb 128 ++i;
lachu 9:b08a28f659eb 129 }
lachu 9:b08a28f659eb 130 if (i >= json_len || json[i] != '"') return -1;
lachu 9:b08a28f659eb 131 ctLen = i - ctPos + 1;
lachu 9:b08a28f659eb 132 } else if (isDigit(json[ctPos]) || json[ctPos] == '-') {
lachu 9:b08a28f659eb 133 ct = TOKEN_NUMBER;
lachu 9:b08a28f659eb 134 char* e;
lachu 9:b08a28f659eb 135 errno = 0;
lachu 9:b08a28f659eb 136 ctNumberVal = strtod(json+ctPos, &e);
lachu 9:b08a28f659eb 137 if (errno || e - json <= 0) return -1;
lachu 9:b08a28f659eb 138 ctLen = (e - json) - ctPos;
lachu 9:b08a28f659eb 139
lachu 9:b08a28f659eb 140 } else if (strncmp(json+ctPos,"true",4) == 0) {
lachu 9:b08a28f659eb 141 ct = TOKEN_TRUE;
lachu 9:b08a28f659eb 142 ctLen = 4;
lachu 9:b08a28f659eb 143 } else if (strncmp(json+ctPos,"false",5) == 0) {
lachu 9:b08a28f659eb 144 ct = TOKEN_FALSE;
lachu 9:b08a28f659eb 145 ctLen = 5;
lachu 9:b08a28f659eb 146 } else if (strncmp(json+ctPos,"null",4) == 0) {
lachu 9:b08a28f659eb 147 ct = TOKEN_NULL;
lachu 9:b08a28f659eb 148 ctLen = 4;
lachu 9:b08a28f659eb 149 } else {
lachu 9:b08a28f659eb 150 ct = TOKEN_DELIMITER;
lachu 9:b08a28f659eb 151 ctLen = 1;
lachu 9:b08a28f659eb 152 }
lachu 9:b08a28f659eb 153 } else {
lachu 9:b08a28f659eb 154 ct = TOKEN_EOS;
lachu 9:b08a28f659eb 155 ctLen = 0;
lachu 9:b08a28f659eb 156 }
lachu 9:b08a28f659eb 157
lachu 9:b08a28f659eb 158 #ifdef DEBUG_JSONTOKENIZER
lachu 9:b08a28f659eb 159
lachu 9:b08a28f659eb 160 switch (ct) {
lachu 9:b08a28f659eb 161 case TOKEN_DELIMITER:
lachu 9:b08a28f659eb 162 dbg.printf("Delimtier - ");
lachu 9:b08a28f659eb 163 break;
lachu 9:b08a28f659eb 164 case TOKEN_EOS:
lachu 9:b08a28f659eb 165 dbg.printf("End of stream");
lachu 9:b08a28f659eb 166 break;
lachu 9:b08a28f659eb 167 case TOKEN_NUMBER:
lachu 9:b08a28f659eb 168 dbg.printf("Number %g - ", ctNumberVal);
lachu 9:b08a28f659eb 169 break;
lachu 9:b08a28f659eb 170 case TOKEN_STRING:
lachu 9:b08a28f659eb 171 dbg.printf("String - ");
lachu 9:b08a28f659eb 172 break;
lachu 9:b08a28f659eb 173 case TOKEN_FALSE:
lachu 9:b08a28f659eb 174 dbg.printf("False - ");
lachu 9:b08a28f659eb 175 break;
lachu 9:b08a28f659eb 176 case TOKEN_TRUE:
lachu 9:b08a28f659eb 177 dbg.printf("True - ");
lachu 9:b08a28f659eb 178 break;
lachu 9:b08a28f659eb 179 case TOKEN_NULL:
lachu 9:b08a28f659eb 180 dbg.printf("Null - ");
lachu 9:b08a28f659eb 181 break;
lachu 9:b08a28f659eb 182 }
lachu 9:b08a28f659eb 183 if (ct != TOKEN_EOS) {
lachu 9:b08a28f659eb 184 for (int i = 0; i < ctLen; ++i)
lachu 9:b08a28f659eb 185 dbg.printf("%c", json[ctPos+i]);
lachu 9:b08a28f659eb 186 }
lachu 9:b08a28f659eb 187 dbg.printf(" (%d,%d)\r\n", ctPos, ctLen);
lachu 9:b08a28f659eb 188
lachu 9:b08a28f659eb 189 #endif
lachu 9:b08a28f659eb 190
lachu 9:b08a28f659eb 191 return 0;
lachu 9:b08a28f659eb 192 }
lachu 9:b08a28f659eb 193
lachu 9:b08a28f659eb 194 int JsonParser::parseObject(JsonValue** object)
lachu 9:b08a28f659eb 195 {
lachu 9:b08a28f659eb 196
lachu 9:b08a28f659eb 197 #ifdef DEBUG_JSONPARSER
lachu 9:b08a28f659eb 198 dbg.printf("Enter parseObject\r\n");
lachu 9:b08a28f659eb 199 #endif
lachu 9:b08a28f659eb 200
lachu 9:b08a28f659eb 201 *object = JsonValue::createMap();
lachu 9:b08a28f659eb 202 map<string,JsonValue*>* m = (*object)->value.map;
lachu 9:b08a28f659eb 203
lachu 9:b08a28f659eb 204 if (ct != TOKEN_DELIMITER || json[ctPos] != '{') return -1;
lachu 9:b08a28f659eb 205 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 206
lachu 9:b08a28f659eb 207 if (ct == TOKEN_STRING) {
lachu 9:b08a28f659eb 208
lachu 9:b08a28f659eb 209 string key;
lachu 9:b08a28f659eb 210 key.assign(json+ctPos+1, ctLen-2);
lachu 9:b08a28f659eb 211
lachu 9:b08a28f659eb 212 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 213
lachu 9:b08a28f659eb 214 if (ct != TOKEN_DELIMITER || json[ctPos] != ':') return -1;
lachu 9:b08a28f659eb 215 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 216
lachu 9:b08a28f659eb 217 JsonValue* pValue;
lachu 9:b08a28f659eb 218 if (parseValue(&pValue) != 0) {
lachu 9:b08a28f659eb 219 delete pValue;
lachu 9:b08a28f659eb 220 return -1;
lachu 9:b08a28f659eb 221 }
lachu 9:b08a28f659eb 222 (*m)[key] = pValue;
lachu 9:b08a28f659eb 223
lachu 9:b08a28f659eb 224 while (ct == TOKEN_DELIMITER && json[ctPos] == ',') {
lachu 9:b08a28f659eb 225 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 226
lachu 9:b08a28f659eb 227 if (ct != TOKEN_STRING) return -1;
lachu 9:b08a28f659eb 228 key.assign(json+ctPos+1, ctLen-2);
lachu 9:b08a28f659eb 229 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 230
lachu 9:b08a28f659eb 231 if (ct != TOKEN_DELIMITER || json[ctPos] != ':') return -1;
lachu 9:b08a28f659eb 232 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 233
lachu 9:b08a28f659eb 234 if (parseValue(&pValue) != 0) {
lachu 9:b08a28f659eb 235 delete pValue;
lachu 9:b08a28f659eb 236 return -1;
lachu 9:b08a28f659eb 237 }
lachu 9:b08a28f659eb 238 (*m)[key] = pValue;
lachu 9:b08a28f659eb 239 }
lachu 9:b08a28f659eb 240 }
lachu 9:b08a28f659eb 241
lachu 9:b08a28f659eb 242 if (ct != TOKEN_DELIMITER || json[ctPos] != '}') return -1;
lachu 9:b08a28f659eb 243 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 244
lachu 9:b08a28f659eb 245 #ifdef DEBUG_JSONPARSER
lachu 9:b08a28f659eb 246 dbg.printf("Exit parseObject\r\n");
lachu 9:b08a28f659eb 247 #endif
lachu 9:b08a28f659eb 248 return 0;
lachu 9:b08a28f659eb 249 }
lachu 9:b08a28f659eb 250
lachu 9:b08a28f659eb 251 int JsonParser::parseValue(JsonValue** value)
lachu 9:b08a28f659eb 252 {
lachu 9:b08a28f659eb 253
lachu 9:b08a28f659eb 254 #ifdef DEBUG_JSONPARSER
lachu 9:b08a28f659eb 255 dbg.printf("Enter parseValue\r\n");
lachu 9:b08a28f659eb 256 #endif
lachu 9:b08a28f659eb 257
lachu 9:b08a28f659eb 258 switch (ct) {
lachu 9:b08a28f659eb 259 case TOKEN_STRING:
lachu 9:b08a28f659eb 260 *value = JsonValue::createString(json+ctPos+1,ctLen-2);
lachu 9:b08a28f659eb 261 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 262 break;
lachu 9:b08a28f659eb 263 case TOKEN_NUMBER:
lachu 9:b08a28f659eb 264 *value = JsonValue::createDouble(ctNumberVal);
lachu 9:b08a28f659eb 265 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 266 break;
lachu 9:b08a28f659eb 267 case TOKEN_NULL:
lachu 9:b08a28f659eb 268 *value = JsonValue::createNull();
lachu 9:b08a28f659eb 269 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 270 break;
lachu 9:b08a28f659eb 271 case TOKEN_FALSE:
lachu 9:b08a28f659eb 272 *value = JsonValue::createBoolean(false);
lachu 9:b08a28f659eb 273 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 274 break;
lachu 9:b08a28f659eb 275 case TOKEN_TRUE:
lachu 9:b08a28f659eb 276 *value = JsonValue::createBoolean(true);
lachu 9:b08a28f659eb 277 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 278 break;
lachu 9:b08a28f659eb 279 case TOKEN_DELIMITER:
lachu 9:b08a28f659eb 280 if (json[ctPos] == '{') {
lachu 9:b08a28f659eb 281 if (parseObject(value) != 0) return -1;
lachu 9:b08a28f659eb 282 } else if (json[ctPos] == '[') {
lachu 9:b08a28f659eb 283 if (parseArray(value) != 0) return -1;
lachu 9:b08a28f659eb 284 }
lachu 9:b08a28f659eb 285 break;
lachu 9:b08a28f659eb 286 default:
lachu 9:b08a28f659eb 287 *value = JsonValue::createNull();
lachu 9:b08a28f659eb 288 return -1;
lachu 9:b08a28f659eb 289 }
lachu 9:b08a28f659eb 290
lachu 9:b08a28f659eb 291 #ifdef DEBUG_JSONPARSER
lachu 9:b08a28f659eb 292 dbg.printf("Exit parseValue\r\n");
lachu 9:b08a28f659eb 293 #endif
lachu 9:b08a28f659eb 294
lachu 9:b08a28f659eb 295 return 0;
lachu 9:b08a28f659eb 296 }
lachu 9:b08a28f659eb 297
lachu 9:b08a28f659eb 298 int JsonParser::parseArray(JsonValue** array)
lachu 9:b08a28f659eb 299 {
lachu 9:b08a28f659eb 300
lachu 9:b08a28f659eb 301 #ifdef DEBUG_JSONPARSER
lachu 9:b08a28f659eb 302 dbg.printf("Enter parseArray\r\n");
lachu 9:b08a28f659eb 303 #endif
lachu 9:b08a28f659eb 304
lachu 9:b08a28f659eb 305 *array = JsonValue::createVector();
lachu 9:b08a28f659eb 306 vector<JsonValue*>* vec = (*array)->value.vec;
lachu 9:b08a28f659eb 307
lachu 9:b08a28f659eb 308 if (ct != TOKEN_DELIMITER || json[ctPos] != '[') return -1;
lachu 9:b08a28f659eb 309 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 310
lachu 9:b08a28f659eb 311 if (ct != TOKEN_DELIMITER || json[ctPos] != ']') {
lachu 9:b08a28f659eb 312
lachu 9:b08a28f659eb 313 JsonValue* pValue;
lachu 9:b08a28f659eb 314 if (parseValue(&pValue) != 0) {
lachu 9:b08a28f659eb 315 delete pValue;
lachu 9:b08a28f659eb 316 return -1;
lachu 9:b08a28f659eb 317 };
lachu 9:b08a28f659eb 318 vec->push_back(pValue);
lachu 9:b08a28f659eb 319
lachu 9:b08a28f659eb 320 while (ct == TOKEN_DELIMITER && json[ctPos] == ',') {
lachu 9:b08a28f659eb 321 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 322
lachu 9:b08a28f659eb 323 if (parseValue(&pValue) != 0) {
lachu 9:b08a28f659eb 324 delete pValue;
lachu 9:b08a28f659eb 325 return -1;
lachu 9:b08a28f659eb 326 };
lachu 9:b08a28f659eb 327 vec->push_back(pValue);
lachu 9:b08a28f659eb 328 }
lachu 9:b08a28f659eb 329 }
lachu 9:b08a28f659eb 330
lachu 9:b08a28f659eb 331 if (ct != TOKEN_DELIMITER || json[ctPos] != ']') return -1;
lachu 9:b08a28f659eb 332 if (goToNextToken() != 0) return -1;
lachu 9:b08a28f659eb 333
lachu 9:b08a28f659eb 334 #ifdef DEBUG_JSONPARSER
lachu 9:b08a28f659eb 335 dbg.printf("Exit parseArray\r\n");
lachu 9:b08a28f659eb 336 #endif
lachu 9:b08a28f659eb 337
lachu 9:b08a28f659eb 338 return 0;
lachu 9:b08a28f659eb 339 }
lachu 9:b08a28f659eb 340
lachu 9:b08a28f659eb 341 int inst = 0;
lachu 9:b08a28f659eb 342
lachu 9:b08a28f659eb 343 JsonValue::JsonValue(const char* buffer, int len)
lachu 9:b08a28f659eb 344 {
lachu 9:b08a28f659eb 345 type = VT_CHAR_PTR;
lachu 9:b08a28f659eb 346 value.s = new char[len+1];
lachu 9:b08a28f659eb 347 strncpy(value.s, buffer, len);
lachu 9:b08a28f659eb 348 value.s[len] = '\0';
lachu 9:b08a28f659eb 349 }
lachu 9:b08a28f659eb 350
lachu 9:b08a28f659eb 351 JsonValue::JsonValue(double d)
lachu 9:b08a28f659eb 352 {
lachu 9:b08a28f659eb 353 type = VT_DOUBLE;
lachu 9:b08a28f659eb 354 value.d = d;
lachu 9:b08a28f659eb 355 }
lachu 9:b08a28f659eb 356
lachu 9:b08a28f659eb 357 JsonValue::JsonValue(bool b)
lachu 9:b08a28f659eb 358 {
lachu 9:b08a28f659eb 359 type = b ? VT_CST_TRUE : VT_CST_FALSE;
lachu 9:b08a28f659eb 360
lachu 9:b08a28f659eb 361 }
lachu 9:b08a28f659eb 362
lachu 9:b08a28f659eb 363 JsonValue::JsonValue()
lachu 9:b08a28f659eb 364 {
lachu 9:b08a28f659eb 365 }
lachu 9:b08a28f659eb 366
lachu 9:b08a28f659eb 367 JsonValue::~JsonValue()
lachu 9:b08a28f659eb 368 {
lachu 9:b08a28f659eb 369 switch (type) {
lachu 9:b08a28f659eb 370 case VT_CHAR_PTR:
lachu 9:b08a28f659eb 371 delete[] value.s;
lachu 9:b08a28f659eb 372 break;
lachu 9:b08a28f659eb 373 case VT_MAP_PTR:
lachu 9:b08a28f659eb 374 for (map<string,JsonValue*>::iterator itr = value.map->begin(); itr != value.map->end(); itr++)
lachu 9:b08a28f659eb 375 delete ((*itr).second);
lachu 9:b08a28f659eb 376 delete value.map;
lachu 9:b08a28f659eb 377 break;
lachu 9:b08a28f659eb 378 case VT_VEC_PTR:
lachu 9:b08a28f659eb 379 for (vector<JsonValue*>::iterator itr = value.vec->begin(); itr != value.vec->end(); itr++)
lachu 9:b08a28f659eb 380 delete (*itr);
lachu 9:b08a28f659eb 381 delete value.vec;
lachu 9:b08a28f659eb 382 break;
lachu 9:b08a28f659eb 383 default:
lachu 9:b08a28f659eb 384 break;
lachu 9:b08a28f659eb 385 }
lachu 9:b08a28f659eb 386 }
lachu 9:b08a28f659eb 387
lachu 9:b08a28f659eb 388 JsonValue* JsonValue::createString(const char* buffer, int len)
lachu 9:b08a28f659eb 389 {
lachu 9:b08a28f659eb 390 return new JsonValue(buffer, len);
lachu 9:b08a28f659eb 391 }
lachu 9:b08a28f659eb 392
lachu 9:b08a28f659eb 393 JsonValue* JsonValue::createDouble(double d)
lachu 9:b08a28f659eb 394 {
lachu 9:b08a28f659eb 395 return new JsonValue(d);
lachu 9:b08a28f659eb 396 }
lachu 9:b08a28f659eb 397
lachu 9:b08a28f659eb 398 JsonValue* JsonValue::createBoolean(bool b)
lachu 9:b08a28f659eb 399 {
lachu 9:b08a28f659eb 400 return new JsonValue(b);
lachu 9:b08a28f659eb 401 }
lachu 9:b08a28f659eb 402
lachu 9:b08a28f659eb 403 JsonValue* JsonValue::createMap()
lachu 9:b08a28f659eb 404 {
lachu 9:b08a28f659eb 405 JsonValue* ret = new JsonValue();
lachu 9:b08a28f659eb 406 ret->type = VT_MAP_PTR;
lachu 9:b08a28f659eb 407 ret->value.map = new map<string,JsonValue*>();
lachu 9:b08a28f659eb 408 return ret;
lachu 9:b08a28f659eb 409 }
lachu 9:b08a28f659eb 410
lachu 9:b08a28f659eb 411 JsonValue* JsonValue::createVector()
lachu 9:b08a28f659eb 412 {
lachu 9:b08a28f659eb 413 JsonValue* ret = new JsonValue();
lachu 9:b08a28f659eb 414 ret->type = VT_VEC_PTR;
lachu 9:b08a28f659eb 415 ret->value.vec = new vector<JsonValue*>();
lachu 9:b08a28f659eb 416 return ret;
lachu 9:b08a28f659eb 417 }
lachu 9:b08a28f659eb 418
lachu 9:b08a28f659eb 419 JsonValue* JsonValue::createNull()
lachu 9:b08a28f659eb 420 {
lachu 9:b08a28f659eb 421 JsonValue* ret = new JsonValue();
lachu 9:b08a28f659eb 422 ret->type = VT_CST_NULL;
lachu 9:b08a28f659eb 423 return ret;
lachu 9:b08a28f659eb 424 }
lachu 9:b08a28f659eb 425
lachu 9:b08a28f659eb 426 void JsonValue::print()
lachu 9:b08a28f659eb 427 {
lachu 9:b08a28f659eb 428 bool c = false;
lachu 9:b08a28f659eb 429 switch (type) {
lachu 9:b08a28f659eb 430 case VT_CHAR_PTR:
lachu 9:b08a28f659eb 431 dbg.printf("\"%s\"", value.s);
lachu 9:b08a28f659eb 432 break;
lachu 9:b08a28f659eb 433 case VT_MAP_PTR:
lachu 9:b08a28f659eb 434 dbg.printf("{");
lachu 9:b08a28f659eb 435 for (map<string,JsonValue*>::iterator itr = value.map->begin(); itr != value.map->end(); itr++) {
lachu 9:b08a28f659eb 436 if (c) dbg.printf(",");
lachu 9:b08a28f659eb 437 else c = true;
lachu 9:b08a28f659eb 438 dbg.printf("\"%s\":",(*itr).first.c_str());
lachu 9:b08a28f659eb 439 (*itr).second->print();
lachu 9:b08a28f659eb 440 }
lachu 9:b08a28f659eb 441 dbg.printf("}");
lachu 9:b08a28f659eb 442 break;
lachu 9:b08a28f659eb 443 case VT_VEC_PTR:
lachu 9:b08a28f659eb 444 dbg.printf("[");
lachu 9:b08a28f659eb 445 for (vector<JsonValue*>::iterator itr = value.vec->begin(); itr != value.vec->end(); itr++) {
lachu 9:b08a28f659eb 446 if (c) dbg.printf(",");
lachu 9:b08a28f659eb 447 else c = true;
lachu 9:b08a28f659eb 448 (*itr)->print();
lachu 9:b08a28f659eb 449 }
lachu 9:b08a28f659eb 450 dbg.printf("]");
lachu 9:b08a28f659eb 451 break;
lachu 9:b08a28f659eb 452 case VT_DOUBLE:
lachu 9:b08a28f659eb 453 dbg.printf("%g", value.d);
lachu 9:b08a28f659eb 454 break;
lachu 9:b08a28f659eb 455 case VT_CST_TRUE:
lachu 9:b08a28f659eb 456 dbg.printf("true");
lachu 9:b08a28f659eb 457 break;
lachu 9:b08a28f659eb 458 case VT_CST_FALSE:
lachu 9:b08a28f659eb 459 dbg.printf("false");
lachu 9:b08a28f659eb 460 break;
lachu 9:b08a28f659eb 461 case VT_CST_NULL:
lachu 9:b08a28f659eb 462 dbg.printf("null");
lachu 9:b08a28f659eb 463 break;
lachu 9:b08a28f659eb 464 default:
lachu 9:b08a28f659eb 465 break;
lachu 9:b08a28f659eb 466 }
lachu 9:b08a28f659eb 467 }
lachu 9:b08a28f659eb 468
lachu 9:b08a28f659eb 469 JsonValue* JsonValue::get(const char* path)
lachu 9:b08a28f659eb 470 {
lachu 9:b08a28f659eb 471 JsonValue* pValue = this;
lachu 9:b08a28f659eb 472 int pos = 0;
lachu 9:b08a28f659eb 473 while (path != NULL && path[pos] != '\0') {
lachu 9:b08a28f659eb 474
lachu 9:b08a28f659eb 475 #ifdef DEBUG_JSONGET
lachu 9:b08a28f659eb 476 dbg.printf("::get ");
lachu 9:b08a28f659eb 477 pValue->print();
lachu 9:b08a28f659eb 478 dbg.printf("\r\n");
lachu 9:b08a28f659eb 479 #endif
lachu 9:b08a28f659eb 480
lachu 9:b08a28f659eb 481 const char* start = path+pos;
lachu 9:b08a28f659eb 482 const char* pSl = strchr(start, '/');
lachu 9:b08a28f659eb 483 int len = pSl == NULL ? strlen(start) : pSl - start;
lachu 9:b08a28f659eb 484 if (len <= 0) return NULL;
lachu 9:b08a28f659eb 485 if (pValue->type == VT_VEC_PTR) {
lachu 9:b08a28f659eb 486 int v = atoi(start);
lachu 9:b08a28f659eb 487 if (v == 0 && path[pos] != '0') {
lachu 9:b08a28f659eb 488 return NULL;
lachu 9:b08a28f659eb 489 }
lachu 9:b08a28f659eb 490 if (v < 0 || v >= pValue->value.vec->size()) {
lachu 9:b08a28f659eb 491 return NULL;
lachu 9:b08a28f659eb 492 }
lachu 9:b08a28f659eb 493 pValue = (*pValue->value.vec)[v];
lachu 9:b08a28f659eb 494 } else if (pValue->type == VT_MAP_PTR) {
lachu 9:b08a28f659eb 495 char* pKey = new char[len+1];
lachu 9:b08a28f659eb 496 strncpy(pKey, start, len);
lachu 9:b08a28f659eb 497 pKey[len] = '\0';
lachu 9:b08a28f659eb 498 pValue = (*pValue->value.map)[pKey];
lachu 9:b08a28f659eb 499 delete[] pKey;
lachu 9:b08a28f659eb 500 if (pValue == NULL) {
lachu 9:b08a28f659eb 501 return NULL;
lachu 9:b08a28f659eb 502 }
lachu 9:b08a28f659eb 503 } else {
lachu 9:b08a28f659eb 504 return NULL;
lachu 9:b08a28f659eb 505 }
lachu 9:b08a28f659eb 506 pos += len;
lachu 9:b08a28f659eb 507 if (pSl) ++pos;
lachu 9:b08a28f659eb 508 }
lachu 9:b08a28f659eb 509
lachu 9:b08a28f659eb 510 #ifdef DEBUG_JSONGET
lachu 9:b08a28f659eb 511 dbg.printf("::get ");
lachu 9:b08a28f659eb 512 pValue->print();
lachu 9:b08a28f659eb 513 dbg.printf("\r\n");
lachu 9:b08a28f659eb 514 #endif
lachu 9:b08a28f659eb 515
lachu 9:b08a28f659eb 516 return pValue;
lachu 9:b08a28f659eb 517 }
lachu 9:b08a28f659eb 518
lachu 9:b08a28f659eb 519 const double* JsonValue::getDouble(const char* path)
lachu 9:b08a28f659eb 520 {
lachu 9:b08a28f659eb 521 JsonValue* pV = get(path);
lachu 9:b08a28f659eb 522 if (pV != NULL && pV->type == VT_DOUBLE) {
lachu 9:b08a28f659eb 523 return &(pV->value.d);
lachu 9:b08a28f659eb 524 } else {
lachu 9:b08a28f659eb 525 return NULL;
lachu 9:b08a28f659eb 526 }
lachu 9:b08a28f659eb 527 }
lachu 9:b08a28f659eb 528
lachu 9:b08a28f659eb 529 const char* JsonValue::getString(const char* path)
lachu 9:b08a28f659eb 530 {
lachu 9:b08a28f659eb 531 JsonValue* pV = get(path);
lachu 9:b08a28f659eb 532 if (pV != NULL && pV->type == VT_CHAR_PTR) {
lachu 9:b08a28f659eb 533 return pV->value.s;
lachu 9:b08a28f659eb 534 } else {
lachu 9:b08a28f659eb 535 return NULL;
lachu 9:b08a28f659eb 536 }
lachu 9:b08a28f659eb 537 }
lachu 9:b08a28f659eb 538 const std::vector<JsonValue*>* JsonValue::getVector(const char* path)
lachu 9:b08a28f659eb 539 {
lachu 9:b08a28f659eb 540 JsonValue* pV = get(path);
lachu 9:b08a28f659eb 541 if (pV != NULL && pV->type == VT_VEC_PTR) {
lachu 9:b08a28f659eb 542 return pV->value.vec;
lachu 9:b08a28f659eb 543 } else {
lachu 9:b08a28f659eb 544 return NULL;
lachu 9:b08a28f659eb 545 }
lachu 9:b08a28f659eb 546 }
lachu 9:b08a28f659eb 547 const std::map<std::string,JsonValue*>* JsonValue::getMap(const char* path)
lachu 9:b08a28f659eb 548 {
lachu 9:b08a28f659eb 549 JsonValue* pV = get(path);
lachu 9:b08a28f659eb 550 if (pV != NULL && pV->type == VT_MAP_PTR) {
lachu 9:b08a28f659eb 551 return pV->value.map;
lachu 9:b08a28f659eb 552 } else {
lachu 9:b08a28f659eb 553 return NULL;
lachu 9:b08a28f659eb 554 }
lachu 9:b08a28f659eb 555 }
lachu 9:b08a28f659eb 556
lachu 9:b08a28f659eb 557 static const bool FALSE = false;
lachu 9:b08a28f659eb 558 static const bool TRUE = true;
lachu 9:b08a28f659eb 559
lachu 9:b08a28f659eb 560 const bool* JsonValue::getBoolean(const char* path)
lachu 9:b08a28f659eb 561 {
lachu 9:b08a28f659eb 562 JsonValue* pV = get(path);
lachu 9:b08a28f659eb 563 if (pV != NULL && (pV->type == VT_CST_TRUE || pV->type == VT_CST_FALSE)) {
lachu 9:b08a28f659eb 564 return (pV->type == VT_CST_TRUE) ? &TRUE : &FALSE;
lachu 9:b08a28f659eb 565 } else {
lachu 9:b08a28f659eb 566 return NULL;
lachu 9:b08a28f659eb 567 }
lachu 9:b08a28f659eb 568 }
lachu 9:b08a28f659eb 569 bool JsonValue::isNull(const char* path)
lachu 9:b08a28f659eb 570 {
lachu 9:b08a28f659eb 571 JsonValue* pV = get(path);
lachu 9:b08a28f659eb 572 return (pV != NULL) && (pV->type == VT_CST_NULL);
lachu 9:b08a28f659eb 573 }
lachu 9:b08a28f659eb 574