Merged MsgPackError and JsonError into DeserializationError.

Return NotSupported if the JSON input contains "\u".
This commit is contained in:
Benoit Blanchon
2018-05-15 18:23:09 +02:00
parent ccb54136a2
commit 4592f23260
38 changed files with 574 additions and 636 deletions

View File

@ -37,7 +37,7 @@ HEAD
> >
> ```c++ > ```c++
> DynamicJsonDocument doc; > DynamicJsonDocument doc;
> JsonError error = deserializeJson(doc, json); > DeserializationError error = deserializeJson(doc, json);
> if (error) { > if (error) {
> >
> } > }

View File

@ -35,7 +35,7 @@ void loadConfiguration(const char *filename, Config &config) {
StaticJsonDocument<512> doc; StaticJsonDocument<512> doc;
// Deserialize the JSON document // Deserialize the JSON document
JsonError error = deserializeJson(doc, file); DeserializationError error = deserializeJson(doc, file);
if (error) if (error)
Serial.println(F("Failed to read file, using default configuration")); Serial.println(F("Failed to read file, using default configuration"));

View File

@ -76,7 +76,7 @@ void setup() {
DynamicJsonDocument doc(capacity); DynamicJsonDocument doc(capacity);
// Parse JSON object // Parse JSON object
JsonError error = deserializeJson(doc, client); DeserializationError error = deserializeJson(doc, client);
if (error) { if (error) {
Serial.print(F("deserializeJson() failed: ")); Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str()); Serial.println(error.c_str());

View File

@ -32,7 +32,7 @@ void setup() {
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
// Deserialize the JSON document // Deserialize the JSON document
JsonError error = deserializeJson(doc, json); DeserializationError error = deserializeJson(doc, json);
// Test if parsing succeeds. // Test if parsing succeeds.
if (error) { if (error) {

View File

@ -45,7 +45,7 @@ void setup() {
// It's a reference to the JsonObject, the actual bytes are inside the // It's a reference to the JsonObject, the actual bytes are inside the
// JsonBuffer with all the other nodes of the object tree. // JsonBuffer with all the other nodes of the object tree.
// Memory is freed when jsonBuffer goes out of scope. // Memory is freed when jsonBuffer goes out of scope.
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
// Test if parsing succeeds. // Test if parsing succeeds.
if (error) { if (error) {

View File

@ -18,8 +18,8 @@ class memstream : public std::istream {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
DynamicJsonDocument doc; DynamicJsonDocument doc;
memstream json(data, size); memstream json(data, size);
JsonError error = deserializeJson(doc, json); DeserializationError error = deserializeJson(doc, json);
if (error == JsonError::Ok) { if (error == DeserializationError::Ok) {
JsonVariant variant = doc.as<JsonVariant>(); JsonVariant variant = doc.as<JsonVariant>();
variant.as<std::string>(); // <- serialize to JSON variant.as<std::string>(); // <- serialize to JSON
} }

View File

@ -10,25 +10,33 @@
namespace ArduinoJson { namespace ArduinoJson {
class JsonError { class DeserializationError {
public: public:
enum Code { Ok, TooDeep, NoMemory, InvalidInput, IncompleteInput }; enum Code {
Ok,
IncompleteInput,
InvalidInput,
NoMemory,
NotSupported,
TooDeep
};
JsonError(Code code) : _code(code) {} DeserializationError() {}
DeserializationError(Code code) : _code(code) {}
friend bool operator==(const JsonError& err, Code code) { friend bool operator==(const DeserializationError& err, Code code) {
return err._code == code; return err._code == code;
} }
friend bool operator==(Code code, const JsonError& err) { friend bool operator==(Code code, const DeserializationError& err) {
return err._code == code; return err._code == code;
} }
friend bool operator!=(const JsonError& err, Code code) { friend bool operator!=(const DeserializationError& err, Code code) {
return err._code != code; return err._code != code;
} }
friend bool operator!=(Code code, const JsonError& err) { friend bool operator!=(Code code, const DeserializationError& err) {
return err._code != code; return err._code != code;
} }
@ -48,6 +56,8 @@ class JsonError {
return "InvalidInput"; return "InvalidInput";
case IncompleteInput: case IncompleteInput:
return "IncompleteInput"; return "IncompleteInput";
case NotSupported:
return "NotSupported";
default: default:
return "???"; return "???";
} }
@ -58,13 +68,14 @@ class JsonError {
}; };
#if ARDUINOJSON_ENABLE_STD_STREAM #if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { inline std::ostream& operator<<(std::ostream& s,
const DeserializationError& e) {
s << e.c_str(); s << e.c_str();
return s; return s;
} }
inline std::ostream& operator<<(std::ostream& s, JsonError::Code c) { inline std::ostream& operator<<(std::ostream& s, DeserializationError::Code c) {
s << JsonError(c).c_str(); s << DeserializationError(c).c_str();
return s; return s;
} }
#endif #endif

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include "../../JsonError.hpp" #include "../../DeserializationError.hpp"
#include "../../JsonVariant.hpp" #include "../../JsonVariant.hpp"
#include "../../Memory/JsonBuffer.hpp" #include "../../Memory/JsonBuffer.hpp"
#include "../../Reading/Reader.hpp" #include "../../Reading/Reader.hpp"
@ -24,8 +24,8 @@ class JsonDeserializer {
_writer(writer), _writer(writer),
_nestingLimit(nestingLimit), _nestingLimit(nestingLimit),
_loaded(false) {} _loaded(false) {}
JsonError parse(JsonVariant &variant) { DeserializationError parse(JsonVariant &variant) {
JsonError err = skipSpacesAndComments(); DeserializationError err = skipSpacesAndComments();
if (err) return err; if (err) return err;
switch (current()) { switch (current()) {
@ -64,22 +64,22 @@ class JsonDeserializer {
return true; return true;
} }
JsonError parseArray(JsonVariant &variant) { DeserializationError parseArray(JsonVariant &variant) {
if (_nestingLimit == 0) return JsonError::TooDeep; if (_nestingLimit == 0) return DeserializationError::TooDeep;
JsonArray *array = new (_buffer) JsonArray(_buffer); JsonArray *array = new (_buffer) JsonArray(_buffer);
if (!array) return JsonError::NoMemory; if (!array) return DeserializationError::NoMemory;
variant = array; variant = array;
// Check opening braket // Check opening braket
if (!eat('[')) return JsonError::InvalidInput; if (!eat('[')) return DeserializationError::InvalidInput;
// Skip spaces // Skip spaces
JsonError err = skipSpacesAndComments(); DeserializationError err = skipSpacesAndComments();
if (err) return err; if (err) return err;
// Empty array? // Empty array?
if (eat(']')) return JsonError::Ok; if (eat(']')) return DeserializationError::Ok;
// Read each value // Read each value
for (;;) { for (;;) {
@ -89,34 +89,34 @@ class JsonDeserializer {
err = parse(value); err = parse(value);
_nestingLimit++; _nestingLimit++;
if (err) return err; if (err) return err;
if (!array->add(value)) return JsonError::NoMemory; if (!array->add(value)) return DeserializationError::NoMemory;
// 2 - Skip spaces // 2 - Skip spaces
err = skipSpacesAndComments(); err = skipSpacesAndComments();
if (err) return err; if (err) return err;
// 3 - More values? // 3 - More values?
if (eat(']')) return JsonError::Ok; if (eat(']')) return DeserializationError::Ok;
if (!eat(',')) return JsonError::InvalidInput; if (!eat(',')) return DeserializationError::InvalidInput;
} }
} }
JsonError parseObject(JsonVariant &variant) { DeserializationError parseObject(JsonVariant &variant) {
if (_nestingLimit == 0) return JsonError::TooDeep; if (_nestingLimit == 0) return DeserializationError::TooDeep;
JsonObject *object = new (_buffer) JsonObject(_buffer); JsonObject *object = new (_buffer) JsonObject(_buffer);
if (!object) return JsonError::NoMemory; if (!object) return DeserializationError::NoMemory;
variant = object; variant = object;
// Check opening brace // Check opening brace
if (!eat('{')) return JsonError::InvalidInput; if (!eat('{')) return DeserializationError::InvalidInput;
// Skip spaces // Skip spaces
JsonError err = skipSpacesAndComments(); DeserializationError err = skipSpacesAndComments();
if (err) return err; if (err) return err;
// Empty object? // Empty object?
if (eat('}')) return JsonError::Ok; if (eat('}')) return DeserializationError::Ok;
// Read each key value pair // Read each key value pair
for (;;) { for (;;) {
@ -130,7 +130,7 @@ class JsonDeserializer {
if (err) return err; if (err) return err;
// Colon // Colon
if (!eat(':')) return JsonError::InvalidInput; if (!eat(':')) return DeserializationError::InvalidInput;
// Parse value // Parse value
JsonVariant value; JsonVariant value;
@ -138,15 +138,15 @@ class JsonDeserializer {
err = parse(value); err = parse(value);
_nestingLimit++; _nestingLimit++;
if (err) return err; if (err) return err;
if (!object->set(key, value)) return JsonError::NoMemory; if (!object->set(key, value)) return DeserializationError::NoMemory;
// Skip spaces // Skip spaces
err = skipSpacesAndComments(); err = skipSpacesAndComments();
if (err) return err; if (err) return err;
// More keys/values? // More keys/values?
if (eat('}')) return JsonError::Ok; if (eat('}')) return DeserializationError::Ok;
if (!eat(',')) return JsonError::InvalidInput; if (!eat(',')) return DeserializationError::InvalidInput;
// Skip spaces // Skip spaces
err = skipSpacesAndComments(); err = skipSpacesAndComments();
@ -154,24 +154,24 @@ class JsonDeserializer {
} }
} }
JsonError parseValue(JsonVariant &variant) { DeserializationError parseValue(JsonVariant &variant) {
bool hasQuotes = isQuote(current()); bool hasQuotes = isQuote(current());
const char *value; const char *value;
JsonError error = parseString(&value); DeserializationError error = parseString(&value);
if (error) return error; if (error) return error;
if (hasQuotes) { if (hasQuotes) {
variant = value; variant = value;
} else { } else {
variant = RawJson(value); variant = RawJson(value);
} }
return JsonError::Ok; return DeserializationError::Ok;
} }
JsonError parseString(const char **result) { DeserializationError parseString(const char **result) {
typename RemoveReference<TWriter>::type::String str = _writer.startString(); typename RemoveReference<TWriter>::type::String str = _writer.startString();
char c = current(); char c = current();
if (c == '\0') return JsonError::IncompleteInput; if (c == '\0') return DeserializationError::IncompleteInput;
if (isQuote(c)) { // quotes if (isQuote(c)) { // quotes
move(); move();
@ -181,14 +181,15 @@ class JsonDeserializer {
move(); move();
if (c == stopChar) break; if (c == stopChar) break;
if (c == '\0') return JsonError::IncompleteInput; if (c == '\0') return DeserializationError::IncompleteInput;
if (c == '\\') { if (c == '\\') {
c = current(); c = current();
if (c == 0) return JsonError::IncompleteInput; if (c == '\0') return DeserializationError::IncompleteInput;
if (c == 'u') return DeserializationError::NotSupported;
// replace char // replace char
c = Encoding::unescapeChar(c); c = Encoding::unescapeChar(c);
if (c == '\0') return JsonError::InvalidInput; if (c == '\0') return DeserializationError::InvalidInput;
move(); move();
} }
@ -201,12 +202,12 @@ class JsonDeserializer {
c = current(); c = current();
} while (canBeInNonQuotedString(c)); } while (canBeInNonQuotedString(c));
} else { } else {
return JsonError::InvalidInput; return DeserializationError::InvalidInput;
} }
*result = str.c_str(); *result = str.c_str();
if (*result == NULL) return JsonError::NoMemory; if (*result == NULL) return DeserializationError::NoMemory;
return JsonError::Ok; return DeserializationError::Ok;
} }
static inline bool isBetween(char c, char min, char max) { static inline bool isBetween(char c, char min, char max) {
@ -222,12 +223,12 @@ class JsonDeserializer {
return c == '\'' || c == '\"'; return c == '\'' || c == '\"';
} }
JsonError skipSpacesAndComments() { DeserializationError skipSpacesAndComments() {
for (;;) { for (;;) {
switch (current()) { switch (current()) {
// end of string // end of string
case '\0': case '\0':
return JsonError::IncompleteInput; return DeserializationError::IncompleteInput;
// spaces // spaces
case ' ': case ' ':
@ -247,7 +248,7 @@ class JsonDeserializer {
bool wasStar = false; bool wasStar = false;
for (;;) { for (;;) {
char c = current(); char c = current();
if (c == '\0') return JsonError::IncompleteInput; if (c == '\0') return DeserializationError::IncompleteInput;
if (c == '/' && wasStar) { if (c == '/' && wasStar) {
move(); move();
break; break;
@ -264,19 +265,19 @@ class JsonDeserializer {
for (;;) { for (;;) {
move(); move();
char c = current(); char c = current();
if (c == '\0') return JsonError::IncompleteInput; if (c == '\0') return DeserializationError::IncompleteInput;
if (c == '\n') break; if (c == '\n') break;
} }
break; break;
// not a comment, just a '/' // not a comment, just a '/'
default: default:
return JsonError::InvalidInput; return DeserializationError::InvalidInput;
} }
break; break;
default: default:
return JsonError::Ok; return DeserializationError::Ok;
} }
} }
} }

View File

@ -4,21 +4,18 @@
#pragma once #pragma once
#include "../DeserializationError.hpp"
#include "../JsonVariant.hpp" #include "../JsonVariant.hpp"
#include "../Memory/JsonBuffer.hpp" #include "../Memory/JsonBuffer.hpp"
#include "../Reading/Reader.hpp" #include "../Reading/Reader.hpp"
#include "../TypeTraits/IsConst.hpp" #include "../TypeTraits/IsConst.hpp"
#include "../Writing/Writer.hpp" #include "../Writing/Writer.hpp"
#include "./MsgPackError.hpp"
#include "./endianess.hpp" #include "./endianess.hpp"
#include "./ieee754.hpp" #include "./ieee754.hpp"
namespace ArduinoJson { namespace ArduinoJson {
namespace Internals { namespace Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
template <typename TReader, typename TWriter> template <typename TReader, typename TWriter>
class MsgPackDeserializer { class MsgPackDeserializer {
public: public:
@ -29,18 +26,18 @@ class MsgPackDeserializer {
_writer(writer), _writer(writer),
_nestingLimit(nestingLimit) {} _nestingLimit(nestingLimit) {}
MsgPackError parse(JsonVariant &variant) { DeserializationError parse(JsonVariant &variant) {
uint8_t code; uint8_t code;
if (!readByte(code)) return MsgPackError::IncompleteInput; if (!readByte(code)) return DeserializationError::IncompleteInput;
if ((code & 0x80) == 0) { if ((code & 0x80) == 0) {
variant = code; variant = code;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
if ((code & 0xe0) == 0xe0) { if ((code & 0xe0) == 0xe0) {
variant = static_cast<int8_t>(code); variant = static_cast<int8_t>(code);
return MsgPackError::Ok; return DeserializationError::Ok;
} }
if ((code & 0xe0) == 0xa0) { if ((code & 0xe0) == 0xa0) {
@ -54,15 +51,15 @@ class MsgPackDeserializer {
switch (code) { switch (code) {
case 0xc0: case 0xc0:
variant = static_cast<char *>(0); variant = static_cast<char *>(0);
return MsgPackError::Ok; return DeserializationError::Ok;
case 0xc2: case 0xc2:
variant = false; variant = false;
return MsgPackError::Ok; return DeserializationError::Ok;
case 0xc3: case 0xc3:
variant = true; variant = true;
return MsgPackError::Ok; return DeserializationError::Ok;
case 0xcc: case 0xcc:
return readInteger<uint8_t>(variant); return readInteger<uint8_t>(variant);
@ -94,7 +91,7 @@ class MsgPackDeserializer {
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
return readInteger<int64_t>(variant); return readInteger<int64_t>(variant);
#else #else
if (!skip(4)) return MsgPackError::IncompleteInput; if (!skip(4)) return DeserializationError::IncompleteInput;
return readInteger<int32_t>(variant); return readInteger<int32_t>(variant);
#endif #endif
@ -126,7 +123,7 @@ class MsgPackDeserializer {
return readObject<uint32_t>(variant); return readObject<uint32_t>(variant);
default: default:
return MsgPackError::NotSupported; return DeserializationError::NotSupported;
} }
} }
@ -176,123 +173,123 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
MsgPackError readInteger(JsonVariant &variant) { DeserializationError readInteger(JsonVariant &variant) {
T value; T value;
if (!readInteger(value)) return MsgPackError::IncompleteInput; if (!readInteger(value)) return DeserializationError::IncompleteInput;
variant = value; variant = value;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
template <typename T> template <typename T>
typename EnableIf<sizeof(T) == 4, MsgPackError>::type readFloat( typename EnableIf<sizeof(T) == 4, DeserializationError>::type readFloat(
JsonVariant &variant) { JsonVariant &variant) {
T value; T value;
if (!readBytes(value)) return MsgPackError::IncompleteInput; if (!readBytes(value)) return DeserializationError::IncompleteInput;
fixEndianess(value); fixEndianess(value);
variant = value; variant = value;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
template <typename T> template <typename T>
typename EnableIf<sizeof(T) == 8, MsgPackError>::type readDouble( typename EnableIf<sizeof(T) == 8, DeserializationError>::type readDouble(
JsonVariant &variant) { JsonVariant &variant) {
T value; T value;
if (!readBytes(value)) return MsgPackError::IncompleteInput; if (!readBytes(value)) return DeserializationError::IncompleteInput;
fixEndianess(value); fixEndianess(value);
variant = value; variant = value;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
template <typename T> template <typename T>
typename EnableIf<sizeof(T) == 4, MsgPackError>::type readDouble( typename EnableIf<sizeof(T) == 4, DeserializationError>::type readDouble(
JsonVariant &variant) { JsonVariant &variant) {
uint8_t i[8]; // input is 8 bytes uint8_t i[8]; // input is 8 bytes
T value; // output is 4 bytes T value; // output is 4 bytes
uint8_t *o = reinterpret_cast<uint8_t *>(&value); uint8_t *o = reinterpret_cast<uint8_t *>(&value);
if (!readBytes(i, 8)) return MsgPackError::IncompleteInput; if (!readBytes(i, 8)) return DeserializationError::IncompleteInput;
doubleToFloat(i, o); doubleToFloat(i, o);
fixEndianess(value); fixEndianess(value);
variant = value; variant = value;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
template <typename T> template <typename T>
MsgPackError readString(JsonVariant &variant) { DeserializationError readString(JsonVariant &variant) {
T size; T size;
if (!readInteger(size)) return MsgPackError::IncompleteInput; if (!readInteger(size)) return DeserializationError::IncompleteInput;
return readString(variant, size); return readString(variant, size);
} }
MsgPackError readString(JsonVariant &variant, size_t n) { DeserializationError readString(JsonVariant &variant, size_t n) {
typename RemoveReference<TWriter>::type::String str = _writer.startString(); typename RemoveReference<TWriter>::type::String str = _writer.startString();
for (; n; --n) { for (; n; --n) {
uint8_t c; uint8_t c;
if (!readBytes(c)) return MsgPackError::IncompleteInput; if (!readBytes(c)) return DeserializationError::IncompleteInput;
str.append(static_cast<char>(c)); str.append(static_cast<char>(c));
} }
const char *s = str.c_str(); const char *s = str.c_str();
if (s == NULL) return MsgPackError::NoMemory; if (s == NULL) return DeserializationError::NoMemory;
variant = s; variant = s;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
template <typename TSize> template <typename TSize>
MsgPackError readArray(JsonVariant &variant) { DeserializationError readArray(JsonVariant &variant) {
TSize size; TSize size;
if (!readInteger(size)) return MsgPackError::IncompleteInput; if (!readInteger(size)) return DeserializationError::IncompleteInput;
return readArray(variant, size); return readArray(variant, size);
} }
MsgPackError readArray(JsonVariant &variant, size_t n) { DeserializationError readArray(JsonVariant &variant, size_t n) {
JsonArray *array = new (_buffer) JsonArray(_buffer); JsonArray *array = new (_buffer) JsonArray(_buffer);
if (!array) return MsgPackError::NoMemory; if (!array) return DeserializationError::NoMemory;
variant = array; variant = array;
return readArray(*array, n); return readArray(*array, n);
} }
MsgPackError readArray(JsonArray &array, size_t n) { DeserializationError readArray(JsonArray &array, size_t n) {
if (_nestingLimit == 0) return MsgPackError::TooDeep; if (_nestingLimit == 0) return DeserializationError::TooDeep;
--_nestingLimit; --_nestingLimit;
for (; n; --n) { for (; n; --n) {
JsonVariant variant; JsonVariant variant;
MsgPackError err = parse(variant); DeserializationError err = parse(variant);
if (err) return err; if (err) return err;
if (!array.add(variant)) return MsgPackError::NoMemory; if (!array.add(variant)) return DeserializationError::NoMemory;
} }
++_nestingLimit; ++_nestingLimit;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
template <typename TSize> template <typename TSize>
MsgPackError readObject(JsonVariant &variant) { DeserializationError readObject(JsonVariant &variant) {
TSize size; TSize size;
if (!readInteger(size)) return MsgPackError::IncompleteInput; if (!readInteger(size)) return DeserializationError::IncompleteInput;
return readObject(variant, size); return readObject(variant, size);
} }
MsgPackError readObject(JsonVariant &variant, size_t n) { DeserializationError readObject(JsonVariant &variant, size_t n) {
JsonObject *object = new (_buffer) JsonObject(_buffer); JsonObject *object = new (_buffer) JsonObject(_buffer);
if (!object) return MsgPackError::NoMemory; if (!object) return DeserializationError::NoMemory;
variant = object; variant = object;
return readObject(*object, n); return readObject(*object, n);
} }
MsgPackError readObject(JsonObject &object, size_t n) { DeserializationError readObject(JsonObject &object, size_t n) {
if (_nestingLimit == 0) return MsgPackError::TooDeep; if (_nestingLimit == 0) return DeserializationError::TooDeep;
--_nestingLimit; --_nestingLimit;
for (; n; --n) { for (; n; --n) {
MsgPackError err; DeserializationError err;
JsonVariant variant; JsonVariant variant;
err = parse(variant); err = parse(variant);
if (err) return err; if (err) return err;
const char *key = variant.as<char *>(); const char *key = variant.as<char *>();
if (!key) return MsgPackError::NotSupported; if (!key) return DeserializationError::NotSupported;
err = parse(variant); err = parse(variant);
if (err) return err; if (err) return err;
if (!object.set(key, variant)) return MsgPackError::NoMemory; if (!object.set(key, variant)) return DeserializationError::NoMemory;
} }
++_nestingLimit; ++_nestingLimit;
return MsgPackError::Ok; return DeserializationError::Ok;
} }
JsonBuffer *_buffer; JsonBuffer *_buffer;

View File

@ -1,74 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#if ARDUINOJSON_ENABLE_STD_STREAM
#include <ostream>
#endif
namespace ArduinoJson {
class MsgPackError {
public:
enum Code { Ok, NotSupported, NoMemory, TooDeep, IncompleteInput };
MsgPackError() {}
MsgPackError(Code code) : _code(code) {}
operator bool() const {
return _code != Ok;
}
friend bool operator==(const MsgPackError& err, Code code) {
return err._code == code;
}
friend bool operator==(Code code, const MsgPackError& err) {
return err._code == code;
}
friend bool operator!=(const MsgPackError& err, Code code) {
return err._code != code;
}
friend bool operator!=(Code code, const MsgPackError& err) {
return err._code != code;
}
const char* c_str() const {
switch (_code) {
case Ok:
return "Ok";
case NotSupported:
return "NotSupported";
case NoMemory:
return "NoMemory";
case TooDeep:
return "TooDeep";
case IncompleteInput:
return "IncompleteInput";
default:
return "???";
}
}
private:
Code _code;
};
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) {
os << err.c_str();
return os;
}
inline std::ostream& operator<<(std::ostream& os, MsgPackError::Code code) {
os << MsgPackError(code).c_str();
return os;
}
#endif
} // namespace ArduinoJson

View File

@ -9,12 +9,12 @@
#include "Writing/Writer.hpp" #include "Writing/Writer.hpp"
namespace ArduinoJson { namespace ArduinoJson {
// JsonError deserializeJson(TDocument& doc, TString input); // DeserializationError deserializeJson(TDocument& doc, TString input);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TString = const std::string&, const String& // TString = const std::string&, const String&
template <typename TDocument, typename TString> template <typename TDocument, typename TString>
typename Internals::EnableIf<!Internals::IsArray<TString>::value, typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonError>::type DeserializationError>::type
deserializeJson(TDocument &doc, const TString &input) { deserializeJson(TDocument &doc, const TString &input) {
using namespace Internals; using namespace Internals;
return makeJsonDeserializer(&doc.buffer(), makeReader(input), return makeJsonDeserializer(&doc.buffer(), makeReader(input),
@ -22,33 +22,34 @@ deserializeJson(TDocument &doc, const TString &input) {
.parse(doc.template to<JsonVariant>()); .parse(doc.template to<JsonVariant>());
} }
// //
// JsonError deserializeJson(TDocument& doc, TChar* input); // DeserializationError deserializeJson(TDocument& doc, TChar* input);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TChar* = char*, const char*, const FlashStringHelper* // TChar* = char*, const char*, const FlashStringHelper*
template <typename TDocument, typename TChar> template <typename TDocument, typename TChar>
JsonError deserializeJson(TDocument &doc, TChar *input) { DeserializationError deserializeJson(TDocument &doc, TChar *input) {
using namespace Internals; using namespace Internals;
return makeJsonDeserializer(&doc.buffer(), makeReader(input), return makeJsonDeserializer(&doc.buffer(), makeReader(input),
makeWriter(doc.buffer(), input), doc.nestingLimit) makeWriter(doc.buffer(), input), doc.nestingLimit)
.parse(doc.template to<JsonVariant>()); .parse(doc.template to<JsonVariant>());
} }
// //
// JsonError deserializeJson(TDocument& doc, TChar* input, size_t inputSize); // DeserializationError deserializeJson(TDocument& doc, TChar* input, size_t
// TDocument = DynamicJsonDocument, StaticJsonDocument // inputSize); TDocument = DynamicJsonDocument, StaticJsonDocument TChar* =
// TChar* = char*, const char*, const FlashStringHelper* // char*, const char*, const FlashStringHelper*
template <typename TDocument, typename TChar> template <typename TDocument, typename TChar>
JsonError deserializeJson(TDocument &doc, TChar *input, size_t inputSize) { DeserializationError deserializeJson(TDocument &doc, TChar *input,
size_t inputSize) {
using namespace Internals; using namespace Internals;
return makeJsonDeserializer(&doc.buffer(), makeReader(input, inputSize), return makeJsonDeserializer(&doc.buffer(), makeReader(input, inputSize),
makeWriter(doc.buffer(), input), doc.nestingLimit) makeWriter(doc.buffer(), input), doc.nestingLimit)
.parse(doc.template to<JsonVariant>()); .parse(doc.template to<JsonVariant>());
} }
// //
// JsonError deserializeJson(TDocument& doc, TStream input); // DeserializationError deserializeJson(TDocument& doc, TStream input);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TStream = std::istream&, Stream& // TStream = std::istream&, Stream&
template <typename TDocument, typename TStream> template <typename TDocument, typename TStream>
JsonError deserializeJson(TDocument &doc, TStream &input) { DeserializationError deserializeJson(TDocument &doc, TStream &input) {
using namespace Internals; using namespace Internals;
return makeJsonDeserializer(&doc.buffer(), makeReader(input), return makeJsonDeserializer(&doc.buffer(), makeReader(input),
makeWriter(doc.buffer(), input), doc.nestingLimit) makeWriter(doc.buffer(), input), doc.nestingLimit)

View File

@ -9,12 +9,12 @@
#include "Writing/Writer.hpp" #include "Writing/Writer.hpp"
namespace ArduinoJson { namespace ArduinoJson {
// MsgPackError deserializeMsgPack(TDocument& doc, TString input); // DeserializationError deserializeMsgPack(TDocument& doc, TString input);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TString = const std::string&, const String& // TString = const std::string&, const String&
template <typename TDocument, typename TString> template <typename TDocument, typename TString>
typename Internals::EnableIf<!Internals::IsArray<TString>::value, typename Internals::EnableIf<!Internals::IsArray<TString>::value,
MsgPackError>::type DeserializationError>::type
deserializeMsgPack(TDocument &doc, const TString &input) { deserializeMsgPack(TDocument &doc, const TString &input) {
using namespace Internals; using namespace Internals;
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), return makeMsgPackDeserializer(&doc.buffer(), makeReader(input),
@ -23,11 +23,11 @@ deserializeMsgPack(TDocument &doc, const TString &input) {
.parse(doc.template to<JsonVariant>()); .parse(doc.template to<JsonVariant>());
} }
// //
// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input); // DeserializationError deserializeMsgPack(TDocument& doc, TChar* input);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TChar* = char*, const char*, const FlashStringHelper* // TChar* = char*, const char*, const FlashStringHelper*
template <typename TDocument, typename TChar> template <typename TDocument, typename TChar>
MsgPackError deserializeMsgPack(TDocument &doc, TChar *input) { DeserializationError deserializeMsgPack(TDocument &doc, TChar *input) {
using namespace Internals; using namespace Internals;
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), return makeMsgPackDeserializer(&doc.buffer(), makeReader(input),
makeWriter(doc.buffer(), input), makeWriter(doc.buffer(), input),
@ -35,12 +35,12 @@ MsgPackError deserializeMsgPack(TDocument &doc, TChar *input) {
.parse(doc.template to<JsonVariant>()); .parse(doc.template to<JsonVariant>());
} }
// //
// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input, size_t // DeserializationError deserializeMsgPack(TDocument& doc, TChar* input, size_t
// inputSize); // inputSize);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TChar* = char*, const char*, const FlashStringHelper* // TChar* = char*, const char*, const FlashStringHelper*
template <typename TDocument, typename TChar> template <typename TDocument, typename TChar>
MsgPackError deserializeMsgPack(TDocument &doc, TChar *input, DeserializationError deserializeMsgPack(TDocument &doc, TChar *input,
size_t inputSize) { size_t inputSize) {
using namespace Internals; using namespace Internals;
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input, inputSize), return makeMsgPackDeserializer(&doc.buffer(), makeReader(input, inputSize),
@ -49,11 +49,11 @@ MsgPackError deserializeMsgPack(TDocument &doc, TChar *input,
.parse(doc.template to<JsonVariant>()); .parse(doc.template to<JsonVariant>());
} }
// //
// MsgPackError deserializeMsgPack(TDocument& doc, TStream input); // DeserializationError deserializeMsgPack(TDocument& doc, TStream input);
// TDocument = DynamicJsonDocument, StaticJsonDocument // TDocument = DynamicJsonDocument, StaticJsonDocument
// TStream = std::istream&, Stream& // TStream = std::istream&, Stream&
template <typename TDocument, typename TStream> template <typename TDocument, typename TStream>
MsgPackError deserializeMsgPack(TDocument &doc, TStream &input) { DeserializationError deserializeMsgPack(TDocument &doc, TStream &input) {
using namespace Internals; using namespace Internals;
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), return makeMsgPackDeserializer(&doc.buffer(), makeReader(input),
makeWriter(doc.buffer(), input), makeWriter(doc.buffer(), input),

View File

@ -27,9 +27,9 @@ TEST_CASE("DynamicJsonBuffer no memory") {
// char json[] = "{[]}"; // char json[] = "{[]}";
// DynamicJsonDocument obj; // DynamicJsonDocument obj;
// JsonError err = deserializeJson(obj, json); // DeserializationError err = deserializeJson(obj, json);
// REQUIRE(err != JsonError::Ok); // REQUIRE(err != DeserializationError::Ok);
// } // }
SECTION("startString()") { SECTION("startString()") {

View File

@ -8,7 +8,7 @@
TEST_CASE("Gbathree") { TEST_CASE("Gbathree") {
DynamicJsonDocument doc; DynamicJsonDocument doc;
JsonError error = deserializeJson( DeserializationError error = deserializeJson(
doc, doc,
"{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,"
"\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_"
@ -23,7 +23,7 @@ TEST_CASE("Gbathree") {
JsonObject& root = doc.as<JsonObject>(); JsonObject& root = doc.as<JsonObject>();
SECTION("Success") { SECTION("Success") {
REQUIRE(error == JsonError::Ok); REQUIRE(error == DeserializationError::Ok);
} }
SECTION("ProtocolName") { SECTION("ProtocolName") {

View File

@ -10,8 +10,8 @@ TEST_CASE("JsonArray::copyTo()") {
SECTION("BiggerOneDimensionIntegerArray") { SECTION("BiggerOneDimensionIntegerArray") {
char json[] = "[1,2,3]"; char json[] = "[1,2,3]";
JsonError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
int destination[4] = {0}; int destination[4] = {0};
@ -26,8 +26,8 @@ TEST_CASE("JsonArray::copyTo()") {
SECTION("SmallerOneDimensionIntegerArray") { SECTION("SmallerOneDimensionIntegerArray") {
char json[] = "[1,2,3]"; char json[] = "[1,2,3]";
JsonError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
int destination[2] = {0}; int destination[2] = {0};
@ -41,8 +41,8 @@ TEST_CASE("JsonArray::copyTo()") {
SECTION("TwoOneDimensionIntegerArray") { SECTION("TwoOneDimensionIntegerArray") {
char json[] = "[[1,2],[3],[4]]"; char json[] = "[[1,2],[3],[4]]";
JsonError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
int destination[3][2] = {{0}}; int destination[3][2] = {{0}};

View File

@ -8,7 +8,7 @@ add_executable(JsonDeserializerTests
deserializeJsonObject.cpp deserializeJsonObject.cpp
deserializeJsonObjectStatic.cpp deserializeJsonObjectStatic.cpp
deserializeJsonValue.cpp deserializeJsonValue.cpp
JsonError.cpp DeserializationError.cpp
nestingLimit.cpp nestingLimit.cpp
std_istream.cpp std_istream.cpp
std_string.cpp std_string.cpp

View File

@ -5,27 +5,28 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
void testStringification(JsonError error, std::string expected) { void testStringification(DeserializationError error, std::string expected) {
REQUIRE(error.c_str() == expected); REQUIRE(error.c_str() == expected);
} }
void testBoolification(JsonError error, bool expected) { void testBoolification(DeserializationError error, bool expected) {
CHECK(error == expected); CHECK(error == expected);
} }
#define TEST_STRINGIFICATION(symbol) \ #define TEST_STRINGIFICATION(symbol) \
testStringification(JsonError::symbol, #symbol) testStringification(DeserializationError::symbol, #symbol)
#define TEST_BOOLIFICATION(symbol, expected) \ #define TEST_BOOLIFICATION(symbol, expected) \
testBoolification(JsonError::symbol, expected) testBoolification(DeserializationError::symbol, expected)
TEST_CASE("JsonError") { TEST_CASE("DeserializationError") {
SECTION("c_str()") { SECTION("c_str()") {
TEST_STRINGIFICATION(Ok); TEST_STRINGIFICATION(Ok);
TEST_STRINGIFICATION(TooDeep); TEST_STRINGIFICATION(TooDeep);
TEST_STRINGIFICATION(NoMemory); TEST_STRINGIFICATION(NoMemory);
TEST_STRINGIFICATION(InvalidInput); TEST_STRINGIFICATION(InvalidInput);
TEST_STRINGIFICATION(IncompleteInput); TEST_STRINGIFICATION(IncompleteInput);
TEST_STRINGIFICATION(NotSupported);
} }
SECTION("as boolean") { SECTION("as boolean") {
@ -34,11 +35,12 @@ TEST_CASE("JsonError") {
TEST_BOOLIFICATION(NoMemory, true); TEST_BOOLIFICATION(NoMemory, true);
TEST_BOOLIFICATION(InvalidInput, true); TEST_BOOLIFICATION(InvalidInput, true);
TEST_BOOLIFICATION(IncompleteInput, true); TEST_BOOLIFICATION(IncompleteInput, true);
TEST_BOOLIFICATION(NotSupported, true);
} }
SECTION("ostream") { SECTION("ostream") {
std::stringstream s; std::stringstream s;
s << JsonError::InvalidInput; s << DeserializationError::InvalidInput;
REQUIRE(s.str() == "InvalidInput"); REQUIRE(s.str() == "InvalidInput");
} }
} }

View File

@ -9,36 +9,36 @@ TEST_CASE("deserialize JSON array") {
DynamicJsonDocument doc; DynamicJsonDocument doc;
SECTION("An empty array") { SECTION("An empty array") {
JsonError err = deserializeJson(doc, "[]"); DeserializationError err = deserializeJson(doc, "[]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(0 == arr.size()); REQUIRE(0 == arr.size());
} }
SECTION("Spaces") { SECTION("Spaces") {
SECTION("Before the opening bracket") { SECTION("Before the opening bracket") {
JsonError err = deserializeJson(doc, " []"); DeserializationError err = deserializeJson(doc, " []");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(0 == arr.size()); REQUIRE(0 == arr.size());
} }
SECTION("Before first value") { SECTION("Before first value") {
JsonError err = deserializeJson(doc, "[ \t\r\n42]"); DeserializationError err = deserializeJson(doc, "[ \t\r\n42]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42); REQUIRE(arr[0] == 42);
} }
SECTION("After first value") { SECTION("After first value") {
JsonError err = deserializeJson(doc, "[42 \t\r\n]"); DeserializationError err = deserializeJson(doc, "[42 \t\r\n]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42); REQUIRE(arr[0] == 42);
} }
@ -46,58 +46,58 @@ TEST_CASE("deserialize JSON array") {
SECTION("Values types") { SECTION("Values types") {
SECTION("On integer") { SECTION("On integer") {
JsonError err = deserializeJson(doc, "[42]"); DeserializationError err = deserializeJson(doc, "[42]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42); REQUIRE(arr[0] == 42);
} }
SECTION("Two integers") { SECTION("Two integers") {
JsonError err = deserializeJson(doc, "[42,84]"); DeserializationError err = deserializeJson(doc, "[42,84]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 42); REQUIRE(arr[0] == 42);
REQUIRE(arr[1] == 84); REQUIRE(arr[1] == 84);
} }
SECTION("Double") { SECTION("Double") {
JsonError err = deserializeJson(doc, "[4.2,1e2]"); DeserializationError err = deserializeJson(doc, "[4.2,1e2]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 4.2); REQUIRE(arr[0] == 4.2);
REQUIRE(arr[1] == 1e2); REQUIRE(arr[1] == 1e2);
} }
SECTION("Unsigned long") { SECTION("Unsigned long") {
JsonError err = deserializeJson(doc, "[4294967295]"); DeserializationError err = deserializeJson(doc, "[4294967295]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 4294967295UL); REQUIRE(arr[0] == 4294967295UL);
} }
SECTION("Boolean") { SECTION("Boolean") {
JsonError err = deserializeJson(doc, "[true,false]"); DeserializationError err = deserializeJson(doc, "[true,false]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == true); REQUIRE(arr[0] == true);
REQUIRE(arr[1] == false); REQUIRE(arr[1] == false);
} }
SECTION("Null") { SECTION("Null") {
JsonError err = deserializeJson(doc, "[null,null]"); DeserializationError err = deserializeJson(doc, "[null,null]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0].as<char*>() == 0); REQUIRE(arr[0].as<char*>() == 0);
REQUIRE(arr[1].as<char*>() == 0); REQUIRE(arr[1].as<char*>() == 0);
@ -106,232 +106,241 @@ TEST_CASE("deserialize JSON array") {
SECTION("Quotes") { SECTION("Quotes") {
SECTION("Double quotes") { SECTION("Double quotes") {
JsonError err = deserializeJson(doc, "[ \"hello\" , \"world\" ]"); DeserializationError err =
deserializeJson(doc, "[ \"hello\" , \"world\" ]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("Single quotes") { SECTION("Single quotes") {
JsonError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); DeserializationError err = deserializeJson(doc, "[ 'hello' , 'world' ]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("No quotes") { SECTION("No quotes") {
JsonError err = deserializeJson(doc, "[ hello , world ]"); DeserializationError err = deserializeJson(doc, "[ hello , world ]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("Double quotes (empty strings)") { SECTION("Double quotes (empty strings)") {
JsonError err = deserializeJson(doc, "[\"\",\"\"]"); DeserializationError err = deserializeJson(doc, "[\"\",\"\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == ""); REQUIRE(arr[0] == "");
REQUIRE(arr[1] == ""); REQUIRE(arr[1] == "");
} }
SECTION("Single quotes (empty strings)") { SECTION("Single quotes (empty strings)") {
JsonError err = deserializeJson(doc, "[\'\',\'\']"); DeserializationError err = deserializeJson(doc, "[\'\',\'\']");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == ""); REQUIRE(arr[0] == "");
REQUIRE(arr[1] == ""); REQUIRE(arr[1] == "");
} }
SECTION("No quotes (empty strings)") { SECTION("No quotes (empty strings)") {
JsonError err = deserializeJson(doc, "[,]"); DeserializationError err = deserializeJson(doc, "[,]");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("Closing single quotes missing") { SECTION("Closing single quotes missing") {
JsonError err = deserializeJson(doc, "[\"]"); DeserializationError err = deserializeJson(doc, "[\"]");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("Closing double quotes missing") { SECTION("Closing double quotes missing") {
JsonError err = deserializeJson(doc, "[\']"); DeserializationError err = deserializeJson(doc, "[\']");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
SECTION("Block comments") { SECTION("Block comments") {
SECTION("Before opening bracket") { SECTION("Before opening bracket") {
JsonError err = deserializeJson(doc, "/*COMMENT*/ [\"hello\"]"); DeserializationError err =
deserializeJson(doc, "/*COMMENT*/ [\"hello\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("After opening bracket") { SECTION("After opening bracket") {
JsonError err = deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); DeserializationError err =
deserializeJson(doc, "[/*COMMENT*/ \"hello\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("Before closing bracket") { SECTION("Before closing bracket") {
JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); DeserializationError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("After closing bracket") { SECTION("After closing bracket") {
JsonError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); DeserializationError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("Before comma") { SECTION("Before comma") {
JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); DeserializationError err =
deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); DeserializationError err =
deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("/*/") { SECTION("/*/") {
JsonError err = deserializeJson(doc, "[/*/\n]"); DeserializationError err = deserializeJson(doc, "[/*/\n]");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("Unfinished comment") { SECTION("Unfinished comment") {
JsonError err = deserializeJson(doc, "[/*COMMENT]"); DeserializationError err = deserializeJson(doc, "[/*COMMENT]");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("Final slash missing") { SECTION("Final slash missing") {
JsonError err = deserializeJson(doc, "[/*COMMENT*]"); DeserializationError err = deserializeJson(doc, "[/*COMMENT*]");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
SECTION("Trailing comments") { SECTION("Trailing comments") {
SECTION("Before opening bracket") { SECTION("Before opening bracket") {
JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); DeserializationError err =
deserializeJson(doc, "//COMMENT\n\t[\"hello\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("After opening bracket") { SECTION("After opening bracket") {
JsonError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); DeserializationError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("Before closing bracket") { SECTION("Before closing bracket") {
JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); DeserializationError err =
deserializeJson(doc, "[\"hello\"//COMMENT\r\n]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("After closing bracket") { SECTION("After closing bracket") {
JsonError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); DeserializationError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
} }
SECTION("Before comma") { SECTION("Before comma") {
JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); DeserializationError err =
deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); DeserializationError err =
deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]");
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size()); REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello"); REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world"); REQUIRE(arr[1] == "world");
} }
SECTION("Invalid comment") { SECTION("Invalid comment") {
JsonError err = deserializeJson(doc, "[/COMMENT\n]"); DeserializationError err = deserializeJson(doc, "[/COMMENT\n]");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("End document with comment") { SECTION("End document with comment") {
JsonError err = deserializeJson(doc, "[//COMMENT"); DeserializationError err = deserializeJson(doc, "[//COMMENT");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
SECTION("Premature null-terminator") { SECTION("Premature null-terminator") {
SECTION("After opening bracket") { SECTION("After opening bracket") {
JsonError err = deserializeJson(doc, "["); DeserializationError err = deserializeJson(doc, "[");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After value") { SECTION("After value") {
JsonError err = deserializeJson(doc, "[1"); DeserializationError err = deserializeJson(doc, "[1");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson(doc, "[1,"); DeserializationError err = deserializeJson(doc, "[1,");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
@ -339,21 +348,21 @@ TEST_CASE("deserialize JSON array") {
const char* input = "[1,2]"; const char* input = "[1,2]";
SECTION("After opening bracket") { SECTION("After opening bracket") {
JsonError err = deserializeJson(doc, input, 1); DeserializationError err = deserializeJson(doc, input, 1);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After value") { SECTION("After value") {
JsonError err = deserializeJson(doc, input, 2); DeserializationError err = deserializeJson(doc, input, 2);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson(doc, input, 3); DeserializationError err = deserializeJson(doc, input, 3);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
@ -362,14 +371,14 @@ TEST_CASE("deserialize JSON array") {
char jsonString[] = char jsonString[] =
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
JsonError err = deserializeJson(doc, jsonString); DeserializationError err = deserializeJson(doc, jsonString);
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
JsonObject& object1 = arr[0]; JsonObject& object1 = arr[0];
const JsonObject& object2 = arr[1]; const JsonObject& object2 = arr[1];
JsonObject& object3 = arr[2]; JsonObject& object3 = arr[2];
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(true == object1.success()); REQUIRE(true == object1.success());
REQUIRE(true == object2.success()); REQUIRE(true == object2.success());

View File

@ -10,45 +10,45 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc; StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc;
char input[] = "[]"; char input[] = "[]";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("TooSmallBufferForArrayWithOneValue") { SECTION("TooSmallBufferForArrayWithOneValue") {
StaticJsonDocument<JSON_ARRAY_SIZE(1) - 1> doc; StaticJsonDocument<JSON_ARRAY_SIZE(1) - 1> doc;
char input[] = "[1]"; char input[] = "[1]";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::NoMemory); REQUIRE(err == DeserializationError::NoMemory);
} }
SECTION("BufferOfTheRightSizeForArrayWithOneValue") { SECTION("BufferOfTheRightSizeForArrayWithOneValue") {
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
char input[] = "[1]"; char input[] = "[1]";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("TooSmallBufferForArrayWithNestedObject") { SECTION("TooSmallBufferForArrayWithNestedObject") {
StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1> doc; StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1> doc;
char input[] = "[{}]"; char input[] = "[{}]";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::NoMemory); REQUIRE(err == DeserializationError::NoMemory);
} }
SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { SECTION("BufferOfTheRightSizeForArrayWithNestedObject") {
StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> doc; StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> doc;
char input[] = "[{}]"; char input[] = "[{}]";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("CopyStringNotSpaces") { SECTION("CopyStringNotSpaces") {
@ -77,10 +77,10 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc;
char input[] = "[1,2]"; char input[] = "[1,2]";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonArray>()); REQUIRE(doc.is<JsonArray>());
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
REQUIRE(arr[0] == 1); REQUIRE(arr[0] == 1);

View File

@ -9,50 +9,50 @@ TEST_CASE("deserialize JSON object") {
DynamicJsonDocument doc; DynamicJsonDocument doc;
SECTION("An empty object") { SECTION("An empty object") {
JsonError err = deserializeJson(doc, "{}"); DeserializationError err = deserializeJson(doc, "{}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 0); REQUIRE(obj.size() == 0);
} }
SECTION("Quotes") { SECTION("Quotes") {
SECTION("Double quotes") { SECTION("Double quotes") {
JsonError err = deserializeJson(doc, "{\"key\":\"value\"}"); DeserializationError err = deserializeJson(doc, "{\"key\":\"value\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("Single quotes") { SECTION("Single quotes") {
JsonError err = deserializeJson(doc, "{'key':'value'}"); DeserializationError err = deserializeJson(doc, "{'key':'value'}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("No quotes") { SECTION("No quotes") {
JsonError err = deserializeJson(doc, "{key:value}"); DeserializationError err = deserializeJson(doc, "{key:value}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("No quotes, allow underscore in key") { SECTION("No quotes, allow underscore in key") {
JsonError err = deserializeJson(doc, "{_k_e_y_:42}"); DeserializationError err = deserializeJson(doc, "{_k_e_y_:42}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["_k_e_y_"] == 42); REQUIRE(obj["_k_e_y_"] == 42);
@ -61,51 +61,51 @@ TEST_CASE("deserialize JSON object") {
SECTION("Spaces") { SECTION("Spaces") {
SECTION("Before the key") { SECTION("Before the key") {
JsonError err = deserializeJson(doc, "{ \"key\":\"value\"}"); DeserializationError err = deserializeJson(doc, "{ \"key\":\"value\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("After the key") { SECTION("After the key") {
JsonError err = deserializeJson(doc, "{\"key\" :\"value\"}"); DeserializationError err = deserializeJson(doc, "{\"key\" :\"value\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("Before the value") { SECTION("Before the value") {
JsonError err = deserializeJson(doc, "{\"key\": \"value\"}"); DeserializationError err = deserializeJson(doc, "{\"key\": \"value\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("After the value") { SECTION("After the value") {
JsonError err = deserializeJson(doc, "{\"key\":\"value\" }"); DeserializationError err = deserializeJson(doc, "{\"key\":\"value\" }");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 1); REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value"); REQUIRE(obj["key"] == "value");
} }
SECTION("Before the colon") { SECTION("Before the colon") {
JsonError err = DeserializationError err =
deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key1"] == "value1");
@ -113,11 +113,11 @@ TEST_CASE("deserialize JSON object") {
} }
SECTION("After the colon") { SECTION("After the colon") {
JsonError err = DeserializationError err =
deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key1"] == "value1");
@ -127,11 +127,11 @@ TEST_CASE("deserialize JSON object") {
SECTION("Values types") { SECTION("Values types") {
SECTION("String") { SECTION("String") {
JsonError err = DeserializationError err =
deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key1"] == "value1");
@ -139,10 +139,11 @@ TEST_CASE("deserialize JSON object") {
} }
SECTION("Integer") { SECTION("Integer") {
JsonError err = deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); DeserializationError err =
deserializeJson(doc, "{\"key1\":42,\"key2\":-42}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 42); REQUIRE(obj["key1"] == 42);
@ -150,10 +151,11 @@ TEST_CASE("deserialize JSON object") {
} }
SECTION("Double") { SECTION("Double") {
JsonError err = deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); DeserializationError err =
deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 12.345); REQUIRE(obj["key1"] == 12.345);
@ -161,10 +163,11 @@ TEST_CASE("deserialize JSON object") {
} }
SECTION("Booleans") { SECTION("Booleans") {
JsonError err = deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); DeserializationError err =
deserializeJson(doc, "{\"key1\":true,\"key2\":false}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == true); REQUIRE(obj["key1"] == true);
@ -172,10 +175,11 @@ TEST_CASE("deserialize JSON object") {
} }
SECTION("Null") { SECTION("Null") {
JsonError err = deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); DeserializationError err =
deserializeJson(doc, "{\"key1\":null,\"key2\":null}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"].as<char*>() == 0); REQUIRE(obj["key1"].as<char*>() == 0);
@ -185,14 +189,14 @@ TEST_CASE("deserialize JSON object") {
SECTION("Array") { SECTION("Array") {
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
JsonError err = deserializeJson(doc, jsonString); DeserializationError err = deserializeJson(doc, jsonString);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
JsonArray& array1 = obj["ab"]; JsonArray& array1 = obj["ab"];
const JsonArray& array2 = obj["cd"]; const JsonArray& array2 = obj["cd"];
JsonArray& array3 = obj["ef"]; JsonArray& array3 = obj["ef"];
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(true == array1.success()); REQUIRE(true == array1.success());
REQUIRE(true == array2.success()); REQUIRE(true == array2.success());
@ -214,127 +218,133 @@ TEST_CASE("deserialize JSON object") {
SECTION("Premature null terminator") { SECTION("Premature null terminator") {
SECTION("After opening brace") { SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{"); DeserializationError err = deserializeJson(doc, "{");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After key") { SECTION("After key") {
JsonError err = deserializeJson(doc, "{\"hello\""); DeserializationError err = deserializeJson(doc, "{\"hello\"");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After colon") { SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\":"); DeserializationError err = deserializeJson(doc, "{\"hello\":");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After value") { SECTION("After value") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\""); DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\","); DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\",");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
SECTION("Misc") { SECTION("Misc") {
SECTION("A quoted key without value") { SECTION("A quoted key without value") {
JsonError err = deserializeJson(doc, "{\"key\"}"); DeserializationError err = deserializeJson(doc, "{\"key\"}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("A non-quoted key without value") { SECTION("A non-quoted key without value") {
JsonError err = deserializeJson(doc, "{key}"); DeserializationError err = deserializeJson(doc, "{key}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("A dangling comma") { SECTION("A dangling comma") {
JsonError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); DeserializationError err = deserializeJson(doc, "{\"key1\":\"value1\",}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("null as a key") { SECTION("null as a key") {
JsonError err = deserializeJson(doc, "{null:\"value\"}"); DeserializationError err = deserializeJson(doc, "{null:\"value\"}");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
} }
SECTION("Block comments") { SECTION("Block comments") {
SECTION("Before opening brace") { SECTION("Before opening brace") {
JsonError err = deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}"); DeserializationError err =
deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("After opening brace") { SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}"); DeserializationError err =
deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before colon") { SECTION("Before colon") {
JsonError err = deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}"); DeserializationError err =
deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("After colon") { SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}"); DeserializationError err =
deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before closing brace") { SECTION("Before closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}"); DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("After closing brace") { SECTION("After closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/"); DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before comma") { SECTION("Before comma") {
JsonError err = deserializeJson( DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}"); doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42); REQUIRE(obj["answer"] == 42);
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson( DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}"); doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42); REQUIRE(obj["answer"] == 42);
} }
@ -342,69 +352,75 @@ TEST_CASE("deserialize JSON object") {
SECTION("Trailing comments") { SECTION("Trailing comments") {
SECTION("Before opening brace") { SECTION("Before opening brace") {
JsonError err = deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}"); DeserializationError err =
deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("After opening brace") { SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}"); DeserializationError err =
deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before colon") { SECTION("Before colon") {
JsonError err = deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}"); DeserializationError err =
deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("After colon") { SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}"); DeserializationError err =
deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before closing brace") { SECTION("Before closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}"); DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("After closing brace") { SECTION("After closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n"); DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before comma") { SECTION("Before comma") {
JsonError err = deserializeJson( DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}"); doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42); REQUIRE(obj["answer"] == 42);
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = deserializeJson( DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}"); doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42); REQUIRE(obj["answer"] == 42);
} }
@ -412,55 +428,55 @@ TEST_CASE("deserialize JSON object") {
SECTION("Dangling slash") { SECTION("Dangling slash") {
SECTION("Before opening brace") { SECTION("Before opening brace") {
JsonError err = deserializeJson(doc, "/{\"hello\":\"world\"}"); DeserializationError err = deserializeJson(doc, "/{\"hello\":\"world\"}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("After opening brace") { SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{/\"hello\":\"world\"}"); DeserializationError err = deserializeJson(doc, "{/\"hello\":\"world\"}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("Before colon") { SECTION("Before colon") {
JsonError err = deserializeJson(doc, "{\"hello\"/:\"world\"}"); DeserializationError err = deserializeJson(doc, "{\"hello\"/:\"world\"}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("After colon") { SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\":/\"world\"}"); DeserializationError err = deserializeJson(doc, "{\"hello\":/\"world\"}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("Before closing brace") { SECTION("Before closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/}"); DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"/}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("After closing brace") { SECTION("After closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/"); DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"}/");
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world"); REQUIRE(obj["hello"] == "world");
} }
SECTION("Before comma") { SECTION("Before comma") {
JsonError err = DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}"); deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("After comma") { SECTION("After comma") {
JsonError err = DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}"); deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
} }

View File

@ -10,45 +10,45 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") {
StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc;
char input[] = "{}"; char input[] = "{}";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("TooSmallBufferForObjectWithOneValue") { SECTION("TooSmallBufferForObjectWithOneValue") {
StaticJsonDocument<JSON_OBJECT_SIZE(1) - 1> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1) - 1> doc;
char input[] = "{\"a\":1}"; char input[] = "{\"a\":1}";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::NoMemory); REQUIRE(err == DeserializationError::NoMemory);
} }
SECTION("BufferOfTheRightSizeForObjectWithOneValue") { SECTION("BufferOfTheRightSizeForObjectWithOneValue") {
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
char input[] = "{\"a\":1}"; char input[] = "{\"a\":1}";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("TooSmallBufferForObjectWithNestedObject") { SECTION("TooSmallBufferForObjectWithNestedObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1> doc;
char input[] = "{\"a\":[]}"; char input[] = "{\"a\":[]}";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::NoMemory); REQUIRE(err == DeserializationError::NoMemory);
} }
SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { SECTION("BufferOfTheRightSizeForObjectWithNestedObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> doc;
char input[] = "{\"a\":[]}"; char input[] = "{\"a\":[]}";
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("Should clear the JsonObject") { SECTION("Should clear the JsonObject") {

View File

@ -11,71 +11,78 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
DynamicJsonDocument doc; DynamicJsonDocument doc;
SECTION("null char*") { SECTION("null char*") {
JsonError err = deserializeJson(doc, static_cast<char*>(0)); DeserializationError err = deserializeJson(doc, static_cast<char*>(0));
REQUIRE(err != JsonError::Ok); REQUIRE(err != DeserializationError::Ok);
} }
SECTION("null const char*") { SECTION("null const char*") {
JsonError err = deserializeJson(doc, static_cast<const char*>(0)); DeserializationError err =
deserializeJson(doc, static_cast<const char*>(0));
REQUIRE(err != JsonError::Ok); REQUIRE(err != DeserializationError::Ok);
} }
SECTION("Integer") { SECTION("Integer") {
JsonError err = deserializeJson(doc, "-42"); DeserializationError err = deserializeJson(doc, "-42");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<int>()); REQUIRE(doc.is<int>());
REQUIRE_FALSE(doc.is<bool>()); REQUIRE_FALSE(doc.is<bool>());
REQUIRE(doc.as<int>() == -42); REQUIRE(doc.as<int>() == -42);
} }
SECTION("Double") { SECTION("Double") {
JsonError err = deserializeJson(doc, "-1.23e+4"); DeserializationError err = deserializeJson(doc, "-1.23e+4");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE_FALSE(doc.is<int>()); REQUIRE_FALSE(doc.is<int>());
REQUIRE(doc.is<double>()); REQUIRE(doc.is<double>());
REQUIRE(doc.as<double>() == Approx(-1.23e+4)); REQUIRE(doc.as<double>() == Approx(-1.23e+4));
} }
SECTION("Double quoted string") { SECTION("Double quoted string") {
JsonError err = deserializeJson(doc, "\"hello world\""); DeserializationError err = deserializeJson(doc, "\"hello world\"");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<char*>()); REQUIRE(doc.is<char*>());
REQUIRE_THAT(doc.as<char*>(), Equals("hello world")); REQUIRE_THAT(doc.as<char*>(), Equals("hello world"));
} }
SECTION("Single quoted string") { SECTION("Single quoted string") {
JsonError err = deserializeJson(doc, "\'hello world\'"); DeserializationError err = deserializeJson(doc, "\'hello world\'");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<char*>()); REQUIRE(doc.is<char*>());
REQUIRE_THAT(doc.as<char*>(), Equals("hello world")); REQUIRE_THAT(doc.as<char*>(), Equals("hello world"));
} }
SECTION("Escape sequences") { SECTION("Escape sequences") {
JsonError err = DeserializationError err =
deserializeJson(doc, "\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); deserializeJson(doc, "\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "1\"2\\3/4\b5\f6\n7\r8\t9"); REQUIRE(doc.as<std::string>() == "1\"2\\3/4\b5\f6\n7\r8\t9");
} }
SECTION("True") { SECTION("UTF-16 surrogate") {
JsonError err = deserializeJson(doc, "true"); DeserializationError err = deserializeJson(doc, "\"\\uD834\\uDD1E\"");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::NotSupported);
}
SECTION("True") {
DeserializationError err = deserializeJson(doc, "true");
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<bool>()); REQUIRE(doc.is<bool>());
REQUIRE(doc.as<bool>() == true); REQUIRE(doc.as<bool>() == true);
} }
SECTION("False") { SECTION("False") {
JsonError err = deserializeJson(doc, "false"); DeserializationError err = deserializeJson(doc, "false");
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<bool>()); REQUIRE(doc.is<bool>());
REQUIRE(doc.as<bool>() == false); REQUIRE(doc.as<bool>() == false);
} }
@ -89,84 +96,84 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
} }
SECTION("Empty input") { SECTION("Empty input") {
JsonError err = deserializeJson(doc, ""); DeserializationError err = deserializeJson(doc, "");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("Just a trailing comment") { SECTION("Just a trailing comment") {
JsonError err = deserializeJson(doc, "// comment"); DeserializationError err = deserializeJson(doc, "// comment");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("Just a block comment") { SECTION("Just a block comment") {
JsonError err = deserializeJson(doc, "/*comment*/"); DeserializationError err = deserializeJson(doc, "/*comment*/");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("Just a slash") { SECTION("Just a slash") {
JsonError err = deserializeJson(doc, "/"); DeserializationError err = deserializeJson(doc, "/");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("Garbage") { SECTION("Garbage") {
JsonError err = deserializeJson(doc, "%*$£¤"); DeserializationError err = deserializeJson(doc, "%*$£¤");
REQUIRE(err == JsonError::InvalidInput); REQUIRE(err == DeserializationError::InvalidInput);
} }
SECTION("Premature null-terminator") { SECTION("Premature null-terminator") {
SECTION("In escape sequence") { SECTION("In escape sequence") {
JsonError err = deserializeJson(doc, "\"\\"); DeserializationError err = deserializeJson(doc, "\"\\");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In block comment") { SECTION("In block comment") {
JsonError err = deserializeJson(doc, "/* comment"); DeserializationError err = deserializeJson(doc, "/* comment");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In double quoted string") { SECTION("In double quoted string") {
JsonError err = deserializeJson(doc, "\"hello"); DeserializationError err = deserializeJson(doc, "\"hello");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In single quoted string") { SECTION("In single quoted string") {
JsonError err = deserializeJson(doc, "'hello"); DeserializationError err = deserializeJson(doc, "'hello");
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
SECTION("Premature end of input") { SECTION("Premature end of input") {
SECTION("In escape sequence") { SECTION("In escape sequence") {
JsonError err = deserializeJson(doc, "\"\\n\"", 2); DeserializationError err = deserializeJson(doc, "\"\\n\"", 2);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In block comment") { SECTION("In block comment") {
JsonError err = deserializeJson(doc, "/* comment */", 10); DeserializationError err = deserializeJson(doc, "/* comment */", 10);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In double quoted string") { SECTION("In double quoted string") {
JsonError err = deserializeJson(doc, "\"hello\"", 6); DeserializationError err = deserializeJson(doc, "\"hello\"", 6);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In single quoted string") { SECTION("In single quoted string") {
JsonError err = deserializeJson(doc, "'hello'", 6); DeserializationError err = deserializeJson(doc, "'hello'", 6);
REQUIRE(err == JsonError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }
} }

View File

@ -5,8 +5,9 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
#define SHOULD_WORK(expression) REQUIRE(JsonError::Ok == expression); #define SHOULD_WORK(expression) REQUIRE(DeserializationError::Ok == expression);
#define SHOULD_FAIL(expression) REQUIRE(JsonError::TooDeep == expression); #define SHOULD_FAIL(expression) \
REQUIRE(DeserializationError::TooDeep == expression);
TEST_CASE("JsonDeserializer nestingLimit") { TEST_CASE("JsonDeserializer nestingLimit") {
DynamicJsonDocument doc; DynamicJsonDocument doc;

View File

@ -12,10 +12,10 @@ TEST_CASE("deserializeJson(std::istream&)") {
SECTION("array") { SECTION("array") {
std::istringstream json(" [ 42 /* comment */ ] "); std::istringstream json(" [ 42 /* comment */ ] ");
JsonError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size()); REQUIRE(1 == arr.size());
REQUIRE(42 == arr[0]); REQUIRE(42 == arr[0]);
} }
@ -23,10 +23,10 @@ TEST_CASE("deserializeJson(std::istream&)") {
SECTION("object") { SECTION("object") {
std::istringstream json(" { hello : world // comment\n }"); std::istringstream json(" { hello : world // comment\n }");
JsonError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == obj.size()); REQUIRE(1 == obj.size());
REQUIRE(std::string("world") == obj["hello"]); REQUIRE(std::string("world") == obj["hello"]);
} }

View File

@ -11,25 +11,25 @@ TEST_CASE("deserializeJson(const std::string&)") {
SECTION("should accept const string") { SECTION("should accept const string") {
const std::string input("[42]"); const std::string input("[42]");
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("should accept temporary string") { SECTION("should accept temporary string") {
JsonError err = deserializeJson(doc, std::string("[42]")); DeserializationError err = deserializeJson(doc, std::string("[42]"));
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("should duplicate content") { SECTION("should duplicate content") {
std::string input("[\"hello\"]"); std::string input("[\"hello\"]");
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
input[2] = 'X'; // alter the string tomake sure we made a copy input[2] = 'X'; // alter the string tomake sure we made a copy
JsonArray &array = doc.as<JsonArray>(); JsonArray &array = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(std::string("hello") == array[0]); REQUIRE(std::string("hello") == array[0]);
} }
} }

View File

@ -14,18 +14,18 @@ TEST_CASE("unsigned char[]") {
unsigned char input[] = "{\"a\":42}"; unsigned char input[] = "{\"a\":42}";
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
JsonError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("deserializeMsgPack()") { SECTION("deserializeMsgPack()") {
unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world"; unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world";
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc;
MsgPackError err = deserializeMsgPack(doc, input); DeserializationError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("JsonVariant") { SECTION("JsonVariant") {

View File

@ -23,9 +23,9 @@ TEST_CASE("Variable Length Array") {
strcpy(vla, "{\"a\":42}"); strcpy(vla, "{\"a\":42}");
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
JsonError err = deserializeJson(doc, vla); DeserializationError err = deserializeJson(doc, vla);
REQUIRE(err == JsonError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("deserializeMsgPack()") { SECTION("deserializeMsgPack()") {
@ -34,9 +34,9 @@ TEST_CASE("Variable Length Array") {
memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15);
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
MsgPackError err = deserializeMsgPack(doc, vla); DeserializationError err = deserializeMsgPack(doc, vla);
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("JsonVariant") { SECTION("JsonVariant") {

View File

@ -3,7 +3,6 @@
# MIT License # MIT License
add_executable(MsgPackTests add_executable(MsgPackTests
MsgPackError.cpp
deserializeArray.cpp deserializeArray.cpp
deserializeObject.cpp deserializeObject.cpp
deserializeStaticVariant.cpp deserializeStaticVariant.cpp

View File

@ -1,44 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
void testStringification(MsgPackError error, std::string expected) {
REQUIRE(error.c_str() == expected);
}
void testBoolification(MsgPackError error, bool expected) {
CHECK(error == expected);
}
#define TEST_STRINGIFICATION(symbol) \
testStringification(MsgPackError::symbol, #symbol)
#define TEST_BOOLIFICATION(symbol, expected) \
testBoolification(MsgPackError::symbol, expected)
TEST_CASE("MsgPackError") {
SECTION("c_str()") {
TEST_STRINGIFICATION(Ok);
TEST_STRINGIFICATION(NotSupported);
TEST_STRINGIFICATION(NoMemory);
TEST_STRINGIFICATION(TooDeep);
TEST_STRINGIFICATION(IncompleteInput);
}
SECTION("as boolean") {
TEST_BOOLIFICATION(Ok, false);
TEST_BOOLIFICATION(NotSupported, true);
TEST_BOOLIFICATION(NoMemory, true);
TEST_BOOLIFICATION(TooDeep, true);
TEST_BOOLIFICATION(IncompleteInput, true);
}
SECTION("ostream") {
std::stringstream s;
s << MsgPackError::NotSupported;
REQUIRE(s.str() == "NotSupported");
}
}

View File

@ -12,20 +12,20 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") {
SECTION("empty") { SECTION("empty") {
const char* input = "\x90"; const char* input = "\x90";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(array.size() == 0); REQUIRE(array.size() == 0);
} }
SECTION("two integers") { SECTION("two integers") {
const char* input = "\x92\x01\x02"; const char* input = "\x92\x01\x02";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(array.size() == 2); REQUIRE(array.size() == 2);
REQUIRE(array[0] == 1); REQUIRE(array[0] == 1);
REQUIRE(array[1] == 2); REQUIRE(array[1] == 2);
@ -36,20 +36,20 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") {
SECTION("empty") { SECTION("empty") {
const char* input = "\xDC\x00\x00"; const char* input = "\xDC\x00\x00";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(array.size() == 0); REQUIRE(array.size() == 0);
} }
SECTION("two strings") { SECTION("two strings") {
const char* input = "\xDC\x00\x02\xA5hello\xA5world"; const char* input = "\xDC\x00\x02\xA5hello\xA5world";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(array.size() == 2); REQUIRE(array.size() == 2);
REQUIRE(array[0] == "hello"); REQUIRE(array[0] == "hello");
REQUIRE(array[1] == "world"); REQUIRE(array[1] == "world");
@ -60,10 +60,10 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") {
SECTION("empty") { SECTION("empty") {
const char* input = "\xDD\x00\x00\x00\x00"; const char* input = "\xDD\x00\x00\x00\x00";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(array.size() == 0); REQUIRE(array.size() == 0);
} }
@ -71,10 +71,10 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") {
const char* input = const char* input =
"\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(array.size() == 2); REQUIRE(array.size() == 2);
REQUIRE(array[0] == 0.0f); REQUIRE(array[0] == 0.0f);
REQUIRE(array[1] == 3.14f); REQUIRE(array[1] == 3.14f);

View File

@ -12,10 +12,10 @@ TEST_CASE("deserialize MsgPack object") {
SECTION("empty") { SECTION("empty") {
const char* input = "\x80"; const char* input = "\x80";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 0); REQUIRE(obj.size() == 0);
} }
@ -23,10 +23,10 @@ TEST_CASE("deserialize MsgPack object") {
SECTION("two integers") { SECTION("two integers") {
const char* input = "\x82\xA3one\x01\xA3two\x02"; const char* input = "\x82\xA3one\x01\xA3two\x02";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["one"] == 1); REQUIRE(obj["one"] == 1);
@ -38,10 +38,10 @@ TEST_CASE("deserialize MsgPack object") {
SECTION("empty") { SECTION("empty") {
const char* input = "\xDE\x00\x00"; const char* input = "\xDE\x00\x00";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 0); REQUIRE(obj.size() == 0);
} }
@ -49,10 +49,10 @@ TEST_CASE("deserialize MsgPack object") {
SECTION("two strings") { SECTION("two strings") {
const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["H"] == "hello"); REQUIRE(obj["H"] == "hello");
@ -64,10 +64,10 @@ TEST_CASE("deserialize MsgPack object") {
SECTION("empty") { SECTION("empty") {
const char* input = "\xDF\x00\x00\x00\x00"; const char* input = "\xDF\x00\x00\x00\x00";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 0); REQUIRE(obj.size() == 0);
} }
@ -77,10 +77,10 @@ TEST_CASE("deserialize MsgPack object") {
"\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48"
"\xF5\xC3"; "\xF5\xC3";
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
JsonObject& obj = doc.as<JsonObject>(); JsonObject& obj = doc.as<JsonObject>();
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.is<JsonObject>()); REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 2); REQUIRE(obj.size() == 2);
REQUIRE(obj["zero"] == 0.0f); REQUIRE(obj["zero"] == 0.0f);

View File

@ -8,124 +8,133 @@
static const size_t epsilon = sizeof(void*); static const size_t epsilon = sizeof(void*);
template <size_t Capacity> template <size_t Capacity>
static void check(const char* input, MsgPackError expected) { static void check(const char* input, DeserializationError expected) {
StaticJsonDocument<Capacity> variant; StaticJsonDocument<Capacity> variant;
MsgPackError error = deserializeMsgPack(variant, input); DeserializationError error = deserializeMsgPack(variant, input);
REQUIRE(error == expected); REQUIRE(error == expected);
} }
TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") {
SECTION("single values always fit") { SECTION("single values always fit") {
check<0>("\xc0", MsgPackError::Ok); // nil check<0>("\xc0", DeserializationError::Ok); // nil
check<0>("\xc2", MsgPackError::Ok); // false check<0>("\xc2", DeserializationError::Ok); // false
check<0>("\xc3", MsgPackError::Ok); // true check<0>("\xc3", DeserializationError::Ok); // true
check<0>("\xcc\x00", MsgPackError::Ok); // uint 8 check<0>("\xcc\x00", DeserializationError::Ok); // uint 8
check<0>("\xcd\x30\x39", MsgPackError::Ok); // uint 16 check<0>("\xcd\x30\x39", DeserializationError::Ok); // uint 16
check<0>("\xCE\x12\x34\x56\x78", MsgPackError::Ok); // uint 32 check<0>("\xCE\x12\x34\x56\x78", DeserializationError::Ok); // uint 32
} }
SECTION("fixstr") { SECTION("fixstr") {
check<0>("\xA0", MsgPackError::Ok); check<0>("\xA0", DeserializationError::Ok);
check<0>("\xA1H", MsgPackError::NoMemory); check<0>("\xA1H", DeserializationError::NoMemory);
check<4>("\xA1H", MsgPackError::Ok); check<4>("\xA1H", DeserializationError::Ok);
check<4>("\xA5Hello", MsgPackError::NoMemory); check<4>("\xA5Hello", DeserializationError::NoMemory);
} }
SECTION("str 8") { SECTION("str 8") {
check<0>("\xD9\x00", MsgPackError::Ok); check<0>("\xD9\x00", DeserializationError::Ok);
check<0>("\xD9\x01H", MsgPackError::NoMemory); check<0>("\xD9\x01H", DeserializationError::NoMemory);
check<4>("\xD9\x01H", MsgPackError::Ok); check<4>("\xD9\x01H", DeserializationError::Ok);
check<4>("\xD9\x05Hello", MsgPackError::NoMemory); check<4>("\xD9\x05Hello", DeserializationError::NoMemory);
} }
SECTION("str 16") { SECTION("str 16") {
check<0>("\xDA\x00\x00", MsgPackError::Ok); check<0>("\xDA\x00\x00", DeserializationError::Ok);
check<0>("\xDA\x00\x01H", MsgPackError::NoMemory); check<0>("\xDA\x00\x01H", DeserializationError::NoMemory);
check<4>("\xDA\x00\x01H", MsgPackError::Ok); check<4>("\xDA\x00\x01H", DeserializationError::Ok);
check<4>("\xDA\x00\x05Hello", MsgPackError::NoMemory); check<4>("\xDA\x00\x05Hello", DeserializationError::NoMemory);
} }
SECTION("str 32") { SECTION("str 32") {
check<0>("\xDB\x00\x00\x00\x00", MsgPackError::Ok); check<0>("\xDB\x00\x00\x00\x00", DeserializationError::Ok);
check<0>("\xDB\x00\x00\x00\x01H", MsgPackError::NoMemory); check<0>("\xDB\x00\x00\x00\x01H", DeserializationError::NoMemory);
check<4>("\xDB\x00\x00\x00\x01H", MsgPackError::Ok); check<4>("\xDB\x00\x00\x00\x01H", DeserializationError::Ok);
check<4>("\xDB\x00\x00\x00\x05Hello", MsgPackError::NoMemory); check<4>("\xDB\x00\x00\x00\x05Hello", DeserializationError::NoMemory);
} }
SECTION("fixarray") { SECTION("fixarray") {
check<JSON_ARRAY_SIZE(0)>("\x90", MsgPackError::Ok); // [] check<JSON_ARRAY_SIZE(0)>("\x90", DeserializationError::Ok); // []
check<JSON_ARRAY_SIZE(0)>("\x91\x01", MsgPackError::NoMemory); // [1] check<JSON_ARRAY_SIZE(0)>("\x91\x01",
check<JSON_ARRAY_SIZE(1)>("\x91\x01", MsgPackError::Ok); // [1] DeserializationError::NoMemory); // [1]
check<JSON_ARRAY_SIZE(1)>("\x92\x01\x02", MsgPackError::NoMemory); // [1,2] check<JSON_ARRAY_SIZE(1)>("\x91\x01", DeserializationError::Ok); // [1]
check<JSON_ARRAY_SIZE(1)>("\x92\x01\x02",
DeserializationError::NoMemory); // [1,2]
} }
SECTION("array 16") { SECTION("array 16") {
check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x00", MsgPackError::Ok); check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x00", DeserializationError::Ok);
check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x01\x01", MsgPackError::NoMemory); check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x01\x01",
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x01\x01", MsgPackError::Ok); DeserializationError::NoMemory);
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x02\x01\x02", MsgPackError::NoMemory); check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x01\x01", DeserializationError::Ok);
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x02\x01\x02",
DeserializationError::NoMemory);
} }
SECTION("array 32") { SECTION("array 32") {
check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x00", MsgPackError::Ok); check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x00", DeserializationError::Ok);
check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x01\x01", check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x01\x01",
MsgPackError::NoMemory); DeserializationError::NoMemory);
check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x01\x01", MsgPackError::Ok); check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x01\x01",
DeserializationError::Ok);
check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x02\x01\x02", check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x02\x01\x02",
MsgPackError::NoMemory); DeserializationError::NoMemory);
} }
SECTION("fixmap") { SECTION("fixmap") {
SECTION("{}") { SECTION("{}") {
check<JSON_OBJECT_SIZE(0)>("\x80", MsgPackError::Ok); check<JSON_OBJECT_SIZE(0)>("\x80", DeserializationError::Ok);
} }
SECTION("{H:1}") { SECTION("{H:1}") {
check<JSON_OBJECT_SIZE(0)>("\x81\xA1H\x01", MsgPackError::NoMemory); check<JSON_OBJECT_SIZE(0)>("\x81\xA1H\x01",
check<JSON_OBJECT_SIZE(1) + epsilon>("\x81\xA1H\x01", MsgPackError::Ok); DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(1) + epsilon>("\x81\xA1H\x01",
DeserializationError::Ok);
} }
SECTION("{H:1,W:2}") { SECTION("{H:1,W:2}") {
check<JSON_OBJECT_SIZE(1) + epsilon>("\x82\xA1H\x01\xA1W\x02", check<JSON_OBJECT_SIZE(1) + epsilon>("\x82\xA1H\x01\xA1W\x02",
MsgPackError::NoMemory); DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(2) + 2 * epsilon>("\x82\xA1H\x01\xA1W\x02", check<JSON_OBJECT_SIZE(2) + 2 * epsilon>("\x82\xA1H\x01\xA1W\x02",
MsgPackError::Ok); DeserializationError::Ok);
} }
} }
SECTION("map 16") { SECTION("map 16") {
SECTION("{}") { SECTION("{}") {
check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x00", MsgPackError::Ok); check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x00", DeserializationError::Ok);
} }
SECTION("{H:1}") { SECTION("{H:1}") {
check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x01\xA1H\x01", check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x01\xA1H\x01",
MsgPackError::NoMemory); DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x01\xA1H\x01", check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x01\xA1H\x01",
MsgPackError::Ok); DeserializationError::Ok);
} }
SECTION("{H:1,W:2}") { SECTION("{H:1,W:2}") {
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02", check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02",
MsgPackError::NoMemory); DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(2) + 2 * epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02", check<JSON_OBJECT_SIZE(2) + 2 * epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02",
MsgPackError::Ok); DeserializationError::Ok);
} }
} }
SECTION("map 32") { SECTION("map 32") {
SECTION("{}") { SECTION("{}") {
check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x00", MsgPackError::Ok); check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x00",
DeserializationError::Ok);
} }
SECTION("{H:1}") { SECTION("{H:1}") {
check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x01\xA1H\x01", check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x01\xA1H\x01",
MsgPackError::NoMemory); DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDF\x00\x00\x00\x01\xA1H\x01", check<JSON_OBJECT_SIZE(1) + epsilon>("\xDF\x00\x00\x00\x01\xA1H\x01",
MsgPackError::Ok); DeserializationError::Ok);
} }
SECTION("{H:1,W:2}") { SECTION("{H:1,W:2}") {
check<JSON_OBJECT_SIZE(1) + epsilon>( check<JSON_OBJECT_SIZE(1) + epsilon>(
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::NoMemory); "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(2) + 2 * epsilon>( check<JSON_OBJECT_SIZE(2) + 2 * epsilon>(
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::Ok); "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok);
} }
} }
} }

View File

@ -9,9 +9,9 @@ template <typename T, typename U>
static void check(const char* input, U expected) { static void check(const char* input, U expected) {
DynamicJsonDocument variant; DynamicJsonDocument variant;
MsgPackError error = deserializeMsgPack(variant, input); DeserializationError error = deserializeMsgPack(variant, input);
REQUIRE(error == MsgPackError::Ok); REQUIRE(error == DeserializationError::Ok);
REQUIRE(variant.is<T>()); REQUIRE(variant.is<T>());
REQUIRE(variant.as<T>() == expected); REQUIRE(variant.as<T>() == expected);
} }

View File

@ -5,17 +5,17 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
MsgPackError deserialize(const char* input, size_t len) { DeserializationError deserialize(const char* input, size_t len) {
DynamicJsonDocument doc; DynamicJsonDocument doc;
return deserializeMsgPack(doc, input, len); return deserializeMsgPack(doc, input, len);
} }
void checkAllSizes(const char* input, size_t len) { void checkAllSizes(const char* input, size_t len) {
REQUIRE(deserialize(input, len) == MsgPackError::Ok); REQUIRE(deserialize(input, len) == DeserializationError::Ok);
while (--len) { while (--len) {
REQUIRE(deserialize(input, len) == MsgPackError::IncompleteInput); REQUIRE(deserialize(input, len) == DeserializationError::IncompleteInput);
} }
} }

View File

@ -5,27 +5,28 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
static void check(const char* input, MsgPackError expected, uint8_t limit) { static void check(const char* input, DeserializationError expected,
uint8_t limit) {
DynamicJsonDocument doc; DynamicJsonDocument doc;
doc.nestingLimit = limit; doc.nestingLimit = limit;
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
REQUIRE(error == expected); REQUIRE(error == expected);
} }
TEST_CASE("Errors returned by deserializeMsgPack()") { TEST_CASE("Errors returned by deserializeMsgPack()") {
SECTION("object too deep") { SECTION("object too deep") {
check("\x80", MsgPackError::TooDeep, 0); // {} check("\x80", DeserializationError::TooDeep, 0); // {}
check("\x80", MsgPackError::Ok, 1); // {} check("\x80", DeserializationError::Ok, 1); // {}
check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}} check("\x81\xA1H\x80", DeserializationError::TooDeep, 1); // {H:{}}
check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}} check("\x81\xA1H\x80", DeserializationError::Ok, 2); // {H:{}}
} }
SECTION("array too deep") { SECTION("array too deep") {
check("\x90", MsgPackError::TooDeep, 0); // [] check("\x90", DeserializationError::TooDeep, 0); // []
check("\x90", MsgPackError::Ok, 1); // [] check("\x90", DeserializationError::Ok, 1); // []
check("\x91\x90", MsgPackError::TooDeep, 1); // [[]] check("\x91\x90", DeserializationError::TooDeep, 1); // [[]]
check("\x91\x90", MsgPackError::Ok, 2); // [[]] check("\x91\x90", DeserializationError::Ok, 2); // [[]]
} }
} }

View File

@ -8,9 +8,9 @@
static void checkNotSupported(const char* input) { static void checkNotSupported(const char* input) {
DynamicJsonDocument doc; DynamicJsonDocument doc;
MsgPackError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
REQUIRE(error == MsgPackError::NotSupported); REQUIRE(error == DeserializationError::NotSupported);
} }
TEST_CASE("deserializeMsgPack() return NotSupported") { TEST_CASE("deserializeMsgPack() return NotSupported") {

View File

@ -11,9 +11,9 @@ TEST_CASE("deserializeMsgPack(std::istream&)") {
SECTION("should accept a zero in input") { SECTION("should accept a zero in input") {
std::istringstream input(std::string("\x92\x00\x02", 3)); std::istringstream input(std::string("\x92\x00\x02", 3));
MsgPackError err = deserializeMsgPack(doc, input); DeserializationError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(arr[0] == 0); REQUIRE(arr[0] == 0);
REQUIRE(arr[1] == 2); REQUIRE(arr[1] == 2);
@ -22,8 +22,8 @@ TEST_CASE("deserializeMsgPack(std::istream&)") {
SECTION("should detect incomplete input") { SECTION("should detect incomplete input") {
std::istringstream input("\x92\x00\x02"); std::istringstream input("\x92\x00\x02");
MsgPackError err = deserializeMsgPack(doc, input); DeserializationError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
} }

View File

@ -11,32 +11,34 @@ TEST_CASE("deserializeMsgPack(const std::string&)") {
SECTION("should accept const string") { SECTION("should accept const string") {
const std::string input("\x92\x01\x02"); const std::string input("\x92\x01\x02");
MsgPackError err = deserializeMsgPack(doc, input); DeserializationError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("should accept temporary string") { SECTION("should accept temporary string") {
MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x01\x02")); DeserializationError err =
deserializeMsgPack(doc, std::string("\x92\x01\x02"));
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
} }
SECTION("should duplicate content") { SECTION("should duplicate content") {
std::string input("\x91\xA5hello"); std::string input("\x91\xA5hello");
MsgPackError err = deserializeMsgPack(doc, input); DeserializationError err = deserializeMsgPack(doc, input);
input[2] = 'X'; // alter the string tomake sure we made a copy input[2] = 'X'; // alter the string tomake sure we made a copy
JsonArray& array = doc.as<JsonArray>(); JsonArray& array = doc.as<JsonArray>();
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
REQUIRE(std::string("hello") == array[0]); REQUIRE(std::string("hello") == array[0]);
} }
SECTION("should accept a zero in input") { SECTION("should accept a zero in input") {
MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x00\x02", 3)); DeserializationError err =
deserializeMsgPack(doc, std::string("\x92\x00\x02", 3));
REQUIRE(err == MsgPackError::Ok); REQUIRE(err == DeserializationError::Ok);
JsonArray& arr = doc.as<JsonArray>(); JsonArray& arr = doc.as<JsonArray>();
REQUIRE(arr[0] == 0); REQUIRE(arr[0] == 0);
REQUIRE(arr[1] == 2); REQUIRE(arr[1] == 2);