/src/arduinojson/src/ArduinoJson/Collection/CollectionImpl.hpp
Line | Count | Source |
1 | | // ArduinoJson - https://arduinojson.org |
2 | | // Copyright © 2014-2026, Benoit BLANCHON |
3 | | // MIT License |
4 | | |
5 | | #pragma once |
6 | | |
7 | | #include <ArduinoJson/Variant/VariantImpl.hpp> |
8 | | |
9 | | ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE |
10 | | |
11 | 73.7k | inline void CollectionIterator::move(const ResourceManager* resources) { |
12 | 73.7k | ARDUINOJSON_ASSERT(slot_); |
13 | 73.7k | auto nextId = slot_->next; |
14 | 73.7k | slot_ = resources->getVariant(nextId); |
15 | 73.7k | currentId_ = nextId; |
16 | 73.7k | } |
17 | | |
18 | | inline VariantImpl::iterator VariantImpl::createIterator( |
19 | 10.2k | VariantData* data, ResourceManager* resources) { |
20 | 10.2k | ARDUINOJSON_ASSERT(data != nullptr); |
21 | 10.2k | ARDUINOJSON_ASSERT(data->isCollection()); |
22 | 10.2k | ARDUINOJSON_ASSERT(resources != nullptr); |
23 | 10.2k | auto head = data->content.asCollection.head; |
24 | 10.2k | return iterator(resources->getVariant(head), head); |
25 | 10.2k | } |
26 | | |
27 | | inline void VariantImpl::addElement(Slot<VariantData> slot, VariantData* data, |
28 | 171k | ResourceManager* resources) { |
29 | 171k | ARDUINOJSON_ASSERT(data != nullptr); |
30 | 171k | ARDUINOJSON_ASSERT(data->isCollection()); |
31 | 171k | ARDUINOJSON_ASSERT(resources != nullptr); |
32 | | |
33 | 171k | auto coll = &data->content.asCollection; |
34 | | |
35 | 171k | if (coll->tail != NULL_SLOT) { |
36 | 160k | auto tail = resources->getVariant(coll->tail); |
37 | 160k | tail->next = slot.id(); |
38 | 160k | coll->tail = slot.id(); |
39 | 160k | } else { |
40 | 11.8k | coll->head = slot.id(); |
41 | 11.8k | coll->tail = slot.id(); |
42 | 11.8k | } |
43 | 171k | } |
44 | | |
45 | | inline void VariantImpl::appendPair(Slot<VariantData> key, |
46 | | Slot<VariantData> value, VariantData* data, |
47 | 13.4k | ResourceManager* resources) { |
48 | 13.4k | ARDUINOJSON_ASSERT(data != nullptr); |
49 | 13.4k | ARDUINOJSON_ASSERT(resources != nullptr); |
50 | | |
51 | 13.4k | key->next = value.id(); |
52 | | |
53 | 13.4k | auto coll = &data->content.asCollection; |
54 | | |
55 | 13.4k | if (coll->tail != NULL_SLOT) { |
56 | 9.36k | auto tail = resources->getVariant(coll->tail); |
57 | 9.36k | tail->next = key.id(); |
58 | 9.36k | coll->tail = value.id(); |
59 | 9.36k | } else { |
60 | 4.11k | coll->head = key.id(); |
61 | 4.11k | coll->tail = value.id(); |
62 | 4.11k | } |
63 | 13.4k | } |
64 | | |
65 | 782 | inline void VariantImpl::empty(VariantData* data, ResourceManager* resources) { |
66 | 782 | ARDUINOJSON_ASSERT(data != nullptr); |
67 | 782 | ARDUINOJSON_ASSERT(data->isCollection()); |
68 | 782 | ARDUINOJSON_ASSERT(resources != nullptr); |
69 | | |
70 | 782 | auto coll = &data->content.asCollection; |
71 | | |
72 | 782 | auto next = coll->head; |
73 | 5.58k | while (next != NULL_SLOT) { |
74 | 4.80k | auto currId = next; |
75 | 4.80k | auto slot = resources->getVariant(next); |
76 | 4.80k | next = slot->next; |
77 | 4.80k | freeVariant({slot, currId}, resources); |
78 | 4.80k | } |
79 | | |
80 | 782 | coll->head = NULL_SLOT; |
81 | 782 | coll->tail = NULL_SLOT; |
82 | 782 | } |
83 | | |
84 | | inline Slot<VariantData> VariantImpl::getPreviousSlot( |
85 | 0 | VariantData* target) const { |
86 | 0 | ARDUINOJSON_ASSERT(data_ != nullptr); |
87 | 0 | ARDUINOJSON_ASSERT(data_->isCollection()); |
88 | 0 | ARDUINOJSON_ASSERT(resources_ != nullptr); |
89 | 0 |
|
90 | 0 | auto prev = Slot<VariantData>(); |
91 | 0 | auto currentId = data_->content.asCollection.head; |
92 | 0 | while (currentId != NULL_SLOT) { |
93 | 0 | auto currentSlot = resources_->getVariant(currentId); |
94 | 0 | if (currentSlot == target) |
95 | 0 | break; |
96 | 0 | prev = Slot<VariantData>(currentSlot, currentId); |
97 | 0 | currentId = currentSlot->next; |
98 | 0 | } |
99 | 0 | return prev; |
100 | 0 | } |
101 | | |
102 | 0 | inline void VariantImpl::removeOne(iterator it) { |
103 | 0 | if (it.done()) |
104 | 0 | return; |
105 | 0 | auto curr = it.slot_; |
106 | 0 | auto prev = getPreviousSlot(curr); |
107 | 0 | auto next = curr->next; |
108 | 0 | auto coll = &data_->content.asCollection; |
109 | 0 | if (prev) |
110 | 0 | prev->next = next; |
111 | 0 | else |
112 | 0 | coll->head = next; |
113 | 0 | if (next == NULL_SLOT) |
114 | 0 | coll->tail = prev.id(); |
115 | 0 | freeVariant({it.slot_, it.currentId_}, resources_); |
116 | 0 | } |
117 | | |
118 | 0 | inline void VariantImpl::removePair(iterator it) { |
119 | 0 | if (it.done()) |
120 | 0 | return; |
121 | 0 |
|
122 | 0 | auto keySlot = it.slot_; |
123 | 0 |
|
124 | 0 | auto valueId = keySlot->next; |
125 | 0 | auto valueSlot = resources_->getVariant(valueId); |
126 | 0 |
|
127 | 0 | // remove value slot |
128 | 0 | keySlot->next = valueSlot->next; |
129 | 0 | freeVariant({valueSlot, valueId}, resources_); |
130 | 0 |
|
131 | 0 | // remove key slot |
132 | 0 | removeOne(it); |
133 | 0 | } |
134 | | |
135 | 0 | inline size_t VariantImpl::nesting() const { |
136 | 0 | if (!data_ || !data_->isCollection()) |
137 | 0 | return 0; |
138 | 0 | size_t maxChildNesting = 0; |
139 | 0 | for (auto it = createIterator(); !it.done(); it.move(resources_)) { |
140 | 0 | size_t childNesting = VariantImpl(it.data(), resources_).nesting(); |
141 | 0 | if (childNesting > maxChildNesting) |
142 | 0 | maxChildNesting = childNesting; |
143 | 0 | } |
144 | 0 | return maxChildNesting + 1; |
145 | 0 | } |
146 | | |
147 | | ARDUINOJSON_END_PRIVATE_NAMESPACE |