Skip to content

Commit a159820

Browse files
committed
CollectionImpl: attach to VariantData* instead of CollectionData*
1 parent c222fc2 commit a159820

File tree

14 files changed

+205
-112
lines changed

14 files changed

+205
-112
lines changed

src/ArduinoJson/Array/ArrayData.hpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,30 @@ class ArrayImpl : public CollectionImpl {
1212
public:
1313
ArrayImpl() {}
1414

15-
ArrayImpl(CollectionData* data, ResourceManager* resources)
15+
ArrayImpl(VariantData* data, ResourceManager* resources)
1616
: CollectionImpl(data, resources) {}
1717

18-
VariantData* addElement();
18+
bool isNull() const {
19+
return !data_ || data_->type != VariantType::Array;
20+
}
21+
22+
VariantData* addElement() {
23+
if (isNull())
24+
return nullptr;
25+
return addElement(data_, resources_);
26+
}
27+
28+
static VariantData* addElement(VariantData*, ResourceManager*);
29+
30+
template <typename T>
31+
bool addValue(const T& value) {
32+
if (isNull())
33+
return false;
34+
return addValue(value, data_, resources_);
35+
}
1936

2037
template <typename T>
21-
bool addValue(const T& value);
38+
static bool addValue(const T& value, VariantData*, ResourceManager*);
2239

2340
VariantData* getOrAddElement(size_t index);
2441

src/ArduinoJson/Array/ArrayImpl.hpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
1212

1313
inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
14+
if (isNull())
15+
return iterator();
16+
1417
auto it = createIterator();
1518
while (!it.done() && index) {
1619
it.next(resources_);
@@ -19,14 +22,16 @@ inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
1922
return it;
2023
}
2124

22-
inline VariantData* ArrayImpl::addElement() {
23-
if (!data_)
24-
return nullptr;
25-
ARDUINOJSON_ASSERT(resources_ != nullptr);
26-
auto slot = resources_->allocVariant();
25+
inline VariantData* ArrayImpl::addElement(VariantData* data,
26+
ResourceManager* resources) {
27+
ARDUINOJSON_ASSERT(data != nullptr);
28+
ARDUINOJSON_ASSERT(data->isArray());
29+
ARDUINOJSON_ASSERT(resources != nullptr);
30+
31+
auto slot = resources->allocVariant();
2732
if (!slot)
2833
return nullptr;
29-
CollectionImpl::appendOne(slot);
34+
CollectionImpl::appendOne(slot, data, resources);
3035
return slot.ptr();
3136
}
3237

@@ -57,19 +62,19 @@ inline void ArrayImpl::removeElement(size_t index) {
5762
}
5863

5964
template <typename T>
60-
inline bool ArrayImpl::addValue(const T& value) {
61-
if (!data_)
62-
return false;
63-
ARDUINOJSON_ASSERT(resources_ != nullptr);
64-
auto slot = resources_->allocVariant();
65+
inline bool ArrayImpl::addValue(const T& value, VariantData* data,
66+
ResourceManager* resources) {
67+
ARDUINOJSON_ASSERT(data != nullptr);
68+
ARDUINOJSON_ASSERT(resources != nullptr);
69+
auto slot = resources->allocVariant();
6570
if (!slot)
6671
return false;
67-
JsonVariant variant(slot.ptr(), resources_);
72+
JsonVariant variant(slot.ptr(), resources);
6873
if (!variant.set(value)) {
69-
resources_->freeVariant(slot);
74+
resources->freeVariant(slot);
7075
return false;
7176
}
72-
CollectionImpl::appendOne(slot);
77+
CollectionImpl::appendOne(slot, data, resources);
7378
return true;
7479
}
7580

src/ArduinoJson/Array/JsonArray.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
2424

2525
// INTERNAL USE ONLY
2626
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
27-
: impl_(detail::VariantImpl::asArray(data, resources)) {}
27+
: impl_(data, resources) {}
2828

2929
// INTERNAL USE ONLY
3030
JsonArray(const detail::ArrayImpl& impl) : impl_(impl) {}

src/ArduinoJson/Array/JsonArrayConst.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
3838

3939
// INTERNAL USE ONLY
4040
JsonArrayConst(detail::VariantData* data, detail::ResourceManager* resources)
41-
: impl_(detail::VariantImpl::asArray(data, resources)) {}
41+
: impl_(data, resources) {}
4242

4343
// INTERNAL USE ONLY
4444
JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}

src/ArduinoJson/Collection/CollectionData.hpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,48 +68,63 @@ class CollectionIterator {
6868

6969
class CollectionImpl {
7070
protected:
71-
CollectionData* data_;
71+
VariantData* data_;
7272
ResourceManager* resources_;
7373

7474
public:
7575
using iterator = CollectionIterator;
7676

7777
CollectionImpl() : data_(nullptr), resources_(nullptr) {}
7878

79-
CollectionImpl(CollectionData* data, ResourceManager* resources)
79+
CollectionImpl(VariantData* data, ResourceManager* resources)
8080
: data_(data), resources_(resources) {}
8181

8282
explicit operator bool() const {
83-
return data_ != nullptr;
83+
return data_ && data_->isCollection();
8484
}
8585

8686
bool isNull() const {
87-
return data_ == nullptr;
87+
return !operator bool();
8888
}
8989

9090
VariantData* getData() const {
91-
void* data = data_; // prevent warning cast-align
92-
return reinterpret_cast<VariantData*>(data);
91+
return data_;
9392
}
9493

9594
ResourceManager* getResourceManager() const {
9695
return resources_;
9796
}
9897

99-
iterator createIterator() const;
98+
iterator createIterator() const {
99+
if (isNull())
100+
return iterator();
101+
return createIterator(data_, resources_);
102+
}
103+
104+
static iterator createIterator(VariantData*, ResourceManager*);
100105

101106
size_t size() const;
102107
size_t nesting() const;
103108

104-
void clear();
109+
void clear() {
110+
if (isNull())
111+
return;
112+
clear(data_, resources_);
113+
}
114+
115+
static void clear(VariantData*, ResourceManager*);
105116

106117
SlotId head() const {
107-
return data_->head;
118+
ARDUINOJSON_ASSERT(data_ != nullptr);
119+
ARDUINOJSON_ASSERT(data_->isCollection());
120+
return data_->content.asCollection.head;
108121
}
109122

110123
protected:
111-
void appendOne(Slot<VariantData> slot);
112-
void appendPair(Slot<VariantData> key, Slot<VariantData> value);
124+
static void appendOne(Slot<VariantData> slot, VariantData*, ResourceManager*);
125+
126+
static void appendPair(Slot<VariantData> key, Slot<VariantData> value,
127+
VariantData*, ResourceManager*);
113128

114129
void removeOne(iterator it);
115130
void removePair(iterator it);

src/ArduinoJson/Collection/CollectionImpl.hpp

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,62 +19,82 @@ inline void CollectionIterator::next(const ResourceManager* resources) {
1919
currentId_ = nextId;
2020
}
2121

22-
inline CollectionImpl::iterator CollectionImpl::createIterator() const {
23-
if (!data_)
24-
return iterator();
25-
return iterator(resources_->getVariant(data_->head), data_->head);
22+
inline CollectionImpl::iterator CollectionImpl::createIterator(
23+
VariantData* data, ResourceManager* resources) {
24+
ARDUINOJSON_ASSERT(data != nullptr);
25+
ARDUINOJSON_ASSERT(data->isCollection());
26+
ARDUINOJSON_ASSERT(resources != nullptr);
27+
auto head = data->content.asCollection.head;
28+
return iterator(resources->getVariant(head), head);
2629
}
2730

28-
inline void CollectionImpl::appendOne(Slot<VariantData> slot) {
29-
ARDUINOJSON_ASSERT(data_ != nullptr);
30-
ARDUINOJSON_ASSERT(resources_ != nullptr);
31+
inline void CollectionImpl::appendOne(Slot<VariantData> slot, VariantData* data,
32+
ResourceManager* resources) {
33+
ARDUINOJSON_ASSERT(data != nullptr);
34+
ARDUINOJSON_ASSERT(data->isCollection());
35+
ARDUINOJSON_ASSERT(resources != nullptr);
36+
37+
auto coll = &data->content.asCollection;
3138

32-
if (data_->tail != NULL_SLOT) {
33-
auto tail = resources_->getVariant(data_->tail);
39+
if (coll->tail != NULL_SLOT) {
40+
auto tail = resources->getVariant(coll->tail);
3441
tail->next = slot.id();
35-
data_->tail = slot.id();
42+
coll->tail = slot.id();
3643
} else {
37-
data_->head = slot.id();
38-
data_->tail = slot.id();
44+
coll->head = slot.id();
45+
coll->tail = slot.id();
3946
}
4047
}
4148

4249
inline void CollectionImpl::appendPair(Slot<VariantData> key,
43-
Slot<VariantData> value) {
44-
ARDUINOJSON_ASSERT(data_ != nullptr);
45-
ARDUINOJSON_ASSERT(resources_ != nullptr);
50+
Slot<VariantData> value,
51+
VariantData* data,
52+
ResourceManager* resources) {
53+
ARDUINOJSON_ASSERT(data != nullptr);
54+
ARDUINOJSON_ASSERT(resources != nullptr);
4655

4756
key->next = value.id();
4857

49-
if (data_->tail != NULL_SLOT) {
50-
auto tail = resources_->getVariant(data_->tail);
58+
auto coll = &data->content.asCollection;
59+
60+
if (coll->tail != NULL_SLOT) {
61+
auto tail = resources->getVariant(coll->tail);
5162
tail->next = key.id();
52-
data_->tail = value.id();
63+
coll->tail = value.id();
5364
} else {
54-
data_->head = key.id();
55-
data_->tail = value.id();
65+
coll->head = key.id();
66+
coll->tail = value.id();
5667
}
5768
}
5869

59-
inline void CollectionImpl::clear() {
60-
if (!data_)
61-
return;
62-
auto next = data_->head;
70+
inline void CollectionImpl::clear(VariantData* data,
71+
ResourceManager* resources) {
72+
ARDUINOJSON_ASSERT(data != nullptr);
73+
ARDUINOJSON_ASSERT(data->isCollection());
74+
ARDUINOJSON_ASSERT(resources != nullptr);
75+
76+
auto coll = &data->content.asCollection;
77+
78+
auto next = coll->head;
6379
while (next != NULL_SLOT) {
6480
auto currId = next;
65-
auto slot = resources_->getVariant(next);
81+
auto slot = resources->getVariant(next);
6682
next = slot->next;
67-
resources_->freeVariant({slot, currId});
83+
resources->freeVariant({slot, currId});
6884
}
6985

70-
data_->head = NULL_SLOT;
71-
data_->tail = NULL_SLOT;
86+
coll->head = NULL_SLOT;
87+
coll->tail = NULL_SLOT;
7288
}
7389

7490
inline Slot<VariantData> CollectionImpl::getPreviousSlot(
7591
VariantData* target) const {
92+
ARDUINOJSON_ASSERT(data_ != nullptr);
93+
ARDUINOJSON_ASSERT(data_->isCollection());
94+
ARDUINOJSON_ASSERT(resources_ != nullptr);
95+
7696
auto prev = Slot<VariantData>();
77-
auto currentId = data_->head;
97+
auto currentId = data_->content.asCollection.head;
7898
while (currentId != NULL_SLOT) {
7999
auto currentSlot = resources_->getVariant(currentId);
80100
if (currentSlot == target)
@@ -91,12 +111,13 @@ inline void CollectionImpl::removeOne(iterator it) {
91111
auto curr = it.slot_;
92112
auto prev = getPreviousSlot(curr);
93113
auto next = curr->next;
114+
auto coll = &data_->content.asCollection;
94115
if (prev)
95116
prev->next = next;
96117
else
97-
data_->head = next;
118+
coll->head = next;
98119
if (next == NULL_SLOT)
99-
data_->tail = prev.id();
120+
coll->tail = prev.id();
100121
resources_->freeVariant({it.slot_, it.currentId_});
101122
}
102123

@@ -118,7 +139,7 @@ inline void CollectionImpl::removePair(ObjectImpl::iterator it) {
118139
}
119140

120141
inline size_t CollectionImpl::nesting() const {
121-
if (!data_)
142+
if (!data_ || !data_->isCollection())
122143
return 0;
123144
size_t maxChildNesting = 0;
124145
for (auto it = createIterator(); !it.done(); it.next(resources_)) {

src/ArduinoJson/Json/JsonDeserializer.hpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,13 @@ class JsonDeserializer {
7171
switch (current()) {
7272
case '[':
7373
if (filter.allowArray())
74-
return parseArray(VariantImpl::toArray(variant, resources_), filter,
75-
nestingLimit);
74+
return parseArray(variant, filter, nestingLimit);
7675
else
7776
return skipArray(nestingLimit);
7877

7978
case '{':
8079
if (filter.allowObject())
81-
return parseObject(VariantImpl::toObject(variant, resources_), filter,
82-
nestingLimit);
80+
return parseObject(variant, filter, nestingLimit);
8381
else
8482
return skipObject(nestingLimit);
8583

@@ -148,10 +146,12 @@ class JsonDeserializer {
148146

149147
template <typename TFilter>
150148
DeserializationError::Code parseArray(
151-
ArrayImpl array, TFilter filter,
149+
VariantData* array, TFilter filter,
152150
DeserializationOption::NestingLimit nestingLimit) {
153151
DeserializationError::Code err;
154152

153+
array->toArray();
154+
155155
if (nestingLimit.reached())
156156
return DeserializationError::TooDeep;
157157

@@ -174,7 +174,7 @@ class JsonDeserializer {
174174
for (;;) {
175175
if (elementFilter.allow()) {
176176
// Allocate slot in array
177-
VariantData* value = array.addElement();
177+
VariantData* value = ArrayImpl::addElement(array, resources_);
178178
if (!value)
179179
return DeserializationError::NoMemory;
180180

@@ -234,10 +234,12 @@ class JsonDeserializer {
234234

235235
template <typename TFilter>
236236
DeserializationError::Code parseObject(
237-
ObjectImpl object, TFilter filter,
237+
VariantData* object, TFilter filter,
238238
DeserializationOption::NestingLimit nestingLimit) {
239239
DeserializationError::Code err;
240240

241+
object->toObject();
242+
241243
if (nestingLimit.reached())
242244
return DeserializationError::TooDeep;
243245

@@ -275,9 +277,10 @@ class JsonDeserializer {
275277
TFilter memberFilter = filter[key];
276278

277279
if (memberFilter.allow()) {
278-
auto member = object.getMember(adaptString(key));
280+
auto member =
281+
ObjectImpl::getMember(adaptString(key), object, resources_);
279282
if (!member) {
280-
auto keyVariant = object.addPair(&member);
283+
auto keyVariant = ObjectImpl::addPair(&member, object, resources_);
281284
if (!keyVariant)
282285
return DeserializationError::NoMemory;
283286

0 commit comments

Comments
 (0)