Copy JsonArray and JsonObject, instead of storing pointers (fixes #780)

This commit is contained in:
Benoit Blanchon
2018-09-11 16:05:56 +02:00
parent 2998a55f0b
commit b106b1ed14
52 changed files with 971 additions and 978 deletions

View File

@@ -5,8 +5,6 @@
#pragma once
#include "Configuration.hpp"
#include "JsonArrayData.hpp"
#include "JsonObjectData.hpp"
#include "JsonVariant.hpp"
#include "Numbers/parseFloat.hpp"
#include "Numbers/parseInteger.hpp"
@@ -15,26 +13,16 @@
namespace ArduinoJson {
inline bool JsonVariant::set(const JsonArray& array) {
if (!_data) return false;
if (array._data)
_data->setArray(*array._data);
else
_data->setNull();
return true;
inline bool JsonVariant::set(JsonArray array) {
return to<JsonArray>().copyFrom(array);
}
inline bool JsonVariant::set(const Internals::JsonArraySubscript& value) {
return set(value.as<JsonVariant>());
}
inline bool JsonVariant::set(const JsonObject& object) {
if (!_data) return false;
if (object._data)
_data->setObject(*object._data);
else
_data->setNull();
return true;
inline bool JsonVariant::set(JsonObject object) {
return to<JsonObject>().copyFrom(object);
}
template <typename TString>
@@ -43,6 +31,28 @@ inline bool JsonVariant::set(
return set(value.template as<JsonVariant>());
}
inline bool JsonVariant::set(const JsonVariant& value) {
if (!_data) return false;
if (!value._data) {
_data->setNull();
return true;
}
switch (value._data->type) {
case Internals::JSON_ARRAY:
return set(value.as<JsonArray>());
case Internals::JSON_OBJECT:
return set(value.as<JsonObject>());
case Internals::JSON_OWNED_STRING:
return set(const_cast<char*>(value._data->content.asString));
case Internals::JSON_OWNED_RAW:
return set(serialized(const_cast<char*>(value._data->content.asRaw.data),
value._data->content.asRaw.size));
default:
*_data = *value._data;
return true;
}
}
template <typename T>
inline typename Internals::enable_if<
Internals::is_same<typename Internals::remove_const<T>::type,
@@ -60,4 +70,69 @@ inline typename Internals::enable_if<
JsonVariant::as() const {
return _data ? JsonObject(_memoryPool, _data->asObject()) : JsonObject();
}
template <typename T>
inline typename Internals::enable_if<Internals::is_same<T, JsonArray>::value,
JsonArray>::type
JsonVariant::to() {
if (!_data) return JsonArray();
return JsonArray(_memoryPool, _data->toArray());
}
template <typename T>
typename Internals::enable_if<Internals::is_same<T, JsonObject>::value,
JsonObject>::type
JsonVariant::to() {
if (!_data) return JsonObject();
return JsonObject(_memoryPool, _data->toObject());
}
template <typename T>
typename Internals::enable_if<Internals::is_same<T, JsonVariant>::value,
JsonVariant>::type
JsonVariant::to() {
if (!_data) return JsonVariant();
_data->setNull();
return *this;
}
template <typename Visitor>
inline void JsonVariant::accept(Visitor& visitor) const {
using namespace Internals;
if (!_data) return visitor.visitNull();
switch (_data->type) {
case JSON_FLOAT:
return visitor.visitFloat(_data->content.asFloat);
case JSON_ARRAY:
return visitor.visitArray(
JsonArray(_memoryPool, &_data->content.asArray));
case JSON_OBJECT:
return visitor.visitObject(
JsonObject(_memoryPool, &_data->content.asObject));
case JSON_LINKED_STRING:
case JSON_OWNED_STRING:
return visitor.visitString(_data->content.asString);
case JSON_LINKED_RAW:
case JSON_OWNED_RAW:
return visitor.visitRawJson(_data->content.asRaw.data,
_data->content.asRaw.size);
case JSON_NEGATIVE_INTEGER:
return visitor.visitNegativeInteger(_data->content.asInteger);
case JSON_POSITIVE_INTEGER:
return visitor.visitPositiveInteger(_data->content.asInteger);
case JSON_BOOLEAN:
return visitor.visitBoolean(_data->content.asInteger != 0);
default:
return visitor.visitNull();
}
}
} // namespace ArduinoJson