forked from bblanchon/ArduinoJson
Added JsonError
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonError.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "../TypeTraits/IsConst.hpp"
|
||||
#include "StringWriter.hpp"
|
||||
@ -24,9 +25,9 @@ class JsonParser {
|
||||
_reader(reader),
|
||||
_writer(writer),
|
||||
_nestingLimit(nestingLimit) {}
|
||||
bool parse(JsonArray &destination);
|
||||
bool parse(JsonObject &destination);
|
||||
bool parse(JsonVariant &destination);
|
||||
JsonError parse(JsonArray &destination);
|
||||
JsonError parse(JsonObject &destination);
|
||||
JsonError parse(JsonVariant &destination);
|
||||
|
||||
private:
|
||||
JsonParser &operator=(const JsonParser &); // non-copiable
|
||||
@ -37,12 +38,12 @@ class JsonParser {
|
||||
}
|
||||
|
||||
const char *parseString();
|
||||
bool parseAnythingTo(JsonVariant *destination);
|
||||
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
|
||||
JsonError parseAnythingTo(JsonVariant *destination);
|
||||
FORCE_INLINE JsonError parseAnythingToUnsafe(JsonVariant *destination);
|
||||
|
||||
inline bool parseArrayTo(JsonVariant *destination);
|
||||
inline bool parseObjectTo(JsonVariant *destination);
|
||||
inline bool parseStringTo(JsonVariant *destination);
|
||||
inline JsonError parseArrayTo(JsonVariant *destination);
|
||||
inline JsonError parseObjectTo(JsonVariant *destination);
|
||||
inline JsonError parseStringTo(JsonVariant *destination);
|
||||
|
||||
static inline bool isBetween(char c, char min, char max) {
|
||||
return min <= c && c <= max;
|
||||
|
@ -18,18 +18,18 @@ inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
|
||||
JsonVariant *destination) {
|
||||
if (_nestingLimit == 0) return false;
|
||||
if (_nestingLimit == 0) return JsonError::TooDeep;
|
||||
_nestingLimit--;
|
||||
bool success = parseAnythingToUnsafe(destination);
|
||||
JsonError error = parseAnythingToUnsafe(destination);
|
||||
_nestingLimit++;
|
||||
return success;
|
||||
return error;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
|
||||
JsonVariant *destination) {
|
||||
skipSpacesAndComments(_reader);
|
||||
@ -47,92 +47,76 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
|
||||
JsonArray &array) {
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(JsonArray &array) {
|
||||
// Check opening braket
|
||||
if (!eat('[')) goto ERROR_MISSING_BRACKET;
|
||||
if (eat(']')) goto SUCCESS_EMPTY_ARRAY;
|
||||
if (!eat('[')) return JsonError::OpeningBracketExpected;
|
||||
if (eat(']')) return JsonError::Ok;
|
||||
|
||||
// Read each value
|
||||
for (;;) {
|
||||
// 1 - Parse value
|
||||
JsonVariant value;
|
||||
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
|
||||
if (!array.add(value)) goto ERROR_NO_MEMORY;
|
||||
JsonError error = parseAnythingTo(&value);
|
||||
if (error != JsonError::Ok) return error;
|
||||
if (!array.add(value)) return JsonError::NoMemory;
|
||||
|
||||
// 2 - More values?
|
||||
if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY;
|
||||
if (!eat(',')) goto ERROR_MISSING_COMMA;
|
||||
if (eat(']')) return JsonError::Ok;
|
||||
if (!eat(',')) return JsonError::ClosingBracketExpected;
|
||||
}
|
||||
|
||||
SUCCESS_EMPTY_ARRAY:
|
||||
SUCCES_NON_EMPTY_ARRAY:
|
||||
return true;
|
||||
|
||||
ERROR_INVALID_VALUE:
|
||||
ERROR_MISSING_BRACKET:
|
||||
ERROR_MISSING_COMMA:
|
||||
ERROR_NO_MEMORY:
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
|
||||
JsonObject &object) {
|
||||
// Check opening brace
|
||||
if (!eat('{')) goto ERROR_MISSING_BRACE;
|
||||
if (eat('}')) goto SUCCESS_EMPTY_OBJECT;
|
||||
if (!eat('{')) return JsonError::OpeningBraceExpected;
|
||||
if (eat('}')) return JsonError::Ok;
|
||||
|
||||
// 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;
|
||||
if (!key) return JsonError::NoMemory;
|
||||
if (!eat(':')) return JsonError::ColonExpected;
|
||||
|
||||
// 2 - Parse value
|
||||
JsonVariant value;
|
||||
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
|
||||
if (!object.set(key, value)) goto ERROR_NO_MEMORY;
|
||||
JsonError error = parseAnythingTo(&value);
|
||||
if (error != JsonError::Ok) return error;
|
||||
if (!object.set(key, value)) return JsonError::NoMemory;
|
||||
|
||||
// 3 - More keys/values?
|
||||
if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT;
|
||||
if (!eat(',')) goto ERROR_MISSING_COMMA;
|
||||
if (eat('}')) return JsonError::Ok;
|
||||
if (!eat(',')) return JsonError::ClosingBraceExpected;
|
||||
}
|
||||
|
||||
SUCCESS_EMPTY_OBJECT:
|
||||
SUCCESS_NON_EMPTY_OBJECT:
|
||||
return true;
|
||||
|
||||
ERROR_INVALID_KEY:
|
||||
ERROR_INVALID_VALUE:
|
||||
ERROR_MISSING_BRACE:
|
||||
ERROR_MISSING_COLON:
|
||||
ERROR_MISSING_COMMA:
|
||||
ERROR_NO_MEMORY:
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
|
||||
JsonVariant &variant) {
|
||||
return parseAnythingTo(&variant);
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
|
||||
JsonVariant *destination) {
|
||||
JsonArray *array = new (_buffer) JsonArray(_buffer);
|
||||
if (!array) return false;
|
||||
if (!array) return JsonError::NoMemory;
|
||||
*destination = array;
|
||||
return parse(*array);
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
|
||||
JsonVariant *destination) {
|
||||
JsonObject *object = new (_buffer) JsonObject(_buffer);
|
||||
if (!object) return false;
|
||||
if (!object) return JsonError::NoMemory;
|
||||
*destination = object;
|
||||
return parse(*object);
|
||||
}
|
||||
@ -177,15 +161,16 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseStringTo(
|
||||
inline ArduinoJson::JsonError
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseStringTo(
|
||||
JsonVariant *destination) {
|
||||
bool hasQuotes = isQuote(_reader.current());
|
||||
const char *value = parseString();
|
||||
if (value == NULL) return false;
|
||||
if (value == NULL) return JsonError::NoMemory;
|
||||
if (hasQuotes) {
|
||||
*destination = value;
|
||||
} else {
|
||||
*destination = RawJson(value);
|
||||
}
|
||||
return true;
|
||||
return JsonError::Ok;
|
||||
}
|
||||
|
83
src/ArduinoJson/JsonError.hpp
Normal file
83
src/ArduinoJson/JsonError.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
class JsonError {
|
||||
public:
|
||||
enum Code {
|
||||
Ok,
|
||||
OpeningBraceExpected,
|
||||
ClosingBraceExpected,
|
||||
OpeningBracketExpected,
|
||||
ClosingBracketExpected,
|
||||
ColonExpected,
|
||||
TooDeep,
|
||||
NoMemory
|
||||
};
|
||||
|
||||
JsonError(Code code) : _code(code) {}
|
||||
|
||||
bool operator==(Code code) const {
|
||||
return _code == code;
|
||||
}
|
||||
|
||||
bool operator!=(Code code) const {
|
||||
return _code != code;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return _code != Ok;
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return to_string(_code);
|
||||
}
|
||||
|
||||
friend const char* to_string(const JsonError err) {
|
||||
return to_string(err._code);
|
||||
}
|
||||
|
||||
friend const char* to_string(JsonError::Code code) {
|
||||
switch (code) {
|
||||
case Ok:
|
||||
return "Ok";
|
||||
case OpeningBraceExpected:
|
||||
return "OpeningBraceExpected";
|
||||
case ClosingBraceExpected:
|
||||
return "ClosingBraceExpected";
|
||||
case OpeningBracketExpected:
|
||||
return "OpeningBracketExpected";
|
||||
case ClosingBracketExpected:
|
||||
return "ClosingBracketExpected";
|
||||
case ColonExpected:
|
||||
return "ColonExpected";
|
||||
case TooDeep:
|
||||
return "TooDeep";
|
||||
case NoMemory:
|
||||
return "NoMemory";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Code _code;
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream& operator<<(std::ostream& s, const JsonError& e) {
|
||||
s << to_string(e);
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& s, JsonError::Code e) {
|
||||
s << to_string(e);
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ArduinoJson
|
@ -7,33 +7,36 @@
|
||||
#include "Deserialization/JsonParser.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
// bool deserializeJson(TDestination& destination, TString json);
|
||||
// JsonError deserializeJson(TDestination& destination, TString json);
|
||||
// TDestination = JsonArray, JsonObject, JsonVariant
|
||||
// TString = const std::string&, const String&
|
||||
template <typename TDestination, typename TString>
|
||||
typename Internals::EnableIf<!Internals::IsArray<TString>::value, bool>::type
|
||||
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
|
||||
JsonError>::type
|
||||
deserializeJson(TDestination &destination, const TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(&destination.buffer(), json, nestingLimit)
|
||||
.parse(destination);
|
||||
}
|
||||
//
|
||||
// bool deserializeJson(TDestination& destination, TString json);
|
||||
// JsonError deserializeJson(TDestination& destination, TString json);
|
||||
// TDestination = JsonArray, JsonObject, JsonVariant
|
||||
// TString = const char*, const char[N], const FlashStringHelper*
|
||||
template <typename TDestination, typename TString>
|
||||
bool deserializeJson(TDestination &destination, TString *json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
JsonError deserializeJson(
|
||||
TDestination &destination, TString *json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(&destination.buffer(), json, nestingLimit)
|
||||
.parse(destination);
|
||||
}
|
||||
//
|
||||
// bool deserializeJson(TDestination& destination, TString json);
|
||||
// JsonError deserializeJson(TDestination& destination, TString json);
|
||||
// TDestination = JsonArray, JsonObject, JsonVariant
|
||||
// TString = std::istream&, Stream&
|
||||
template <typename TDestination, typename TString>
|
||||
bool deserializeJson(TDestination &destination, TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
JsonError deserializeJson(
|
||||
TDestination &destination, TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(&destination.buffer(), json, nestingLimit)
|
||||
.parse(destination);
|
||||
}
|
||||
|
Reference in New Issue
Block a user