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

bblanchon / ArduinoJson / 9115317806

16 May 2024 03:47PM UTC coverage: 99.554%. Remained the same
9115317806

push

github

bblanchon
CI: don't build fuzzers with Clang 11

Clang 11 fails on GitHub Actions with the following error:
ERROR: UndefinedBehaviorSanitizer failed to allocate 0x0 (0) bytes of SetAlternateSignalStack (error code: 22)
Sanitizer CHECK failed: /build/llvm-toolchain-11-mnvtwk/llvm-toolchain-11-11.1.0/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp:54 ((0 && "unable to mmap")) != (0) (0, 0)

3793 of 3810 relevant lines covered (99.55%)

10938.8 hits per line

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

99.26
/src/ArduinoJson/Document/JsonDocument.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2024, 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/ResourceManager.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/v7/api/jsondocument/
20
class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
21
  friend class detail::VariantAttorney;
22

23
 public:
24
  explicit JsonDocument(Allocator* alloc = detail::DefaultAllocator::instance())
1,919✔
25
      : resources_(alloc) {}
1,919✔
26

27
  // Copy-constructor
28
  JsonDocument(const JsonDocument& src) : JsonDocument(src.allocator()) {
7✔
29
    set(src);
7✔
30
  }
7✔
31

32
  // Move-constructor
33
  JsonDocument(JsonDocument&& src)
2✔
34
      : JsonDocument(detail::DefaultAllocator::instance()) {
2✔
35
    swap(*this, src);
2✔
36
  }
2✔
37

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

51
  JsonDocument& operator=(JsonDocument src) {
4✔
52
    swap(*this, src);
4✔
53
    return *this;
4✔
54
  }
55

56
  template <typename T>
57
  JsonDocument& operator=(const T& src) {
5✔
58
    set(src);
5✔
59
    return *this;
5✔
60
  }
61

62
  Allocator* allocator() const {
7✔
63
    return resources_.allocator();
7✔
64
  }
65

66
  // Reduces the capacity of the memory pool to match the current usage.
67
  // https://arduinojson.org/v7/api/jsondocument/shrinktofit/
68
  void shrinkToFit() {
1,315✔
69
    resources_.shrinkToFit();
1,315✔
70
  }
1,315✔
71

72
  // Casts the root to the specified type.
73
  // https://arduinojson.org/v7/api/jsondocument/as/
74
  template <typename T>
75
  T as() {
581✔
76
    return getVariant().template as<T>();
1,118✔
77
  }
78

79
  // Casts the root to the specified type.
80
  // https://arduinojson.org/v7/api/jsondocument/as/
81
  template <typename T>
82
  T as() const {
10✔
83
    return getVariant().template as<T>();
20✔
84
  }
85

86
  // Empties the document and resets the memory pool
87
  // https://arduinojson.org/v7/api/jsondocument/clear/
88
  void clear() {
1,847✔
89
    resources_.clear();
1,847✔
90
    data_.reset();
1,847✔
91
  }
1,847✔
92

93
  // Returns true if the root is of the specified type.
94
  // https://arduinojson.org/v7/api/jsondocument/is/
95
  template <typename T>
96
  bool is() {
90✔
97
    return getVariant().template is<T>();
180✔
98
  }
99

100
  // Returns true if the root is of the specified type.
101
  // https://arduinojson.org/v7/api/jsondocument/is/
102
  template <typename T>
103
  bool is() const {
104
    return getVariant().template is<T>();
105
  }
106

107
  // Returns true if the root is null.
108
  // https://arduinojson.org/v7/api/jsondocument/isnull/
109
  bool isNull() const {
14✔
110
    return getVariant().isNull();
14✔
111
  }
112

113
  // Returns trues if the memory pool was too small.
114
  // https://arduinojson.org/v7/api/jsondocument/overflowed/
115
  bool overflowed() const {
32✔
116
    return resources_.overflowed();
32✔
117
  }
118

119
  // Returns the depth (nesting level) of the array.
120
  // https://arduinojson.org/v7/api/jsondocument/nesting/
