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

bblanchon / ArduinoJson / 5059873495

pending completion
5059873495

push

github

Benoit Blanchon
Remove VariantImpl.hpp

2 of 2 new or added lines in 1 file covered. (100.0%)

3280 of 3299 relevant lines covered (99.42%)

6312.26 hits per line

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

99.17
/src/ArduinoJson/Document/JsonDocument.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2023, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <ArduinoJson/Array/ElementProxy.hpp>
8
#include <ArduinoJson/Memory/Allocator.hpp>
9
#include <ArduinoJson/Memory/MemoryPool.hpp>
10
#include <ArduinoJson/Object/JsonObject.hpp>
11
#include <ArduinoJson/Object/MemberProxy.hpp>
12
#include <ArduinoJson/Polyfills/utility.hpp>
13
#include <ArduinoJson/Variant/JsonVariantConst.hpp>
14
#include <ArduinoJson/Variant/VariantTo.hpp>
15

16
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
17

18
// A JSON document.
19
// https://arduinojson.org/v6/api/jsondocument/
20
class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
21
  friend class detail::VariantAttorney;
22

23
 public:
24
  explicit JsonDocument(size_t capa,
1,957✔
25
                        Allocator* alloc = detail::DefaultAllocator::instance())
26
      : pool_(capa, alloc) {}
1,957✔
27

28
  // Copy-constructor
29
  JsonDocument(const JsonDocument& src)
4✔
30
      : JsonDocument(src.pool_.capacity(), src.allocator()) {
4✔
31
    set(src);
4✔
32
  }
4✔
33

34
  // Move-constructor
35
  JsonDocument(JsonDocument&& src) : pool_(0, src.allocator()) {
2✔
36
    // TODO: use the copy and swap idiom
37
    moveAssignFrom(src);
2✔
38
  }
2✔
39

40
  // Construct from variant, array, or object
41
  template <typename T>
42
  JsonDocument(const T& src,
3✔
43
               Allocator* alloc = detail::DefaultAllocator::instance(),
44
               typename detail::enable_if<
45
                   detail::is_same<T, JsonVariant>::value ||
46
                   detail::is_same<T, JsonVariantConst>::value ||
47
                   detail::is_same<T, JsonArray>::value ||
48
                   detail::is_same<T, JsonArrayConst>::value ||
49
                   detail::is_same<T, JsonObject>::value ||
50
                   detail::is_same<T, JsonObjectConst>::value>::type* = 0)
51
      : JsonDocument(src.memoryUsage(), alloc) {
3✔
52
    set(src);
3✔
53
  }
3✔
54

55
  // disambiguate
56
  // TODO: still needed?
57
  JsonDocument(JsonVariant src) : JsonDocument(src.memoryUsage()) {
58
    set(src);
59
  }
60

61
  JsonDocument& operator=(const JsonDocument& src) {
3✔
62
    // TODO: use the copy and swap idiom
63
    copyAssignFrom(src);
3✔
64
    return *this;
3✔
65
  }
66

67
  JsonDocument& operator=(JsonDocument&& src) {
3✔
68
    // TODO: use the copy and swap idiom
69
    moveAssignFrom(src);
3✔
70
    return *this;
3✔
71
  }
72

73
  template <typename T>
74
  JsonDocument& operator=(const T& src) {
5✔
75
    size_t requiredSize = src.memoryUsage();
5✔
76
    if (requiredSize > pool_.capacity())
5✔
77
      pool_.reallocPool(requiredSize);
×
78
    set(src);
5✔
79
    return *this;
5✔
80
  }
81

82
  Allocator* allocator() const {
6✔
83
    return pool_.allocator();
6✔
84
  }
85

86
  // Reduces the capacity of the memory pool to match the current usage.
87
  // https://arduinojson.org/v6/api/JsonDocument/shrinktofit/
