mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-19 21:42:30 +02:00
Implement variant copy at the JsonVariant
level
This commit is contained in:
@ -42,6 +42,7 @@
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||
#include "ArduinoJson/Variant/JsonVariantCopier.hpp"
|
||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||
|
||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||
|
@ -24,9 +24,8 @@ inline bool ArrayData::copyFrom(const ArrayData& src,
|
||||
|
||||
for (auto it = src.createIterator(); !it.done(); it.next()) {
|
||||
auto var = addElement(resources);
|
||||
if (!var)
|
||||
return false;
|
||||
if (!var->copyFrom(*it, resources))
|
||||
if (!copyVariant(JsonVariant(var, resources),
|
||||
JsonVariantConst(it.data(), resources)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -18,9 +18,8 @@ inline bool ObjectData::copyFrom(const ObjectData& src,
|
||||
JsonString key(it.key(),
|
||||
it.ownsKey() ? JsonString::Copied : JsonString::Linked);
|
||||
auto var = addMember(adaptString(key), resources);
|
||||
if (!var)
|
||||
return false;
|
||||
if (!var->copyFrom(*it, resources))
|
||||
if (!copyVariant(JsonVariant(var, resources),
|
||||
JsonVariantConst(it.data(), resources)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -302,9 +302,11 @@ struct ConverterNeedsWriteableRef {
|
||||
|
||||
template <>
|
||||
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
|
||||
static void toJson(JsonVariantConst src, JsonVariant dst) {
|
||||
detail::VariantData::copy(getData(dst), getData(src),
|
||||
getResourceManager(dst));
|
||||
static void toJson(JsonArrayConst src, JsonVariant dst) {
|
||||
if (src.isNull())
|
||||
dst.set(nullptr);
|
||||
else
|
||||
dst.to<JsonArray>().set(src);
|
||||
}
|
||||
|
||||
static JsonArrayConst fromJson(JsonVariantConst src) {
|
||||
@ -322,8 +324,10 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
|
||||
template <>
|
||||
struct Converter<JsonArray> : private detail::VariantAttorney {
|
||||
static void toJson(JsonVariantConst src, JsonVariant dst) {
|
||||
detail::VariantData::copy(getData(dst), getData(src),
|
||||
getResourceManager(dst));
|
||||
if (src.isNull())
|
||||
dst.set(nullptr);
|
||||
else
|
||||
dst.to<JsonArray>().set(src);
|
||||
}
|
||||
|
||||
static JsonArray fromJson(JsonVariant src) {
|
||||
@ -348,8 +352,10 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
|
||||
template <>
|
||||
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
|
||||
static void toJson(JsonVariantConst src, JsonVariant dst) {
|
||||
detail::VariantData::copy(getData(dst), getData(src),
|
||||
getResourceManager(dst));
|
||||
if (src.isNull())
|
||||
dst.set(nullptr);
|
||||
else
|
||||
dst.to<JsonObject>().set(src);
|
||||
}
|
||||
|
||||
static JsonObjectConst fromJson(JsonVariantConst src) {
|
||||
@ -367,8 +373,10 @@ struct Converter<JsonObjectConst> : private detail::VariantAttorney {
|
||||
template <>
|
||||
struct Converter<JsonObject> : private detail::VariantAttorney {
|
||||
static void toJson(JsonVariantConst src, JsonVariant dst) {
|
||||
detail::VariantData::copy(getData(dst), getData(src),
|
||||
getResourceManager(dst));
|
||||
if (src.isNull())
|
||||
dst.set(nullptr);
|
||||
else
|
||||
dst.to<JsonObject>().set(src);
|
||||
}
|
||||
|
||||
static JsonObject fromJson(JsonVariant src) {
|
||||
|
@ -39,11 +39,14 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
bool copyVariant(JsonVariant dst, JsonVariantConst src);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Converter<JsonVariant> : private detail::VariantAttorney {
|
||||
static void toJson(JsonVariant src, JsonVariant dst) {
|
||||
detail::VariantData::copy(getData(dst), getData(src),
|
||||
getResourceManager(dst));
|
||||
copyVariant(dst, src);
|
||||
}
|
||||
|
||||
static JsonVariant fromJson(JsonVariant src) {
|
||||
@ -66,8 +69,7 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
|
||||
template <>
|
||||
struct Converter<JsonVariantConst> : private detail::VariantAttorney {
|
||||
static void toJson(JsonVariantConst src, JsonVariant dst) {
|
||||
detail::VariantData::copy(getData(dst), getData(src),
|
||||
getResourceManager(dst));
|
||||
copyVariant(dst, src);
|
||||
}
|
||||
|
||||
static JsonVariantConst fromJson(JsonVariantConst src) {
|
||||
|
34
src/ArduinoJson/Variant/JsonVariantCopier.hpp
Normal file
34
src/ArduinoJson/Variant/JsonVariantCopier.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Variant/JsonVariant.hpp>
|
||||
#include <ArduinoJson/Variant/JsonVariantVisitor.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class JsonVariantCopier {
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
JsonVariantCopier(JsonVariant dst) : dst_(dst) {}
|
||||
|
||||
template <typename T>
|
||||
bool visit(T src) {
|
||||
return dst_.set(src);
|
||||
}
|
||||
|
||||
private:
|
||||
JsonVariant dst_;
|
||||
};
|
||||
|
||||
inline bool copyVariant(JsonVariant dst, JsonVariantConst src) {
|
||||
if (dst.isUnbound())
|
||||
return false;
|
||||
JsonVariantCopier copier(dst);
|
||||
return accept(src, copier);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -185,47 +185,6 @@ class VariantData {
|
||||
}
|
||||
}
|
||||
|
||||
bool copyFrom(const VariantData& src, ResourceManager* resources) {
|
||||
release(resources);
|
||||
switch (src.type()) {
|
||||
case VALUE_IS_ARRAY:
|
||||
return toArray().copyFrom(src.content_.asArray, resources);
|
||||
case VALUE_IS_OBJECT:
|
||||
return toObject().copyFrom(src.content_.asObject, resources);
|
||||
case VALUE_IS_OWNED_STRING: {
|
||||
auto str = adaptString(src.asString());
|
||||
auto dup = resources->saveString(str);
|
||||
if (!dup)
|
||||
return false;
|
||||
setOwnedString(dup);
|
||||
return true;
|
||||
}
|
||||
case VALUE_IS_RAW_STRING: {
|
||||
auto str = adaptString(src.asRawString());
|
||||
auto dup = resources->saveString(str);
|
||||
if (!dup)
|
||||
return false;
|
||||
setRawString(dup);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
content_ = src.content_;
|
||||
flags_ = src.flags_;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool copy(VariantData* dst, const VariantData* src,
|
||||
ResourceManager* resources) {
|
||||
if (!dst)
|
||||
return false;
|
||||
if (!src) {
|
||||
dst->setNull();
|
||||
return true;
|
||||
}
|
||||
return dst->copyFrom(*src, resources);
|
||||
}
|
||||
|
||||
VariantData* getElement(size_t index) const {
|
||||
auto array = asArray();
|
||||
if (!array)
|
||||
|
Reference in New Issue
Block a user