Create or assign a JsonDocument from a JsonArray/JsonObject/JsonVariant

This commit is contained in:
Benoit Blanchon
2019-01-23 10:47:20 +01:00
parent 2a3b51ac3a
commit 4167b11434
10 changed files with 334 additions and 98 deletions

View File

@ -13,16 +13,24 @@ namespace ARDUINOJSON_NAMESPACE {
class DynamicJsonDocument : public JsonDocument {
public:
explicit DynamicJsonDocument(size_t capa)
: JsonDocument(allocPool(addPadding(capa))) {}
: JsonDocument(allocPool(capa)) {}
DynamicJsonDocument(const DynamicJsonDocument& src)
: JsonDocument(allocPool(src.capacity())) {
copy(src);
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
DynamicJsonDocument(const JsonDocument& src)
: JsonDocument(allocPool(src.capacity())) {
copy(src);
template <typename T>
DynamicJsonDocument(const T& src,
typename enable_if<IsVisitable<T>::value>::type* = 0)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
// disambiguate
DynamicJsonDocument(VariantRef src)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
~DynamicJsonDocument() {
@ -31,19 +39,20 @@ class DynamicJsonDocument : public JsonDocument {
DynamicJsonDocument& operator=(const DynamicJsonDocument& src) {
reallocPoolIfTooSmall(src.memoryUsage());
copy(src);
set(src);
return *this;
}
template <typename T>
DynamicJsonDocument& operator=(const JsonDocument& src) {
DynamicJsonDocument& operator=(const T& src) {
reallocPoolIfTooSmall(src.memoryUsage());
copy(src);
set(src);
return *this;
}
private:
MemoryPool allocPool(size_t capa) {
MemoryPool allocPool(size_t requiredSize) {
size_t capa = addPadding(requiredSize);
return MemoryPool(reinterpret_cast<char*>(malloc(capa)), capa);
}

View File

@ -5,6 +5,7 @@
#pragma once
#include "../Memory/MemoryPool.hpp"
#include "../Object/ObjectRef.hpp"
#include "../Variant/VariantRef.hpp"
#include "../Variant/VariantTo.hpp"
@ -53,6 +54,16 @@ class JsonDocument : public Visitable {
return _pool.capacity();
}
bool set(const JsonDocument& src) {
return to<VariantRef>().set(src.as<VariantRef>());
}
template <typename T>
typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set(
const T& src) {
return to<VariantRef>().set(src);
}
template <typename T>
typename VariantTo<T>::type to() {
clear();

View File

@ -16,13 +16,31 @@ class StaticJsonDocument : public JsonDocument {
public:
StaticJsonDocument() : JsonDocument(_buffer, ACTUAL_CAPACITY) {}
StaticJsonDocument(const JsonDocument& src)
StaticJsonDocument(const StaticJsonDocument& src)
: JsonDocument(_buffer, ACTUAL_CAPACITY) {
copy(src);
set(src);
}
StaticJsonDocument operator=(const JsonDocument& src) {
copy(src);
template <typename T>
StaticJsonDocument(const T& src,
typename enable_if<IsVisitable<T>::value>::type* = 0)
: JsonDocument(_buffer, ACTUAL_CAPACITY) {
set(src);
}
// disambiguate
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, ACTUAL_CAPACITY) {
set(src);
}
StaticJsonDocument operator=(const StaticJsonDocument& src) {
set(src);
return *this;
}
template <typename T>
StaticJsonDocument operator=(const T& src) {
set(src);
return *this;
}

View File

@ -77,6 +77,14 @@ variantAs(const VariantData* _data) {
return _data != 0 ? _data->asString() : 0;
}
template <typename T>
inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs(
const VariantData* _data);
template <typename T>
inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs(
const VariantData* _data);
template <typename T>
inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type
variantAs(const VariantData* _data);

View File

@ -5,10 +5,23 @@
#pragma once
#include "../Serialization/DynamicStringWriter.hpp"
#include "VariantFunctions.hpp"
#include "VariantRef.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename T>
inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs(
const VariantData* _data) {
return ArrayConstRef(variantAsArray(_data));
}
template <typename T>
inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs(
const VariantData* _data) {
return ObjectConstRef(variantAsObject(_data));
}
template <typename T>
inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type
variantAs(const VariantData* _data) {

View File

@ -67,10 +67,7 @@ class VariantData {
}
CollectionData *asArray() {
if (type() == VALUE_IS_ARRAY)
return &_content.asCollection;
else
return 0;
return type() == VALUE_IS_ARRAY ? &_content.asCollection : 0;
}
const CollectionData *asArray() const {
@ -78,10 +75,7 @@ class VariantData {
}
CollectionData *asObject() {
if (type() == VALUE_IS_OBJECT)
return &_content.asCollection;
else
return 0;
return type() == VALUE_IS_OBJECT ? &_content.asCollection : 0;
}
const CollectionData *asObject() const {

View File

@ -16,6 +16,10 @@ inline void variantAccept(const VariantData *var, Visitor &visitor) {
visitor.visitNull();
}
inline const CollectionData *variantAsArray(const VariantData *var) {
return var != 0 ? var->asArray() : 0;
}
inline const CollectionData *variantAsObject(const VariantData *var) {
return var != 0 ? var->asObject() : 0;
}