diff options
Diffstat (limited to 'include/lib/ArduinoJson/Deserialization/JsonParserImpl.hpp')
-rw-r--r-- | include/lib/ArduinoJson/Deserialization/JsonParserImpl.hpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/Deserialization/JsonParserImpl.hpp b/include/lib/ArduinoJson/Deserialization/JsonParserImpl.hpp new file mode 100644 index 0000000..5042673 --- /dev/null +++ b/include/lib/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -0,0 +1,189 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "Comments.hpp" +#include "JsonParser.hpp" + +template <typename TReader, typename TWriter> +inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat( + TReader &reader, char charToSkip) { + skipSpacesAndComments(reader); + if (reader.current() != charToSkip) return false; + reader.move(); + return true; +} + +template <typename TReader, typename TWriter> +inline bool +ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo( + JsonVariant *destination) { + skipSpacesAndComments(_reader); + + switch (_reader.current()) { + case '[': + return parseArrayTo(destination); + + case '{': + return parseObjectTo(destination); + + default: + return parseStringTo(destination); + } +} + +template <typename TReader, typename TWriter> +inline ArduinoJson::JsonArray & +ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() { + if (_nestingLimit == 0) return JsonArray::invalid(); + _nestingLimit--; + + // Create an empty array + JsonArray &array = _buffer->createArray(); + + // Check opening braket + if (!eat('[')) goto ERROR_MISSING_BRACKET; + if (eat(']')) goto SUCCESS_EMPTY_ARRAY; + + // Read each value + for (;;) { + // 1 - Parse value + JsonVariant value; + if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; + if (!array.add(value)) goto ERROR_NO_MEMORY; + + // 2 - More values? + if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY; + if (!eat(',')) goto ERROR_MISSING_COMMA; + } + +SUCCESS_EMPTY_ARRAY: +SUCCES_NON_EMPTY_ARRAY: + _nestingLimit++; + return array; + +ERROR_INVALID_VALUE: +ERROR_MISSING_BRACKET: +ERROR_MISSING_COMMA: +ERROR_NO_MEMORY: + return JsonArray::invalid(); +} + +template <typename TReader, typename TWriter> +inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo( + JsonVariant *destination) { + JsonArray &array = parseArray(); + if (!array.success()) return false; + + *destination = array; + return true; +} + +template <typename TReader, typename TWriter> +inline ArduinoJson::JsonObject & +ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() { + if (_nestingLimit == 0) return JsonObject::invalid(); + _nestingLimit--; + + // Create an empty object + JsonObject &object = _buffer->createObject(); + + // Check opening brace + if (!eat('{')) goto ERROR_MISSING_BRACE; + if (eat('}')) goto SUCCESS_EMPTY_OBJECT; + + // Read each key value pair + for (;;) { + // 1 - Parse key + const char *key = parseString(); + if (!key) goto ERROR_INVALID_KEY; + if (!eat(':')) goto ERROR_MISSING_COLON; + + // 2 - Parse value + JsonVariant value; + if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; + if (!object.set(key, value)) goto ERROR_NO_MEMORY; + + // 3 - More keys/values? + if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT; + if (!eat(',')) goto ERROR_MISSING_COMMA; + } + +SUCCESS_EMPTY_OBJECT: +SUCCESS_NON_EMPTY_OBJECT: + _nestingLimit++; + return object; + +ERROR_INVALID_KEY: +ERROR_INVALID_VALUE: +ERROR_MISSING_BRACE: +ERROR_MISSING_COLON: +ERROR_MISSING_COMMA: +ERROR_NO_MEMORY: + return JsonObject::invalid(); +} + +template <typename TReader, typename TWriter> +inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo( + JsonVariant *destination) { + JsonObject &object = parseObject(); + if (!object.success()) return false; + + *destination = object; + return true; +} + +template <typename TReader, typename TWriter> +inline const char * +ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() { + typename RemoveReference<TWriter>::type::String str = _writer.startString(); + + skipSpacesAndComments(_reader); + char c = _reader.current(); + + if (isQuote(c)) { // quotes + _reader.move(); + char stopChar = c; + for (;;) { + c = _reader.current(); + if (c == '\0') break; + _reader.move(); + + if (c == stopChar) break; + + if (c == '\\') { + // replace char + c = Encoding::unescapeChar(_reader.current()); + if (c == '\0') break; + _reader.move(); + } + + str.append(c); + } + } else { // no quotes + for (;;) { + if (!canBeInNonQuotedString(c)) break; + _reader.move(); + str.append(c); + c = _reader.current(); + } + } + + return str.c_str(); +} + +template <typename TReader, typename TWriter> +inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseStringTo( + JsonVariant *destination) { + bool hasQuotes = isQuote(_reader.current()); + const char *value = parseString(); + if (value == NULL) return false; + if (hasQuotes) { + *destination = value; + } else { + *destination = RawJson(value); + } + return true; +} |