121
  size_t nesting() const {
4✔
122
    return data_.nesting(&resources_);
4✔
123
  }
124

125
  // Returns the number of elements in the root array or object.
126
  // https://arduinojson.org/v7/api/jsondocument/size/
127
  size_t size() const {
13✔
128
    return data_.size(&resources_);
13✔
129
  }
130

131
  // Copies the specified document.
132
  // https://arduinojson.org/v7/api/jsondocument/set/
133
  bool set(const JsonDocument& src) {
7✔
134
    return to<JsonVariant>().set(src.as<JsonVariantConst>());
7✔
135
  }
136

137
  // Replaces the root with the specified value.
138
  // https://arduinojson.org/v7/api/jsondocument/set/
139
  template <typename T>
140
  typename detail::enable_if<!detail::is_base_of<JsonDocument, T>::value,
141
                             bool>::type
142
  set(const T& src) {
67✔
143
    return to<JsonVariant>().set(src);
67✔
144
  }
145

146
  // Clears the document and converts it to the specified type.
147
  // https://arduinojson.org/v7/api/jsondocument/to/
148
  template <typename T>
149
  typename detail::VariantTo<T>::type to() {
803✔
150
    clear();
803✔
151
    return getVariant().template to<T>();
1,606✔
152
  }
153

154
  // Returns true if the root object contains the specified key.
155
  // https://arduinojson.org/v7/api/jsondocument/containskey/
156
  template <typename TChar>
157
  bool containsKey(TChar* key) const {
7✔
158
    return data_.getMember(detail::adaptString(key), &resources_) != 0;
7✔
159
  }
160

161
  // Returns true if the root object contains the specified key.
162
  // https://arduinojson.org/v7/api/jsondocument/containskey/
163
  template <typename TString>
164
  typename detail::enable_if<detail::IsString<TString>::value, bool>::type
165
  containsKey(const TString& key) const {
1✔
166
    return data_.getMember(detail::adaptString(key), &resources_) != 0;
1✔
167
  }
168

169
  // Returns true if the root object contains the specified key.
170
  // https://arduinojson.org/v7/api/jsondocument/containskey/
171
  template <typename TVariant>
172
  typename detail::enable_if<detail::IsVariant<TVariant>::value, bool>::type
173
  containsKey(const TVariant& key) const {
2✔
174
    return containsKey(key.template as<const char*>());
2✔
175
  }
176

177
  // Gets or sets a root object's member.
178
  // https://arduinojson.org/v7/api/jsondocument/subscript/
179
  template <typename TString>
180
  typename detail::enable_if<detail::IsString<TString>::value,
181
                             detail::MemberProxy<JsonDocument&, TString>>::type
182
  operator[](const TString& key) {
15✔
183
    return {*this, key};
15✔
184
  }
185

186
  // Gets or sets a root object's member.
187
  // https://arduinojson.org/v7/api/jsondocument/subscript/
188
  template <typename TChar>
189
  typename detail::enable_if<detail::IsString<TChar*>::value,
190
                             detail::MemberProxy<JsonDocument&, TChar*>>::type
191
  operator[](TChar* key) {
477✔
192
    return {*this, key};
477✔
193
  }
194

195
  // Gets a root object's member.
196
  // https://arduinojson.org/v7/api/jsondocument/subscript/
197
  template <typename TString>
198
  typename detail::enable_if<detail::IsString<TString>::value,
199
                             JsonVariantConst>::type
200
  operator[](const TString& key) const {
1✔
201
    return JsonVariantConst(
1✔
202
        data_.getMember(detail::adaptString(key), &resources_), &resources_);
2✔
203
  }
204

205
  // Gets a root object's member.
206
  // https://arduinojson.org/v7/api/jsondocument/subscript/
207
  template <typename TChar>
208
  typename detail::enable_if<detail::IsString<TChar*>::value,
209
                             JsonVariantConst>::type
210
  operator[](TChar* key) const {
4✔
211
    return JsonVariantConst(
4✔
212
        data_.getMember(detail::adaptString(key), &resources_), &resources_);
8✔
213
  }
