forked from bblanchon/ArduinoJson
Redesigned JsonVariant to leverage converting constructors instead of assignment operators
This commit is contained in:
@ -38,25 +38,27 @@ bool JsonParser::skip(const char *wordToSkip) {
|
||||
return *charToSkip == '\0';
|
||||
}
|
||||
|
||||
void JsonParser::parseAnythingTo(JsonVariant &destination) {
|
||||
if (_nestingLimit == 0) return;
|
||||
bool JsonParser::parseAnythingTo(JsonVariant *destination) {
|
||||
if (_nestingLimit == 0) return false;
|
||||
_nestingLimit--;
|
||||
bool success = parseAnythingToUnsafe(destination);
|
||||
_nestingLimit++;
|
||||
return success;
|
||||
}
|
||||
|
||||
inline bool JsonParser::parseAnythingToUnsafe(JsonVariant *destination) {
|
||||
skipSpaces();
|
||||
|
||||
switch (*_ptr) {
|
||||
case '[':
|
||||
destination = parseArray();
|
||||
break;
|
||||
return parseArrayTo(destination);
|
||||
|
||||
case '{':
|
||||
destination = parseObject();
|
||||
break;
|
||||
return parseObjectTo(destination);
|
||||
|
||||
case 't':
|
||||
case 'f':
|
||||
parseBooleanTo(destination);
|
||||
break;
|
||||
return parseBooleanTo(destination);
|
||||
|
||||
case '-':
|
||||
case '.':
|
||||
@ -70,20 +72,14 @@ void JsonParser::parseAnythingTo(JsonVariant &destination) {
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
parseNumberTo(destination);
|
||||
break;
|
||||
return parseNumberTo(destination);
|
||||
|
||||
case 'n':
|
||||
parseNullTo(destination);
|
||||
break;
|
||||
return parseNullTo(destination);
|
||||
|
||||
case '\'':
|
||||
case '\"':
|
||||
destination = parseString();
|
||||
break;
|
||||
default:
|
||||
return parseStringTo(destination);
|
||||
}
|
||||
|
||||
_nestingLimit++;
|
||||
}
|
||||
|
||||
JsonArray &JsonParser::parseArray() {
|
||||
@ -97,9 +93,9 @@ JsonArray &JsonParser::parseArray() {
|
||||
// Read each value
|
||||
for (;;) {
|
||||
// 1 - Parse value
|
||||
JsonVariant &value = array.add();
|
||||
parseAnythingTo(value);
|
||||
if (!value.success()) goto ERROR_INVALID_VALUE;
|
||||
JsonVariant value;
|
||||
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
|
||||
if (!array.add(value)) goto ERROR_NO_MEMORY;
|
||||
|
||||
// 2 - More values?
|
||||
if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
|
||||
@ -113,9 +109,18 @@ SUCCES_NON_EMPTY_ARRAY:
|
||||
ERROR_INVALID_VALUE:
|
||||
ERROR_MISSING_BRACKET:
|
||||
ERROR_MISSING_COMMA:
|
||||
ERROR_NO_MEMORY:
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
bool JsonParser::parseArrayTo(JsonVariant *destination) {
|
||||
JsonArray &array = parseArray();
|
||||
if (!array.success()) return false;
|
||||
|
||||
*destination = array;
|
||||
return true;
|
||||
}
|
||||
|
||||
JsonObject &JsonParser::parseObject() {
|
||||
// Create an empty object
|
||||
JsonObject &object = _buffer->createObject();
|
||||
@ -132,9 +137,9 @@ JsonObject &JsonParser::parseObject() {
|
||||
if (!skip(':')) goto ERROR_MISSING_COLON;
|
||||
|
||||
// 2 - Parse value
|
||||
JsonVariant &value = object.add(key);
|
||||
parseAnythingTo(value);
|
||||
if (!value.success()) goto ERROR_INVALID_VALUE;
|
||||
JsonVariant value;
|
||||
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
|
||||
if (!object.set(key, value)) goto ERROR_NO_MEMORY;
|
||||
|
||||
// 3 - More keys/values?
|
||||
if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
|
||||
@ -150,19 +155,31 @@ ERROR_INVALID_VALUE:
|
||||
ERROR_MISSING_BRACE:
|
||||
ERROR_MISSING_COLON:
|
||||
ERROR_MISSING_COMMA:
|
||||
ERROR_NO_MEMORY:
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
void JsonParser::parseBooleanTo(JsonVariant &destination) {
|
||||
if (skip("true"))
|
||||
destination = true;
|
||||
else if (skip("false"))
|
||||
destination = false;
|
||||
else
|
||||
destination = JsonVariant::invalid();
|
||||
bool JsonParser::parseObjectTo(JsonVariant *destination) {
|
||||
JsonObject &object = parseObject();
|
||||
if (!object.success()) return false;
|
||||
|
||||
*destination = object;
|
||||
return true;
|
||||
}
|
||||
|
||||
void JsonParser::parseNumberTo(JsonVariant &destination) {
|
||||
bool JsonParser::parseBooleanTo(JsonVariant *destination) {
|
||||
if (skip("true")) {
|
||||
*destination = true;
|
||||
return true;
|
||||
} else if (skip("false")) {
|
||||
*destination = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonParser::parseNumberTo(JsonVariant *destination) {
|
||||
char *endOfLong;
|
||||
long longValue = strtol(_ptr, &endOfLong, 10);
|
||||
char stopChar = *endOfLong;
|
||||
@ -176,22 +193,28 @@ void JsonParser::parseNumberTo(JsonVariant &destination) {
|
||||
// Count the decimal digits
|
||||
uint8_t decimals = static_cast<uint8_t>(_ptr - endOfLong - 1);
|
||||
// Set the variant as a double
|
||||
destination.set(doubleValue, decimals);
|
||||
*destination = JsonVariant(doubleValue, decimals);
|
||||
} else {
|
||||
// No => set the variant as a long
|
||||
_ptr = endOfLong;
|
||||
destination = longValue;
|
||||
*destination = longValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void JsonParser::parseNullTo(JsonVariant &destination) {
|
||||
bool JsonParser::parseNullTo(JsonVariant *destination) {
|
||||
const char *NULL_STRING = NULL;
|
||||
if (skip("null"))
|
||||
destination = NULL_STRING;
|
||||
else
|
||||
destination = JsonVariant::invalid();
|
||||
if (!skip("null")) return false;
|
||||
*destination = NULL_STRING;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *JsonParser::parseString() {
|
||||
return QuotedString::extractFrom(_ptr, &_ptr);
|
||||
}
|
||||
|
||||
bool JsonParser::parseStringTo(JsonVariant *destination) {
|
||||
const char *value = parseString();
|
||||
*destination = value;
|
||||
return value != NULL;
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ using namespace ArduinoJson;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
template <typename T>
|
||||
int List<T>::size() const {
|
||||
int nodeCount = 0;
|
||||
size_t List<T>::size() const {
|
||||
size_t nodeCount = 0;
|
||||
for (node_type *node = _firstNode; node; node = node->next) nodeCount++;
|
||||
return nodeCount;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ inline size_t Prettyfier::handleMarkupChar(uint8_t c) {
|
||||
return handleBlockClose(c);
|
||||
|
||||
case ':':
|
||||
return handleColumn();
|
||||
return handleColon();
|
||||
|
||||
case ',':
|
||||
return handleComma();
|
||||
@ -54,7 +54,7 @@ inline size_t Prettyfier::handleBlockClose(uint8_t c) {
|
||||
return unindentIfNeeded() + _sink.write(c);
|
||||
}
|
||||
|
||||
inline size_t Prettyfier::handleColumn() {
|
||||
inline size_t Prettyfier::handleColon() {
|
||||
return _sink.write(':') + _sink.write(' ');
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user