diff --git a/README.md b/README.md index 9af895e..a92b9dd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Google OAuth2.0 Access Token generation Arduino Library v1.0.2 +# Google OAuth2.0 Access Token generation Arduino Library v1.0.3 This is the library will create the OAuth2.0 access token used in the Google API's http request (REST). diff --git a/library.json b/library.json index bc813d7..5da9ab2 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Signer", - "version": "1.0.2", + "version": "1.0.3", "keywords": "communication, REST, esp32, esp8266, arduino", "description": "The Google OAuth2.0 access token generation for Google REST API's http request.", "repository": { diff --git a/library.properties b/library.properties index 06fa49d..d65c57b 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Signer -version=1.0.2 +version=1.0.3 author=Mobizt diff --git a/src/ESPSigner.cpp b/src/ESPSigner.cpp index 5bb30ef..d1a8db6 100644 --- a/src/ESPSigner.cpp +++ b/src/ESPSigner.cpp @@ -1,5 +1,5 @@ /** - * Google's OAuth2.0 Access token Generation class, Signer.h version 1.0.2 + * Google's OAuth2.0 Access token Generation class, Signer.h version 1.0.3 * * This library use RS256 for signing algorithm. * @@ -7,7 +7,7 @@ * * This library supports Espressif ESP8266 and ESP32 * - * Created March 25, 2021 + * Created April 4, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2021 K. Suwatchai (Mobizt) @@ -546,7 +546,7 @@ bool ESP_Signer::handleTokenResponse() int chunkedDataState = 0; int chunkedDataSize = 0; int chunkedDataLen = 0; - int defaultChunkSize = 2048; + int defaultChunkSize = ESP_SIGNER_DEFAULT_RESPONSE_BUFFER_SIZE; char *header = nullptr; char *payload = nullptr; char *pChunk = nullptr; diff --git a/src/ESPSigner.h b/src/ESPSigner.h index 03e4ee3..2cfea96 100644 --- a/src/ESPSigner.h +++ b/src/ESPSigner.h @@ -1,5 +1,5 @@ /** - * Google's OAuth2.0 Access token Generation class, Signer.h version 1.0.2 + * Google's OAuth2.0 Access token Generation class, Signer.h version 1.0.3 * * This library use RS256 for signing algorithm. * @@ -7,7 +7,7 @@ * * This library supports Espressif ESP8266 and ESP32 * - * Created March 25, 2021 + * Created April 4, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2021 K. Suwatchai (Mobizt) diff --git a/src/SignerCommon.h b/src/SignerCommon.h index 06b2c0e..4faa51f 100644 --- a/src/SignerCommon.h +++ b/src/SignerCommon.h @@ -1,6 +1,6 @@ /** - * Created March 22, 2021 + * Created April 4, 2021 * * Copyright (c) 2021 K. Suwatchai (Mobizt) * @@ -55,6 +55,7 @@ #define WIFI_RECONNECT_TIMEOUT 10000 #define MAX_EXCHANGE_TOKEN_ATTEMPTS 5 #define ESP_DEFAULT_TS 1510644967 +#define ESP_SIGNER_DEFAULT_RESPONSE_BUFFER_SIZE 2560 enum esp_signer_mem_storage_type { diff --git a/src/json/FirebaseJson.cpp b/src/json/FirebaseJson.cpp index 0816bf8..0f08b3a 100644 --- a/src/json/FirebaseJson.cpp +++ b/src/json/FirebaseJson.cpp @@ -1,9 +1,9 @@ /* - * FirebaseJson, version 2.3.11 + * FirebaseJson, version 2.3.13 * * The Easiest Arduino library to parse, create and edit JSON object using a relative path. * - * March 25, 2021 + * April 4, 2021 * * Features * - None recursive operations @@ -70,61 +70,62 @@ FirebaseJson::~FirebaseJson() _parser.reset(); _parser = nullptr; _finalize(); + delete helper; } void FirebaseJson::_init() { _finalize(); - _qt = strP(FirebaseJson_STR_2); - _tab = strP(FirebaseJson_STR_22); - _brk1 = strP(FirebaseJson_STR_8); - _brk2 = strP(FirebaseJson_STR_9); - _brk3 = strP(FirebaseJson_STR_10); - _brk4 = strP(FirebaseJson_STR_11); - _cm = strP(FirebaseJson_STR_1); - _pr2 = strP(FirebaseJson_STR_3); - _nl = strP(FirebaseJson_STR_24); - _nll = strP(FirebaseJson_STR_18); - _pr = strP(FirebaseJson_STR_25); - _pd = strP(FirebaseJson_STR_4); - _pf = strP(FirebaseJson_STR_5); - _fls = strP(FirebaseJson_STR_6); - _tr = strP(FirebaseJson_STR_7); - _string = strP(FirebaseJson_STR_12); - _int = strP(FirebaseJson_STR_13); - _dbl = strP(FirebaseJson_STR_14); - _bl = strP(FirebaseJson_STR_15); - _obj = strP(FirebaseJson_STR_16); - _arry = strP(FirebaseJson_STR_17); - _undef = strP(FirebaseJson_STR_19); - _dot = strP(FirebaseJson_STR_20); + _qt = helper->strP(fb_json_str_2); + _tab = helper->strP(fb_json_str_22); + _brk1 = helper->strP(fb_json_str_8); + _brk2 = helper->strP(fb_json_str_9); + _brk3 = helper->strP(fb_json_str_10); + _brk4 = helper->strP(fb_json_str_11); + _cm = helper->strP(fb_json_str_1); + _pr2 = helper->strP(fb_json_str_3); + _nl = helper->strP(fb_json_str_24); + _nll = helper->strP(fb_json_str_18); + _pr = helper->strP(fb_json_str_25); + _pd = helper->strP(fb_json_str_4); + _pf = helper->strP(fb_json_str_5); + _fls = helper->strP(fb_json_str_6); + _tr = helper->strP(fb_json_str_7); + _string = helper->strP(fb_json_str_12); + _int = helper->strP(fb_json_str_13); + _dbl = helper->strP(fb_json_str_14); + _bl = helper->strP(fb_json_str_15); + _obj = helper->strP(fb_json_str_16); + _arry = helper->strP(fb_json_str_17); + _undef = helper->strP(fb_json_str_19); + _dot = helper->strP(fb_json_str_20); } void FirebaseJson::_finalize() { - delS(_qt); - delS(_tab); - delS(_brk1); - delS(_brk2); - delS(_brk3); - delS(_brk4); - delS(_cm); - delS(_pr2); - delS(_nl); - delS(_nll); - delS(_pr); - delS(_pd); - delS(_pf); - delS(_fls); - delS(_tr); - delS(_string); - delS(_int); - delS(_dbl); - delS(_bl); - delS(_obj); - delS(_arry); - delS(_undef); - delS(_dot); + helper->delS(_qt); + helper->delS(_tab); + helper->delS(_brk1); + helper->delS(_brk2); + helper->delS(_brk3); + helper->delS(_brk4); + helper->delS(_cm); + helper->delS(_pr2); + helper->delS(_nl); + helper->delS(_nll); + helper->delS(_pr); + helper->delS(_pd); + helper->delS(_pf); + helper->delS(_fls); + helper->delS(_tr); + helper->delS(_string); + helper->delS(_int); + helper->delS(_dbl); + helper->delS(_bl); + helper->delS(_obj); + helper->delS(_arry); + helper->delS(_undef); + helper->delS(_dot); } FirebaseJson &FirebaseJson::_setJsonData(std::string &data) @@ -137,24 +138,24 @@ FirebaseJson &FirebaseJson::setJsonData(const String &data) _topLevelTkType = JSMN_OBJECT; if (data.length() > 0) { - int p1 = strpos(data.c_str(), _brk1, 0); - int p2 = rstrpos(data.c_str(), _brk2, data.length() - 1); + int p1 = helper->strpos(data.c_str(), _brk1, 0); + int p2 = helper->rstrpos(data.c_str(), _brk2, data.length() - 1); if (p1 != -1) p1 += 1; if (p1 != -1 && p2 != -1) _rawbuf = data.substring(p1, p2).c_str(); else { - p1 = strpos(data.c_str(), _brk3, 0); - p2 = rstrpos(data.c_str(), _brk4, data.length() - 1); + p1 = helper->strpos(data.c_str(), _brk3, 0); + p2 = helper->rstrpos(data.c_str(), _brk4, data.length() - 1); if (p1 != -1) p1 += 1; if (p1 != -1 && p2 != -1) { - char *_r = strP(FirebaseJson_STR_21); + char *_r = helper->strP(fb_json_str_21); _rawbuf = _r; _rawbuf += data.c_str(); - delS(_r); + helper->delS(_r); _topLevelTkType = JSMN_ARRAY; } else @@ -236,6 +237,7 @@ FirebaseJson &FirebaseJson::add(const String &key, FirebaseJson &json) FirebaseJson &FirebaseJson::add(const String &key, FirebaseJsonArray &arr) { + arr._lastErr = &_lastErr; _addArray(key.c_str(), &arr); return *this; } @@ -262,34 +264,39 @@ FirebaseJson &FirebaseJson::add(const String &key, T value) void FirebaseJson::_addString(const std::string &key, const std::string &value) { + helper->clearLastError(); _add(key.c_str(), value.c_str(), key.length(), value.length(), true, true); } void FirebaseJson::_addInt(const std::string &key, int value) { - char *buf = intStr(value); + helper->clearLastError(); + char *buf = helper->intStr(value); _add(key.c_str(), buf, key.length(), 60, false, true); - delS(buf); + helper->delS(buf); } void FirebaseJson::_addFloat(const std::string &key, float value) { - char *buf = floatStr(value); - _trimDouble(buf); + helper->clearLastError(); + char *buf = helper->floatStr(value); + helper->trimDouble(buf); _add(key.c_str(), buf, key.length(), 60, false, true); - delS(buf); + helper->delS(buf); } void FirebaseJson::_addDouble(const std::string &key, double value) { - char *buf = doubleStr(value); - _trimDouble(buf); + helper->clearLastError(); + char *buf = helper->doubleStr(value); + helper->trimDouble(buf); _add(key.c_str(), buf, key.length(), 60, false, true); - delS(buf); + helper->delS(buf); } void FirebaseJson::_addBool(const std::string &key, bool value) { + helper->clearLastError(); if (value) _add(key.c_str(), _tr, key.length(), 6, false, true); else @@ -298,11 +305,13 @@ void FirebaseJson::_addBool(const std::string &key, bool value) void FirebaseJson::_addNull(const std::string &key) { + helper->clearLastError(); _add(key.c_str(), _nll, key.length(), 6, false, true); } void FirebaseJson::_addJson(const std::string &key, FirebaseJson *json) { + helper->clearLastError(); std::string s; json->_toStdString(s); _add(key.c_str(), s.c_str(), key.length(), s.length(), false, true); @@ -311,60 +320,13 @@ void FirebaseJson::_addJson(const std::string &key, FirebaseJson *json) void FirebaseJson::_addArray(const std::string &key, FirebaseJsonArray *arr) { + helper->clearLastError(); + arr->_lastErr = &_lastErr; String arrStr; arr->toString(arrStr); _add(key.c_str(), arrStr.c_str(), key.length(), arrStr.length(), false, true); } -char *FirebaseJson::floatStr(float value) -{ - char *buf = newS(36); - helper.dtostrf(value, 7, 6, buf); - return buf; -} - -char *FirebaseJson::intStr(int value) -{ - char *buf = newS(36); - sprintf(buf, "%d", value); - return buf; -} - -char *FirebaseJson::boolStr(bool value) -{ - char *buf = nullptr; - if (value) - buf = strP(FirebaseJson_STR_7); - else - buf = strP(FirebaseJson_STR_6); - return buf; -} - -char *FirebaseJson::doubleStr(double value) -{ - char *buf = newS(36); - helper.dtostrf(value, 12, 9, buf); - return buf; -} - -void FirebaseJson::_trimDouble(char *buf) -{ - size_t i = strlen(buf) - 1; - while (buf[i] == '0' && i > 0) - { - if (buf[i - 1] == '.') - { - i--; - break; - } - if (buf[i - 1] != '0') - break; - i--; - } - if (i < strlen(buf) - 1) - buf[i] = '\0'; -} - void FirebaseJson::toString(String &buf, bool prettify) { if (prettify) @@ -390,16 +352,22 @@ void FirebaseJson::_tostr(std::string &s, bool prettify) std::string().swap(_jsonData._dbuf); } -void FirebaseJson::int_toStdString(std::string &s,bool isJson) +void FirebaseJson::int_toStdString(std::string &s, bool isJson) { _toStdString(s, isJson); } +void FirebaseJson::setBufferLimit(size_t limit) +{ + if (limit >= 32 || limit <= 8192) + _parser_buff_len = limit; +} + void FirebaseJson::_toStdString(std::string &s, bool isJson) { s.clear(); size_t bufSize = 20; - char *buf = newS(bufSize); + char *buf = helper->newS(bufSize); if (_topLevelTkType != JSMN_PRIMITIVE) { if (isJson) @@ -419,15 +387,22 @@ void FirebaseJson::_toStdString(std::string &s, bool isJson) strcat(buf, _brk4); } s += buf; - delS(buf); + helper->delS(buf); } FirebaseJson &FirebaseJson::_add(const char *key, const char *value, size_t klen, size_t vlen, bool isString, bool isJson) { - size_t bufSize = klen + vlen + 1024; - char *buf = newS(bufSize); + helper->clearLastError(); + size_t bufSize = klen + vlen + _parser_buff_len; + char *buf = helper->newS(bufSize); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return *this; + } + if (_rawbuf.length() > 0) - strcpy_P(buf, FirebaseJson_STR_1); + strcpy_P(buf, fb_json_str_1); if (isJson) { strcat(buf, _qt); @@ -441,18 +416,20 @@ FirebaseJson &FirebaseJson::_add(const char *key, const char *value, size_t klen if (isString) strcat(buf, _qt); _rawbuf += buf; - delS(buf); + helper->delS(buf); return *this; } FirebaseJson &FirebaseJson::_addArrayStr(const char *value, size_t len, bool isString) { + helper->clearLastError(); _add("", value, 0, len, isString, false); return *this; } bool FirebaseJson::get(FirebaseJsonData &jsonData, const String &path, bool prettify) { + helper->clearLastError(); clearPathTk(); _strToTk(path.c_str(), _pathTk, '/'); std::string().swap(_jsonData._dbuf); @@ -463,7 +440,7 @@ bool FirebaseJson::get(FirebaseJsonData &jsonData, const String &path, bool pret _parse(path.c_str(), PRINT_MODE_PLAIN); if (_jsonData.success) { - if (_jsonData._type == FirebaseJson::JSMN_STRING && _jsonData._dbuf.c_str()[0] == '"' && _jsonData._dbuf.c_str()[_jsonData._dbuf.length() - 1] == '"') + if (_jsonData._type == JSMN_STRING && _jsonData._dbuf.c_str()[0] == '"' && _jsonData._dbuf.c_str()[_jsonData._dbuf.length() - 1] == '"') _jsonData.stringValue = _jsonData._dbuf.substr(1, _jsonData._dbuf.length() - 2).c_str(); else _jsonData.stringValue = _jsonData._dbuf.c_str(); @@ -479,27 +456,34 @@ bool FirebaseJson::get(FirebaseJsonData &jsonData, const String &path, bool pret size_t FirebaseJson::iteratorBegin(const char *data) { + helper->clearLastError(); if (data) setJsonData(data); _fbjs_parse(true); std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return 0; + } strcpy(buf, s.c_str()); std::string().swap(s); int depth = -1; - _collectTk = true; + _parser_info.collectTk = true; _eltk.clear(); - for (uint16_t i = 0; i < _tokenCount; i++) + for (uint16_t i = 0; i < _parser_info.tokenCount; i++) _parseToken(i, buf, depth, "", -2, PRINT_MODE_NONE); _el.clear(); - delS(buf); + helper->delS(buf); return _eltk.size(); } void FirebaseJson::iteratorEnd() { + helper->clearLastError(); _eltk.clear(); clearPathTk(); _jsonData.stringValue = ""; @@ -512,56 +496,94 @@ void FirebaseJson::iteratorEnd() void FirebaseJson::iteratorGet(size_t index, int &type, String &key, String &value) { + helper->clearLastError(); if (_eltk.size() < index + 1) return; std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(buf, s.c_str()); std::string().swap(s); if (_eltk[index].type == 0) { FirebaseJson::fbjs_tok_t *h = &_tokens.get()[_eltk[index].index]; size_t len = h->end - h->start + 3; - char *k = newS(len); + char *k = helper->newS(len); + if (!k) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(k, buf + h->start, h->end - h->start); FirebaseJson::fbjs_tok_t *g = &_tokens.get()[_eltk[index].index + 1]; size_t len2 = g->end - g->start + 3; - char *v = newS(len2); + char *v = helper->newS(len2); + if (!v) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(v, buf + g->start, g->end - g->start); key = k; value = v; type = JSON_OBJECT; - delS(k); - delS(v); + helper->delS(k); + helper->delS(v); } else if (_eltk[index].type == 1) { FirebaseJson::fbjs_tok_t *g = &_tokens.get()[_eltk[index].index]; size_t len2 = g->end - g->start + 3; - char *v = newS(len2); + char *v = helper->newS(len2); + if (!v) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(v, buf + g->start, g->end - g->start); value = v; key = ""; type = JSON_ARRAY; - delS(v); + helper->delS(v); } - delS(buf); + helper->delS(buf); } void FirebaseJson::_fbjs_parse(bool collectTk) { + helper->clearLastError(); std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(buf, s.c_str()); std::string().swap(s); _tokens.reset(); - _collectTk = collectTk; + _parser_info.collectTk = collectTk; _eltk.clear(); int cnt = fbjs_parse(_parser.get(), buf, bufLen, (FirebaseJson::fbjs_tok_t *)NULL, 0); + if (cnt < 0) + { + /** Invalid character inside JSON string */ + if (cnt == JSMN_ERROR_INVAL) + helper->setLastError(-3, __FILE__, __LINE__, fb_json_str_29); + + /** The string is not a full JSON packet, more bytes expected */ + else if (cnt == JSMN_ERROR_PART) + helper->setLastError(-4, __FILE__, __LINE__, fb_json_str_30); + } + int cnt2 = 0; int a = 0; int b = 0; @@ -572,6 +594,7 @@ void FirebaseJson::_fbjs_parse(bool collectTk) else if (buf[i] == '[' || buf[i] == '{') b++; } + cnt2 = 10 + (2 * (a + 1)) + b; if (cnt < cnt2) @@ -579,20 +602,27 @@ void FirebaseJson::_fbjs_parse(bool collectTk) _tokens = std::shared_ptr(new FirebaseJson::fbjs_tok_t[cnt + 10]); fbjs_init(_parser.get()); - _tokenCount = fbjs_parse(_parser.get(), buf, bufLen, _tokens.get(), cnt + 10); - _paresRes = true; - if (_tokenCount < 0) - _paresRes = false; - if (_tokenCount < 1 || _tokens.get()[0].type != FirebaseJson::JSMN_OBJECT) - _paresRes = false; - _jsonData.success = _paresRes; - _nextToken = 0; - _nextDepth = 0; - _tokenMatch = false; - _refToken = -1; + _parser_info.tokenCount = fbjs_parse(_parser.get(), buf, bufLen, _tokens.get(), cnt + 10); + if (_parser_info.tokenCount < 0) + { + /** Not enough tokens were provided */ + if (cnt == JSMN_ERROR_NOMEM) + helper->setLastError(-2, __FILE__, __LINE__, fb_json_str_31); + } + + _parser_info.paresRes = true; + if (_parser_info.tokenCount < 0) + _parser_info.paresRes = false; + if (_parser_info.tokenCount < 1 || _tokens.get()[0].type != JSMN_OBJECT) + _parser_info.paresRes = false; + _jsonData.success = _parser_info.paresRes; + _parser_info.nextToken = 0; + _parser_info.nextDepth = 0; + _parser_info.tokenMatch = false; + _parser_info.refToken = -1; _resetParseResult(); _setElementType(); - delS(buf); + helper->delS(buf); } void FirebaseJson::_setMark(int depth, bool mark) @@ -641,7 +671,7 @@ void FirebaseJson::_getTkIndex(int depth, tk_index_t &tk) tk.oindex = 0; tk.olen = 0; tk.omark = false; - tk.type = FirebaseJson::JSMN_UNDEFINED; + tk.type = JSMN_UNDEFINED; tk.depth = -1; tk.skip = false; tk.ref = false; @@ -672,7 +702,7 @@ bool FirebaseJson::_updateTkIndex(uint16_t index, int &depth, const char *search { if (_el[i].depth == depth - 1) { - if (_el[i].type == FirebaseJson::JSMN_OBJECT || _el[i].type == FirebaseJson::JSMN_ARRAY) + if (_el[i].type == JSMN_OBJECT || _el[i].type == JSMN_ARRAY) { _el[i].oindex++; if (_el[i].oindex >= _el[i].olen) @@ -680,21 +710,21 @@ bool FirebaseJson::_updateTkIndex(uint16_t index, int &depth, const char *search depth = _el[i].depth; len = _el[i].olen; skip = _el[i].skip; - if (!_TkRefOk && _el[i].type == FirebaseJson::JSMN_OBJECT) + + if (!_parser_info.TkRefOk && _el[i].type == JSMN_OBJECT) ref = _el[i].ref; - else if (!_TkRefOk && _el[i].type == FirebaseJson::JSMN_ARRAY && searchIndex > -1) + else if (!_parser_info.TkRefOk && _el[i].type == JSMN_ARRAY && searchIndex > -1) ref = _el[i].ref; - if (i > 0) - _el.erase(_el.begin() + i); - else - _el.erase(_el.begin()); + + _el.erase(_el.begin() + i); + if (printMode != PRINT_MODE_NONE && !skip) { - if (len > 0 && !_arrReplaced) + if (len > 0 && !_parser_info.arrReplaced) { if (ref) _jsonData._dbuf += _cm; - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) { if (printMode == PRINT_MODE_PRETTY) _jsonData._dbuf += _nl; @@ -708,11 +738,11 @@ bool FirebaseJson::_updateTkIndex(uint16_t index, int &depth, const char *search if (ref) { if (!advanceCount) - _parseCompleted++; + _parser_info.parseCompleted++; - if (!_arrReplaced) + if (!_parser_info.arrReplaced) { - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) { if (printMode == PRINT_MODE_PRETTY) { @@ -726,11 +756,11 @@ bool FirebaseJson::_updateTkIndex(uint16_t index, int &depth, const char *search _jsonData._dbuf += _pr; else _jsonData._dbuf += _pr2; - if (_parseCompleted == (int)_pathTk.size()) + if (_parser_info.parseCompleted == (int)_pathTk.size()) _jsonData._dbuf += replace; else _insertChilds(replace, printMode); - _arrReplaced = true; + _parser_info.arrReplaced = true; if (printMode == PRINT_MODE_PRETTY) { _jsonData._dbuf += _nl; @@ -750,11 +780,11 @@ bool FirebaseJson::_updateTkIndex(uint16_t index, int &depth, const char *search } if (k == searchIndex - 1) { - if (_parseCompleted == (int)_pathTk.size()) + if (_parser_info.parseCompleted == (int)_pathTk.size()) _jsonData._dbuf += replace; else _insertChilds(replace, printMode); - _arrReplaced = true; + _parser_info.arrReplaced = true; } else { @@ -766,10 +796,10 @@ bool FirebaseJson::_updateTkIndex(uint16_t index, int &depth, const char *search } _setRef(depth, false); if (!advanceCount) - _parseCompleted = _pathTk.size(); + _parser_info.parseCompleted = _pathTk.size(); } - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) _jsonData._dbuf += _brk2; else { @@ -803,7 +833,7 @@ bool FirebaseJson::_updateTkIndex2(std::string &str, uint16_t index, int &depth, { if (_el[i].depth == depth - 1) { - if (_el[i].type == FirebaseJson::JSMN_OBJECT || _el[i].type == FirebaseJson::JSMN_ARRAY) + if (_el[i].type == JSMN_OBJECT || _el[i].type == JSMN_ARRAY) { _el[i].oindex++; if (_el[i].oindex >= _el[i].olen) @@ -811,21 +841,20 @@ bool FirebaseJson::_updateTkIndex2(std::string &str, uint16_t index, int &depth, depth = _el[i].depth; len = _el[i].olen; skip = _el[i].skip; - if (!_TkRefOk && _el[i].type == FirebaseJson::JSMN_OBJECT) + if (!_parser_info.TkRefOk && _el[i].type == JSMN_OBJECT) ref = _el[i].ref; - else if (!_TkRefOk && _el[i].type == FirebaseJson::JSMN_ARRAY && searchIndex > -1) + else if (!_parser_info.TkRefOk && _el[i].type == JSMN_ARRAY && searchIndex > -1) ref = _el[i].ref; - if (i > 0) - _el.erase(_el.begin() + i); - else - _el.erase(_el.begin()); + + _el.erase(_el.begin() + i); + if (printMode != PRINT_MODE_NONE && !skip) { if (len > 0) { if (printMode == PRINT_MODE_PRETTY) str += _nl; - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) { if (printMode == PRINT_MODE_PRETTY && !ref) { @@ -844,7 +873,7 @@ bool FirebaseJson::_updateTkIndex2(std::string &str, uint16_t index, int &depth, } if (ref) _setRef(depth, false); - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) str += _brk2; else str += _brk4; @@ -867,7 +896,7 @@ bool FirebaseJson::_updateTkIndex3(uint16_t index, int &depth, const char *searc { if (_el[i].depth == depth - 1) { - if (_el[i].type == FirebaseJson::JSMN_OBJECT || _el[i].type == FirebaseJson::JSMN_ARRAY) + if (_el[i].type == JSMN_OBJECT || _el[i].type == JSMN_ARRAY) { _el[i].oindex++; if (_el[i].oindex >= _el[i].olen) @@ -875,15 +904,14 @@ bool FirebaseJson::_updateTkIndex3(uint16_t index, int &depth, const char *searc depth = _el[i].depth; len = _el[i].olen; skip = _el[i].skip; - if (!_TkRefOk && _el[i].type == FirebaseJson::JSMN_OBJECT) + if (!_parser_info.TkRefOk && _el[i].type == JSMN_OBJECT) ref = _el[i].ref; - else if (!_TkRefOk && _el[i].type == FirebaseJson::JSMN_ARRAY && searchIndex > -1) + else if (!_parser_info.TkRefOk && _el[i].type == JSMN_ARRAY && searchIndex > -1) ref = _el[i].ref; - if (i > 0) - _el.erase(_el.begin() + i); - else - _el.erase(_el.begin()); - if (depth < _skipDepth) + + _el.erase(_el.begin() + i); + + if (depth < _parser_info.skipDepth) return false; if (printMode != PRINT_MODE_NONE && skip) { @@ -891,11 +919,11 @@ bool FirebaseJson::_updateTkIndex3(uint16_t index, int &depth, const char *searc { if (printMode == PRINT_MODE_PRETTY) _jsonData._dbuf += _nl; - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) { if (printMode == PRINT_MODE_PRETTY && !ref) { - for (int j = 0; j < depth + 1 - (_skipDepth + 1); j++) + for (int j = 0; j < depth + 1 - (_parser_info.skipDepth + 1); j++) _jsonData._dbuf += _tab; } } @@ -903,7 +931,7 @@ bool FirebaseJson::_updateTkIndex3(uint16_t index, int &depth, const char *searc { if (printMode == PRINT_MODE_PRETTY) { - for (int j = 0; j < depth + 1 - (_skipDepth + 1); j++) + for (int j = 0; j < depth + 1 - (_parser_info.skipDepth + 1); j++) _jsonData._dbuf += _tab; } } @@ -911,7 +939,7 @@ bool FirebaseJson::_updateTkIndex3(uint16_t index, int &depth, const char *searc if (ref) _setRef(depth, false); - if (_el[i].type == FirebaseJson::JSMN_OBJECT) + if (_el[i].type == JSMN_OBJECT) _jsonData._dbuf += _brk2; else _jsonData._dbuf += _brk4; @@ -928,7 +956,7 @@ bool FirebaseJson::_updateTkIndex3(uint16_t index, int &depth, const char *searc void FirebaseJson::_insertChilds(const char *data, PRINT_MODE printMode) { std::string str = ""; - for (int i = _pathTk.size() - 1; i > _parseCompleted - 1; i--) + for (int i = _pathTk.size() - 1; i > _parser_info.parseCompleted - 1; i--) { if (_isArrTk(i)) { @@ -945,7 +973,7 @@ void FirebaseJson::_insertChilds(const char *data, PRINT_MODE printMode) std::string().swap(_str); } } - if ((int)_pathTk.size() == _parseCompleted) + if ((int)_pathTk.size() == _parser_info.parseCompleted) str = data; _jsonData._dbuf += str; std::string().swap(str); @@ -1021,6 +1049,7 @@ void FirebaseJson::_addObjNodes(std::string &str, std::string &str2, int index, void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *searchKey, int searchIndex, PRINT_MODE printMode) { + helper->clearLastError(); tk_index_t tk; _getTkIndex(depth, tk); FirebaseJson::fbjs_tok_t *h = &_tokens.get()[i]; @@ -1035,31 +1064,36 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s tk_index_t tk2; int depth2 = depth - 1; _getTkIndex(depth2, tk2); - if (tk.type == FirebaseJson::JSMN_ARRAY && _parseDepth == depth && tk2.oindex == _parentIndex) + if (tk.type == JSMN_ARRAY && _parser_info.parseDepth == depth && tk2.oindex == _parser_info.parentIndex) { if (tk.oindex == searchIndex) { - _nextToken = i; - _nextDepth = depth; - _parentIndex = tk.oindex; + _parser_info.nextToken = i; + _parser_info.nextDepth = depth; + _parser_info.parentIndex = tk.oindex; - if ((int)_pathTk.size() != _parseDepth + 1) + if ((int)_pathTk.size() != _parser_info.parseDepth + 1) { - _tokenMatch = true; - _parseCompleted++; + _parser_info.tokenMatch = true; + _parser_info.parseCompleted++; } else { - if (!_TkRefOk) + if (!_parser_info.TkRefOk) { - _parseCompleted++; - _refTkIndex = i + 1; - _refToken = i + 1; - _TkRefOk = true; - char *dat1 = newS(h->end - h->start + 10); + _parser_info.parseCompleted++; + _parser_info.refTkIndex = i + 1; + _parser_info.refToken = i + 1; + _parser_info.TkRefOk = true; + char *dat1 = helper->newS(h->end - h->start + 10); + if (!dat1) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(dat1, buf + h->start, h->end - h->start); _jsonData.stringValue = dat1; - delS(dat1); + helper->delS(dat1); _jsonData._type = h->type; _jsonData._k_start = h->start; _jsonData._start = h->start; @@ -1075,7 +1109,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s { std::string().swap(_jsonData._dbuf); std::string().swap(_tbuf); - _tokenMatch = true; + _parser_info.tokenMatch = true; ex = true; } } @@ -1093,33 +1127,43 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s } else { - char *key = newS(h->end - h->start + 10); + char *key = helper->newS(h->end - h->start + 10); + if (!key) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(key, buf + h->start, h->end - h->start); - if (tk.type != FirebaseJson::JSMN_UNDEFINED && _parseDepth == depth) + if (tk.type != JSMN_UNDEFINED && _parser_info.parseDepth == depth) { if (strcmp(searchKey, key) == 0) { - _nextToken = i + 1; - _nextDepth = depth; - _parentIndex = tk.oindex; - if ((int)_pathTk.size() != _parseDepth + 1) + _parser_info.nextToken = i + 1; + _parser_info.nextDepth = depth; + _parser_info.parentIndex = tk.oindex; + if ((int)_pathTk.size() != _parser_info.parseDepth + 1) { - _tokenMatch = true; - _parseCompleted++; + _parser_info.tokenMatch = true; + _parser_info.parseCompleted++; } else { - if (!_TkRefOk) + if (!_parser_info.TkRefOk) { - _parseCompleted++; - _refTkIndex = i + 1; - _refToken = i + 1; - _TkRefOk = true; + _parser_info.parseCompleted++; + _parser_info.refTkIndex = i + 1; + _parser_info.refToken = i + 1; + _parser_info.TkRefOk = true; h = &_tokens.get()[i + 1]; - char *dat2 = newS(h->end - h->start + 10); + char *dat2 = helper->newS(h->end - h->start + 10); + if (!dat2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(dat2, buf + h->start, h->end - h->start); _jsonData.stringValue = dat2; - delS(dat2); + helper->delS(dat2); _jsonData._type = h->type; _jsonData._k_start = h->start; _jsonData._start = h->start; @@ -1135,7 +1179,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s { std::string().swap(_jsonData._dbuf); std::string().swap(_tbuf); - _tokenMatch = true; + _parser_info.tokenMatch = true; ex = true; } } @@ -1150,21 +1194,21 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s } } } - delS(key); + helper->delS(key); } if (ex) return; - if (_refTkIndex == i + 1) + if (_parser_info.refTkIndex == i + 1) { - if (tk.type == FirebaseJson::JSMN_OBJECT) + if (tk.type == JSMN_OBJECT) oskip = true; tk.skip = true; - _skipDepth = depth; + _parser_info.skipDepth = depth; } h = &_tokens.get()[i]; - if (h->type == FirebaseJson::JSMN_OBJECT || h->type == FirebaseJson::JSMN_ARRAY) + if (h->type == JSMN_OBJECT || h->type == JSMN_ARRAY) { - if (printMode != PRINT_MODE_NONE && (tk.skip || _refTkIndex == i + 1)) + if (printMode != PRINT_MODE_NONE && (tk.skip || _parser_info.refTkIndex == i + 1)) { if (!tk.omark && i > 0 && resLen > 0) { @@ -1174,12 +1218,12 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s _jsonData._dbuf += _nl; if (printMode == PRINT_MODE_PRETTY && h->size >= 0) { - for (int j = 0; j < depth - (_skipDepth + 1); j++) + for (int j = 0; j < depth - (_parser_info.skipDepth + 1); j++) _jsonData._dbuf += _tab; _jsonData._dbuf += _tab; } } - if (h->type == FirebaseJson::JSMN_OBJECT) + if (h->type == JSMN_OBJECT) _jsonData._dbuf += _brk1; else _jsonData._dbuf += _brk3; @@ -1192,7 +1236,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s e.depth = depth; e.omark = false; e.ref = false; - if (_refToken != -1) + if (_parser_info.refToken != -1) e.skip = true; else e.skip = tk.skip; @@ -1208,7 +1252,12 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s } else { - char *tmp = newS(h->end - h->start + 10); + char *tmp = helper->newS(h->end - h->start + 10); + if (!tmp) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } if (buf[h->start - 1] != '"') strncpy(tmp, buf + h->start, h->end - h->start); else @@ -1223,7 +1272,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s _jsonData._dbuf += _nl; if (printMode == PRINT_MODE_PRETTY && h->size > 0) { - for (int j = 0; j < depth - (_skipDepth + 1); j++) + for (int j = 0; j < depth - (_parser_info.skipDepth + 1); j++) _jsonData._dbuf += _tab; _jsonData._dbuf += _tab; } @@ -1233,21 +1282,32 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s else _jsonData._dbuf += _pr2; } - if (_collectTk) + if (_parser_info.collectTk) { eltk_t el; el.index = i; el.type = 0; _eltk.push_back(el); } - char *tmp2 = newS(h->end - h->start + 10); + char *tmp2 = helper->newS(h->end - h->start + 10); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(tmp2, buf + h->start, h->end - h->start); h = &_tokens.get()[i + 1]; - delS(tmp2); - if (h->type != FirebaseJson::JSMN_OBJECT && h->type != FirebaseJson::JSMN_ARRAY) + helper->delS(tmp2); + + if (h->type != JSMN_OBJECT && h->type != JSMN_ARRAY) { - char *tmp2 = newS(h->end - h->start + 10); + char *tmp2 = helper->newS(h->end - h->start + 10); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(tmp2, buf + h->start, h->end - h->start); if (printMode != PRINT_MODE_NONE && tk.skip) { @@ -1257,7 +1317,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s strncpy(tmp2, buf + h->start - 1, h->end - h->start + 2); _jsonData._dbuf += tmp2; } - delS(tmp2); + helper->delS(tmp2); i++; while (_updateTkIndex3(i, depth, searchKey, searchIndex, printMode)) { @@ -1266,7 +1326,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s } else { - if (_refToken == i + 1) + if (_parser_info.refToken == i + 1) { _setSkip(depth, true); } @@ -1286,7 +1346,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s if (printMode == PRINT_MODE_PRETTY && tk.olen > 0 && resLen > 0) { - for (int j = 0; j < depth - (_skipDepth + 1); j++) + for (int j = 0; j < depth - (_parser_info.skipDepth + 1); j++) _jsonData._dbuf += _tab; _jsonData._dbuf += _tab; } @@ -1296,7 +1356,7 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s { delay(0); } - if (_collectTk) + if (_parser_info.collectTk) { eltk_t el; el.index = i; @@ -1304,18 +1364,19 @@ void FirebaseJson::_parseToken(uint16_t &i, char *buf, int &depth, const char *s _eltk.push_back(el); } } - delS(tmp); + helper->delS(tmp); - if (_refToken == -1 && _skipDepth == depth) + if (_parser_info.refToken == -1 && _parser_info.skipDepth == depth) _setSkip(depth, false); } - _nextToken = i + 1; - _refToken = -1; + _parser_info.nextToken = i + 1; + _parser_info.refToken = -1; } void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char *searchKey, int searchIndex, PRINT_MODE printMode, const char *replace, int refTokenIndex, bool removeTk) { - if (_tokenMatch) + helper->clearLastError(); + if (_parser_info.tokenMatch) return; tk_index_t tk; _getTkIndex(depth, tk); @@ -1328,39 +1389,39 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char tk_index_t tk2; int depth2 = depth - 1; _getTkIndex(depth2, tk2); - if (tk.type == FirebaseJson::JSMN_ARRAY && _parseDepth == depth && tk2.oindex == _parentIndex) + if (tk.type == JSMN_ARRAY && _parser_info.parseDepth == depth && tk2.oindex == _parser_info.parentIndex) { if (tk.oindex == searchIndex) { - _nextToken = i; - _nextDepth = depth; - _parentIndex = tk.oindex; - if ((int)_pathTk.size() != _parseDepth + 1) + _parser_info.nextToken = i; + _parser_info.nextDepth = depth; + _parser_info.parentIndex = tk.oindex; + if ((int)_pathTk.size() != _parser_info.parseDepth + 1) { - _tokenMatch = true; - _parseCompleted++; - _refTkIndex = i + 1; + _parser_info.tokenMatch = true; + _parser_info.parseCompleted++; + _parser_info.refTkIndex = i + 1; } else { - if (!_TkRefOk) + if (!_parser_info.TkRefOk) { - _parseCompleted++; - _refTkIndex = i + 1; - _refToken = i + 1; - _TkRefOk = true; + _parser_info.parseCompleted++; + _parser_info.refTkIndex = i + 1; + _parser_info.refToken = i + 1; + _parser_info.TkRefOk = true; single_child_parent_t p = _findSCParent(depth); if (p.success) { - _remTkIndex = p.index + 1; - _remFirstTk = p.firstTk; - _remLastTk = p.lastTk; + _parser_info.remTkIndex = p.index + 1; + _parser_info.remFirstTk = p.firstTk; + _parser_info.remLastTk = p.lastTk; } else { - _remTkIndex = i + 1; - _remFirstTk = tk.oindex == 0; - _remLastTk = tk.oindex + 1 == tk.olen; + _parser_info.remTkIndex = i + 1; + _parser_info.remFirstTk = tk.oindex == 0; + _parser_info.remLastTk = tk.oindex + 1 == tk.olen; } } } @@ -1377,41 +1438,46 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char } else { - char *key = newS(h->end - h->start + 10); + char *key = helper->newS(h->end - h->start + 10); + if (!key) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(key, buf + h->start, h->end - h->start); - if (tk.type != FirebaseJson::JSMN_UNDEFINED && _parseDepth == depth) + if (tk.type != JSMN_UNDEFINED && _parser_info.parseDepth == depth) { if (strcmp(searchKey, key) == 0) { - _nextToken = i + 1; - _nextDepth = depth; - _parentIndex = tk.oindex; - if ((int)_pathTk.size() != _parseDepth + 1) + _parser_info.nextToken = i + 1; + _parser_info.nextDepth = depth; + _parser_info.parentIndex = tk.oindex; + if ((int)_pathTk.size() != _parser_info.parseDepth + 1) { - _tokenMatch = true; - _parseCompleted++; - _refTkIndex = i + 1; + _parser_info.tokenMatch = true; + _parser_info.parseCompleted++; + _parser_info.refTkIndex = i + 1; } else { - if (!_TkRefOk) + if (!_parser_info.TkRefOk) { - _parseCompleted++; - _refTkIndex = i + 1; - _refToken = i + 1; - _TkRefOk = true; + _parser_info.parseCompleted++; + _parser_info.refTkIndex = i + 1; + _parser_info.refToken = i + 1; + _parser_info.TkRefOk = true; single_child_parent_t p = _findSCParent(depth); if (p.success) { - _remTkIndex = p.index + 1; - _remFirstTk = p.firstTk; - _remLastTk = p.lastTk; + _parser_info.remTkIndex = p.index + 1; + _parser_info.remFirstTk = p.firstTk; + _parser_info.remLastTk = p.lastTk; } else { - _remTkIndex = i + 1; - _remFirstTk = tk.oindex == 0; - _remLastTk = tk.oindex + 1 == tk.olen; + _parser_info.remTkIndex = i + 1; + _parser_info.remFirstTk = tk.oindex == 0; + _parser_info.remLastTk = tk.oindex + 1 == tk.olen; } } } @@ -1427,23 +1493,23 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char } else { - if (_tokenCount == 1 && h->size == 0 && !removeTk) + if (_parser_info.tokenCount == 1 && h->size == 0 && !removeTk) { _insertChilds(replace, printMode); - _nextToken = i + 1; - _nextDepth = 0; - _parseCompleted = _pathTk.size(); - _tokenMatch = true; + _parser_info.nextToken = i + 1; + _parser_info.nextDepth = 0; + _parser_info.parseCompleted = _pathTk.size(); + _parser_info.tokenMatch = true; ex = true; } } - delS(key); + helper->delS(key); } if (ex) return; h = &_tokens.get()[i]; - if (h->type == FirebaseJson::JSMN_OBJECT || h->type == FirebaseJson::JSMN_ARRAY) + if (h->type == JSMN_OBJECT || h->type == JSMN_ARRAY) { if (printMode != PRINT_MODE_NONE && !tk.skip) { @@ -1460,14 +1526,14 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char _jsonData._dbuf += _tab; } } - if (_refToken == -1) + if (_parser_info.refToken == -1) { - if (h->type == FirebaseJson::JSMN_OBJECT) + if (h->type == JSMN_OBJECT) _jsonData._dbuf += _brk1; else _jsonData._dbuf += _brk3; } - else if (_refToken != -1 && searchIndex > -1) + else if (_parser_info.refToken != -1 && searchIndex > -1) _jsonData._dbuf += replace; } el_t e; @@ -1478,7 +1544,7 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char e.depth = depth; e.omark = false; e.ref = false; - if (_refToken != -1) + if (_parser_info.refToken != -1) e.skip = true; else e.skip = tk.skip; @@ -1494,13 +1560,18 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char } else { - if (_refTkIndex == refTokenIndex && refTokenIndex > -1) + if (_parser_info.refTkIndex == refTokenIndex && refTokenIndex > -1) { - _refToken = refTokenIndex; - _refTkIndex = -1; + _parser_info.refToken = refTokenIndex; + _parser_info.refTkIndex = -1; insertFlag = true; } - char *tmp = newS(h->end - h->start + 10); + char *tmp = helper->newS(h->end - h->start + 10); + if (!tmp) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } if (buf[h->start - 1] != '"') strncpy(tmp, buf + h->start, h->end - h->start); else @@ -1525,14 +1596,24 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char else _jsonData._dbuf += _pr2; } - char *tmp2 = newS(h->end - h->start + 10); + char *tmp2 = helper->newS(h->end - h->start + 10); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(tmp2, buf + h->start, h->end - h->start); h = &_tokens.get()[i + 1]; - delS(tmp2); + helper->delS(tmp2); - if (h->type != FirebaseJson::JSMN_OBJECT && h->type != FirebaseJson::JSMN_ARRAY) + if (h->type != JSMN_OBJECT && h->type != JSMN_ARRAY) { - char *tmp2 = newS(h->end - h->start + 10); + char *tmp2 = helper->newS(h->end - h->start + 10); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(tmp2, buf + h->start, h->end - h->start); if (printMode != PRINT_MODE_NONE && !tk.skip) @@ -1541,7 +1622,7 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char strncpy(tmp2, buf + h->start, h->end - h->start); else strncpy(tmp2, buf + h->start - 1, h->end - h->start + 2); - if (_refToken == i + 1) + if (_parser_info.refToken == i + 1) { if (!insertFlag) _jsonData._dbuf += replace; @@ -1551,7 +1632,7 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char else _jsonData._dbuf += tmp2; } - delS(tmp2); + helper->delS(tmp2); i++; while (_updateTkIndex(i, depth, searchKey, searchIndex, replace, printMode, removeTk)) { @@ -1560,10 +1641,10 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char } else { - if (_refToken == i + 1) + if (_parser_info.refToken == i + 1) { _setSkip(depth, true); - _skipDepth = depth; + _parser_info.skipDepth = depth; if (!insertFlag) _jsonData._dbuf += replace; else @@ -1598,13 +1679,13 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char _jsonData._dbuf += _tab; } - if (_refToken == i + 1 && !_arrInserted) + if (_parser_info.refToken == i + 1 && !_parser_info.arrInserted) { if (!insertFlag) _jsonData._dbuf += replace; else _insertChilds(replace, printMode); - _arrInserted = true; + _parser_info.arrInserted = true; } else _jsonData._dbuf += tmp; @@ -1614,36 +1695,37 @@ void FirebaseJson::_compileToken(uint16_t &i, char *buf, int &depth, const char delay(0); } } - delS(tmp); + helper->delS(tmp); - if (_refToken == -1 && _skipDepth == depth) + if (_parser_info.refToken == -1 && _parser_info.skipDepth == depth) _setSkip(depth, false); } - _nextToken = i + 1; - _refToken = -1; + _parser_info.nextToken = i + 1; + _parser_info.refToken = -1; } void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char *searchKey, int searchIndex, PRINT_MODE printMode, const char *replace, int refTokenIndex, bool removeTk) { + helper->clearLastError(); bool ncm = false; tk_index_t tk; _getTkIndex(depth, tk); FirebaseJson::fbjs_tok_t *h = &_tokens.get()[i]; delay(0); if (refTokenIndex == i && refTokenIndex > -1) - ncm = _remFirstTk; - if (refTokenIndex != i || (refTokenIndex == i && _remLastTk)) + ncm = _parser_info.remFirstTk; + if (refTokenIndex != i || (refTokenIndex == i && _parser_info.remLastTk)) _jsonData._dbuf += _tbuf; _tbuf.clear(); bool flag = tk.oindex > 0 && !ncm && _jsonData._dbuf.c_str()[_jsonData._dbuf.length() - 1] != '{' && _jsonData._dbuf.c_str()[_jsonData._dbuf.length() - 1] != '['; if (refTokenIndex == i + 1 && refTokenIndex > -1) { - _refToken = refTokenIndex; - _refTkIndex = -1; + _parser_info.refToken = refTokenIndex; + _parser_info.refTkIndex = -1; tk.skip = true; } h = &_tokens.get()[i]; - if (h->type == FirebaseJson::JSMN_OBJECT || h->type == FirebaseJson::JSMN_ARRAY) + if (h->type == JSMN_OBJECT || h->type == JSMN_ARRAY) { if (printMode != PRINT_MODE_NONE && !tk.skip) { @@ -1660,14 +1742,14 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * _tbuf += _tab; } } - if (_refToken == -1) + if (_parser_info.refToken == -1) { - if (h->type == FirebaseJson::JSMN_OBJECT) + if (h->type == JSMN_OBJECT) _tbuf += _brk1; else _tbuf += _brk3; } - else if (_refToken != -1 && searchIndex > -1) + else if (_parser_info.refToken != -1 && searchIndex > -1) _tbuf += replace; } el_t e; @@ -1678,7 +1760,7 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * e.depth = depth; e.omark = false; e.ref = false; - if (_refToken != -1) + if (_parser_info.refToken != -1) e.skip = true; else e.skip = tk.skip; @@ -1694,7 +1776,12 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * } else { - char *tmp = newS(h->end - h->start + 10); + char *tmp = helper->newS(h->end - h->start + 10); + if (!tmp) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } if (buf[h->start - 1] != '"') strncpy(tmp, buf + h->start, h->end - h->start); else @@ -1720,13 +1807,23 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * _tbuf += _pr2; } - char *tmp2 = newS(h->end - h->start + 10); + char *tmp2 = helper->newS(h->end - h->start + 10); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(tmp2, buf + h->start, h->end - h->start); h = &_tokens.get()[i + 1]; - delS(tmp2); - if (h->type != FirebaseJson::JSMN_OBJECT && h->type != FirebaseJson::JSMN_ARRAY) + helper->delS(tmp2); + if (h->type != JSMN_OBJECT && h->type != JSMN_ARRAY) { - char *tmp2 = newS(h->end - h->start + 10); + char *tmp2 = helper->newS(h->end - h->start + 10); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strncpy(tmp2, buf + h->start, h->end - h->start); if (printMode != PRINT_MODE_NONE && !tk.skip) { @@ -1736,7 +1833,7 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * strncpy(tmp2, buf + h->start - 1, h->end - h->start + 2); _tbuf += tmp2; } - delS(tmp2); + helper->delS(tmp2); i++; while (_updateTkIndex2(_tbuf, i, depth, searchKey, searchIndex, replace, printMode)) { @@ -1745,10 +1842,10 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * } else { - if (_refToken == i + 1) + if (_parser_info.refToken == i + 1) { _setSkip(depth, true); - _skipDepth = depth; + _parser_info.skipDepth = depth; _tbuf += replace; if (printMode != PRINT_MODE_NONE && (depth > 0 || tk.oindex == tk.olen - 1)) { @@ -1786,13 +1883,13 @@ void FirebaseJson::_removeToken(uint16_t &i, char *buf, int &depth, const char * delay(0); } } - delS(tmp); + helper->delS(tmp); - if (_refToken == -1 && _skipDepth == depth) + if (_parser_info.refToken == -1 && _parser_info.skipDepth == depth) _setSkip(depth, false); } - _nextToken = i + 1; - _refToken = -1; + _parser_info.nextToken = i + 1; + _parser_info.refToken = -1; _lastTk.olen = tk.olen; _lastTk.oindex = tk.oindex; _lastTk.type = tk.type; @@ -1830,33 +1927,39 @@ FirebaseJson::single_child_parent_t FirebaseJson::_findSCParent(int depth) void FirebaseJson::_get(const char *key, int depth, int index) { - _tokenMatch = false; - if (_paresRes) + helper->clearLastError(); + _parser_info.tokenMatch = false; + if (_parser_info.paresRes) { std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(buf, s.c_str()); std::string().swap(s); if (_jsonData.success) { _jsonData._dbuf.clear(); - _parseDepth = depth; - if (_nextToken < 0) - _nextToken = 0; - for (uint16_t i = _nextToken; i < _tokenCount; i++) + _parser_info.parseDepth = depth; + if (_parser_info.nextToken < 0) + _parser_info.nextToken = 0; + for (uint16_t i = _parser_info.nextToken; i < _parser_info.tokenCount; i++) { - _parseToken(i, buf, _nextDepth, (char *)key, index, PRINT_MODE_NONE); - if (_tokenMatch) + _parseToken(i, buf, _parser_info.nextDepth, (char *)key, index, PRINT_MODE_NONE); + if (_parser_info.tokenMatch) break; } } - delS(buf); - if (!_tokenMatch) + helper->delS(buf); + if (!_parser_info.tokenMatch) { - _paresRes = false; + _parser_info.paresRes = false; _jsonData.success = false; _resetParseResult(); } @@ -1916,18 +2019,19 @@ void FirebaseJson::int_parse(const char *path, PRINT_MODE printMode) void FirebaseJson::_parse(const char *path, PRINT_MODE printMode) { + helper->clearLastError(); clearPathTk(); std::string _path; if (_topLevelTkType == JSMN_ARRAY) { - char *_root = strP(FirebaseJson_STR_26); - char *_slash = strP(FirebaseJson_STR_27); + char *_root = helper->strP(fb_json_str_26); + char *_slash = helper->strP(fb_json_str_27); _path = _root; _path += _slash; _path += path; - delS(_root); - delS(_slash); + helper->delS(_root); + helper->delS(_slash); } else _path = path; @@ -1939,17 +2043,12 @@ void FirebaseJson::_parse(const char *path, PRINT_MODE printMode) return; _jsonData.success = false; int len = _pathTk.size(); - _nextDepth = -1; - _nextToken = 0; - _skipDepth = -1; - _parentIndex = -1; - _TkRefOk = false; - _parseCompleted = 0; - _arrReplaced = false; - _refTkIndex = -1; - _remTkIndex = -1; - _remFirstTk = false; - _remLastTk = false; + + _resetParsserInfo(); + + _parser_info.remTkIndex = -1; + _parser_info.remFirstTk = false; + _parser_info.remLastTk = false; _el.clear(); _eltk.clear(); if (len == 0) @@ -1968,7 +2067,7 @@ void FirebaseJson::_parse(const char *path, PRINT_MODE printMode) else _parse(_pathTk[i].tk.c_str(), i, -1, printMode); } - _jsonData.success = _parseCompleted == len; + _jsonData.success = _parser_info.parseCompleted == len; } _el.clear(); _eltk.clear(); @@ -2006,55 +2105,61 @@ size_t FirebaseJson::int_get_jsondata_len() void FirebaseJson::_parse(const char *key, int depth, int index, PRINT_MODE printMode) { - _tokenMatch = false; - if (_paresRes) + helper->clearLastError(); + _parser_info.tokenMatch = false; + if (_parser_info.paresRes) { std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(buf, s.c_str()); std::string().swap(s); - _parseDepth = depth; - if (_nextToken < 0) - _nextToken = 0; + _parser_info.parseDepth = depth; + if (_parser_info.nextToken < 0) + _parser_info.nextToken = 0; - for (uint16_t i = _nextToken; i < _tokenCount; i++) + for (uint16_t i = _parser_info.nextToken; i < _parser_info.tokenCount; i++) { - int oDepth = _nextDepth; + int oDepth = _parser_info.nextDepth; - _parseToken(i, buf, _nextDepth, (char *)key, index, printMode); + _parseToken(i, buf, _parser_info.nextDepth, (char *)key, index, printMode); - if (index > -1 && oDepth == _nextDepth && _tokenMatch) + if (index > -1 && oDepth == _parser_info.nextDepth && _parser_info.tokenMatch) { - _tokenMatch = false; + _parser_info.tokenMatch = false; break; } - if (oDepth > _nextDepth && index == -1) + if (oDepth > _parser_info.nextDepth && index == -1) { - if (_nextDepth > -1 && _nextDepth < (int)_pathTk.size()) + if (_parser_info.nextDepth > -1 && _parser_info.nextDepth < (int)_pathTk.size()) { - if (_pathTk[_nextDepth].matched) + if (_pathTk[_parser_info.nextDepth].matched) { - _tokenMatch = false; + _parser_info.tokenMatch = false; break; } } } - if (_tokenMatch) + if (_parser_info.tokenMatch) { _pathTk[depth].matched = true; break; } } - delS(buf); - if (!_tokenMatch) + helper->delS(buf); + if (!_parser_info.tokenMatch) { - _paresRes = false; + _parser_info.paresRes = false; _jsonData.success = false; } } @@ -2062,28 +2167,34 @@ void FirebaseJson::_parse(const char *key, int depth, int index, PRINT_MODE prin void FirebaseJson::_compile(const char *key, int depth, int index, const char *replace, PRINT_MODE printMode, int refTokenIndex, bool removeTk) { - _tokenMatch = false; - if (_paresRes) + helper->clearLastError(); + _parser_info.tokenMatch = false; + if (_parser_info.paresRes) { std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(buf, s.c_str()); std::string().swap(s); - _parseDepth = depth; - if (_nextToken < 0) - _nextToken = 0; - for (uint16_t i = _nextToken; i < _tokenCount; i++) + _parser_info.parseDepth = depth; + if (_parser_info.nextToken < 0) + _parser_info.nextToken = 0; + for (uint16_t i = _parser_info.nextToken; i < _parser_info.tokenCount; i++) { - _compileToken(i, buf, _nextDepth, key, index, printMode, replace, refTokenIndex, removeTk); - if (_tokenMatch) + _compileToken(i, buf, _parser_info.nextDepth, key, index, printMode, replace, refTokenIndex, removeTk); + if (_parser_info.tokenMatch) break; } - delS(buf); - if (!_tokenMatch) + helper->delS(buf); + if (!_parser_info.tokenMatch) { - _paresRes = false; + _parser_info.paresRes = false; _jsonData.success = false; } } @@ -2091,22 +2202,28 @@ void FirebaseJson::_compile(const char *key, int depth, int index, const char *r void FirebaseJson::_remove(const char *key, int depth, int index, const char *replace, int refTokenIndex, bool removeTk) { - if (_paresRes) + helper->clearLastError(); + if (_parser_info.paresRes) { std::string s; _toStdString(s); - int bufLen = s.length() + 1024; - char *buf = newS(bufLen); + int bufLen = s.length() + _parser_buff_len; + char *buf = helper->newS(bufLen); + if (!buf) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(buf, s.c_str()); std::string().swap(s); - _parseDepth = depth; - if (_nextToken < 0) - _nextToken = 0; - for (uint16_t i = _nextToken; i < _tokenCount; i++) + _parser_info.parseDepth = depth; + if (_parser_info.nextToken < 0) + _parser_info.nextToken = 0; + for (uint16_t i = _parser_info.nextToken; i < _parser_info.tokenCount; i++) { - _removeToken(i, buf, _nextDepth, (char *)key, index, PRINT_MODE_PLAIN, (char *)replace, refTokenIndex, removeTk); + _removeToken(i, buf, _parser_info.nextDepth, (char *)key, index, PRINT_MODE_PLAIN, (char *)replace, refTokenIndex, removeTk); } - delS(buf); + helper->delS(buf); } } @@ -2139,51 +2256,62 @@ int FirebaseJson::_getArrIndex(int index) void FirebaseJson::set(const String &path) { + helper->clearLastError(); _setNull(path.c_str()); } void FirebaseJson::set(const String &path, const String &value) { + helper->clearLastError(); _setString(path.c_str(), value.c_str()); } void FirebaseJson::set(const String &path, const char *value) { + helper->clearLastError(); _setString(path.c_str(), value); } void FirebaseJson::set(const String &path, int value) { + helper->clearLastError(); _setInt(path.c_str(), value); } void FirebaseJson::set(const String &path, unsigned short value) { + helper->clearLastError(); _setInt(path.c_str(), value); } void FirebaseJson::set(const String &path, float value) { + helper->clearLastError(); _setFloat(path.c_str(), value); } void FirebaseJson::set(const String &path, double value) { + helper->clearLastError(); _setDouble(path.c_str(), value); } void FirebaseJson::set(const String &path, bool value) { + helper->clearLastError(); _setBool(path.c_str(), value); } void FirebaseJson::set(const String &path, FirebaseJson &json) { + helper->clearLastError(); _setJson(path.c_str(), &json); } void FirebaseJson::set(const String &path, FirebaseJsonArray &arr) { + helper->clearLastError(); + arr._lastErr = &_lastErr; _setArray(path.c_str(), &arr); } @@ -2208,38 +2336,44 @@ bool FirebaseJson::set(const String &path, T value) void FirebaseJson::_setString(const std::string &path, const std::string &value) { - char *tmp = newS(value.length() + 1024); + helper->clearLastError(); + char *tmp = helper->newS(value.length() + _parser_buff_len); + if (!tmp) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(tmp, _qt); strcat(tmp, value.c_str()); strcat(tmp, _qt); _set(path.c_str(), tmp); - delS(tmp); + helper->delS(tmp); std::string().swap(_jsonData._dbuf); } void FirebaseJson::_setInt(const std::string &path, int value) { - char *tmp = intStr(value); + char *tmp = helper->intStr(value); _set(path.c_str(), tmp); - delS(tmp); + helper->delS(tmp); std::string().swap(_jsonData._dbuf); } void FirebaseJson::_setFloat(const std::string &path, float value) { - char *tmp = floatStr(value); - _trimDouble(tmp); + char *tmp = helper->floatStr(value); + helper->trimDouble(tmp); _set(path.c_str(), tmp); - delS(tmp); + helper->delS(tmp); std::string().swap(_jsonData._dbuf); } void FirebaseJson::_setDouble(const std::string &path, double value) { - char *tmp = doubleStr(value); - _trimDouble(tmp); + char *tmp = helper->doubleStr(value); + helper->trimDouble(tmp); _set(path.c_str(), tmp); - delS(tmp); + helper->delS(tmp); std::string().swap(_jsonData._dbuf); } @@ -2268,6 +2402,7 @@ void FirebaseJson::_setJson(const std::string &path, FirebaseJson *json) void FirebaseJson::_setArray(const std::string &path, FirebaseJsonArray *arr) { + arr->_lastErr = &_lastErr; std::string s; arr->_toStdString(s); _set(path.c_str(), s.c_str()); @@ -2276,18 +2411,19 @@ void FirebaseJson::_setArray(const std::string &path, FirebaseJsonArray *arr) void FirebaseJson::_set(const char *path, const char *data) { + helper->clearLastError(); clearPathTk(); std::string _path; if (_topLevelTkType == JSMN_ARRAY) { - char *_root = strP(FirebaseJson_STR_26); - char *_slash = strP(FirebaseJson_STR_27); + char *_root = helper->strP(fb_json_str_26); + char *_slash = helper->strP(fb_json_str_27); _path = _root; _path += _slash; _path += path; - delS(_root); - delS(_slash); + helper->delS(_root); + helper->delS(_slash); } else _path = path; @@ -2299,18 +2435,12 @@ void FirebaseJson::_set(const char *path, const char *data) return; _jsonData.success = false; int len = _pathTk.size(); - _nextDepth = -1; - _nextToken = 0; - _skipDepth = -1; - _parentIndex = -1; - _TkRefOk = false; - _parseCompleted = 0; - _arrReplaced = false; - _arrInserted = false; - _refTkIndex = -1; - _remTkIndex = -1; - _remFirstTk = false; - _remLastTk = false; + + _resetParsserInfo(); + + _parser_info.remTkIndex = -1; + _parser_info.remFirstTk = false; + _parser_info.remLastTk = false; _el.clear(); _eltk.clear(); for (int i = 0; i < len; i++) @@ -2324,21 +2454,16 @@ void FirebaseJson::_set(const char *path, const char *data) } _el.clear(); _eltk.clear(); - if (_parseCompleted != len) + if (_parser_info.parseCompleted != len) { std::string().swap(_jsonData._dbuf); std::string().swap(_tbuf); - int refTokenIndex = _refTkIndex; - _nextDepth = -1; - _nextToken = 0; - _skipDepth = -1; - _parentIndex = -1; - _TkRefOk = false; - _parseCompleted = 0; - _arrReplaced = false; - _refTkIndex = -1; - _tokenMatch = false; - _paresRes = true; + int refTokenIndex = _parser_info.refTkIndex; + + _resetParsserInfo(); + + _parser_info.tokenMatch = false; + _parser_info.paresRes = true; for (int i = 0; i < len; i++) { if (_isStrTk(i)) @@ -2367,18 +2492,19 @@ void FirebaseJson::_set(const char *path, const char *data) bool FirebaseJson::remove(const String &path) { + helper->clearLastError(); clearPathTk(); std::string _path; if (_topLevelTkType == JSMN_ARRAY) { - char *_root = strP(FirebaseJson_STR_26); - char *_slash = strP(FirebaseJson_STR_27); + char *_root = helper->strP(fb_json_str_26); + char *_slash = helper->strP(fb_json_str_27); _path = _root; _path += _slash; _path += path.c_str(); - delS(_root); - delS(_slash); + helper->delS(_root); + helper->delS(_slash); } else _path = path.c_str(); @@ -2391,17 +2517,12 @@ bool FirebaseJson::remove(const String &path) _jsonData.success = false; int len = _pathTk.size(); - _nextDepth = -1; - _nextToken = 0; - _skipDepth = -1; - _parentIndex = -1; - _TkRefOk = false; - _parseCompleted = 0; - _arrReplaced = false; - _refTkIndex = -1; - _remTkIndex = -1; - _remFirstTk = false; - _remLastTk = false; + + _resetParsserInfo(); + + _parser_info.remTkIndex = -1; + _parser_info.remFirstTk = false; + _parser_info.remLastTk = false; _el.clear(); _eltk.clear(); for (int i = 0; i < len; i++) @@ -2416,19 +2537,14 @@ bool FirebaseJson::remove(const String &path) _el.clear(); _eltk.clear(); std::string().swap(_jsonData._dbuf); - int refTokenIndex = _remTkIndex; - if (_parseCompleted == len) - { - _nextDepth = -1; - _nextToken = 0; - _skipDepth = -1; - _parentIndex = -1; - _TkRefOk = false; - _parseCompleted = 0; - _arrReplaced = false; - _refTkIndex = -1; - _tokenMatch = false; - _paresRes = true; + int refTokenIndex = _parser_info.remTkIndex; + if (_parser_info.parseCompleted == len) + { + + _resetParsserInfo(); + + _parser_info.tokenMatch = false; + _parser_info.paresRes = true; _jsonData.success = true; _lastTk.skip = false; _lastTk.olen = 0; @@ -2453,6 +2569,23 @@ bool FirebaseJson::remove(const String &path) return _jsonData.success; } +fb_json_last_error_t FirebaseJson::getLastError() +{ + return _lastErr; +} + +void FirebaseJson::_resetParsserInfo() +{ + _parser_info.nextDepth = -1; + _parser_info.nextToken = 0; + _parser_info.skipDepth = -1; + _parser_info.parentIndex = -1; + _parser_info.TkRefOk = false; + _parser_info.parseCompleted = 0; + _parser_info.arrReplaced = false; + _parser_info.refTkIndex = -1; +} + void FirebaseJson::_resetParseResult() { _jsonData._type = 0; @@ -2468,34 +2601,45 @@ void FirebaseJson::_resetParseResult() void FirebaseJson::_setElementType() { + helper->clearLastError(); bool typeSet = false; - char *buf = newS(1024); - char *tmp = newS(1024); + char *buf = helper->newS(_parser_buff_len); + char *tmp = helper->newS(_parser_buff_len); + if (!buf || !tmp) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } char *tmp2 = nullptr; - if (_jsonData._type == FirebaseJson::JSMN_PRIMITIVE) + if (_jsonData._type == JSMN_PRIMITIVE) { - tmp2 = newS(_jsonData.stringValue.length() + 1); + tmp2 = helper->newS(_jsonData.stringValue.length() + 1); + if (!tmp2) + { + helper->setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return; + } strcpy(tmp2, _jsonData.stringValue.c_str()); } switch (_jsonData._type) { - case FirebaseJson::JSMN_UNDEFINED: + case JSMN_UNDEFINED: strcpy(buf, _undef); _jsonData.typeNum = JSON_UNDEFINED; break; - case FirebaseJson::JSMN_OBJECT: + case JSMN_OBJECT: strcpy(buf, _obj); _jsonData.typeNum = JSON_OBJECT; break; - case FirebaseJson::JSMN_ARRAY: + case JSMN_ARRAY: strcpy(buf, _arry); _jsonData.typeNum = JSON_ARRAY; break; - case FirebaseJson::JSMN_STRING: + case JSMN_STRING: strcpy(buf, _string); _jsonData.typeNum = JSON_STRING; break; - case FirebaseJson::JSMN_PRIMITIVE: + case JSMN_PRIMITIVE: if (!typeSet && strcmp(tmp2, _tr) == 0) { typeSet = true; @@ -2542,7 +2686,7 @@ void FirebaseJson::_setElementType() } else { - if (strpos(tmp2, tmp, 0) > -1) + if (helper->strpos(tmp2, tmp, 0) > -1) { strcpy(buf, _dbl); _jsonData.floatValue = (float)d; @@ -2567,100 +2711,10 @@ void FirebaseJson::_setElementType() break; } _jsonData.type = buf; - delS(buf); - delS(tmp); + helper->delS(buf); + helper->delS(tmp); if (tmp2) - delS(tmp2); -} - -int FirebaseJson::strpos(const char *haystack, const char *needle, int offset) -{ - size_t len = strlen(haystack); - size_t len2 = strlen(needle); - if (len == 0 || len < len2 || len2 == 0) - return -1; - char *_haystack = newS(len - offset + 1); - _haystack[len - offset] = 0; - strncpy(_haystack, haystack + offset, len - offset); - char *p = strstr(_haystack, needle); - int r = -1; - if (p) - r = p - _haystack + offset; - delS(_haystack); - return r; -} - -int FirebaseJson::rstrpos(const char *haystack, const char *needle, int offset) -{ - size_t len = strlen(haystack); - size_t len2 = strlen(needle); - if (len == 0 || len < len2 || len2 == 0) - return -1; - char *_haystack = newS(len - offset + 1); - _haystack[len - offset] = 0; - strncpy(_haystack, haystack + offset, len - offset); - char *p = rstrstr(_haystack, needle); - int r = -1; - if (p) - r = p - _haystack + offset; - delS(_haystack); - return r; -} - -char *FirebaseJson::rstrstr(const char *haystack, const char *needle) -{ - size_t needle_length = strlen(needle); - const char *haystack_end = haystack + strlen(haystack) - needle_length; - const char *p; - size_t i; - for (p = haystack_end; p >= haystack; --p) - { - for (i = 0; i < needle_length; ++i) - { - if (p[i] != needle[i]) - goto next; - } - return (char *)p; - next:; - } - return 0; -} - -void FirebaseJson::delS(char *p) -{ - if (p != nullptr) - delete[] p; -} - -char *FirebaseJson::newS(size_t len) -{ - char *p = new char[len]; - memset(p, 0, len); - return p; -} - -char *FirebaseJson::newS(char *p, size_t len) -{ - delS(p); - p = newS(len); - return p; -} - -char *FirebaseJson::newS(char *p, size_t len, char *d) -{ - delS(p); - p = newS(len); - strcpy(p, d); - return p; -} - -char *FirebaseJson::strP(PGM_P pgm) -{ - size_t len = strlen_P(pgm) + 1; - char *buf = newS(len); - strcpy_P(buf, pgm); - buf[len - 1] = 0; - return buf; + helper->delS(tmp2); } /** @@ -3058,27 +3112,36 @@ FirebaseJsonArray::FirebaseJsonArray() { _init(); } +FirebaseJsonArray::FirebaseJsonArray(fb_json_last_error_t *lastErr, size_t bufLimit) +{ + if (bufLimit >= 32 || bufLimit <= 8192) + _parser_buff_len = bufLimit; + _lastErr = lastErr; +}; + FirebaseJsonArray::~FirebaseJsonArray() { _finalize(); std::string().swap(_jbuf); + delete helper; }; void FirebaseJsonArray::_init() { _finalize(); - _pd = strP(FirebaseJson_STR_4); - _pf = strP(FirebaseJson_STR_5); - _fls = strP(FirebaseJson_STR_6); - _tr = strP(FirebaseJson_STR_7); - _brk3 = strP(FirebaseJson_STR_10); - _brk4 = strP(FirebaseJson_STR_11); - _nll = strP(FirebaseJson_STR_18); - _root = strP(FirebaseJson_STR_21); - _root2 = strP(FirebaseJson_STR_26); - _qt = strP(FirebaseJson_STR_2); - _slash = strP(FirebaseJson_STR_27); + _pd = helper->strP(fb_json_str_4); + _pf = helper->strP(fb_json_str_5); + _fls = helper->strP(fb_json_str_6); + _tr = helper->strP(fb_json_str_7); + _brk3 = helper->strP(fb_json_str_10); + _brk4 = helper->strP(fb_json_str_11); + _nll = helper->strP(fb_json_str_18); + _root = helper->strP(fb_json_str_21); + _root2 = helper->strP(fb_json_str_26); + _qt = helper->strP(fb_json_str_2); + _slash = helper->strP(fb_json_str_27); + helper->clearLastError(); } std::string *FirebaseJsonArray::int_dbuf() @@ -3108,109 +3171,19 @@ void FirebaseJsonArray::int_set_arr_len(size_t len) _arrLen = len; } -int FirebaseJsonArray::strpos(const char *haystack, const char *needle, int offset) -{ - size_t len = strlen(haystack); - size_t len2 = strlen(needle); - if (len == 0 || len < len2 || len2 == 0) - return -1; - char *_haystack = newS(len - offset + 1); - _haystack[len - offset] = 0; - strncpy(_haystack, haystack + offset, len - offset); - char *p = strstr(_haystack, needle); - int r = -1; - if (p) - r = p - _haystack + offset; - delS(_haystack); - return r; -} - -int FirebaseJsonArray::rstrpos(const char *haystack, const char *needle, int offset) -{ - size_t len = strlen(haystack); - size_t len2 = strlen(needle); - if (len == 0 || len < len2 || len2 == 0) - return -1; - char *_haystack = newS(len - offset + 1); - _haystack[len - offset] = 0; - strncpy(_haystack, haystack + offset, len - offset); - char *p = rstrstr(_haystack, needle); - int r = -1; - if (p) - r = p - _haystack + offset; - delS(_haystack); - return r; -} - -char *FirebaseJsonArray::rstrstr(const char *haystack, const char *needle) -{ - size_t needle_length = strlen(needle); - const char *haystack_end = haystack + strlen(haystack) - needle_length; - const char *p; - size_t i; - for (p = haystack_end; p >= haystack; --p) - { - for (i = 0; i < needle_length; ++i) - { - if (p[i] != needle[i]) - goto next; - } - return (char *)p; - next:; - } - return 0; -} - -void FirebaseJsonArray::delS(char *p) -{ - if (p != nullptr) - delete[] p; -} - -char *FirebaseJsonArray::newS(size_t len) -{ - char *p = new char[len]; - memset(p, 0, len); - return p; -} - -char *FirebaseJsonArray::newS(char *p, size_t len) -{ - delS(p); - p = newS(len); - return p; -} - -char *FirebaseJsonArray::newS(char *p, size_t len, char *d) -{ - delS(p); - p = newS(len); - strcpy(p, d); - return p; -} - -char *FirebaseJsonArray::strP(PGM_P pgm) -{ - size_t len = strlen_P(pgm) + 1; - char *buf = newS(len); - strcpy_P(buf, pgm); - buf[len - 1] = 0; - return buf; -} - void FirebaseJsonArray::_finalize() { - delS(_pd); - delS(_pf); - delS(_fls); - delS(_tr); - delS(_brk3); - delS(_brk4); - delS(_nll); - delS(_root); - delS(_root2); - delS(_qt); - delS(_slash); + helper->delS(_pd); + helper->delS(_pf); + helper->delS(_fls); + helper->delS(_tr); + helper->delS(_brk3); + helper->delS(_brk4); + helper->delS(_nll); + helper->delS(_root); + helper->delS(_root2); + helper->delS(_qt); + helper->delS(_slash); } FirebaseJsonArray &FirebaseJsonArray::add() @@ -3300,28 +3273,28 @@ void FirebaseJsonArray::_addString(const std::string &value) void FirebaseJsonArray::_addInt(int value) { _arrLen++; - char *buf = intStr(value); + char *buf = helper->intStr(value); sprintf(buf, _pd, value); _json._addArrayStr(buf, 60, false); - delS(buf); + helper->delS(buf); } void FirebaseJsonArray::_addFloat(float value) { _arrLen++; - char *buf = floatStr(value); - _trimDouble(buf); + char *buf = helper->floatStr(value); + helper->trimDouble(buf); _json._addArrayStr(buf, 60, false); - delS(buf); + helper->delS(buf); } void FirebaseJsonArray::_addDouble(double value) { _arrLen++; - char *buf = doubleStr(value); - _trimDouble(buf); + char *buf = helper->doubleStr(value); + helper->trimDouble(buf); _json._addArrayStr(buf, 60, false); - delS(buf); + helper->delS(buf); } void FirebaseJsonArray::_addBool(bool value) @@ -3363,16 +3336,16 @@ FirebaseJsonArray &FirebaseJsonArray::setJsonArrayData(const String &data) if (start_pos != -1 && end_pos != -1 && start_pos != end_pos) { - char *r = strP(FirebaseJson_STR_21); + char *r = helper->strP(fb_json_str_21); _json._rawbuf = r; _json._rawbuf += data.c_str(); - delS(r); - r = strP(FirebaseJson_STR_26); - FirebaseJsonData data; + helper->delS(r); + r = helper->strP(fb_json_str_26); + FirebaseJsonData data(_parser_buff_len); _json.get(data, r); - delS(r); + helper->delS(r); data.getArray(*this); - data.stringValue.clear(); + data.stringValue = ""; } return *this; } @@ -3384,14 +3357,14 @@ bool FirebaseJsonArray::get(FirebaseJsonData &jsonData, const String &path) bool FirebaseJsonArray::get(FirebaseJsonData &jsonData, int index) { - char *tmp = intStr(index); + char *tmp = helper->intStr(index); std::string path = ""; path += _brk3; path += tmp; path += _brk4; bool ret = _get(jsonData, path.c_str()); std::string().swap(path); - delS(tmp); + helper->delS(tmp); return ret; } @@ -3435,58 +3408,9 @@ size_t FirebaseJsonArray::size() return _arrLen; } -char *FirebaseJsonArray::floatStr(float value) -{ - char *buf = newS(36); - helper.dtostrf(value, 7, 6, buf); - return buf; -} - -char *FirebaseJsonArray::intStr(int value) -{ - char *buf = newS(36); - sprintf(buf, "%d", value); - return buf; -} - -char *FirebaseJsonArray::boolStr(bool value) -{ - char *buf = nullptr; - if (value) - buf = strP(FirebaseJson_STR_7); - else - buf = strP(FirebaseJson_STR_6); - return buf; -} - -char *FirebaseJsonArray::doubleStr(double value) -{ - char *buf = newS(36); - helper.dtostrf(value, 12, 9, buf); - return buf; -} - -void FirebaseJsonArray::_trimDouble(char *buf) -{ - size_t i = strlen(buf) - 1; - while (buf[i] == '0' && i > 0) - { - if (buf[i - 1] == '.') - { - i--; - break; - } - if (buf[i - 1] != '0') - break; - i--; - } - if (i < strlen(buf) - 1) - buf[i] = '\0'; -} - void FirebaseJsonArray::toString(String &buf, bool prettify) { - char *tmp = newS(1024); + char *tmp = helper->newS(_parser_buff_len); std::string().swap(_json._jsonData._dbuf); std::string().swap(_json._tbuf); _json._toStdString(_jbuf, false); @@ -3501,7 +3425,7 @@ void FirebaseJsonArray::toString(String &buf, bool prettify) _json.clearPathTk(); _json._tokens.reset(); _json._tokens = nullptr; - delS(tmp); + helper->delS(tmp); _json._rawbuf = _json._jsonData._dbuf.substr(1, _json._jsonData._dbuf.length() - 2); buf = _json._jsonData._dbuf.c_str(); std::string().swap(_json._jsonData._dbuf); @@ -3523,14 +3447,14 @@ FirebaseJsonArray &FirebaseJsonArray::clear() } void FirebaseJsonArray::_set2(int index, const char *value, bool isStr) { - char *tmp = newS(50); + char *tmp = helper->newS(50); std::string path = _brk3; sprintf(tmp, "%d", index); path += tmp; path += _brk4; _set(path.c_str(), value, isStr); std::string().swap(path); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_set(const char *path, const char *value, bool isStr) @@ -3539,7 +3463,7 @@ void FirebaseJsonArray::_set(const char *path, const char *value, bool isStr) _json._toStdString(_jbuf, false); _json._rawbuf = _root; _json._rawbuf += _jbuf; - char *tmp2 = newS(strlen(value) + 10); + char *tmp2 = helper->newS(strlen(value) + 10); if (isStr) strcpy_P(tmp2, _qt); strcat(tmp2, value); @@ -3552,18 +3476,18 @@ void FirebaseJsonArray::_set(const char *path, const char *value, bool isStr) _json._strToTk(path2, _json._pathTk, '/'); if (!_json._isArrTk(1)) { - delS(tmp2); + helper->delS(tmp2); goto ex_2; } if (_json._getArrIndex(1) < 0) { - delS(tmp2); + helper->delS(tmp2); goto ex_2; } _json._set(path2.c_str(), tmp2); - delS(tmp2); + helper->delS(tmp2); std::string().swap(path2); if (_json._jsonData.success) { @@ -3679,11 +3603,13 @@ void FirebaseJsonArray::set(const String &path, FirebaseJson &json) void FirebaseJsonArray::set(int index, FirebaseJsonArray &arr) { + arr._lastErr = _lastErr; _setArray(index, &arr); } void FirebaseJsonArray::set(const String &path, FirebaseJsonArray &arr) { + arr._lastErr = _lastErr; _setArray(path, &arr); } @@ -3737,48 +3663,48 @@ void FirebaseJsonArray::_setString(const String &path, const std::string &value) void FirebaseJsonArray::_setInt(int index, int value) { - char *tmp = intStr(value); + char *tmp = helper->intStr(value); _set2(index, tmp, false); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_setInt(const String &path, int value) { - char *tmp = intStr(value); + char *tmp = helper->intStr(value); _set(path.c_str(), tmp, false); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_setFloat(int index, float value) { - char *tmp = floatStr(value); - _trimDouble(tmp); + char *tmp = helper->floatStr(value); + helper->trimDouble(tmp); _set2(index, tmp, false); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_setFloat(const String &path, float value) { - char *tmp = floatStr(value); - _trimDouble(tmp); + char *tmp = helper->floatStr(value); + helper->trimDouble(tmp); _set(path.c_str(), tmp, false); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_setDouble(int index, double value) { - char *tmp = doubleStr(value); - _trimDouble(tmp); + char *tmp = helper->doubleStr(value); + helper->trimDouble(tmp); _set2(index, tmp, false); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_setDouble(const String &path, double value) { - char *tmp = doubleStr(value); - _trimDouble(tmp); + char *tmp = helper->doubleStr(value); + helper->trimDouble(tmp); _set(path.c_str(), tmp, false); - delS(tmp); + helper->delS(tmp); } void FirebaseJsonArray::_setBool(int index, bool value) @@ -3825,6 +3751,7 @@ void FirebaseJsonArray::_setJson(const String &path, FirebaseJson *json) void FirebaseJsonArray::_setArray(int index, FirebaseJsonArray *arr) { + arr->_lastErr = _lastErr; std::string s; arr->_toStdString(s); _set2(index, s.c_str(), false); @@ -3833,6 +3760,7 @@ void FirebaseJsonArray::_setArray(int index, FirebaseJsonArray *arr) void FirebaseJsonArray::_setArray(const String &path, FirebaseJsonArray *arr) { + arr->_lastErr = _lastErr; std::string s; arr->_toStdString(s); _set(path.c_str(), s.c_str(), false); @@ -3841,14 +3769,14 @@ void FirebaseJsonArray::_setArray(const String &path, FirebaseJsonArray *arr) bool FirebaseJsonArray::remove(int index) { - char *tmp = intStr(index); + char *tmp = helper->intStr(index); std::string path = ""; path += _brk3; path += tmp; path += _brk4; bool ret = _remove(path.c_str()); std::string().swap(path); - delS(tmp); + helper->delS(tmp); return ret; } @@ -3905,6 +3833,12 @@ FirebaseJsonData::FirebaseJsonData() { } +FirebaseJsonData::FirebaseJsonData(size_t bufLimit) +{ + if (bufLimit >= 32 || bufLimit <= 8192) + _parser_buff_len = bufLimit; +} + FirebaseJsonData::~FirebaseJsonData() { std::string().swap(_dbuf); @@ -3914,16 +3848,16 @@ bool FirebaseJsonData::getArray(FirebaseJsonArray &jsonArray) { if (typeNum != FirebaseJson::JSON_ARRAY || !success) return false; - char *tmp = new char[1024]; - memset(tmp, 0, 1024); + char *tmp = new char[_parser_buff_len]; + memset(tmp, 0, _parser_buff_len); char *nbuf = new char[2]; memset(nbuf, 0, 2); - strcpy_P(tmp, FirebaseJson_STR_21); + strcpy_P(tmp, fb_json_str_21); jsonArray._json._toStdString(jsonArray._jbuf, false); jsonArray._json._rawbuf = tmp; jsonArray._json._rawbuf += stringValue.c_str(); - memset(tmp, 0, 1024); - strcpy_P(tmp, FirebaseJson_STR_26); + memset(tmp, 0, _parser_buff_len); + strcpy_P(tmp, fb_json_str_26); std::string().swap(jsonArray._json._jsonData._dbuf); std::string().swap(jsonArray._json._tbuf); jsonArray._json._parse(tmp, FirebaseJson::PRINT_MODE_PLAIN); diff --git a/src/json/FirebaseJson.h b/src/json/FirebaseJson.h index 54b6da5..f5bc7f7 100644 --- a/src/json/FirebaseJson.h +++ b/src/json/FirebaseJson.h @@ -1,9 +1,9 @@ -/* - * FirebaseJson, version 2.3.11 +/** + * FirebaseJson, version 2.3.13 * * The Easiest Arduino library to parse, create and edit JSON object using a relative path. * - * March 25, 2021 + * April 4, 2021 * * Features * - None recursive operations @@ -39,6 +39,14 @@ #ifndef FirebaseJson_H #define FirebaseJson_H +#if defined __has_include +#if __has_include() +#include +#undef min +#undef max +#endif +#endif + #include #include #include @@ -47,59 +55,85 @@ #include #include -#if defined __has_include -#if __has_include() -#include -#endif -#endif - -#if defined(__arm__) -#include -#elif defined(__AVR__) -#else -#endif - -static const char FirebaseJson_STR_1[] PROGMEM = ","; -static const char FirebaseJson_STR_2[] PROGMEM = "\""; -static const char FirebaseJson_STR_3[] PROGMEM = ":"; -static const char FirebaseJson_STR_4[] PROGMEM = "%d"; -static const char FirebaseJson_STR_5[] PROGMEM = "%f"; -static const char FirebaseJson_STR_6[] PROGMEM = "false"; -static const char FirebaseJson_STR_7[] PROGMEM = "true"; -static const char FirebaseJson_STR_8[] PROGMEM = "{"; -static const char FirebaseJson_STR_9[] PROGMEM = "}"; -static const char FirebaseJson_STR_10[] PROGMEM = "["; -static const char FirebaseJson_STR_11[] PROGMEM = "]"; -static const char FirebaseJson_STR_12[] PROGMEM = "string"; -static const char FirebaseJson_STR_13[] PROGMEM = "int"; -static const char FirebaseJson_STR_14[] PROGMEM = "double"; -static const char FirebaseJson_STR_15[] PROGMEM = "bool"; -static const char FirebaseJson_STR_16[] PROGMEM = "object"; -static const char FirebaseJson_STR_17[] PROGMEM = "array"; -static const char FirebaseJson_STR_18[] PROGMEM = "null"; -static const char FirebaseJson_STR_19[] PROGMEM = "undefined"; -static const char FirebaseJson_STR_20[] PROGMEM = "."; -static const char FirebaseJson_STR_21[] PROGMEM = "\"root\":"; -static const char FirebaseJson_STR_22[] PROGMEM = " "; -static const char FirebaseJson_STR_24[] PROGMEM = "\n"; -static const char FirebaseJson_STR_25[] PROGMEM = ": "; -static const char FirebaseJson_STR_26[] PROGMEM = "root"; -static const char FirebaseJson_STR_27[] PROGMEM = "/"; +#define FB_JSON_EXTRAS_BUFFER_LENGTH 1024 + +static const char fb_json_str_1[] PROGMEM = ","; +static const char fb_json_str_2[] PROGMEM = "\""; +static const char fb_json_str_3[] PROGMEM = ":"; +static const char fb_json_str_4[] PROGMEM = "%d"; +static const char fb_json_str_5[] PROGMEM = "%f"; +static const char fb_json_str_6[] PROGMEM = "false"; +static const char fb_json_str_7[] PROGMEM = "true"; +static const char fb_json_str_8[] PROGMEM = "{"; +static const char fb_json_str_9[] PROGMEM = "}"; +static const char fb_json_str_10[] PROGMEM = "["; +static const char fb_json_str_11[] PROGMEM = "]"; +static const char fb_json_str_12[] PROGMEM = "string"; +static const char fb_json_str_13[] PROGMEM = "int"; +static const char fb_json_str_14[] PROGMEM = "double"; +static const char fb_json_str_15[] PROGMEM = "bool"; +static const char fb_json_str_16[] PROGMEM = "object"; +static const char fb_json_str_17[] PROGMEM = "array"; +static const char fb_json_str_18[] PROGMEM = "null"; +static const char fb_json_str_19[] PROGMEM = "undefined"; +static const char fb_json_str_20[] PROGMEM = "."; +static const char fb_json_str_21[] PROGMEM = "\"root\":"; +static const char fb_json_str_22[] PROGMEM = " "; +static const char fb_json_str_24[] PROGMEM = "\n"; +static const char fb_json_str_25[] PROGMEM = ": "; +static const char fb_json_str_26[] PROGMEM = "root"; +static const char fb_json_str_27[] PROGMEM = "/"; +static const char fb_json_str_28[] PROGMEM = "memory allocation error"; +static const char fb_json_str_29[] PROGMEM = "invalid character inside JSON object or array"; +static const char fb_json_str_30[] PROGMEM = "incompleted JSON object or array"; +static const char fb_json_str_31[] PROGMEM = "token array buffer is to small"; class FirebaseJson; class FirebaseJsonArray; +typedef struct +{ + int code = 0; + std::string function = ""; + int line = 0; + std::string messagge = ""; +} fb_json_last_error_t; + +typedef struct +{ + int nextDepth = 0; + int nextToken = 0; + int skipDepth = -1; + int parentIndex = -1; + bool TkRefOk = false; + int parseCompleted = -1; + bool arrReplaced = false; + bool arrInserted = false; + int refTkIndex = -1; + int remTkIndex = -1; + bool remFirstTk = false; + bool remLastTk = false; + + int refToken = -1; + int parseDepth = 0; + int tokenCount = 0; + bool tokenMatch = false; + bool collectTk = false; + bool paresRes = false; + +} fb_json_parser_info_t; + class FirebaseJsonHelper { public: - FirebaseJsonHelper(){}; + FirebaseJsonHelper(fb_json_last_error_t *err) { last_err = err; }; ~FirebaseJsonHelper(){}; - /** dtostrf function is taken from + /*** dtostrf function is taken from * https://github.com/stm32duino/Arduino_Core_STM32/blob/master/cores/arduino/avr/dtostrf.c */ - /** + /*** * dtostrf - Emulation for dtostrf function from avr-libc * Copyright (c) 2013 Arduino. All rights reserved. * Written by Cristian Maglie @@ -119,7 +153,7 @@ class FirebaseJsonHelper char *dtostrf(double val, signed char width, unsigned char prec, char *sout) { //Commented code is the original version - /** + /*** char fmt[20]; sprintf(fmt, "%%%d.%df", width, prec); sprintf(sout, fmt, val); @@ -215,6 +249,167 @@ class FirebaseJsonHelper return sout; } + + char *strP(PGM_P pgm) + { + size_t len = strlen_P(pgm) + 1; + char *buf = newS(len); + strcpy_P(buf, pgm); + buf[len - 1] = 0; + return buf; + } + + void setLastError(int code, const char *file, int line, PGM_P msg) + { + if (last_err) + { + last_err->code = code; + last_err->function = file; + last_err->line = line; + char *tmp = strP(msg); + last_err->messagge = tmp; + delS(tmp); + } + } + + void clearLastError() + { + if (last_err) + { + last_err->code = 0; + last_err->function = ""; + last_err->line = 0; + last_err->messagge = ""; + } + } + + int strpos(const char *haystack, const char *needle, int offset) + { + size_t len = strlen(haystack); + size_t len2 = strlen(needle); + if (len == 0 || len < len2 || len2 == 0) + return -1; + char *_haystack = newS(len - offset + 1); + if (!_haystack) + { + setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return -1; + } + _haystack[len - offset] = 0; + strncpy(_haystack, haystack + offset, len - offset); + char *p = strstr(_haystack, needle); + int r = -1; + if (p) + r = p - _haystack + offset; + delS(_haystack); + return r; + } + + int rstrpos(const char *haystack, const char *needle, int offset) + { + size_t len = strlen(haystack); + size_t len2 = strlen(needle); + if (len == 0 || len < len2 || len2 == 0) + return -1; + char *_haystack = newS(len - offset + 1); + if (!_haystack) + { + setLastError(-1, __FILE__, __LINE__, fb_json_str_28); + return -1; + } + _haystack[len - offset] = 0; + strncpy(_haystack, haystack + offset, len - offset); + char *p = rstrstr(_haystack, needle); + int r = -1; + if (p) + r = p - _haystack + offset; + delS(_haystack); + return r; + } + + char *rstrstr(const char *haystack, const char *needle) + { + size_t needle_length = strlen(needle); + const char *haystack_end = haystack + strlen(haystack) - needle_length; + const char *p; + size_t i; + for (p = haystack_end; p >= haystack; --p) + { + for (i = 0; i < needle_length; ++i) + { + if (p[i] != needle[i]) + goto next; + } + return (char *)p; + next:; + } + return 0; + } + + void delS(char *p) + { + if (p != nullptr) + delete[] p; + } + + char *newS(size_t len) + { + char *p = new char[len]; + memset(p, 0, len); + return p; + } + + char *floatStr(float value) + { + char *buf = newS(36); + dtostrf(value, 7, 6, buf); + return buf; + } + + char *intStr(int value) + { + char *buf = newS(36); + sprintf(buf, "%d", value); + return buf; + } + + char *boolStr(bool value) + { + char *buf = nullptr; + if (value) + buf = strP(fb_json_str_7); + else + buf = strP(fb_json_str_6); + return buf; + } + + char *doubleStr(double value) + { + char *buf = newS(36); + dtostrf(value, 12, 9, buf); + return buf; + } + + void trimDouble(char *buf) + { + size_t i = strlen(buf) - 1; + while (buf[i] == '0' && i > 0) + { + if (buf[i - 1] == '.') + { + i--; + break; + } + if (buf[i - 1] != '0') + break; + i--; + } + if (i < strlen(buf) - 1) + buf[i] = '\0'; + } + +private: + fb_json_last_error_t *last_err = nullptr; }; class FirebaseJsonData @@ -224,73 +419,69 @@ class FirebaseJsonData public: FirebaseJsonData(); + FirebaseJsonData(size_t bufLimit); ~FirebaseJsonData(); - /* - Get array data as FirebaseJsonArray object from FirebaseJsonData object. - - @param jsonArray - The returning FirebaseJsonArray object. - - @return bool status for successful operation. - - This should call after parse or get function. - - */ + /** + * Get array data as FirebaseJsonArray object from FirebaseJsonData object. + * + * @param jsonArray - The returning FirebaseJsonArray object. + * @return bool status for successful operation. + * This should call after parse or get function. + */ bool getArray(FirebaseJsonArray &jsonArray); - /* - Get array data as FirebaseJson object from FirebaseJsonData object. - - @param jsonArray - The returning FirebaseJson object. - - @return bool status for successful operation. - - This should call after parse or get function. - - */ + /** + * Get array data as FirebaseJson object from FirebaseJsonData object. + * + * @param jsonArray - The returning FirebaseJson object. + * @return bool status for successful operation. + * This should call after parse or get function. + */ bool getJSON(FirebaseJson &json); - /* - The String value of parses data. - */ + /** + * The String value of parses data. + */ String stringValue = ""; - /* - The int value of parses data. - */ + /** + * The int value of parses data. + */ int intValue = 0; - /* - The float value of parses data. - */ + /** + * The float value of parses data. + */ float floatValue = 0.0f; - /* - The double value of parses data. - */ + /** + * The double value of parses data. + */ double doubleValue = 0.0; - /* - The bool value of parses data. - */ + /** + * The bool value of parses data. + */ bool boolValue = false; - /* - The type String of parses data. - */ + /** + * The type String of parses data. + */ String type = ""; - /* - The type (number) of parses data. - */ + /** + * The type (number) of parses data. + */ uint8_t typeNum = 0; - /* - The success flag of parsing data. - */ + /** + * The success flag of parsing data. + */ bool success = false; private: + size_t _parser_buff_len = FB_JSON_EXTRAS_BUFFER_LENGTH; int _type = 0; int _k_start = 0; int _start = 0; @@ -320,7 +511,8 @@ class FirebaseJson JSON_NULL = 8 } jsonDataType; - typedef enum { + typedef enum + { PRINT_MODE_NONE = -1, PRINT_MODE_PLAIN = 0, PRINT_MODE_PRETTY = 1 @@ -370,14 +562,15 @@ class FirebaseJson bool skip; } tk_index_t; - /** + /*** * JSON type identifier. Basic types are: * o Object * o Array * o String * o Other primitive: number, boolean (true/false) or null */ - typedef enum { + typedef enum + { JSMN_UNDEFINED = 0, JSMN_OBJECT = 1, JSMN_ARRAY = 2, @@ -387,15 +580,15 @@ class FirebaseJson enum fbjs_err { - /* Not enough tokens were provided */ + /** Not enough tokens were provided */ JSMN_ERROR_NOMEM = -1, - /* Invalid character inside JSON string */ + /** Invalid character inside JSON string */ JSMN_ERROR_INVAL = -2, - /* The string is not a full JSON packet, more bytes expected */ + /** The string is not a full JSON packet, more bytes expected */ JSMN_ERROR_PART = -3 }; - /** + /*** * JSON token description. * type type (object, array, string etc.) * start start position in JSON data string @@ -412,363 +605,298 @@ class FirebaseJson #endif } fbjs_tok_t; - /** + /*** * JSON parser. Contains an array of token blocks available. Also stores * the string being parsed now and current position in that string */ typedef struct { - unsigned int pos; /* offset in the JSON string */ - unsigned int toknext; /* next token to allocate */ - int toksuper; /* superior token node, e.g parent object or array */ + unsigned int pos; /** offset in the JSON string */ + unsigned int toknext; /** next token to allocate */ + int toksuper; /** superior token node, e.g parent object or array */ } fbjs_parser; FirebaseJson(); FirebaseJson(std::string &data); ~FirebaseJson(); - /* - Clear internal buffer of FirebaseJson object.z - - @return instance of an object. - - */ + /** + * Clear internal buffer of FirebaseJson object. + * + * @return instance of an object. + */ FirebaseJson &clear(); - /* - Set JSON data (JSON object string) to FirebaseJson object. - - @param data - The JSON object string. - - @return instance of an object. - - */ + /** + * Set JSON data (JSON object string) to FirebaseJson object. + * + * @param data - The JSON object string. + * @return instance of an object. + */ FirebaseJson &setJsonData(const String &data); - /* - Add null to FirebaseJson object. - - @param key - The new key string that null to be added. - - @return instance of an object. - - */ + /** + * Add null to FirebaseJson object. + * + * @param key - The new key string that null to be added. + * @return instance of an object. + */ FirebaseJson &add(const String &key); - /* - Add string to FirebaseJson object. - - @param key - The new key string that string value to be added. - - @param value - The string value for the new specified key. - - @return instance of an object. - - */ + /** + * Add string to FirebaseJson object. + * + * @param key - The new key string that string value to be added. + * @param value - The string value for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, const String &value); - /* - Add string (chars array) to FirebaseJson object. - - @param key - The new key string that string (chars array) value to be added. - - @param value - The char array for the new specified key. - - @return instance of an object. - - */ + /** + * Add string (chars array) to FirebaseJson object. + * + * @param key - The new key string that string (chars array) value to be added. + * @param value - The char array for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, const char *value); - /* - Add integer/unsigned short to FirebaseJson object. - - @param key - The new key string in which value to be added. - - @param value - The integer/unsigned short value for the new specified key. - - @return instance of an object. - - */ + /** + * Add integer/unsigned short to FirebaseJson object. + * + * @param key - The new key string in which value to be added. + * @param value - The integer/unsigned short value for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, int value); FirebaseJson &add(const String &key, unsigned short value); - /* - Add float to FirebaseJson object. - - @param key - The new key string that double value to be added. - - @param value - The double value for the new specified key. - - @return instance of an object. - - */ - + /** + * Add float to FirebaseJson object. + * + * @param key - The new key string that double value to be added. + * @param value - The double value for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, float value); - /* - Add double to FirebaseJson object. - - @param key - The new key string that double value to be added. - - @param value - The double value for the new specified key. - - @return instance of an object. - - */ + /** + * Add double to FirebaseJson object. + * + * @param key - The new key string that double value to be added. + * @param value - The double value for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, double value); - /* - Add boolean to FirebaseJson object. - - @param key - The new key string that bool value to be added. - - @param value - The boolean value for the new specified key. - - @return instance of an object. - - */ + /** + * Add boolean to FirebaseJson object. + * + * @param key - The new key string that bool value to be added. + * @param value - The boolean value for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, bool value); - /* - Add nested FirebaseJson object into FirebaseJson object. - - @param key - The new key string that FirebaseJson object to be added. - - @param json - The FirebaseJson object for the new specified key. - - @return instance of an object. - - */ + /** + * Add nested FirebaseJson object into FirebaseJson object. + * + * @param key - The new key string that FirebaseJson object to be added. + * @param json - The FirebaseJson object for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, FirebaseJson &json); - /* - Add nested FirebaseJsonArray object into FirebaseJson object. - - @param key - The new key string that FirebaseJsonArray object to be added. - - @param arr - The FirebaseJsonArray for the new specified key. - - @return instance of an object. - - */ + /** + * Add nested FirebaseJsonArray object into FirebaseJson object. + * + * @param key - The new key string that FirebaseJsonArray object to be added. + * @param arr - The FirebaseJsonArray for the new specified key. + * @return instance of an object. + */ FirebaseJson &add(const String &key, FirebaseJsonArray &arr); - /* - Get the FirebaseJson object serialized string. - - @param buf - The returning String object. - - @param prettify - Boolean flag for return the pretty format string i.e. with text indentation and newline. - - */ + /** + * Get the FirebaseJson object serialized string. + * + * @param buf - The returning String object. + * @param prettify - Boolean flag for return the pretty format string i.e. with text indentation and newline. + */ void toString(String &buf, bool prettify = false); - /* - Get the value from the specified node path in FirebaseJson object. - - @param jsonData - The returning FirebaseJsonData that holds the returned data. - - @param path - Relative path to the specific node in FirebaseJson object. - - @param prettify - The bool flag for a prettifying string in FirebaseJsonData's stringValue. - - @return boolean status of the operation. - - The FirebaseJsonData object holds the returned data which can be read from the following properties. - - jsonData.stringValue - contains the returned string. - - jsonData.intValue - contains the returned integer value. - - jsonData.floatValue - contains the returned float value. - - jsonData.doubleValue - contains the returned double value. - - jsonData.boolValue - contains the returned boolean value. - - jsonData.success - used to determine the result of the get operation. - - jsonData.type - used to determine the type of returned value in string represent - the types of value e.g. string, int, double, boolean, array, object, null and undefined. - - jsonData.typeNum used to determine the type of returned value is an integer as represented by the following value. - - FirebaseJson::UNDEFINED = 0 - FirebaseJson::OBJECT = 1 - FirebaseJson::ARRAY = 2 - FirebaseJson::STRING = 3 - FirebaseJson::INT = 4 - FirebaseJson::FLOAT = 5 - FirebaseJson::DOUBLE = 6 - FirebaseJson::BOOL = 7 and - FirebaseJson::NULL = 8 - - */ + /** + * Get the value from the specified node path in FirebaseJson object. + * + * @param jsonData - The returning FirebaseJsonData that holds the returned data. + * @param path - Relative path to the specific node in FirebaseJson object. + * @param prettify - The bool flag for a prettifying string in FirebaseJsonData's stringValue. + * @return boolean status of the operation. + * + * The FirebaseJsonData object holds the returned data which can be read from the following properties. + * jsonData.stringValue - contains the returned string. + * jsonData.intValue - contains the returned integer value. + * jsonData.floatValue - contains the returned float value. + * jsonData.doubleValue - contains the returned double value. + * jsonData.boolValue - contains the returned boolean value. + * jsonData.success - used to determine the result of the get operation. + * jsonData.type - used to determine the type of returned value in string represent + * the types of value e.g. string, int, double, boolean, array, object, null and undefined. + * + * jsonData.typeNum used to determine the type of returned value is an integer as represented by the following value. + * FirebaseJson::UNDEFINED = 0 + * FirebaseJson::OBJECT = 1 + * FirebaseJson::ARRAY = 2 + * FirebaseJson::STRING = 3 + * FirebaseJson::INT = 4 + * FirebaseJson::FLOAT = 5 + * FirebaseJson::DOUBLE = 6 + * FirebaseJson::BOOL = 7 and + * FirebaseJson::NULL = 8 + */ bool get(FirebaseJsonData &jsonData, const String &path, bool prettify = false); - /* - Parse and collect all node/array elements in FirebaseJson object. - - @param data - The JSON data string to parse (optional to replace the internal buffer with new data). - - @return number of child/array elements in FirebaseJson object. - - */ + /** + * Parse and collect all node/array elements in FirebaseJson object. + * + * @param data - The JSON data string to parse (optional to replace the internal buffer with new data). + * @return number of child/array elements in FirebaseJson object. + */ size_t iteratorBegin(const char *data = NULL); - /* - Get child/array elements from FirebaseJson objects at specified index. - - @param index - The element index to get. - - @param type - The integer which holds the type of data i.e. JSON_OBJECT and JSON_ARR - - @param key - The string which holds the key/name of an object, can return empty String if the data type is an array. - - @param value - The string which holds the value for the element key or array. - - */ + /** + * Get child/array elements from FirebaseJson objects at specified index. + * + * @param index - The element index to get. + * @param type - The integer which holds the type of data i.e. JSON_OBJECT and JSON_ARR + * @param key - The string which holds the key/name of an object, can return empty String if the data type is an array. + * @param value - The string which holds the value for the element key or array. + */ void iteratorGet(size_t index, int &type, String &key, String &value); - /* - Clear all iterator buffer (should be called since iteratorBegin was called). - - */ + /** + * Clear all iterator buffer (should be called since iteratorBegin was called). + */ void iteratorEnd(); - /* - Set null to FirebaseJson object at the specified node path. - - @param path - The relative path that null to be set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set null to FirebaseJson object at the specified node path. + * + * @param path - The relative path that null to be set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path); - /* - Set String value to FirebaseJson object at the specified node path. - - @param path - The relative path that string value to be set. - - @param value - The string value to set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set String value to FirebaseJson object at the specified node path. + * + * @param path - The relative path that string value to be set. + * @param value - The string value to set. + * + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, const String &value); - /* - Set string (chars array) value to FirebaseJson object at the specified node path. - - @param path - The relative path that string (chars array) to be set. - - @param value - The char array to set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set string (chars array) value to FirebaseJson object at the specified node path. + * + * @param path - The relative path that string (chars array) to be set. + * @param value - The char array to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, const char *value); - /* - Set integer/unsigned short value to FirebaseJson object at specified node path. - - @param path - The relative path that int value to be set. - - @param value - The integer/unsigned short value to set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set integer/unsigned short value to FirebaseJson object at specified node path. + * + * @param path - The relative path that int value to be set. + * @param value - The integer/unsigned short value to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, int value); void set(const String &path, unsigned short value); - /* - Set the float value to FirebaseJson object at the specified node path. - - @param path - The relative path that float value to be set. - - @param value - The float value to set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set the float value to FirebaseJson object at the specified node path. + * + * @param path - The relative path that float value to be set. + * @param value - The float value to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, float value); - /* - Set the double value to FirebaseJson object at the specified node path. - - @param path - The relative path that double value to be set. - - @param value - The double value to set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set the double value to FirebaseJson object at the specified node path. + * + * @param path - The relative path that double value to be set. + * @param value - The double value to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, double value); - /* - Set boolean value to FirebaseJson object at the specified node path. - - @param path - The relative path that bool value to be set. - - @param value - The boolean value to set. - - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set boolean value to FirebaseJson object at the specified node path. + * + * @param path - The relative path that bool value to be set. + * @param value - The boolean value to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, bool value); - /* - Set nested FirebaseJson object to FirebaseJson object at the specified node path. - - @param path - The relative path that nested FirebaseJson object to be set. - - @param json - The FirebaseJson object to set. - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set nested FirebaseJson object to FirebaseJson object at the specified node path. + * + * @param path - The relative path that nested FirebaseJson object to be set. + * @param json - The FirebaseJson object to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, FirebaseJson &json); - /* - Set nested FirebaseJsonAtrray object to FirebaseJson object at specified node path. - - @param path - The relative path that nested FirebaseJsonAtrray object to be set. - - @param arr - The FirebaseJsonAtrray object to set. - - - The relative path can be mixed with array index (number placed inside square brackets) and node names - e.g. /myRoot/[2]/Sensor1/myData/[3]. - - */ + /** + * Set nested FirebaseJsonAtrray object to FirebaseJson object at specified node path. + * + * @param path - The relative path that nested FirebaseJsonAtrray object to be set. + * @param arr - The FirebaseJsonAtrray object to set. + * The relative path can be mixed with array index (number placed inside square brackets) and node names + * e.g. /myRoot/[2]/Sensor1/myData/[3]. + */ void set(const String &path, FirebaseJsonArray &arr); - /* - Remove the specified node and its content. - - @param path - The relative path to remove its contents/children. - - @return bool value represents the success operation. + /** + * Remove the specified node and its content. + * + * @param path - The relative path to remove its contents/children. + * @return bool value represents the success operation. */ bool remove(const String &path); + /** + * Set the parser internal buffer length limit + * + * @param limit The size of internal parer buffer (32 to 8192 bytes) + */ + void setBufferLimit(size_t limit); + + /** + * Get last error of operation. + * + * @return fb_json_last_error_t structured data of error + */ + fb_json_last_error_t getLastError(); + template FirebaseJson &add(const String &key, T value); + template bool set(const String &path, T value); - void int_parse(const char *path, PRINT_MODE printMode); void int_clearPathTk(); void int_clearTokens(); @@ -777,27 +905,16 @@ class FirebaseJson void int_toStdString(std::string &s, bool isJson = true); private: - FirebaseJsonHelper helper; - int _nextToken = 0; - int _refToken = -1; - int _nextDepth = 0; - int _parentIndex = -1; - int _parseDepth = 0; - int _skipDepth = -1; - int _parseCompleted = -1; - int _refTkIndex = -1; - int _remTkIndex = -1; - int _tokenCount = 0; - bool _TkRefOk = false; - bool _tokenMatch = false; - bool _remFirstTk = false; - bool _remLastTk = false; - bool _collectTk = false; - bool _paresRes = false; - bool _arrReplaced = false; - bool _arrInserted = false; + size_t _parser_buff_len = FB_JSON_EXTRAS_BUFFER_LENGTH; + + fb_json_last_error_t _lastErr; + + FirebaseJsonHelper *helper = new FirebaseJsonHelper(&_lastErr); + fbjs_type_t _topLevelTkType = JSMN_OBJECT; + fb_json_parser_info_t _parser_info; + char *_qt = nullptr; char *_tab = nullptr; char *_brk1 = nullptr; @@ -838,6 +955,7 @@ class FirebaseJson FirebaseJson &_setJsonData(std::string &data); FirebaseJson &_add(const char *key, const char *value, size_t klen, size_t vlen, bool isString = true, bool isJson = true); FirebaseJson &_addArrayStr(const char *value, size_t len, bool isString); + void _resetParsserInfo(); void _resetParseResult(); void _setElementType(); void _addString(const std::string &key, const std::string &value); @@ -880,11 +998,6 @@ class FirebaseJson bool _isArrTk(int index); bool _isStrTk(int index); int _getArrIndex(int index); - char *floatStr(float value); - char *doubleStr(double value); - char *intStr(int value); - char *boolStr(bool value); - void _trimDouble(char *buf); void _get(const char *key, int depth, int index = -1); void _ltrim(std::string &str, const std::string &chars = " "); void _rtrim(std::string &str, const std::string &chars = " "); @@ -892,14 +1005,6 @@ class FirebaseJson void _toStdString(std::string &s, bool isJson = true); void _tostr(std::string &s, bool prettify = false); void _strToTk(const std::string &str, std::vector &tk, char delim); - int strpos(const char *haystack, const char *needle, int offset); - int rstrpos(const char *haystack, const char *needle, int offset); - char *rstrstr(const char *haystack, const char *needle); - void delS(char *p); - char *newS(size_t len); - char *newS(char *p, size_t len); - char *newS(char *p, size_t len, char *d); - char *strP(PGM_P pgm); void fbjs_init(fbjs_parser *parser); int fbjs_parse(fbjs_parser *parser, const char *js, size_t len, @@ -922,388 +1027,311 @@ class FirebaseJsonArray public: FirebaseJsonArray(); + FirebaseJsonArray(fb_json_last_error_t *lastErr, size_t bufLimit = FB_JSON_EXTRAS_BUFFER_LENGTH); ~FirebaseJsonArray(); void _init(); void _finalize(); - /* - Add null to FirebaseJsonArray object. - - @return instance of an object. - - */ + /** + * Add null to FirebaseJsonArray object. + * + * @return instance of an object. + */ FirebaseJsonArray &add(); - /* - Add string to FirebaseJsonArray object. - - @param value - The string value to add. - - @return instance of an object. - - */ + /** + * Add string to FirebaseJsonArray object. + * + * @param value - The string value to add. + * @return instance of an object. + */ FirebaseJsonArray &add(const String &value); - /* - Add string (chars arrar) to FirebaseJsonArray object. - - @param value - The char array to add. - - @return instance of an object. - - */ + /** + * Add string (chars arrar) to FirebaseJsonArray object. + * + * @param value - The char array to add. + * @return instance of an object. + */ FirebaseJsonArray &add(const char *value); - /* - Add integer/unsigned short to FirebaseJsonArray object. - - @param value - The integer/unsigned short value to add. - - @return instance of an object. - - */ + /** + * Add integer/unsigned short to FirebaseJsonArray object. + * + * @param value - The integer/unsigned short value to add. + * @return instance of an object. + */ FirebaseJsonArray &add(int value); FirebaseJsonArray &add(unsigned short value); - /* - Add float to FirebaseJsonArray object. - - @param value - The float value to add. - - @return instance of an object. - - */ + /** + * Add float to FirebaseJsonArray object. + * + * @param value - The float value to add. + * @return instance of an object. + */ FirebaseJsonArray &add(float value); - /* - Add double to FirebaseJsonArray object. - - @param value - The double value to add. - - @return instance of an object. - - */ + /** + * Add double to FirebaseJsonArray object. + * + * @param value - The double value to add. + * @return instance of an object. + */ FirebaseJsonArray &add(double value); - /* - Add boolean to FirebaseJsonArray object. - - @param value - The boolean value to add. - - @return instance of an object. - - */ + /** + * Add boolean to FirebaseJsonArray object. + * + * @param value - The boolean value to add. + * @return instance of an object. + */ FirebaseJsonArray &add(bool value); - /* - Add nested FirebaseJson object to FirebaseJsonArray object. - - @param json - The FirebaseJson object to add. - - @return instance of an object. - - */ + /** + * Add nested FirebaseJson object to FirebaseJsonArray object. + * + * @param json - The FirebaseJson object to add. + * @return instance of an object. + */ FirebaseJsonArray &add(FirebaseJson &json); - /* - Add nested FirebaseJsonArray object to FirebaseJsonArray object. - - @param arr - The FirebaseJsonArray object to add. - - @return instance of an object. - - */ + /** + * Add nested FirebaseJsonArray object to FirebaseJsonArray object. + * + * @param arr - The FirebaseJsonArray object to add. + * @return instance of an object. + */ FirebaseJsonArray &add(FirebaseJsonArray &arr); - /* - Set JSON array data (JSON array string) to FirebaseJsonArray object. - - @param data - The JSON array string. - - @return instance of an object. - - */ + /** + * Set JSON array data (JSON array string) to FirebaseJsonArray object. + * + * @param data - The JSON array string. + * @return instance of an object. + */ FirebaseJsonArray &setJsonArrayData(const String &data); - /* - Get the array value at the specified index from the FirebaseJsonArray object. - - @param jsonData - The returning FirebaseJsonData object that holds data at the specified index. - - @param index - Index of data in FirebaseJsonArray object. - - @return boolean status of the operation. - - */ + /** + * Get the array value at the specified index from the FirebaseJsonArray object. + * + * @param jsonData - The returning FirebaseJsonData object that holds data at the specified index. + * @param index - Index of data in FirebaseJsonArray object. + * @return boolean status of the operation. + */ bool get(FirebaseJsonData &jsonData, int index); bool get(FirebaseJsonData *jsonData, int index); - /* - Get the array value at the specified path from FirebaseJsonArray object. - - @param jsonData - The returning FirebaseJsonData object that holds data at the specified path. - - @param path - Relative path to data in FirebaseJsonArray object. - - @return boolean status of the operation. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2 - - */ + /** + * Get the array value at the specified path from FirebaseJsonArray object. + * + * @param jsonData - The returning FirebaseJsonData object that holds data at the specified path. + * @param path - Relative path to data in FirebaseJsonArray object. + * @return boolean status of the operation. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2 + */ bool get(FirebaseJsonData &jsonData, const String &path); - /* - Get the length of the array in FirebaseJsonArray object. - - @return length of the array. - - */ + /** + * Get the length of the array in FirebaseJsonArray object. + * + * @return length of the array. + */ size_t size(); - /* - Get the FirebaseJsonArray object serialized string. - - @param buf - The returning String object. - - @param prettify - Boolean flag for return the pretty format string i.e. with text indentation and newline. - - */ + /** + * Get the FirebaseJsonArray object serialized string. + * + * @param buf - The returning String object. + * @param prettify - Boolean flag for return the pretty format string i.e. with text indentation and newline. + */ void toString(String &buf, bool prettify = false); - /* - Clear all array in FirebaseJsonArray object. - - @return instance of an object. - - */ + /** + * Clear all array in FirebaseJsonArray object. + * + * @return instance of an object. + */ FirebaseJsonArray &clear(); - /* - Set null to FirebaseJsonArray object at specified index. - - @param index - The array index that null to be set. - - */ + /** + * Set null to FirebaseJsonArray object at specified index. + * + * @param index - The array index that null to be set. + */ void set(int index); - /* - Set String to FirebaseJsonArray object at the specified index. - - @param index - The array index that String value to be set. - - @param value - The String to set. - - */ + /** + * Set String to FirebaseJsonArray object at the specified index. + * + * @param index - The array index that String value to be set. + * @param value - The String to set. + */ void set(int index, const String &value); - /* - Set string (chars array) to FirebaseJsonArray object at specified index. - - @param index - The array index that string (chars array) to be set. - - @param value - The char array to set. - - */ + /** + * Set string (chars array) to FirebaseJsonArray object at specified index. + * + * @param index - The array index that string (chars array) to be set. + * @param value - The char array to set. + */ void set(int index, const char *value); - /* - Set integer/unsigned short value to FirebaseJsonArray object at specified index. - - @param index - The array index that int/unsigned short to be set. - - @param value - The integer/unsigned short value to set. - - */ + /** + * Set integer/unsigned short value to FirebaseJsonArray object at specified index. + * + * @param index - The array index that int/unsigned short to be set. + * @param value - The integer/unsigned short value to set. + */ void set(int index, int value); void set(int index, unsigned short value); - /* - Set float value to FirebaseJsonArray object at specified index. - - @param index - The array index that float value to be set. - - @param value - The float value to set. - - */ + /** + * Set float value to FirebaseJsonArray object at specified index. + * + * @param index - The array index that float value to be set. + * @param value - The float value to set. + */ void set(int index, float value); - /* - Set double value to FirebaseJsonArray object at specified index. - - @param index - The array index that double value to be set. - - @param value - The double value to set. - - */ + /** + * Set double value to FirebaseJsonArray object at specified index. + * + * @param index - The array index that double value to be set. + * @param value - The double value to set. + */ void set(int index, double value); - /* - Set boolean value to FirebaseJsonArray object at specified index. - - @param index - The array index that bool value to be set. - - @param value - The boolean value to set. - - */ + /** + * Set boolean value to FirebaseJsonArray object at specified index. + * + * @param index - The array index that bool value to be set. + * @param value - The boolean value to set. + */ void set(int index, bool value); - /* - Set nested FirebaseJson object to FirebaseJsonArray object at specified index. - - @param index - The array index that nested FirebaseJson object to be set. - - @param value - The FirebaseJson object to set. - - */ + /** + * Set nested FirebaseJson object to FirebaseJsonArray object at specified index. + * + * @param index - The array index that nested FirebaseJson object to be set. + * @param value - The FirebaseJson object to set. + */ void set(int index, FirebaseJson &json); - /* - Set nested FirebaseJsonArray object to FirebaseJsonArray object at specified index. - - @param index - The array index that nested FirebaseJsonArray object to be set. - - @param value - The FirebaseJsonArray object to set. - - */ + /** + * Set nested FirebaseJsonArray object to FirebaseJsonArray object at specified index. + * + * @param index - The array index that nested FirebaseJsonArray object to be set. + * @param value - The FirebaseJsonArray object to set. + */ void set(int index, FirebaseJsonArray &arr); - /* - Set null to FirebaseJson object at the specified path. - - @param path - The relative path that null to be set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set null to FirebaseJson object at the specified path. + * + * @param path - The relative path that null to be set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path); - /* - Set String to FirebaseJsonArray object at the specified path. - - @param path - The relative path that string value to be set. - - @param value - The String to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set String to FirebaseJsonArray object at the specified path. + * + * @param path - The relative path that string value to be set. + * @param value - The String to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, const String &value); - /* - Set string (chars array) to FirebaseJsonArray object at the specified path. - - @param path - The relative path that string (chars array) value to be set. - - @param value - The char array to set. - - The relative path must begin with array index (number places inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set string (chars array) to FirebaseJsonArray object at the specified path. + * + * @param path - The relative path that string (chars array) value to be set. + * @param value - The char array to set. + * The relative path must begin with array index (number places inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, const char *value); - /* - Set integer/unsigned short value to FirebaseJsonArray object at specified path. - - @param path - The relative path that integer/unsigned short value to be set. - - @param value - The integer value to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set integer/unsigned short value to FirebaseJsonArray object at specified path. + * + * @param path - The relative path that integer/unsigned short value to be set. + * @param value - The integer value to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, int value); void set(const String &path, unsigned short value); - /* - Set float value to FirebaseJsonArray object at specified path. - - @param path - The relative path that float value to be set. - - @param value - The float to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set float value to FirebaseJsonArray object at specified path. + * + * @param path - The relative path that float value to be set. + * @param value - The float to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, float value); - /* - Set double value to FirebaseJsonArray object at specified path. - - @param path - The relative path that double value to be set. - - @param value - The double to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set double value to FirebaseJsonArray object at specified path. + * + * @param path - The relative path that double value to be set. + * @param value - The double to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, double value); - /* - Set boolean value to FirebaseJsonArray object at specified path. - - @param path - The relative path that bool value to be set. - - @param value - The boolean value to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set boolean value to FirebaseJsonArray object at specified path. + * + * @param path - The relative path that bool value to be set. + * @param value - The boolean value to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, bool value); - /* - Set the nested FirebaseJson object to FirebaseJsonArray object at the specified path. - - @param path - The relative path that nested FirebaseJson object to be set. - - @param value - The FirebaseJson object to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set the nested FirebaseJson object to FirebaseJsonArray object at the specified path. + * + * @param path - The relative path that nested FirebaseJson object to be set. + * @param value - The FirebaseJson object to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, FirebaseJson &json); - /* - Set the nested FirebaseJsonArray object to FirebaseJsonArray object at specified path. - - @param path - The relative path that nested FirebaseJsonArray object to be set. - - @param value - The FirebaseJsonArray object to set. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. - - */ + /** + * Set the nested FirebaseJsonArray object to FirebaseJsonArray object at specified path. + * + * @param path - The relative path that nested FirebaseJsonArray object to be set. + * @param value - The FirebaseJsonArray object to set. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would get the data from myData key inside the array indexes 2. + */ void set(const String &path, FirebaseJsonArray &arr); - /* - Remove the array value at the specified index from the FirebaseJsonArray object. - - @param index - The array index to be removed. - - @return bool value represents the successful operation. - + /** + * Remove the array value at the specified index from the FirebaseJsonArray object. + * + * @param index - The array index to be removed. + * @return bool value represents the successful operation. */ bool remove(int index); - /* - Remove the array value at the specified path from FirebaseJsonArray object. - - @param path - The relative path to array in FirebaseJsonArray object to be removed. - - @return bool value represents the successful operation. - - The relative path must begin with array index (number placed inside square brackets) followed by - other array indexes or node names e.g. /[2]/myData would remove the data of myData key inside the array indexes 2. - + /** + * Remove the array value at the specified path from FirebaseJsonArray object. + * + * @param path - The relative path to array in FirebaseJsonArray object to be removed. + * @return bool value represents the successful operation. + * The relative path must begin with array index (number placed inside square brackets) followed by + * other array indexes or node names e.g. /[2]/myData would remove the data of myData key inside the array indexes 2. */ bool remove(const String &path); @@ -1314,8 +1342,6 @@ class FirebaseJsonArray template FirebaseJsonArray &add(T value); - - std::string *int_dbuf(); std::string *int_tbuf(); std::string *int_jbuf(); @@ -1325,7 +1351,9 @@ class FirebaseJsonArray void int_toStdString(std::string &s); private: - FirebaseJsonHelper helper; + fb_json_last_error_t *_lastErr = nullptr; + size_t _parser_buff_len = FB_JSON_EXTRAS_BUFFER_LENGTH; + FirebaseJsonHelper *helper = new FirebaseJsonHelper(_lastErr); std::string _jbuf = ""; FirebaseJson _json; size_t _arrLen = 0; @@ -1370,19 +1398,6 @@ class FirebaseJsonArray void _set(const char *path, const char *value, bool isStr = true); bool _get(FirebaseJsonData &jsonData, const char *path); bool _remove(const char *path); - void _trimDouble(char *buf); - char *floatStr(float value); - char *doubleStr(double value); - char *intStr(int value); - char *boolStr(bool value); - char *strP(PGM_P pgm); - int strpos(const char *haystack, const char *needle, int offset); - int rstrpos(const char *haystack, const char *needle, int offset); - char *rstrstr(const char *haystack, const char *needle); - void delS(char *p); - char *newS(size_t len); - char *newS(char *p, size_t len); - char *newS(char *p, size_t len, char *d); }; #endif \ No newline at end of file