214

215
  // Gets or sets a root array's element.
216
  // https://arduinojson.org/v7/api/jsondocument/subscript/
217
  template <typename T>
218
  typename detail::enable_if<detail::is_integral<T>::value,
219
                             detail::ElementProxy<JsonDocument&>>::type
220
  operator[](T index) {
134✔
221
    return {*this, size_t(index)};
134✔
222
  }
223

224
  // Gets a root array's member.
225
  // https://arduinojson.org/v7/api/jsondocument/subscript/
226
  JsonVariantConst operator[](size_t index) const {
3✔
227
    return JsonVariantConst(data_.getElement(index, &resources_), &resources_);
3✔
228
  }
229

230
  // Gets or sets a root object's member.
231
  // https://arduinojson.org/v7/api/jsondocument/subscript/
232
  template <typename TVariant>
233
  typename detail::enable_if<detail::IsVariant<TVariant>::value,
234
                             JsonVariantConst>::type
235
  operator[](const TVariant& key) const {
4✔
236
    if (key.template is<const char*>())
4✔
237
      return operator[](key.template as<const char*>());
2✔
238
    if (key.template is<size_t>())
2✔
239
      return operator[](key.template as<size_t>());
2✔
240
    return {};
×
241
  }
242

243
  // Appends a new (empty) element to the root array.
244
  // Returns a reference to the new element.
245
  // https://arduinojson.org/v7/api/jsondocument/add/
246
  template <typename T>
247
  typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type
248
  add() {
54✔
249
    return add<JsonVariant>().to<T>();
108✔
250
  }
251

252
  // Appends a new (null) element to the root array.
253
  // Returns a reference to the new element.
254
  // https://arduinojson.org/v7/api/jsondocument/add/
255
  template <typename T>
256
  typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type
257
  add() {
207✔
258
    return JsonVariant(data_.addElement(&resources_), &resources_);
207✔
259
  }
260

261
  // Appends a value to the root array.
262
  // https://arduinojson.org/v7/api/jsondocument/add/
263
  template <typename TValue>
264
  bool add(const TValue& value) {
66✔
265
    return add<JsonVariant>().set(value);
66✔
266
  }
267

268
  // Appends a value to the root array.
269
  // https://arduinojson.org/v7/api/jsondocument/add/
270
  template <typename TChar>
271
  bool add(TChar* value) {
18✔
272
    return add<JsonVariant>().set(value);
18✔
273
  }
274

275
  // Removes an element of the root array.
276
  // https://arduinojson.org/v7/api/jsondocument/remove/
277
  template <typename T>
278
  typename detail::enable_if<detail::is_integral<T>::value>::type remove(
2✔
279
      T index) {
280
    detail::VariantData::removeElement(getData(), size_t(index),
2✔
281
                                       getResourceManager());
282
  }
2✔
283

284
  // Removes a member of the root object.
285
  // https://arduinojson.org/v7/api/jsondocument/remove/
286
  template <typename TChar>
287
  typename detail::enable_if<detail::IsString<TChar*>::value>::type remove(
3✔
288
      TChar* key) {
289
    detail::VariantData::removeMember(getData(), detail::adaptString(key),
3✔
290
                                      getResourceManager());
291
  }
3✔
292

293
  // Removes a member of the root object.
294
  // https://arduinojson.org/v7/api/jsondocument/remove/
295
  template <typename TString>
296
  typename detail::enable_if<detail::IsString<TString>::value>::type remove(
1✔
297
      const TString& key) {
298
    detail::VariantData::removeMember(getData(), detail::adaptString(key),
1✔
299
                                      getResourceManager());
300
  }
1✔
301

302
  // Removes a member of the root object or an element of the root array.
303
  // https://arduinojson.org/v7/api/jsondocument/remove/
304
  template <typename TVariant>
305
  typename detail::enable_if<detail::IsVariant<TVariant>::value>::type remove(
3✔
306
      const TVariant& key) {
307
    if (key.template is<const char*>())
3✔
308
      remove(key.template as<const char*>());
1✔
309
    if (key.template is<size_t>())
3✔
310
      remove(key.template as<size_t>());
1✔
311
  }
