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

bblanchon / ArduinoJson / 5082307777

pending completion
5082307777

push

github

Benoit Blanchon
Move all functions from `VariantFunctions.hpp` to ``VariantData.hpp`

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

3317 of 3336 relevant lines covered (99.43%)

6264.05 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,
25
                        Allocator* alloc = detail::DefaultAllocator::instance())
26
      : pool_(capa, alloc) {}
27

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

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

40
  // Construct from variant, array, or object
41
  template <typename T>
42
  JsonDocument(const T& src,
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) {
52
    set(src);
53
  }
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) {
62
    // TODO: use the copy and swap idiom
63
    copyAssignFrom(src);
64
    return *this;
65
  }
66

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

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

82
  Allocator* allocator() const {
83
    return pool_.allocator();
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() {
89
    auto offset = pool_.shrinkToFit();
90
    data_.movePointers(offset);
91
  }
92

93
  // Reclaims the memory leaked when removing and replacing values.
94
  // https://arduinojson.org/v6/api/jsondocument/garbagecollect/
95
  bool garbageCollect() {
96
    // make a temporary clone and move assign
97
    JsonDocument tmp(*this);
98
    if (!tmp.pool_.capacity())
99
      return false;
100
    moveAssignFrom(tmp);
101
    return true;
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() {
108
    return getVariant().template as<T>();
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 {
115
    return getVariant().template as<T>();
116
  }
117

118
  // Empties the document and resets the memory pool
119
  // https://arduinojson.org/v6/api/jsondocument/clear/
120
  void clear() {
121
    pool_.clear();
122
    data_.reset();
123
  }
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() {
129
    return getVariant().template is<T>();
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 {
142
    return getVariant().isNull();
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 {
148
    return pool_.size();
149
  }
150

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

157
  // Returns the depth (nesting level) of the array.
158
  // https://arduinojson.org/v6/api/jsondocument/nesting/
159
  size_t nesting() const {
160
    return variantNesting(&data_);
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 {
166
    return data_.size();
167
  }
168

169
  // Copies the specified document.
170
  // https://arduinojson.org/v6/api/jsondocument/set/
171
  bool set(const JsonDocument& src) {
172
    return to<JsonVariant>().set(src.as<JsonVariantConst>());
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) {
181
    return to<JsonVariant>().set(src);
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() {
188
    clear();
189
    return getVariant().template to<T>();
190
  }
191

192
  // Creates an array and appends it to the root array.
193
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
194
  JsonArray createNestedArray() {
195
    return add().to<JsonArray>();
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) {
202
    return operator[](key).template to<JsonArray>();
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) {
209
    return operator[](key).template to<JsonArray>();
210
  }
211

212
  // Creates an object and appends it to the root array.
213
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
214
  JsonObject createNestedObject() {
215
    return add().to<JsonObject>();
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) {
222
    return operator[](key).template to<JsonObject>();
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) {
229
    return operator[](key).template to<JsonObject>();
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 {
236
    return data_.getMember(detail::adaptString(key)) != 0;
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 {
243
    return data_.getMember(detail::adaptString(key)) != 0;
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};
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};
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)));
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)));
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};
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));
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_));
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);
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);
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());
322
  }
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());
331
  }
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());
341
  }
342

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

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

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

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

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

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

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

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

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

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

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

391
inline void convertToJson(const JsonDocument& src, JsonVariant dst) {
392
  dst.set(src.as<JsonVariantConst>());
393
}
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