/src/arduinojson/src/ArduinoJson/Collection/CollectionImpl.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // ArduinoJson - https://arduinojson.org |
2 | | // Copyright © 2014-2024, Benoit BLANCHON |
3 | | // MIT License |
4 | | |
5 | | #pragma once |
6 | | |
7 | | #include <ArduinoJson/Collection/CollectionData.hpp> |
8 | | #include <ArduinoJson/Memory/Alignment.hpp> |
9 | | #include <ArduinoJson/Strings/StringAdapters.hpp> |
10 | | #include <ArduinoJson/Variant/VariantCompare.hpp> |
11 | | #include <ArduinoJson/Variant/VariantData.hpp> |
12 | | |
13 | | ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE |
14 | | |
15 | | inline CollectionIterator::CollectionIterator(VariantData* slot, SlotId slotId) |
16 | 1.73k | : slot_(slot), currentId_(slotId) { |
17 | 1.73k | nextId_ = slot_ ? slot_->next() : NULL_SLOT; |
18 | 1.73k | } |
19 | | |
20 | 6.68k | inline void CollectionIterator::next(const ResourceManager* resources) { |
21 | 6.68k | ARDUINOJSON_ASSERT(currentId_ != NULL_SLOT); |
22 | 6.68k | slot_ = resources->getVariant(nextId_); |
23 | 6.68k | currentId_ = nextId_; |
24 | 6.68k | if (slot_) |
25 | 5.76k | nextId_ = slot_->next(); |
26 | 6.68k | } |
27 | | |
28 | | inline CollectionData::iterator CollectionData::createIterator( |
29 | 1.73k | const ResourceManager* resources) const { |
30 | 1.73k | return iterator(resources->getVariant(head_), head_); |
31 | 1.73k | } |
32 | | |
33 | | inline void CollectionData::appendOne(Slot<VariantData> slot, |
34 | 11.0k | const ResourceManager* resources) { |
35 | 11.0k | if (tail_ != NULL_SLOT) { |
36 | 9.08k | auto tail = resources->getVariant(tail_); |
37 | 9.08k | tail->setNext(slot.id()); |
38 | 9.08k | tail_ = slot.id(); |
39 | 9.08k | } else { |
40 | 2.01k | head_ = slot.id(); |
41 | 2.01k | tail_ = slot.id(); |
42 | 2.01k | } |
43 | 11.0k | } |
44 | | |
45 | | inline void CollectionData::appendPair(Slot<VariantData> key, |
46 | | Slot<VariantData> value, |
47 | 2.10k | const ResourceManager* resources) { |
48 | 2.10k | key->setNext(value.id()); |
49 | | |
50 | 2.10k | if (tail_ != NULL_SLOT) { |
51 | 1.51k | auto tail = resources->getVariant(tail_); |
52 | 1.51k | tail->setNext(key.id()); |
53 | 1.51k | tail_ = value.id(); |
54 | 1.51k | } else { |
55 | 591 | head_ = key.id(); |
56 | 591 | tail_ = value.id(); |
57 | 591 | } |
58 | 2.10k | } |
59 | | |
60 | 0 | inline void CollectionData::clear(ResourceManager* resources) { |
61 | 0 | auto next = head_; |
62 | 0 | while (next != NULL_SLOT) { |
63 | 0 | auto currId = next; |
64 | 0 | auto slot = resources->getVariant(next); |
65 | 0 | next = slot->next(); |
66 | 0 | resources->freeVariant({slot, currId}); |
67 | 0 | } |
68 | 0 |
|
69 | 0 | head_ = NULL_SLOT; |
70 | 0 | tail_ = NULL_SLOT; |
71 | 0 | } |
72 | | |
73 | | inline Slot<VariantData> CollectionData::getPreviousSlot( |
74 | 0 | VariantData* target, const ResourceManager* resources) const { |
75 | 0 | auto prev = Slot<VariantData>(); |
76 | 0 | auto currentId = head_; |
77 | 0 | while (currentId != NULL_SLOT) { |
78 | 0 | auto currentSlot = resources->getVariant(currentId); |
79 | 0 | if (currentSlot == target) |
80 | 0 | break; |
81 | 0 | prev = Slot<VariantData>(currentSlot, currentId); |
82 | 0 | currentId = currentSlot->next(); |
83 | 0 | } |
84 | 0 | return prev; |
85 | 0 | } |
86 | | |
87 | 0 | inline void CollectionData::removeOne(iterator it, ResourceManager* resources) { |
88 | 0 | if (it.done()) |
89 | 0 | return; |
90 | 0 | auto curr = it.slot_; |
91 | 0 | auto prev = getPreviousSlot(curr, resources); |
92 | 0 | auto next = curr->next(); |
93 | 0 | if (prev) |
94 | 0 | prev->setNext(next); |
95 | 0 | else |
96 | 0 | head_ = next; |
97 | 0 | if (next == NULL_SLOT) |
98 | 0 | tail_ = prev.id(); |
99 | 0 | resources->freeVariant({it.slot_, it.currentId_}); |
100 | 0 | } |
101 | | |
102 | | inline void CollectionData::removePair(ObjectData::iterator it, |
103 | 0 | ResourceManager* resources) { |
104 | 0 | if (it.done()) |
105 | 0 | return; |
106 | 0 |
|
107 | 0 | auto keySlot = it.slot_; |
108 | 0 |
|
109 | 0 | auto valueId = it.nextId_; |
110 | 0 | auto valueSlot = resources->getVariant(valueId); |
111 | 0 |
|
112 | 0 | // remove value slot |
113 | 0 | keySlot->setNext(valueSlot->next()); |
114 | 0 | resources->freeVariant({valueSlot, valueId}); |
115 | 0 |
|
116 | 0 | // remove key slot |
117 | 0 | removeOne(it, resources); |
118 | 0 | } |
119 | | |
120 | 0 | inline size_t CollectionData::nesting(const ResourceManager* resources) const { |
121 | 0 | size_t maxChildNesting = 0; |
122 | 0 | for (auto it = createIterator(resources); !it.done(); it.next(resources)) { |
123 | 0 | size_t childNesting = it->nesting(resources); |
124 | 0 | if (childNesting > maxChildNesting) |
125 | 0 | maxChildNesting = childNesting; |
126 | 0 | } |
127 | 0 | return maxChildNesting + 1; |
128 | 0 | } |
129 | | |
130 | 1.73k | inline size_t CollectionData::size(const ResourceManager* resources) const { |
131 | 1.73k | size_t count = 0; |
132 | 8.41k | for (auto it = createIterator(resources); !it.done(); it.next(resources)) |
133 | 6.68k | count++; |
134 | 1.73k | return count; |
135 | 1.73k | } |
136 | | |
137 | | ARDUINOJSON_END_PRIVATE_NAMESPACE |