• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 5371678521

pending completion
5371678521

push

github

bblanchon
Manage resources in `CollectionData`

107 of 107 new or added lines in 8 files covered. (100.0%)

3383 of 3405 relevant lines covered (99.35%)

6273.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.38
/src/ArduinoJson/Collection/CollectionImpl.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2023, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <ArduinoJson/Collection/CollectionData.hpp>
8
#include <ArduinoJson/Strings/StringAdapters.hpp>
9
#include <ArduinoJson/Variant/VariantCompare.hpp>
10
#include <ArduinoJson/Variant/VariantData.hpp>
11

12
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
13

14
inline void CollectionData::addSlot(VariantSlot* slot) {
70,715✔
15
  ARDUINOJSON_ASSERT(slot != nullptr);
16

17
  if (tail_) {
70,715✔
18
    tail_->setNextNotNull(slot);
68,526✔
19
    tail_ = slot;
68,526✔
20
  } else {
21
    head_ = slot;
2,189✔
22
    tail_ = slot;
2,189✔
23
  }
24
}
70,715✔
25

26
inline VariantData* CollectionData::addElement(ResourceManager* resources) {
68,510✔
27
  auto slot = resources->allocVariant();
68,510✔
28
  if (!slot)
68,510✔
29
    return nullptr;
19✔
30
  addSlot(slot);
68,491✔
31
  return slot->data();
68,491✔
32
}
33

34
inline VariantData* CollectionData::addMember(StringNode* key,
1,333✔
35
                                              ResourceManager* resources) {
36
  ARDUINOJSON_ASSERT(key != nullptr);
37
  auto slot = resources->allocVariant();
1,333✔
38
  if (!slot)
1,333✔
39
    return nullptr;
2✔
40

41
  slot->setKey(key);
1,331✔
42
  addSlot(slot);
1,331✔
43
  return slot->data();
1,331✔
44
}
45

46
template <typename TAdaptedString>
47
inline VariantData* CollectionData::addMember(TAdaptedString key,
783✔
48
                                              ResourceManager* resources) {
49
  ARDUINOJSON_ASSERT(!key.isNull());
50
  auto slot = resources->allocVariant();
783✔
51
  if (!slot)
783✔
52
    return nullptr;
3✔
53
  if (key.isLinked())
780✔
54
    slot->setKey(key.data());
720✔
55
  else {
56
    auto storedKey = resources->saveString(key);
60✔
57
    if (!storedKey)
60✔
58
      return nullptr;
1✔
59
    slot->setKey(storedKey);
59✔
60
  }
61
  addSlot(slot);
779✔
62
  return slot->data();
779✔
63
}
64

65
template <typename TAdaptedString>
66
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
3,657✔
67
  return slotData(getSlot(key));
3,657✔
68
}
69

70
inline VariantData* CollectionData::getOrAddElement(
135✔
71
    size_t index, ResourceManager* resources) {
72
  VariantSlot* slot = head_;
135✔
73
  while (slot && index > 0) {
145✔
74
    slot = slot->next();
10✔
75
    index--;
10✔
76
  }
77
  if (!slot)
135✔
78
    index++;
101✔
79
  while (index > 0) {
249✔
80
    slot = resources->allocVariant();
114✔
81
    if (!slot)
114✔
82
      return nullptr;
×
83
    addSlot(slot);
114✔
84
    index--;
114✔
85
  }
86
  return slot->data();
135✔
87
}
88

89
template <typename TAdaptedString>
90
VariantData* CollectionData::getOrAddMember(TAdaptedString key,
797✔
91
                                            ResourceManager* resources) {
92
  auto slot = getSlot(key);
797✔
93
  if (slot)
797✔
94
    return slot->data();
33✔
95
  return addMember(key, resources);
764✔
96
}
97

98
inline VariantData* CollectionData::getElement(size_t index) const {
412✔
99
  return slotData(getSlot(index));
412✔
100
}
101

102
inline void CollectionData::clear(ResourceManager* resources) {
39✔
103
  for (auto slot = head_; slot; slot = slot->next())
43✔
104
    slotRelease(slot, resources);
4✔
105
  head_ = 0;
39✔
106
  tail_ = 0;
39✔
107
}
39✔
108

109
inline bool CollectionData::copyFrom(const CollectionData& src,
37✔
110
                                     ResourceManager* resources) {
111
  clear(resources);
37✔
112

113
  for (VariantSlot* s = src.head(); s; s = s->next()) {
58✔
114
    VariantData* var;
115
    if (s->key() != 0) {
25✔
116
      JsonString key(s->key(),
117
                     s->ownsKey() ? JsonString::Copied : JsonString::Linked);
19✔
118
      var = addMember(adaptString(key), resources);
19✔
119
    } else {
120
      var = addElement(resources);
6✔
121
    }
122
    if (!variantCopyFrom(var, s->data(), resources))
25✔
123
      return false;
4✔
124
  }
125
  return true;
33✔
126
}
127

