forked from bblanchon/ArduinoJson
Added implicit conversion from JsonArray
and JsonObject
to JsonVariant
This commit is contained in:
@ -1,6 +1,11 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
HEAD
|
||||
----
|
||||
|
||||
* Added implicit conversion from `JsonArray` and `JsonObject` to `JsonVariant`
|
||||
|
||||
v6.4.0-beta (2018-09-11)
|
||||
-----------
|
||||
|
||||
|
@ -4,158 +4,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Numbers/parseFloat.hpp"
|
||||
#include "../Numbers/parseInteger.hpp"
|
||||
#include "JsonVariantContent.hpp"
|
||||
#include "JsonVariantType.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// this struct must be a POD type to prevent error calling offsetof on clang
|
||||
struct JsonVariantData {
|
||||
JsonVariantType type;
|
||||
JsonVariantContent content;
|
||||
|
||||
JsonVariantData() {
|
||||
type = JSON_NULL;
|
||||
}
|
||||
|
||||
void setBoolean(bool value) {
|
||||
type = JSON_BOOLEAN;
|
||||
content.asInteger = static_cast<JsonUInt>(value);
|
||||
}
|
||||
|
||||
void setFloat(JsonFloat value) {
|
||||
type = JSON_FLOAT;
|
||||
content.asFloat = value;
|
||||
}
|
||||
|
||||
void setNegativeInteger(JsonUInt value) {
|
||||
type = JSON_NEGATIVE_INTEGER;
|
||||
content.asInteger = value;
|
||||
}
|
||||
|
||||
void setPostiveInteger(JsonUInt value) {
|
||||
type = JSON_POSITIVE_INTEGER;
|
||||
content.asInteger = value;
|
||||
}
|
||||
|
||||
void setOwnedString(const char *value) {
|
||||
type = JSON_OWNED_STRING;
|
||||
content.asString = value;
|
||||
}
|
||||
|
||||
void setLinkedString(const char *value) {
|
||||
type = JSON_LINKED_STRING;
|
||||
content.asString = value;
|
||||
}
|
||||
|
||||
void setOwnedRaw(const char *data, size_t size) {
|
||||
type = JSON_OWNED_RAW;
|
||||
content.asRaw.data = data;
|
||||
content.asRaw.size = size;
|
||||
}
|
||||
|
||||
void setLinkedRaw(const char *data, size_t size) {
|
||||
type = JSON_LINKED_RAW;
|
||||
content.asRaw.data = data;
|
||||
content.asRaw.size = size;
|
||||
}
|
||||
|
||||
void setNull() {
|
||||
type = JSON_NULL;
|
||||
}
|
||||
|
||||
JsonArrayData *toArray() {
|
||||
type = JSON_ARRAY;
|
||||
content.asArray.head = 0;
|
||||
content.asArray.tail = 0;
|
||||
return &content.asArray;
|
||||
}
|
||||
|
||||
JsonObjectData *toObject() {
|
||||
type = JSON_OBJECT;
|
||||
content.asObject.head = 0;
|
||||
content.asObject.tail = 0;
|
||||
return &content.asObject;
|
||||
}
|
||||
|
||||
JsonArrayData *asArray() {
|
||||
return type == JSON_ARRAY ? &content.asArray : 0;
|
||||
}
|
||||
|
||||
JsonObjectData *asObject() {
|
||||
return type == JSON_OBJECT ? &content.asObject : 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T asInteger() const {
|
||||
switch (type) {
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
return T(content.asInteger);
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return T(~content.asInteger + 1);
|
||||
case JSON_LINKED_STRING:
|
||||
case JSON_OWNED_STRING:
|
||||
return parseInteger<T>(content.asString);
|
||||
case JSON_FLOAT:
|
||||
return T(content.asFloat);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T asFloat() const {
|
||||
switch (type) {
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
return static_cast<T>(content.asInteger);
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return -static_cast<T>(content.asInteger);
|
||||
case JSON_LINKED_STRING:
|
||||
case JSON_OWNED_STRING:
|
||||
return parseFloat<T>(content.asString);
|
||||
case JSON_FLOAT:
|
||||
return static_cast<T>(content.asFloat);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *asString() const {
|
||||
return isString() ? content.asString : NULL;
|
||||
}
|
||||
|
||||
bool isArray() const {
|
||||
return type == JSON_ARRAY;
|
||||
}
|
||||
|
||||
bool isBoolean() const {
|
||||
return type == JSON_BOOLEAN;
|
||||
}
|
||||
|
||||
bool isFloat() const {
|
||||
return type == JSON_FLOAT || type == JSON_POSITIVE_INTEGER ||
|
||||
type == JSON_NEGATIVE_INTEGER;
|
||||
}
|
||||
|
||||
bool isInteger() const {
|
||||
return type == JSON_POSITIVE_INTEGER || type == JSON_NEGATIVE_INTEGER;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return type == JSON_NULL;
|
||||
}
|
||||
|
||||
bool isObject() const {
|
||||
return type == JSON_OBJECT;
|
||||
}
|
||||
|
||||
bool isString() const {
|
||||
return type == JSON_LINKED_STRING || type == JSON_OWNED_STRING;
|
||||
}
|
||||
};
|
||||
|
||||
inline JsonVariantData *getVariantData(JsonArrayData *arr) {
|
||||
const ptrdiff_t offset = offsetof(JsonVariantData, content) -
|
||||
offsetof(JsonVariantContent, asArray);
|
||||
if (!arr) return 0;
|
||||
return reinterpret_cast<JsonVariantData *>(reinterpret_cast<char *>(arr) -
|
||||
offset);
|
||||
}
|
||||
|
||||
inline JsonVariantData *getVariantData(JsonObjectData *obj) {
|
||||
const ptrdiff_t offset = offsetof(JsonVariantData, content) -
|
||||
offsetof(JsonVariantContent, asObject);
|
||||
if (!obj) return 0;
|
||||
return reinterpret_cast<JsonVariantData *>(reinterpret_cast<char *>(obj) -
|
||||
offset);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
||||
|
@ -37,7 +37,7 @@ class DynamicJsonDocument {
|
||||
|
||||
void clear() {
|
||||
_memoryPool.clear();
|
||||
_rootData.setNull();
|
||||
_rootData.type = Internals::JSON_NULL;
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
|
@ -26,9 +26,14 @@ class JsonArray {
|
||||
typedef JsonArrayIterator iterator;
|
||||
|
||||
FORCE_INLINE JsonArray() : _memoryPool(0), _data(0) {}
|
||||
FORCE_INLINE JsonArray(Internals::MemoryPool* buf,
|
||||
FORCE_INLINE JsonArray(Internals::MemoryPool* pool,
|
||||
Internals::JsonArrayData* arr)
|
||||
: _memoryPool(buf), _data(arr) {}
|
||||
: _memoryPool(pool), _data(arr) {}
|
||||
|
||||
operator JsonVariant() {
|
||||
using namespace Internals;
|
||||
return JsonVariant(_memoryPool, getVariantData(_data));
|
||||
}
|
||||
|
||||
// Adds the specified value at the end of the array.
|
||||
//
|
||||
|
@ -24,6 +24,11 @@ class JsonObject {
|
||||
Internals::JsonObjectData* object)
|
||||
: _memoryPool(buf), _data(object) {}
|
||||
|
||||
operator JsonVariant() {
|
||||
using namespace Internals;
|
||||
return JsonVariant(_memoryPool, getVariantData(_data));
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data) return iterator();
|
||||
return iterator(_memoryPool, _data->head);
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "JsonVariant.hpp"
|
||||
#include "JsonVariantBase.hpp"
|
||||
#include "Memory/MemoryPool.hpp"
|
||||
#include "Numbers/parseFloat.hpp"
|
||||
#include "Numbers/parseInteger.hpp"
|
||||
#include "Polyfills/type_traits.hpp"
|
||||
#include "Serialization/DynamicStringWriter.hpp"
|
||||
#include "SerializedValue.hpp"
|
||||
@ -41,7 +43,8 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
// set(bool value)
|
||||
FORCE_INLINE bool set(bool value) {
|
||||
if (!_data) return false;
|
||||
_data->setBoolean(value);
|
||||
_data->type = Internals::JSON_BOOLEAN;
|
||||
_data->content.asInteger = static_cast<Internals::JsonUInt>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -52,7 +55,8 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
T value, typename Internals::enable_if<
|
||||
Internals::is_floating_point<T>::value>::type * = 0) {
|
||||
if (!_data) return false;
|
||||
_data->setFloat(static_cast<Internals::JsonFloat>(value));
|
||||
_data->type = Internals::JSON_FLOAT;
|
||||
_data->content.asFloat = static_cast<Internals::JsonFloat>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -68,10 +72,13 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
Internals::is_signed<T>::value>::type * =
|
||||
0) {
|
||||
if (!_data) return false;
|
||||
if (value >= 0)
|
||||
_data->setPostiveInteger(static_cast<Internals::JsonUInt>(value));
|
||||
else
|
||||
_data->setNegativeInteger(~static_cast<Internals::JsonUInt>(value) + 1);
|
||||
if (value >= 0) {
|
||||
_data->type = Internals::JSON_POSITIVE_INTEGER;
|
||||
_data->content.asInteger = static_cast<Internals::JsonUInt>(value);
|
||||
} else {
|
||||
_data->type = Internals::JSON_NEGATIVE_INTEGER;
|
||||
_data->content.asInteger = ~static_cast<Internals::JsonUInt>(value) + 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -85,14 +92,17 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
Internals::is_unsigned<T>::value>::type * =
|
||||
0) {
|
||||
if (!_data) return false;
|
||||
_data->setPostiveInteger(static_cast<Internals::JsonUInt>(value));
|
||||
_data->type = Internals::JSON_POSITIVE_INTEGER;
|
||||
_data->content.asInteger = static_cast<Internals::JsonUInt>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// set(SerializedValue<const char *>)
|
||||
FORCE_INLINE bool set(Internals::SerializedValue<const char *> value) {
|
||||
if (!_data) return false;
|
||||
_data->setLinkedRaw(value.data(), value.size());
|
||||
_data->type = Internals::JSON_LINKED_RAW;
|
||||
_data->content.asRaw.data = value.data();
|
||||
_data->content.asRaw.size = value.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -107,11 +117,15 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
if (!_data) return false;
|
||||
const char *dup =
|
||||
Internals::makeString(value.data(), value.size()).save(_memoryPool);
|
||||
if (dup)
|
||||
_data->setOwnedRaw(dup, value.size());
|
||||
else
|
||||
_data->setNull();
|
||||
return true;
|
||||
if (dup) {
|
||||
_data->type = Internals::JSON_OWNED_RAW;
|
||||
_data->content.asRaw.data = dup;
|
||||
_data->content.asRaw.size = value.size();
|
||||
return true;
|
||||
} else {
|
||||
_data->type = Internals::JSON_NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set(const std::string&)
|
||||
@ -124,10 +138,11 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
if (!_data) return false;
|
||||
const char *dup = Internals::makeString(value).save(_memoryPool);
|
||||
if (dup) {
|
||||
_data->setOwnedString(dup);
|
||||
_data->type = Internals::JSON_OWNED_STRING;
|
||||
_data->content.asString = dup;
|
||||
return true;
|
||||
} else {
|
||||
_data->setNull();
|
||||
_data->type = Internals::JSON_NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -141,10 +156,11 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
if (!_data) return false;
|
||||
const char *dup = Internals::makeString(value).save(_memoryPool);
|
||||
if (dup) {
|
||||
_data->setOwnedString(dup);
|
||||
_data->type = Internals::JSON_OWNED_STRING;
|
||||
_data->content.asString = dup;
|
||||
return true;
|
||||
} else {
|
||||
_data->setNull();
|
||||
_data->type = Internals::JSON_NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -152,7 +168,8 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
// set(const char*);
|
||||
FORCE_INLINE bool set(const char *value) {
|
||||
if (!_data) return false;
|
||||
_data->setLinkedString(value);
|
||||
_data->type = Internals::JSON_LINKED_STRING;
|
||||
_data->content.asString = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -179,14 +196,28 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
FORCE_INLINE const typename Internals::enable_if<
|
||||
Internals::is_integral<T>::value, T>::type
|
||||
as() const {
|
||||
return _data ? _data->asInteger<T>() : T();
|
||||
if (!_data) return 0;
|
||||
switch (_data->type) {
|
||||
case Internals::JSON_POSITIVE_INTEGER:
|
||||
case Internals::JSON_BOOLEAN:
|
||||
return T(_data->content.asInteger);
|
||||
case Internals::JSON_NEGATIVE_INTEGER:
|
||||
return T(~_data->content.asInteger + 1);
|
||||
case Internals::JSON_LINKED_STRING:
|
||||
case Internals::JSON_OWNED_STRING:
|
||||
return Internals::parseInteger<T>(_data->content.asString);
|
||||
case Internals::JSON_FLOAT:
|
||||
return T(_data->content.asFloat);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// bool as<bool>() const
|
||||
template <typename T>
|
||||
FORCE_INLINE const typename Internals::enable_if<
|
||||
Internals::is_same<T, bool>::value, T>::type
|
||||
as() const {
|
||||
return _data && _data->asInteger<int>() != 0;
|
||||
return as<int>() != 0;
|
||||
}
|
||||
//
|
||||
// double as<double>() const;
|
||||
@ -195,7 +226,21 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
FORCE_INLINE const typename Internals::enable_if<
|
||||
Internals::is_floating_point<T>::value, T>::type
|
||||
as() const {
|
||||
return _data ? _data->asFloat<T>() : 0;
|
||||
if (!_data) return 0;
|
||||
switch (_data->type) {
|
||||
case Internals::JSON_POSITIVE_INTEGER:
|
||||
case Internals::JSON_BOOLEAN:
|
||||
return static_cast<T>(_data->content.asInteger);
|
||||
case Internals::JSON_NEGATIVE_INTEGER:
|
||||
return -static_cast<T>(_data->content.asInteger);
|
||||
case Internals::JSON_LINKED_STRING:
|
||||
case Internals::JSON_OWNED_STRING:
|
||||
return Internals::parseFloat<T>(_data->content.asString);
|
||||
case Internals::JSON_FLOAT:
|
||||
return static_cast<T>(_data->content.asFloat);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//
|
||||
// const char* as<const char*>() const;
|
||||
@ -206,7 +251,12 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
Internals::is_same<T, char *>::value,
|
||||
const char *>::type
|
||||
as() const {
|
||||
return _data ? _data->asString() : 0;
|
||||
if (!_data) return 0;
|
||||
if (_data && (_data->type == Internals::JSON_LINKED_STRING ||
|
||||
_data->type == Internals::JSON_OWNED_STRING))
|
||||
return _data->content.asString;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// std::string as<std::string>() const;
|
||||
@ -216,7 +266,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
typename Internals::enable_if<Internals::IsWriteableString<T>::value,
|
||||
T>::type
|
||||
as() const {
|
||||
const char *cstr = _data ? _data->asString() : 0;
|
||||
const char *cstr = as<const char *>();
|
||||
if (cstr) return T(cstr);
|
||||
T s;
|
||||
serializeJson(*this, s);
|
||||
@ -266,7 +316,8 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
FORCE_INLINE typename Internals::enable_if<Internals::is_integral<T>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return _data && _data->isInteger();
|
||||
return _data && (_data->type == Internals::JSON_POSITIVE_INTEGER ||
|
||||
_data->type == Internals::JSON_NEGATIVE_INTEGER);
|
||||
}
|
||||
//
|
||||
// bool is<double>() const;
|
||||
@ -276,7 +327,9 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
typename Internals::enable_if<Internals::is_floating_point<T>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return _data && _data->isFloat();
|
||||
return _data && (_data->type == Internals::JSON_FLOAT ||
|
||||
_data->type == Internals::JSON_POSITIVE_INTEGER ||
|
||||
_data->type == Internals::JSON_NEGATIVE_INTEGER);
|
||||
}
|
||||
//
|
||||
// bool is<bool>() const
|
||||
@ -284,7 +337,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
FORCE_INLINE typename Internals::enable_if<Internals::is_same<T, bool>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return _data && _data->isBoolean();
|
||||
return _data && _data->type == Internals::JSON_BOOLEAN;
|
||||
}
|
||||
//
|
||||
// bool is<const char*>() const;
|
||||
@ -295,7 +348,8 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
Internals::is_same<T, char *>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return _data && _data->isString();
|
||||
return _data && (_data->type == Internals::JSON_LINKED_STRING ||
|
||||
_data->type == Internals::JSON_OWNED_STRING);
|
||||
}
|
||||
//
|
||||
// bool is<JsonArray> const;
|
||||
@ -306,7 +360,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
JsonArray>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return _data && _data->isArray();
|
||||
return _data && _data->type == Internals::JSON_ARRAY;
|
||||
}
|
||||
//
|
||||
// bool is<JsonObject> const;
|
||||
@ -317,11 +371,11 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
JsonObject>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return _data && _data->isObject();
|
||||
return _data && _data->type == Internals::JSON_OBJECT;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0 || _data->isNull();
|
||||
return _data == 0 || _data->type == Internals::JSON_NULL;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isInvalid() const {
|
||||
@ -354,5 +408,16 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
||||
private:
|
||||
Internals::MemoryPool *_memoryPool;
|
||||
Internals::JsonVariantData *_data;
|
||||
}; // namespace ArduinoJson
|
||||
};
|
||||
|
||||
class JsonVariantLocal : public JsonVariant {
|
||||
public:
|
||||
explicit JsonVariantLocal(Internals::MemoryPool *memoryPool)
|
||||
: JsonVariant(memoryPool, &_localData) {
|
||||
_localData.type = Internals::JSON_NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
Internals::JsonVariantData _localData;
|
||||
};
|
||||
} // namespace ArduinoJson
|
||||
|
@ -34,7 +34,7 @@ inline bool JsonVariant::set(
|
||||
inline bool JsonVariant::set(const JsonVariant& value) {
|
||||
if (!_data) return false;
|
||||
if (!value._data) {
|
||||
_data->setNull();
|
||||
_data->type = Internals::JSON_NULL;
|
||||
return true;
|
||||
}
|
||||
switch (value._data->type) {
|
||||
@ -59,7 +59,10 @@ inline typename Internals::enable_if<
|
||||
JsonArray>::value,
|
||||
JsonArray>::type
|
||||
JsonVariant::as() const {
|
||||
return _data ? JsonArray(_memoryPool, _data->asArray()) : JsonArray();
|
||||
if (_data && _data->type == Internals::JSON_ARRAY)
|
||||
return JsonArray(_memoryPool, &_data->content.asArray);
|
||||
else
|
||||
return JsonArray();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -68,7 +71,10 @@ inline typename Internals::enable_if<
|
||||
JsonObject>::value,
|
||||
T>::type
|
||||
JsonVariant::as() const {
|
||||
return _data ? JsonObject(_memoryPool, _data->asObject()) : JsonObject();
|
||||
if (_data && _data->type == Internals::JSON_OBJECT)
|
||||
return JsonObject(_memoryPool, &_data->content.asObject);
|
||||
else
|
||||
return JsonObject();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -76,7 +82,10 @@ inline typename Internals::enable_if<Internals::is_same<T, JsonArray>::value,
|
||||
JsonArray>::type
|
||||
JsonVariant::to() {
|
||||
if (!_data) return JsonArray();
|
||||
return JsonArray(_memoryPool, _data->toArray());
|
||||
_data->type = Internals::JSON_ARRAY;
|
||||
_data->content.asArray.head = 0;
|
||||
_data->content.asArray.tail = 0;
|
||||
return JsonArray(_memoryPool, &_data->content.asArray);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -84,7 +93,10 @@ typename Internals::enable_if<Internals::is_same<T, JsonObject>::value,
|
||||
JsonObject>::type
|
||||
JsonVariant::to() {
|
||||
if (!_data) return JsonObject();
|
||||
return JsonObject(_memoryPool, _data->toObject());
|
||||
_data->type = Internals::JSON_OBJECT;
|
||||
_data->content.asObject.head = 0;
|
||||
_data->content.asObject.tail = 0;
|
||||
return JsonObject(_memoryPool, &_data->content.asObject);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -92,7 +104,7 @@ typename Internals::enable_if<Internals::is_same<T, JsonVariant>::value,
|
||||
JsonVariant>::type
|
||||
JsonVariant::to() {
|
||||
if (!_data) return JsonVariant();
|
||||
_data->setNull();
|
||||
_data->type = Internals::JSON_NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -277,13 +277,12 @@ class MsgPackDeserializer {
|
||||
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
||||
--_nestingLimit;
|
||||
for (; n; --n) {
|
||||
JsonVariantData keyData;
|
||||
JsonVariant key(_memoryPool, &keyData);
|
||||
JsonVariantLocal key(_memoryPool);
|
||||
DeserializationError err = parse(key);
|
||||
if (err) return err;
|
||||
if (!keyData.isString()) return DeserializationError::NotSupported;
|
||||
if (!key.is<char *>()) return DeserializationError::NotSupported;
|
||||
|
||||
JsonVariant value = object.set(keyData.asString());
|
||||
JsonVariant value = object.set(key.as<char *>());
|
||||
if (value.isInvalid()) return DeserializationError::NoMemory;
|
||||
|
||||
err = parse(value);
|
||||
|
@ -39,7 +39,7 @@ class StaticJsonDocument {
|
||||
|
||||
void clear() {
|
||||
_memoryPool.clear();
|
||||
_rootData.setNull();
|
||||
_rootData.type = Internals::JSON_NULL;
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
|
@ -8,6 +8,7 @@ add_executable(JsonVariantTests
|
||||
copy.cpp
|
||||
is.cpp
|
||||
isnull.cpp
|
||||
misc.cpp
|
||||
or.cpp
|
||||
set_get.cpp
|
||||
subscript.cpp
|
||||
|
50
test/JsonVariant/misc.cpp
Normal file
50
test/JsonVariant/misc.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonVariant from JsonArray") {
|
||||
SECTION("JsonArray is null") {
|
||||
JsonArray arr;
|
||||
JsonVariant v = arr;
|
||||
REQUIRE(v.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("JsonArray is not null") {
|
||||
DynamicJsonDocument doc;
|
||||
JsonArray arr = doc.to<JsonArray>();
|
||||
arr.add(12);
|
||||
arr.add(34);
|
||||
|
||||
JsonVariant v = arr;
|
||||
|
||||
REQUIRE(v.is<JsonArray>() == true);
|
||||
REQUIRE(v.size() == 2);
|
||||
REQUIRE(v[0] == 12);
|
||||
REQUIRE(v[1] == 34);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant from JsonObject") {
|
||||
SECTION("JsonObject is null") {
|
||||
JsonObject obj;
|
||||
JsonVariant v = obj;
|
||||
REQUIRE(v.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("JsonObject is not null") {
|
||||
DynamicJsonDocument doc;
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
obj["a"] = 12;
|
||||
obj["b"] = 34;
|
||||
|
||||
JsonVariant v = obj;
|
||||
|
||||
REQUIRE(v.is<JsonObject>() == true);
|
||||
REQUIRE(v.size() == 2);
|
||||
REQUIRE(v["a"] == 12);
|
||||
REQUIRE(v["b"] == 34);
|
||||
}
|
||||
}
|
@ -205,7 +205,20 @@ TEST_CASE("JsonVariant and strings") {
|
||||
|
||||
REQUIRE(variant == "hello");
|
||||
}
|
||||
|
||||
// TODO: string
|
||||
// TODO: serialized()
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant with not enough memory") {
|
||||
StaticJsonDocument<1> doc;
|
||||
|
||||
JsonVariant v = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("std::string") {
|
||||
v.set(std::string("hello"));
|
||||
REQUIRE(v.isNull());
|
||||
}
|
||||
|
||||
SECTION("Serialized<std::string>") {
|
||||
v.set(serialized(std::string("hello")));
|
||||
REQUIRE(v.isNull());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user