88
  void shrinkToFit() {
14✔
89
    auto offset = pool_.shrinkToFit();
14✔
90
    data_.movePointers(offset);
14✔
91
  }
14✔
92

93
  // Reclaims the memory leaked when removing and replacing values.
94
  // https://arduinojson.org/v6/api/jsondocument/garbagecollect/
95
  bool garbageCollect() {
3✔
96
    // make a temporary clone and move assign
97
    JsonDocument tmp(*this);
6✔
98
    if (!tmp.pool_.capacity())
3✔
99
      return false;
1✔
100
    moveAssignFrom(tmp);
2✔
101
    return true;
2✔
102
  }
103

104
  // Casts the root to the specified type.
105
  // https://arduinojson.org/v6/api/jsondocument/as/
106
  template <typename T>
107
  T as() {
502✔
108
    return getVariant().template as<T>();
1,004✔
109
  }
110

111
  // Casts the root to the specified type.
112
  // https://arduinojson.org/v6/api/jsondocument/as/
113
  template <typename T>
114
  T as() const {
10✔
115
    return getVariant().template as<T>();
20✔
116
  }
117

118
  // Empties the document and resets the memory pool
119
  // https://arduinojson.org/v6/api/jsondocument/clear/
120
  void clear() {
1,756✔
121
    pool_.clear();
1,756✔
122
    data_.reset();
1,756✔
123
  }
1,756✔
124

125
  // Returns true if the root is of the specified type.
126
  // https://arduinojson.org/v6/api/jsondocument/is/
127
  template <typename T>
128
  bool is() {
94✔
129
    return getVariant().template is<T>();
188✔
130
  }
131

132
  // Returns true if the root is of the specified type.
133
  // https://arduinojson.org/v6/api/jsondocument/is/
134
  template <typename T>
135
  bool is() const {
136
    return getVariant().template is<T>();
137
  }
138

139
  // Returns true if the root is null.
140
  // https://arduinojson.org/v6/api/jsondocument/isnull/
141
  bool isNull() const {
12✔
142
    return getVariant().isNull();
24✔
143
  }
144

145
  // Returns the number of used bytes in the memory pool.
146
  // https://arduinojson.org/v6/api/jsondocument/memoryusage/
147
  size_t memoryUsage() const {
282✔
148
    return pool_.size();
282✔
149
  }
150

151
  // Returns trues if the memory pool was too small.
152
  // https://arduinojson.org/v6/api/jsondocument/overflowed/
153
  bool overflowed() const {
21✔
154
    return pool_.overflowed();
21✔
155
  }
156

157
  // Returns the depth (nesting level) of the array.
158
  // https://arduinojson.org/v6/api/jsondocument/nesting/
159
  size_t nesting() const {
4✔
160
    return variantNesting(&data_);
4✔
161
  }
162

163
  // Returns the number of elements in the root array or object.
164
  // https://arduinojson.org/v6/api/jsondocument/size/
165
  size_t size() const {
12✔
166
    return data_.size();
12✔
167
  }
168

169
  // Copies the specified document.
170
  // https://arduinojson.org/v6/api/jsondocument/set/
171
  bool set(const JsonDocument& src) {
7✔
172
    return to<JsonVariant>().set(src.as<JsonVariantConst>());
14✔
173
  }
174

175
  // Replaces the root with the specified value.
176
  // https://arduinojson.org/v6/api/jsondocument/set/
177
  template <typename T>
178
  typename detail::enable_if<!detail::is_base_of<JsonDocument, T>::value,
179
                             bool>::type
180
  set(const T& src) {
39✔
181
    return to<JsonVariant>().set(src);
78✔
182
  }
183

184
  // Clears the document and converts it to the specified type.
185
  // https://arduinojson.org/v6/api/jsondocument/to/
186
  template <typename T>
187
  typename detail::VariantTo<T>::type to() {
717✔
188
    clear();
717✔
189
    return getVariant().template to<T>();
1,434✔
190
  }