128
template <typename TAdaptedString>
129
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
4,479✔
130
  if (key.isNull())
4,479✔
131
    return 0;
1✔
132
  VariantSlot* slot = head_;
4,478✔
133
  while (slot) {
14,524✔
134
    if (stringEquals(key, adaptString(slot->key())))
11,276✔
135
      break;
1,230✔
136
    slot = slot->next();
10,046✔
137
  }
138
  return slot;
4,478✔
139
}
140

141
inline VariantSlot* CollectionData::getSlot(size_t index) const {
422✔
142
  if (!head_)
422✔
143
    return 0;
1✔
144
  return head_->next(index);
421✔
145
}
146

147
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
40✔
148
  VariantSlot* current = head_;
40✔
149
  while (current) {
76✔
150
    VariantSlot* next = current->next();
59✔
151
    if (next == target)
59✔
152
      return current;
23✔
153
    current = next;
36✔
154
  }
155
  return 0;
17✔
156
}
157

158
inline void CollectionData::removeSlot(VariantSlot* slot,
42✔
159
                                       ResourceManager* resources) {
160
  if (!slot)
42✔
161
    return;
2✔
162
  VariantSlot* prev = getPreviousSlot(slot);
40✔
163
  VariantSlot* next = slot->next();
40✔
164
  if (prev)
40✔
165
    prev->setNext(next);
23✔
166
  else
167
    head_ = next;
17✔
168
  if (!next)
40✔
169
    tail_ = prev;
19✔
170
  slotRelease(slot, resources);
40✔
171
}
172

173
inline void CollectionData::removeElement(size_t index,
10✔
174
                                          ResourceManager* resources) {
175
  removeSlot(getSlot(index), resources);
10✔
176
}
10✔
177

178
template <typename TAdaptedString>
179
inline void CollectionData::removeMember(TAdaptedString key,
25✔
180
                                         ResourceManager* resources) {
181
  removeSlot(getSlot(key), resources);
25✔
182
}
25✔
183

184
inline size_t CollectionData::memoryUsage() const {
20✔
185
  size_t total = 0;
20✔
186
  for (VariantSlot* s = head_; s; s = s->next()) {
38✔
187
    total += sizeof(VariantSlot) + s->data()->memoryUsage();
18✔
188
    if (s->ownsKey())
18✔
189
      total += sizeofString(strlen(s->key()));
1✔
190
  }
191
  return total;
20✔
192
}
193

194
inline size_t CollectionData::size() const {
356✔
195
  return slotSize(head_);
356✔
196
}
197

198
template <typename T>
199
inline void movePointer(T*& p, ptrdiff_t offset) {
20✔
200
  if (!p)
20✔
201
    return;
4✔
202
  p = reinterpret_cast<T*>(
16✔
203
      reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset));
16✔
204
  ARDUINOJSON_ASSERT(isAligned(p));
205
}
206

207
inline void CollectionData::movePointers(ptrdiff_t variantDistance) {
10✔
208
  movePointer(head_, variantDistance);
10✔
209
  movePointer(tail_, variantDistance);
10✔
210
  for (VariantSlot* slot = head_; slot; slot = slot->next())
18✔
211
    slot->data()->movePointers(variantDistance);
8✔
212
}
10✔
213

214
inline bool arrayEquals(const CollectionData& lhs, const CollectionData& rhs) {
249✔
215
  auto a = lhs.head();
249✔
216
  auto b = rhs.head();
249✔
217

218
  for (;;) {
219
    if (!a && !b)  // both ended
665✔
220
      return true;
189✔
221
    if (!a || !b)  // one ended
476✔
222
      return false;
4✔
223
    if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
472✔
224
      return false;
56✔
225
    a = a->next();
416✔
226
    b = b->next();
416✔
227
  }
228
}
229

230
inline bool arrayEquals(const CollectionData* lhs, const CollectionData* rhs) {
25✔
231
  if (lhs == rhs)
25✔
232
    return true;
4✔
233
  if (!lhs || !rhs)
21✔
234
    return false;
6✔
235

236
  return arrayEquals(*lhs, *rhs);
15✔
237
}
238

239
inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) {
254✔
240
  size_t count = 0;
254✔
241
  for (auto a = lhs.head(); a; a = a->next()) {
614✔
242
    auto b = rhs.getMember(adaptString(a->key()));
420✔
243
    if (!b)
420✔
244
      return false;
6✔
245
    if (compare(a->data(), b) != COMPARE_RESULT_EQUAL)
414✔
246
      return false;
54✔
247
    count++;
360✔
248
  }
249
  return count == rhs.size();
194✔
250
}
251

252
inline bool objectEquals(const CollectionData* lhs, const CollectionData* rhs) {
25✔
253
  if (lhs == rhs)
25✔
254
    return true;
3✔
255

256
  if (!lhs || !rhs)
22✔
257
    return false;
6✔
258

259
  return objectEquals(*lhs, *rhs);
16✔
260
}
261

262
ARDUINOJSON_END_PRIVATE_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc