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

bblanchon / ArduinoJson / 4720032563

pending completion
4720032563

push

github

Benoit Blanchon
Simplify `CollectionData` to work only with `VariantSlot*`

33 of 33 new or added lines in 10 files covered. (100.0%)

3317 of 3345 relevant lines covered (99.16%)

6641.65 hits per line

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

96.79
/src/ArduinoJson/Variant/VariantFunctions.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2023, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <ArduinoJson/Polyfills/assert.hpp>
8
#include <ArduinoJson/Polyfills/attributes.hpp>
9
#include <ArduinoJson/Strings/StoragePolicy.hpp>
10
#include <ArduinoJson/Variant/VariantData.hpp>
11
#include <ArduinoJson/Variant/Visitor.hpp>
12

13
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
14

15
void slotRelease(const VariantSlot* slot, MemoryPool* pool);
16
bool collectionCopy(CollectionData* dst, const CollectionData* src,
17
                    MemoryPool* pool);
18
VariantData* collectionAddElement(CollectionData* array, MemoryPool* pool);
19
void collectionRemoveElement(CollectionData* data, size_t index,
20
                             MemoryPool* pool);
21
template <typename TAdaptedString>
22
void collectionRemoveMember(CollectionData* data, TAdaptedString key,
23
                            MemoryPool* pool);
24

25
template <typename TVisitor>
26
inline typename TVisitor::result_type variantAccept(const VariantData* var,
5,535✔
27
                                                    TVisitor& visitor) {
28
  if (var != 0)
5,535✔
29
    return var->accept(visitor);
5,378✔
30
  else
31
    return visitor.visitNull();
157✔
32
}
33

34
inline void variantRelease(const VariantData* var, MemoryPool* pool) {
67,824✔
35
  ARDUINOJSON_ASSERT(var != nullptr);
36
  auto s = var->getOwnedString();
67,824✔
37
  if (s)
67,824✔
38
    pool->dereferenceString(s);
11✔
39

40
  auto c = var->asCollection();
67,824✔
41
  if (c) {
67,824✔
42
    for (auto slot = c->head(); slot; slot = slot->next())
21✔
43
      slotRelease(slot, pool);
10✔
44
  }
45
}
67,824✔
46

47
inline bool variantCopyFrom(VariantData* dst, const VariantData* src,
73✔
48
                            MemoryPool* pool) {
49
  if (!dst)
73✔
50
    return false;
4✔
51
  if (!src) {
69✔
52
    dst->setNull();
4✔
53
    return true;
4✔
54
  }
55
  switch (src->type()) {
65✔
56
    case VALUE_IS_ARRAY:
12✔
57
      return collectionCopy(&dst->toArray(), src->asArray(), pool);
12✔
58
    case VALUE_IS_OBJECT:
17✔
59
      return collectionCopy(&dst->toObject(), src->asObject(), pool);
17✔
60
    case VALUE_IS_OWNED_STRING: {
10✔
61
      auto str = storeString(pool, adaptString(src->asString()),
10✔
62
                             StringStoragePolicy::Copy());
10✔
63
      dst->setString(str);
10✔
64
      return !str.isNull();
10✔
65
    }
66
    case VALUE_IS_OWNED_RAW: {
2✔
67
      auto str = adaptString(src->asRaw());
2✔
68
      auto dup = pool->saveString(str);
2✔
69
      if (!dup)
2✔
70
        return false;
×
71
      dst->setOwnedRaw(dup, str.size());
2✔
72
      return true;
2✔
73
    }
74
    default:
24✔
75
      *dst = *src;
24✔
76
      return true;
24✔
77
  }
78
}
79

80
inline void variantSetNull(VariantData* var, MemoryPool* pool) {
416✔
81
  if (!var)
416✔
82
    return;
1✔
83
  variantRelease(var, pool);
415✔
84
  var->setNull();
415✔
85
}
86

87
inline void variantSetBoolean(VariantData* var, bool value, MemoryPool* pool) {
253✔
88
  if (!var)
253✔
89
    return;
4✔
90
  variantRelease(var, pool);
249✔
91
  var->setBoolean(value);
249✔
92
}
93

94
inline void variantSetFloat(VariantData* var, JsonFloat value,
63✔
95
                            MemoryPool* pool) {
96
  if (!var)
63✔
97
    return;
2✔
98
  variantRelease(var, pool);
61✔
99
  var->setFloat(value);
61✔
100
}
101

102
template <typename T>
103
inline void variantSetInteger(VariantData* var, T value, MemoryPool* pool) {
590✔
104
  if (!var)
590✔
105
    return;
19✔
106
  variantRelease(var, pool);
571✔
107
  var->setInteger(value);
571✔
108
}
109

110
template <typename TAdaptedString>
111
inline void variantSetString(VariantData* var, TAdaptedString value,
65,958✔
112
                             MemoryPool* pool) {
113
  if (!var)
65,958✔
114
    return;
5✔
115
  variantRelease(var, pool);
65,953✔
116
  JsonString str = storeString(pool, value);
65,953✔
117
  if (str)
65,953✔
118
    var->setString(str);
397✔
119
  else
120
    var->setNull();
65,556✔
121
}
122