191

192
  // Creates an array and appends it to the root array.
193
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
194
  JsonArray createNestedArray() {
25✔
195
    return add().to<JsonArray>();
50✔
196
  }
197

198
  // Creates an array and adds it to the root object.
199
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
200
  template <typename TChar>
201
  JsonArray createNestedArray(TChar* key) {
1✔
202
    return operator[](key).template to<JsonArray>();
1✔
203
  }
204

205
  // Creates an array and adds it to the root object.
206
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
207
  template <typename TString>
208
  JsonArray createNestedArray(const TString& key) {
1✔
209
    return operator[](key).template to<JsonArray>();
1✔
210
  }
211

212
  // Creates an object and appends it to the root array.
213
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
214
  JsonObject createNestedObject() {
25✔
215
    return add().to<JsonObject>();
50✔
216
  }
217

218
  // Creates an object and adds it to the root object.
219
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
220
  template <typename TChar>
221
  JsonObject createNestedObject(TChar* key) {
1✔
222
    return operator[](key).template to<JsonObject>();
1✔
223
  }
224

225
  // Creates an object and adds it to the root object.
226
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
227
  template <typename TString>
228
  JsonObject createNestedObject(const TString& key) {
1✔
229
    return operator[](key).template to<JsonObject>();
1✔
230
  }
231

232
  // Returns true if the root object contains the specified key.
233
  // https://arduinojson.org/v6/api/jsondocument/containskey/
234
  template <typename TChar>
235
  bool containsKey(TChar* key) const {
5✔
236
    return data_.getMember(detail::adaptString(key)) != 0;
5✔
237
  }
238

239
  // Returns true if the root object contains the specified key.
240
  // https://arduinojson.org/v6/api/jsondocument/containskey/
241
  template <typename TString>
242
  bool containsKey(const TString& key) const {
1✔
243
    return data_.getMember(detail::adaptString(key)) != 0;
1✔
244
  }
245

246
  // Gets or sets a root object's member.
247
  // https://arduinojson.org/v6/api/jsondocument/subscript/
248
  template <typename TString>
249
  FORCE_INLINE typename detail::enable_if<
250
      detail::IsString<TString>::value,
251
      detail::MemberProxy<JsonDocument&, TString>>::type
252
  operator[](const TString& key) {
253
    return {*this, key};
18✔
254
  }
255

256
  // Gets or sets a root object's member.
257
  // https://arduinojson.org/v6/api/jsondocument/subscript/
258
  template <typename TChar>
259
  FORCE_INLINE typename detail::enable_if<
260
      detail::IsString<TChar*>::value,
261
      detail::MemberProxy<JsonDocument&, TChar*>>::type
262
  operator[](TChar* key) {
263
    return {*this, key};
431✔
264
  }
265

266
  // Gets a root object's member.
267
  // https://arduinojson.org/v6/api/jsondocument/subscript/
268
  template <typename TString>
269
  FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value,
270
                                          JsonVariantConst>::type
271
  operator[](const TString& key) const {
272
    return JsonVariantConst(data_.getMember(detail::adaptString(key)));
1✔
273
  }
274

275
  // Gets a root object's member.
276
  // https://arduinojson.org/v6/api/jsondocument/subscript/
277
  template <typename TChar>
278
  FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value,
279
                                          JsonVariantConst>::type
280
  operator[](TChar* key) const {
281
    return JsonVariantConst(data_.getMember(detail::adaptString(key)));
1✔
282
  }
283

284
  // Gets or sets a root array's element.
285
  // https://arduinojson.org/v6/api/jsondocument/subscript/
286
  FORCE_INLINE detail::ElementProxy<JsonDocument&> operator[](size_t index) {
287
    return {*this, index};
124✔
288
  }
289

290
  // Gets a root array's member.
291
  // https://arduinojson.org/v6/api/jsondocument/subscript/
