Api wrapper to communicate with EVRYTHNG's Engine.
Dependencies: EthernetInterface mbed-rtos
Dependents: EvrythngApiExample
JsonParser.cpp
00001 /* 00002 * (c) Copyright 2012 EVRYTHNG Ltd London / Zurich 00003 * www.evrythng.com 00004 * 00005 * --- DISCLAIMER --- 00006 * 00007 * EVRYTHNG provides this source code "as is" and without warranty of any kind, 00008 * and hereby disclaims all express or implied warranties, including without 00009 * limitation warranties of merchantability, fitness for a particular purpose, 00010 * performance, accuracy, reliability, and non-infringement. 00011 * 00012 * Author: Michel Yerly 00013 * 00014 */ 00015 #include "JsonParser.h" 00016 #include "string.h" 00017 #include "stdlib.h" 00018 #include "errno.h" 00019 #include "util.h" 00020 00021 //#define DEBUG_JSONTOKENIZER 00022 //#define DEBUG_JSONPARSER 00023 //#define DEBUG_JSONGET 00024 00025 using namespace std; 00026 00027 bool isDigit(char c) 00028 { 00029 return c >= '0' && c <= '9'; 00030 } 00031 00032 JsonParser::JsonParser() 00033 { 00034 this->pDocument = NULL; 00035 } 00036 00037 JsonParser::~JsonParser() 00038 { 00039 if (this->pDocument) { 00040 delete this->pDocument; 00041 } 00042 } 00043 00044 int JsonParser::parse(const char* json) 00045 { 00046 this->json = json; 00047 this->json_len = strlen(json); 00048 00049 if (this->pDocument) { 00050 delete this->pDocument; 00051 this->pDocument = NULL; 00052 } 00053 00054 ctPos = 0; 00055 ctLen = 0; 00056 if (goToNextToken() != 0) return -1; 00057 bool ok = true; 00058 if (json[ctPos] == '{') { 00059 if (parseObject(&pDocument) != 0) { 00060 ok = false; 00061 } 00062 } else { 00063 if (parseArray(&pDocument) != 0) ok = false; 00064 } 00065 if (ct != TOKEN_EOS) { 00066 ok = false; 00067 } 00068 00069 if (!ok) { 00070 delete pDocument; 00071 pDocument = NULL; 00072 return -1; 00073 } 00074 00075 return 0; 00076 } 00077 00078 JsonValue* JsonParser::getDocument() 00079 { 00080 return pDocument; 00081 } 00082 00083 int JsonParser::goToNextToken() 00084 { 00085 00086 #ifdef DEBUG_JSONTOKENIZER 00087 00088 dbg.printf("Token: "); 00089 00090 #endif 00091 00092 ctPos += ctLen; 00093 00094 // Skip whitespaces 00095 while (ctPos < json_len && 00096 (json[ctPos] == ' ' || json[ctPos] == '\t' || 00097 json[ctPos] == '\r' || json[ctPos] == '\n')) 00098 ++ctPos; 00099 00100 if (ctPos < json_len) { 00101 if (json[ctPos] == '"') { 00102 ct = TOKEN_STRING; 00103 int i = ctPos+1; 00104 while (i < json_len && json[i] != '"') { 00105 if (json[i] == '\\') { 00106 if (i+1 < json_len) { 00107 switch (json[i+1]) { 00108 case '\\': 00109 case '"': 00110 case '/': 00111 case 'b': 00112 case 'f': 00113 case 'n': 00114 case 'r': 00115 case 't': 00116 ++i; 00117 break; 00118 case 'u': 00119 i+= 5; 00120 break; 00121 default: 00122 return -1; 00123 } 00124 } else { 00125 return -1; 00126 } 00127 } 00128 ++i; 00129 } 00130 if (i >= json_len || json[i] != '"') return -1; 00131 ctLen = i - ctPos + 1; 00132 } else if (isDigit(json[ctPos]) || json[ctPos] == '-') { 00133 ct = TOKEN_NUMBER; 00134 char* e; 00135 errno = 0; 00136 ctNumberVal = strtod(json+ctPos, &e); 00137 if (errno || e - json <= 0) return -1; 00138 ctLen = (e - json) - ctPos; 00139 00140 } else if (strncmp(json+ctPos,"true",4) == 0) { 00141 ct = TOKEN_TRUE; 00142 ctLen = 4; 00143 } else if (strncmp(json+ctPos,"false",5) == 0) { 00144 ct = TOKEN_FALSE; 00145 ctLen = 5; 00146 } else if (strncmp(json+ctPos,"null",4) == 0) { 00147 ct = TOKEN_NULL; 00148 ctLen = 4; 00149 } else { 00150 ct = TOKEN_DELIMITER; 00151 ctLen = 1; 00152 } 00153 } else { 00154 ct = TOKEN_EOS; 00155 ctLen = 0; 00156 } 00157 00158 #ifdef DEBUG_JSONTOKENIZER 00159 00160 switch (ct) { 00161 case TOKEN_DELIMITER: 00162 dbg.printf("Delimtier - "); 00163 break; 00164 case TOKEN_EOS: 00165 dbg.printf("End of stream"); 00166 break; 00167 case TOKEN_NUMBER: 00168 dbg.printf("Number %g - ", ctNumberVal); 00169 break; 00170 case TOKEN_STRING: 00171 dbg.printf("String - "); 00172 break; 00173 case TOKEN_FALSE: 00174 dbg.printf("False - "); 00175 break; 00176 case TOKEN_TRUE: 00177 dbg.printf("True - "); 00178 break; 00179 case TOKEN_NULL: 00180 dbg.printf("Null - "); 00181 break; 00182 } 00183 if (ct != TOKEN_EOS) { 00184 for (int i = 0; i < ctLen; ++i) 00185 dbg.printf("%c", json[ctPos+i]); 00186 } 00187 dbg.printf(" (%d,%d)\r\n", ctPos, ctLen); 00188 00189 #endif 00190 00191 return 0; 00192 } 00193 00194 int JsonParser::parseObject(JsonValue** object) 00195 { 00196 00197 #ifdef DEBUG_JSONPARSER 00198 dbg.printf("Enter parseObject\r\n"); 00199 #endif 00200 00201 *object = JsonValue::createMap(); 00202 map<string,JsonValue*>* m = (*object)->value.map; 00203 00204 if (ct != TOKEN_DELIMITER || json[ctPos] != '{') return -1; 00205 if (goToNextToken() != 0) return -1; 00206 00207 if (ct == TOKEN_STRING) { 00208 00209 string key; 00210 key.assign(json+ctPos+1, ctLen-2); 00211 00212 if (goToNextToken() != 0) return -1; 00213 00214 if (ct != TOKEN_DELIMITER || json[ctPos] != ':') return -1; 00215 if (goToNextToken() != 0) return -1; 00216 00217 JsonValue* pValue; 00218 if (parseValue(&pValue) != 0) { 00219 delete pValue; 00220 return -1; 00221 } 00222 (*m)[key] = pValue; 00223 00224 while (ct == TOKEN_DELIMITER && json[ctPos] == ',') { 00225 if (goToNextToken() != 0) return -1; 00226 00227 if (ct != TOKEN_STRING) return -1; 00228 key.assign(json+ctPos+1, ctLen-2); 00229 if (goToNextToken() != 0) return -1; 00230 00231 if (ct != TOKEN_DELIMITER || json[ctPos] != ':') return -1; 00232 if (goToNextToken() != 0) return -1; 00233 00234 if (parseValue(&pValue) != 0) { 00235 delete pValue; 00236 return -1; 00237 } 00238 (*m)[key] = pValue; 00239 } 00240 } 00241 00242 if (ct != TOKEN_DELIMITER || json[ctPos] != '}') return -1; 00243 if (goToNextToken() != 0) return -1; 00244 00245 #ifdef DEBUG_JSONPARSER 00246 dbg.printf("Exit parseObject\r\n"); 00247 #endif 00248 return 0; 00249 } 00250 00251 int JsonParser::parseValue(JsonValue** value) 00252 { 00253 00254 #ifdef DEBUG_JSONPARSER 00255 dbg.printf("Enter parseValue\r\n"); 00256 #endif 00257 00258 switch (ct) { 00259 case TOKEN_STRING: 00260 *value = JsonValue::createString(json+ctPos+1,ctLen-2); 00261 if (goToNextToken() != 0) return -1; 00262 break; 00263 case TOKEN_NUMBER: 00264 *value = JsonValue::createDouble(ctNumberVal); 00265 if (goToNextToken() != 0) return -1; 00266 break; 00267 case TOKEN_NULL: 00268 *value = JsonValue::createNull(); 00269 if (goToNextToken() != 0) return -1; 00270 break; 00271 case TOKEN_FALSE: 00272 *value = JsonValue::createBoolean(false); 00273 if (goToNextToken() != 0) return -1; 00274 break; 00275 case TOKEN_TRUE: 00276 *value = JsonValue::createBoolean(true); 00277 if (goToNextToken() != 0) return -1; 00278 break; 00279 case TOKEN_DELIMITER: 00280 if (json[ctPos] == '{') { 00281 if (parseObject(value) != 0) return -1; 00282 } else if (json[ctPos] == '[') { 00283 if (parseArray(value) != 0) return -1; 00284 } 00285 break; 00286 default: 00287 *value = JsonValue::createNull(); 00288 return -1; 00289 } 00290 00291 #ifdef DEBUG_JSONPARSER 00292 dbg.printf("Exit parseValue\r\n"); 00293 #endif 00294 00295 return 0; 00296 } 00297 00298 int JsonParser::parseArray(JsonValue** array) 00299 { 00300 00301 #ifdef DEBUG_JSONPARSER 00302 dbg.printf("Enter parseArray\r\n"); 00303 #endif 00304 00305 *array = JsonValue::createVector(); 00306 vector<JsonValue*>* vec = (*array)->value.vec; 00307 00308 if (ct != TOKEN_DELIMITER || json[ctPos] != '[') return -1; 00309 if (goToNextToken() != 0) return -1; 00310 00311 if (ct != TOKEN_DELIMITER || json[ctPos] != ']') { 00312 00313 JsonValue* pValue; 00314 if (parseValue(&pValue) != 0) { 00315 delete pValue; 00316 return -1; 00317 }; 00318 vec->push_back(pValue); 00319 00320 while (ct == TOKEN_DELIMITER && json[ctPos] == ',') { 00321 if (goToNextToken() != 0) return -1; 00322 00323 if (parseValue(&pValue) != 0) { 00324 delete pValue; 00325 return -1; 00326 }; 00327 vec->push_back(pValue); 00328 } 00329 } 00330 00331 if (ct != TOKEN_DELIMITER || json[ctPos] != ']') return -1; 00332 if (goToNextToken() != 0) return -1; 00333 00334 #ifdef DEBUG_JSONPARSER 00335 dbg.printf("Exit parseArray\r\n"); 00336 #endif 00337 00338 return 0; 00339 } 00340 00341 int inst = 0; 00342 00343 JsonValue::JsonValue(const char* buffer, int len) 00344 { 00345 type = VT_CHAR_PTR; 00346 value.s = new char[len+1]; 00347 strncpy(value.s, buffer, len); 00348 value.s[len] = '\0'; 00349 } 00350 00351 JsonValue::JsonValue(double d) 00352 { 00353 type = VT_DOUBLE; 00354 value.d = d; 00355 } 00356 00357 JsonValue::JsonValue(bool b) 00358 { 00359 type = b ? VT_CST_TRUE : VT_CST_FALSE; 00360 00361 } 00362 00363 JsonValue::JsonValue() 00364 { 00365 } 00366 00367 JsonValue::~JsonValue() 00368 { 00369 switch (type) { 00370 case VT_CHAR_PTR: 00371 delete[] value.s; 00372 break; 00373 case VT_MAP_PTR: 00374 for (map<string,JsonValue*>::iterator itr = value.map->begin(); itr != value.map->end(); itr++) 00375 delete ((*itr).second); 00376 delete value.map; 00377 break; 00378 case VT_VEC_PTR: 00379 for (vector<JsonValue*>::iterator itr = value.vec->begin(); itr != value.vec->end(); itr++) 00380 delete (*itr); 00381 delete value.vec; 00382 break; 00383 default: 00384 break; 00385 } 00386 } 00387 00388 JsonValue* JsonValue::createString(const char* buffer, int len) 00389 { 00390 return new JsonValue(buffer, len); 00391 } 00392 00393 JsonValue* JsonValue::createDouble(double d) 00394 { 00395 return new JsonValue(d); 00396 } 00397 00398 JsonValue* JsonValue::createBoolean(bool b) 00399 { 00400 return new JsonValue(b); 00401 } 00402 00403 JsonValue* JsonValue::createMap() 00404 { 00405 JsonValue* ret = new JsonValue(); 00406 ret->type = VT_MAP_PTR; 00407 ret->value.map = new map<string,JsonValue*>(); 00408 return ret; 00409 } 00410 00411 JsonValue* JsonValue::createVector() 00412 { 00413 JsonValue* ret = new JsonValue(); 00414 ret->type = VT_VEC_PTR; 00415 ret->value.vec = new vector<JsonValue*>(); 00416 return ret; 00417 } 00418 00419 JsonValue* JsonValue::createNull() 00420 { 00421 JsonValue* ret = new JsonValue(); 00422 ret->type = VT_CST_NULL; 00423 return ret; 00424 } 00425 00426 void JsonValue::print() 00427 { 00428 bool c = false; 00429 switch (type) { 00430 case VT_CHAR_PTR: 00431 dbg.printf("\"%s\"", value.s); 00432 break; 00433 case VT_MAP_PTR: 00434 dbg.printf("{"); 00435 for (map<string,JsonValue*>::iterator itr = value.map->begin(); itr != value.map->end(); itr++) { 00436 if (c) dbg.printf(","); 00437 else c = true; 00438 dbg.printf("\"%s\":",(*itr).first.c_str()); 00439 (*itr).second->print(); 00440 } 00441 dbg.printf("}"); 00442 break; 00443 case VT_VEC_PTR: 00444 dbg.printf("["); 00445 for (vector<JsonValue*>::iterator itr = value.vec->begin(); itr != value.vec->end(); itr++) { 00446 if (c) dbg.printf(","); 00447 else c = true; 00448 (*itr)->print(); 00449 } 00450 dbg.printf("]"); 00451 break; 00452 case VT_DOUBLE: 00453 dbg.printf("%g", value.d); 00454 break; 00455 case VT_CST_TRUE: 00456 dbg.printf("true"); 00457 break; 00458 case VT_CST_FALSE: 00459 dbg.printf("false"); 00460 break; 00461 case VT_CST_NULL: 00462 dbg.printf("null"); 00463 break; 00464 default: 00465 break; 00466 } 00467 } 00468 00469 JsonValue* JsonValue::get(const char* path) 00470 { 00471 JsonValue* pValue = this; 00472 int pos = 0; 00473 while (path != NULL && path[pos] != '\0') { 00474 00475 #ifdef DEBUG_JSONGET 00476 dbg.printf("::get "); 00477 pValue->print(); 00478 dbg.printf("\r\n"); 00479 #endif 00480 00481 const char* start = path+pos; 00482 const char* pSl = strchr(start, '/'); 00483 int len = pSl == NULL ? strlen(start) : pSl - start; 00484 if (len <= 0) return NULL; 00485 if (pValue->type == VT_VEC_PTR) { 00486 int v = atoi(start); 00487 if (v == 0 && path[pos] != '0') { 00488 return NULL; 00489 } 00490 if (v < 0 || v >= pValue->value.vec->size()) { 00491 return NULL; 00492 } 00493 pValue = (*pValue->value.vec)[v]; 00494 } else if (pValue->type == VT_MAP_PTR) { 00495 char* pKey = new char[len+1]; 00496 strncpy(pKey, start, len); 00497 pKey[len] = '\0'; 00498 pValue = (*pValue->value.map)[pKey]; 00499 delete[] pKey; 00500 if (pValue == NULL) { 00501 return NULL; 00502 } 00503 } else { 00504 return NULL; 00505 } 00506 pos += len; 00507 if (pSl) ++pos; 00508 } 00509 00510 #ifdef DEBUG_JSONGET 00511 dbg.printf("::get "); 00512 pValue->print(); 00513 dbg.printf("\r\n"); 00514 #endif 00515 00516 return pValue; 00517 } 00518 00519 const double* JsonValue::getDouble(const char* path) 00520 { 00521 JsonValue* pV = get(path); 00522 if (pV != NULL && pV->type == VT_DOUBLE) { 00523 return &(pV->value.d); 00524 } else { 00525 return NULL; 00526 } 00527 } 00528 00529 const char* JsonValue::getString(const char* path) 00530 { 00531 JsonValue* pV = get(path); 00532 if (pV != NULL && pV->type == VT_CHAR_PTR) { 00533 return pV->value.s; 00534 } else { 00535 return NULL; 00536 } 00537 } 00538 const std::vector<JsonValue*>* JsonValue::getVector(const char* path) 00539 { 00540 JsonValue* pV = get(path); 00541 if (pV != NULL && pV->type == VT_VEC_PTR) { 00542 return pV->value.vec; 00543 } else { 00544 return NULL; 00545 } 00546 } 00547 const std::map<std::string,JsonValue*>* JsonValue::getMap(const char* path) 00548 { 00549 JsonValue* pV = get(path); 00550 if (pV != NULL && pV->type == VT_MAP_PTR) { 00551 return pV->value.map; 00552 } else { 00553 return NULL; 00554 } 00555 } 00556 00557 static const bool FALSE = false; 00558 static const bool TRUE = true; 00559 00560 const bool* JsonValue::getBoolean(const char* path) 00561 { 00562 JsonValue* pV = get(path); 00563 if (pV != NULL && (pV->type == VT_CST_TRUE || pV->type == VT_CST_FALSE)) { 00564 return (pV->type == VT_CST_TRUE) ? &TRUE : &FALSE; 00565 } else { 00566 return NULL; 00567 } 00568 } 00569 bool JsonValue::isNull(const char* path) 00570 { 00571 JsonValue* pV = get(path); 00572 return (pV != NULL) && (pV->type == VT_CST_NULL); 00573 } 00574
Generated on Tue Jul 12 2022 16:31:38 by 1.7.2