Skip to content

Commit a69601d

Browse files
committed
VariantImpl: add copy functions
1 parent 5e6df3c commit a69601d

File tree

12 files changed

+142
-94
lines changed

12 files changed

+142
-94
lines changed

src/ArduinoJson.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
#include "ArduinoJson/Object/MemberProxy.hpp"
4949
#include "ArduinoJson/Object/ObjectImpl.hpp"
5050
#include "ArduinoJson/Variant/ConverterImpl.hpp"
51-
#include "ArduinoJson/Variant/JsonVariantCopier.hpp"
5251
#include "ArduinoJson/Variant/VariantCompare.hpp"
5352
#include "ArduinoJson/Variant/VariantRefBaseImpl.hpp"
5453

src/ArduinoJson/Array/ArrayImpl.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,31 @@ inline void VariantImpl::removeElement(size_t index) {
7676
removeElement(at(index));
7777
}
7878

79+
inline bool VariantImpl::copyArray(const VariantImpl& src) {
80+
ARDUINOJSON_ASSERT(isNull());
81+
82+
if (!data_)
83+
return false;
84+
85+
data_->toArray();
86+
87+
for (auto it = src.createIterator(); !it.done(); it.move()) {
88+
auto slot = allocVariant();
89+
if (!slot)
90+
return false;
91+
92+
VariantImpl element(slot.ptr(), resources_);
93+
if (!element.copyVariant(*it)) {
94+
freeVariant(slot);
95+
return false;
96+
}
97+
98+
addElement(slot);
99+
}
100+
101+
return true;
102+
}
103+
79104
// Returns the size (in bytes) of an array with n elements.
80105
constexpr size_t sizeofArray(size_t n) {
81106
return n * sizeof(VariantData);

src/ArduinoJson/Array/JsonArray.hpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
8989
// Copies an array.
9090
// https://arduinojson.org/v7/api/jsonarray/set/
9191
bool set(JsonArrayConst src) const {
92-
if (isNull())
93-
return false;
94-
95-
clear();
96-
for (auto element : src) {
97-
if (!add(element))
98-
return false;
99-
}
100-
101-
return true;
92+
impl_.clear();
93+
return impl_.copyArray(detail::VariantAttorney::getImpl(src));
10294
}
10395

10496
// Removes the element at the specified iterator.

src/ArduinoJson/Collection/CollectionImpl.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ inline VariantImpl::iterator VariantImpl::createIterator() const {
1818
return iterator(coll->head, resources_);
1919
}
2020

21-
inline void VariantImpl::appendPair(Slot<VariantData> key,
22-
Slot<VariantData> value) {
21+
inline void VariantImpl::addMember(Slot<VariantData> key,
22+
Slot<VariantData> value) {
23+
ARDUINOJSON_ASSERT(isObject());
24+
ARDUINOJSON_ASSERT(key);
25+
ARDUINOJSON_ASSERT(value);
26+
2327
auto coll = getCollectionData();
2428

2529
key->next = value.id();

src/ArduinoJson/Json/JsonDeserializer.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,18 @@ class JsonDeserializer {
280280
VariantImpl object(objectData, resources_);
281281
auto member = object.getMember(adaptString(key));
282282
if (!member) {
283-
auto keyVariant = object.addPair(&member);
284-
if (!keyVariant)
283+
auto keySlot = resources_->allocVariant();
284+
if (!keySlot)
285285
return DeserializationError::NoMemory;
286286

287-
stringBuilder_.save(keyVariant);
287+
auto valueSlot = resources_->allocVariant();
288+
if (!valueSlot)
289+
return DeserializationError::NoMemory;
290+
291+
object.addMember(keySlot, valueSlot);
292+
293+
stringBuilder_.save(keySlot.ptr());
294+
member = valueSlot.ptr();
288295
} else {
289296
VariantImpl(member, resources_).clear();
290297
}

src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,18 @@ class MsgPackDeserializer {
401401
VariantData* member = 0;
402402

403403
if (memberFilter.allow()) {
404-
auto keyVariant = object.addPair(&member);
405-
if (!keyVariant)
404+
auto keySlot = resources_->allocVariant();
405+
if (!keySlot)
406406
return DeserializationError::NoMemory;
407407

408-
stringBuffer_.save(keyVariant);
408+
auto valueSlot = resources_->allocVariant();
409+
if (!valueSlot)
410+
return DeserializationError::NoMemory;
411+
412+
object.addMember(keySlot, valueSlot);
413+
414+
member = valueSlot.ptr();
415+
stringBuffer_.save(keySlot.ptr());
409416
}
410417

411418
err = parseVariant(member, memberFilter, nestingLimit.decrement());

src/ArduinoJson/Object/JsonObject.hpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,11 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
8383
// Copies an object.
8484
// https://arduinojson.org/v7/api/jsonobject/set/
8585
bool set(JsonObjectConst src) {
86-
if (isNull() || src.isNull())
86+
if (isNull() ||
87+
src.isNull()) // TODO: this check is not consistent with JsonArray
8788
return false;
88-
89-
clear();
90-
for (auto kvp : src) {
91-
if (!operator[](kvp.key()).set(kvp.value()))
92-
return false;
93-
}
94-
95-
return true;
89+
impl_.clear();
90+
return impl_.copyObject(detail::VariantAttorney::getImpl(src));
9691
}
9792

9893
// Gets or sets the member with specified key.

src/ArduinoJson/Object/ObjectImpl.hpp

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,46 @@
99

1010
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
1111

12+
inline bool VariantImpl::copyObject(const VariantImpl& src) {
13+
ARDUINOJSON_ASSERT(isNull());
14+
15+
if (!data_)
16+
return false;
17+
18+
data_->toObject();
19+
20+
for (auto it = src.createIterator(); !it.done(); it.move()) {
21+
auto keySlot = allocVariant();
22+
if (!keySlot)
23+
return false;
24+
25+
auto key = VariantImpl(keySlot.ptr(), resources_);
26+
if (!key.copyVariant(*it)) {
27+
freeVariant(keySlot);
28+
return false;
29+
}
30+
31+
it.move(); // move to value
32+
ARDUINOJSON_ASSERT(!it.done());
33+
34+
auto valueSlot = allocVariant();
35+
if (!valueSlot) {
36+
freeVariant(keySlot);
37+
return false;
38+
}
39+
40+
// TODO: we add the pair before copying the value to be keep the old
41+
// behavior but this is not consistent with issue #2081
42+
addMember(keySlot, valueSlot);
43+
44+
auto value = VariantImpl(valueSlot.ptr(), resources_);
45+
if (!value.copyVariant(*it))
46+
return false;
47+
}
48+
49+
return true;
50+
}
51+
1252
template <typename TAdaptedString>
1353
inline VariantData* VariantImpl::getMember(TAdaptedString key) const {
1454
auto it = findKey(key);
@@ -70,28 +110,11 @@ inline VariantData* VariantImpl::addMember(TAdaptedString key) {
70110
if (!keyImpl.setString(key))
71111
return nullptr;
72112

73-
VariantImpl::appendPair(keySlot, valueSlot);
113+
addMember(keySlot, valueSlot);
74114

75115
return valueSlot.ptr();
76116
}
77117

78-
inline VariantData* VariantImpl::addPair(VariantData** value) {
79-
ARDUINOJSON_ASSERT(isObject());
80-
81-
auto keySlot = allocVariant();
82-
if (!keySlot)
83-
return nullptr;
84-
85-
auto valueSlot = allocVariant();
86-
if (!valueSlot)
87-
return nullptr;
88-
*value = valueSlot.ptr();
89-
90-
VariantImpl::appendPair(keySlot, valueSlot);
91-
92-
return keySlot.ptr();
93-
}
94-
95118
// Returns the size (in bytes) of an object with n members.
96119
constexpr size_t sizeofObject(size_t n) {
97120
return 2 * n * sizeof(VariantData);

src/ArduinoJson/Variant/JsonVariant.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,12 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
3737
mutable detail::VariantImpl impl_;
3838
};
3939

40-
namespace detail {
41-
bool copyVariant(JsonVariant dst, JsonVariantConst src);
42-
}
43-
4440
template <>
4541
struct Converter<JsonVariant> : private detail::VariantAttorney {
4642
static bool toJson(JsonVariantConst src, JsonVariant dst) {
47-
return copyVariant(dst, src);
43+
auto impl = getImpl(dst);
44+
impl.clear();
45+
return impl.copyVariant(getImpl(src));
4846
}
4947

5048
static JsonVariant fromJson(JsonVariant src) {
@@ -59,7 +57,9 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
5957
template <>
6058
struct Converter<JsonVariantConst> : private detail::VariantAttorney {
6159
static bool toJson(JsonVariantConst src, JsonVariant dst) {
62-
return copyVariant(dst, src);
60+
auto impl = getImpl(dst);
61+
impl.clear();
62+
return impl.copyVariant(getImpl(src));
6363
}
6464

6565
static JsonVariantConst fromJson(JsonVariantConst src) {

src/ArduinoJson/Variant/JsonVariantCopier.hpp

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)