292
  FORCE_INLINE JsonVariantConst operator[](size_t index) const {
293
    return JsonVariantConst(data_.getElement(index));
1✔
294
  }
295

296
  // Appends a new (null) element to the root array.
297
  // Returns a reference to the new element.
298
  // https://arduinojson.org/v6/api/jsondocument/add/
299
  FORCE_INLINE JsonVariant add() {
300
    return JsonVariant(&pool_, variantAddElement(&data_, &pool_));
170✔
301
  }
302

303
  // Appends a value to the root array.
304
  // https://arduinojson.org/v6/api/jsondocument/add/
305
  template <typename TValue>
306
  FORCE_INLINE bool add(const TValue& value) {
307
    return add().set(value);
92✔
308
  }
309

310
  // Appends a value to the root array.
311
  // https://arduinojson.org/v6/api/jsondocument/add/
312
  template <typename TChar>
313
  FORCE_INLINE bool add(TChar* value) {
314
    return add().set(value);
24✔
315
  }
316

317
  // Removes an element of the root array.
318
  // ⚠️ Doesn't release the memory associated with the removed element.
319
  // https://arduinojson.org/v6/api/jsondocument/remove/
320
  FORCE_INLINE void remove(size_t index) {
321
    variantRemoveElement(getData(), index, getPool());
1✔
322
  }
1✔
323

324
  // Removes a member of the root object.
325
  // ⚠️ Doesn't release the memory associated with the removed element.
326
  // https://arduinojson.org/v6/api/jsondocument/remove/
327
  template <typename TChar>
328
  FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value>::type
329
  remove(TChar* key) {
330
    variantRemoveMember(getData(), detail::adaptString(key), getPool());
4✔
331
  }
4✔
332

333
  // Removes a member of the root object.
334
  // ⚠️ Doesn't release the memory associated with the removed element.
335
  // https://arduinojson.org/v6/api/jsondocument/remove/
336
  template <typename TString>
337
  FORCE_INLINE
338
      typename detail::enable_if<detail::IsString<TString>::value>::type
339
      remove(const TString& key) {
340
    variantRemoveMember(getData(), detail::adaptString(key), getPool());
1✔
341
  }
1✔
342

343
  FORCE_INLINE operator JsonVariant() {
344
    return getVariant();
1✔
345
  }
346

347
  FORCE_INLINE operator JsonVariantConst() const {
348
    return getVariant();
297✔
349
  }
350

351
 private:
352
  JsonVariant getVariant() {
1,314✔
353
    return JsonVariant(&pool_, &data_);
1,314✔
354
  }
355

356
  JsonVariantConst getVariant() const {
319✔
357
    return JsonVariantConst(&data_);
319✔
358
  }
359

360
  void copyAssignFrom(const JsonDocument& src) {
3✔
361
    pool_.reallocPool(src.pool_.capacity());
3✔
362
    set(src);
3✔
363
  }
3✔
364

365
  void moveAssignFrom(JsonDocument& src) {
7✔
366
    data_ = src.data_;
7✔
367
    src.data_.reset();
7✔
368
    pool_ = move(src.pool_);
7✔
369
  }
7✔
370

371
  detail::MemoryPool* getPool() {
2,405✔
372
    return &pool_;
2,405✔
373
  }
374

375
  detail::VariantData* getData() {
1,285✔
376
    return &data_;
1,285✔
377
  }
378

379
  const detail::VariantData* getData() const {
6✔
380
    return &data_;
6✔
381
  }
382

383
  detail::VariantData* getOrCreateData() {
401✔
384
    return &data_;
401✔
385
  }
386

387
  detail::MemoryPool pool_;
388
  detail::VariantData data_;
389
};
390

391
inline void convertToJson(const JsonDocument& src, JsonVariant dst) {
1✔
392
  dst.set(src.as<JsonVariantConst>());
1✔
393
}
1✔
394

395
ARDUINOJSON_END_PUBLIC_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