123
template <typename T>
124
inline void variantSetOwnedRaw(VariantData* var, SerializedValue<T> value,
12✔
125
                               MemoryPool* pool) {
126
  if (!var)
12✔
127
    return;
×
128
  variantRelease(var, pool);
12✔
129
  const char* dup = pool->saveString(adaptString(value.data(), value.size()));
12✔
130
  if (dup)
12✔
131
    var->setOwnedRaw(dup, value.size());
10✔
132
  else
133
    var->setNull();
2✔
134
}
135

136
inline void variantSetLinkedRaw(VariantData* var,
20✔
137
                                SerializedValue<const char*> value,
138
                                MemoryPool* pool) {
139
  if (!var)
20✔
140
    return;
2✔
141
  variantRelease(var, pool);
18✔
142
  if (value.data())
18✔
143
    var->setLinkedRaw(value.data(), value.size());
17✔
144
  else
145
    var->setNull();
1✔
146
}
147

148
inline size_t variantSize(const VariantData* var) {
30✔
149
  return var != 0 ? var->size() : 0;
30✔
150
}
151

152
inline CollectionData* variantToArray(VariantData* var, MemoryPool* pool) {
222✔
153
  if (!var)
222✔
154
    return 0;
2✔
155
  variantRelease(var, pool);
220✔
156
  return &var->toArray();
220✔
157
}
158

159
inline CollectionData* variantToObject(VariantData* var, MemoryPool* pool) {
273✔
160
  if (!var)
273✔
161
    return 0;
2✔
162
  variantRelease(var, pool);
271✔
163
  return &var->toObject();
271✔
164
}
165

166
inline VariantData* variantGetElement(const VariantData* var, size_t index) {
429✔
167
  return var != 0 ? var->getElement(index) : 0;
429✔
168
}
169

170
inline VariantData* variantAddElement(VariantData* var, MemoryPool* pool) {
248✔
171
  if (!var)
248✔
172
    return nullptr;
6✔
173
  auto array = var->isNull() ? &var->toArray() : var->asArray();
242✔
174
  return collectionAddElement(array, pool);
242✔
175
}
176

177
inline NO_INLINE VariantData* variantGetOrAddElement(VariantData* var,
137✔
178
                                                     size_t index,
179
                                                     MemoryPool* pool) {
180
  if (!var)
137✔
181
    return nullptr;
1✔
182
  auto array = var->isNull() ? &var->toArray() : var->asArray();
136✔
183
  if (!array)
136✔
184
    return nullptr;
1✔
185
  VariantSlot* slot = array->head();
135✔
186
  while (slot && index > 0) {
145✔
187
    slot = slot->next();
10✔
188
    index--;
10✔
189
  }
190
  if (!slot)
135✔
191
    index++;
101✔
192
  while (index > 0) {
249✔
193
    slot = pool->allocVariant();
114✔
194
    if (!slot)
114✔
195
      return nullptr;
×
196
    array->add(slot);
114✔
197
    index--;
114✔
198
  }
199
  return slot->data();
135✔
200
}
201

202
inline void variantRemoveElement(VariantData* var, size_t index,
7✔
203
                                 MemoryPool* pool) {
204
  if (!var)
7✔
205
    return;
×
206
  collectionRemoveElement(var->asArray(), index, pool);
7✔
207
}
208

209
template <typename TAdaptedString>
210
VariantData* variantGetMember(const VariantData* var, TAdaptedString key) {
2,139✔
211
  if (!var)
2,139✔
212
    return 0;
12✔
213
  return var->getMember(key);
2,127✔
214
}
215

216
template <typename TAdaptedString>
217
VariantData* variantGetOrAddMember(VariantData* var, TAdaptedString key,
803✔
218
                                   MemoryPool* pool) {
219
  if (!var || key.isNull())
803✔
220
    return nullptr;
6✔
221
  auto obj = var->isNull() ? &var->toObject() : var->asObject();
797✔
222
  if (!obj)
797✔
223
    return nullptr;
1✔
224
  auto slot = obj->get(key);
796✔
225
  if (slot)
796✔
226
    return slot->data();
33✔
227
  return collectionAddMember(obj, key, pool);
763✔
228
}
229

230
template <typename TAdaptedString>
231
void variantRemoveMember(VariantData* var, TAdaptedString key,
13✔
232
                         MemoryPool* pool) {
233
  if (!var)
13✔
234
    return;
×
235
  collectionRemoveMember(var->asObject(), key, pool);
13✔
236
}
237

238
inline bool variantIsNull(const VariantData* var) {
1,237✔
239
  return var == 0 || var->isNull();
1,237✔
240
}
241

242
inline size_t variantNesting(const VariantData* var) {
24✔
243
  if (!var)
24✔
244
    return 0;
3✔
245

246
  const CollectionData* collection = var->asCollection();
21✔
247
  if (!collection)
21✔
248
    return 0;
5✔
249

250
  size_t maxChildNesting = 0;
16✔
251
  for (const VariantSlot* s = collection->head(); s; s = s->next()) {
22✔
252
    size_t childNesting = variantNesting(s->data());
6✔
253
    if (childNesting > maxChildNesting)
6✔
254
      maxChildNesting = childNesting;
4✔
255
  }
256
  return maxChildNesting + 1;
16✔
257
}
258

259
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

© 2026 Coveralls, Inc