3✔
312

313
  operator JsonVariant() {
1✔
314
    return getVariant();
1✔
315
  }
316

317
  operator JsonVariantConst() const {
278✔
318
    return getVariant();
278✔
319
  }
320

321
  friend void swap(JsonDocument& a, JsonDocument& b) {
7✔
322
    swap(a.resources_, b.resources_);
7✔
323
    swap_(a.data_, b.data_);
7✔
324
  }
7✔
325

326
  // DEPRECATED: use add<JsonVariant>() instead
327
  ARDUINOJSON_DEPRECATED("use add<JsonVariant>() instead")
328
  JsonVariant add() {
2✔
329
    return add<JsonVariant>();
2✔
330
  }
331

332
  // DEPRECATED: use add<JsonArray>() instead
333
  ARDUINOJSON_DEPRECATED("use add<JsonArray>() instead")
334
  JsonArray createNestedArray() {
1✔
335
    return add<JsonArray>();
1✔
336
  }
337

338
  // DEPRECATED: use doc[key].to<JsonArray>() instead
339
  template <typename TChar>
340
  ARDUINOJSON_DEPRECATED("use doc[key].to<JsonArray>() instead")
341
  JsonArray createNestedArray(TChar* key) {
2✔
342
    return operator[](key).template to<JsonArray>();
2✔
343
  }
344

345
  // DEPRECATED: use doc[key].to<JsonArray>() instead
346
  template <typename TString>
347
  ARDUINOJSON_DEPRECATED("use doc[key].to<JsonArray>() instead")
348
  JsonArray createNestedArray(const TString& key) {
1✔
349
    return operator[](key).template to<JsonArray>();
1✔
350
  }
351

352
  // DEPRECATED: use add<JsonObject>() instead
353
  ARDUINOJSON_DEPRECATED("use add<JsonObject>() instead")
354
  JsonObject createNestedObject() {
1✔
355
    return add<JsonObject>();
1✔
356
  }
357

358
  // DEPRECATED: use doc[key].to<JsonObject>() instead
359
  template <typename TChar>
360
  ARDUINOJSON_DEPRECATED("use doc[key].to<JsonObject>() instead")
361
  JsonObject createNestedObject(TChar* key) {
2✔
362
    return operator[](key).template to<JsonObject>();
2✔
363
  }
364

365
  // DEPRECATED: use doc[key].to<JsonObject>() instead
366
  template <typename TString>
367
  ARDUINOJSON_DEPRECATED("use doc[key].to<JsonObject>() instead")
368
  JsonObject createNestedObject(const TString& key) {
1✔
369
    return operator[](key).template to<JsonObject>();
1✔
370
  }
371

372
  // DEPRECATED: always returns zero
373
  ARDUINOJSON_DEPRECATED("always returns zero")
374
  size_t memoryUsage() const {
1✔
375
    return 0;
1✔
376
  }
377

378
 private:
379
  JsonVariant getVariant() {
1,475✔
380
    return JsonVariant(&data_, &resources_);
1,475✔
381
  }
382

383
  JsonVariantConst getVariant() const {
302✔
384
    return JsonVariantConst(&data_, &resources_);
302✔
385
  }
386

387
  detail::ResourceManager* getResourceManager() {
2,998✔
388
    return &resources_;
2,998✔
389
  }
390

391
  detail::VariantData* getData() {
237✔
392
    return &data_;
237✔
393
  }
394

395
  const detail::VariantData* getData() const {
396
    return &data_;
397
  }
398

399
  detail::VariantData* getOrCreateData() {
1,500✔
400
    return &data_;
1,500✔
401
  }
402

403
  detail::ResourceManager resources_;
404
  detail::VariantData data_;
405
};
406

407
inline void convertToJson(const JsonDocument& src, JsonVariant dst) {
1✔
408
  dst.set(src.as<JsonVariantConst>());
1✔
409
}
1✔
410

411
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

© 2026 Coveralls, Inc