Api wrapper to communicate with EVRYTHNG's Engine.

Dependencies:   EthernetInterface mbed-rtos

Dependents:   EvrythngApiExample

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers JsonParser.cpp Source File

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