Coverage Report

Created: 2023-09-07 15:05

/src/arduinojson/src/ArduinoJson/Document/JsonDocument.hpp
Line
Count
Source (jump to first uncovered line)
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2022, Benoit BLANCHON
3
// MIT License
4
5
#pragma once
6
7
#include <ArduinoJson/Array/ElementProxy.hpp>
8
#include <ArduinoJson/Memory/MemoryPool.hpp>
9
#include <ArduinoJson/Object/JsonObject.hpp>
10
#include <ArduinoJson/Object/MemberProxy.hpp>
11
#include <ArduinoJson/Strings/StoragePolicy.hpp>
12
#include <ArduinoJson/Variant/JsonVariantConst.hpp>
13
#include <ArduinoJson/Variant/VariantTo.hpp>
14
15
namespace ARDUINOJSON_NAMESPACE {
16
17
// A JSON document.
18
// https://arduinojson.org/v6/api/jsondocument/
19
class JsonDocument : public VariantOperators<const JsonDocument&> {
20
  friend class VariantAttorney;
21
22
 public:
23
  // Casts the root to the specified type.
24
  // https://arduinojson.org/v6/api/jsondocument/as/
25
  template <typename T>
26
  T as() {
27
    return getVariant().template as<T>();
28
  }
29
30
  // Casts the root to the specified type.
31
  // https://arduinojson.org/v6/api/jsondocument/as/
32
  template <typename T>
33
0
  T as() const {
34
0
    return getVariant().template as<T>();
35
0
  }
36
37
  // Empties the document and resets the memory pool
38
  // https://arduinojson.org/v6/api/jsondocument/clear/
39
24.1k
  void clear() {
40
24.1k
    _pool.clear();
41
24.1k
    _data.init();
42
24.1k
  }
43
44
  // Returns true if the root is of the specified type.
45
  // https://arduinojson.org/v6/api/jsondocument/is/
46
  template <typename T>
47
  bool is() {
48
    return getVariant().template is<T>();
49
  }
50
51
  // Returns true if the root is of the specified type.
52
  // https://arduinojson.org/v6/api/jsondocument/is/
53
  template <typename T>
54
  bool is() const {
55
    return getVariant().template is<T>();
56
  }
57
58
  // Returns true if the root is null.
59
  // https://arduinojson.org/v6/api/jsondocument/isnull/
60
0
  bool isNull() const {
61
0
    return getVariant().isNull();
62
0
  }
63
64
  // Returns the number of used bytes in the memory pool.
65
  // https://arduinojson.org/v6/api/jsondocument/memoryusage/
66
0
  size_t memoryUsage() const {
67
0
    return _pool.size();
68
0
  }
69
70
  // Returns trues if the memory pool was too small.
71
  // https://arduinojson.org/v6/api/jsondocument/overflowed/
72
0
  bool overflowed() const {
73
0
    return _pool.overflowed();
74
0
  }
75
76
  // Returns the depth (nesting level) of the array.
77
  // https://arduinojson.org/v6/api/jsondocument/nesting/
78
0
  size_t nesting() const {
79
0
    return variantNesting(&_data);
80
0
  }
81
82
  // Returns the capacity of the memory pool.
83
  // https://arduinojson.org/v6/api/jsondocument/capacity/
84
0
  size_t capacity() const {
85
0
    return _pool.capacity();
86
0
  }
87
88
  // Returns the number of elements in the root array or object.
89
  // https://arduinojson.org/v6/api/jsondocument/size/
90
0
  size_t size() const {
91
0
    return _data.size();
92
0
  }
93
94
  // Copies the specified document.
95
  // https://arduinojson.org/v6/api/jsondocument/set/
96
0
  bool set(const JsonDocument& src) {
97
0
    return to<JsonVariant>().set(src.as<JsonVariantConst>());
98
0
  }
99
100
  // Replaces the root with the specified value.
101
  // https://arduinojson.org/v6/api/jsondocument/set/
102
  template <typename T>
103
  typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set(
104
      const T& src) {
105
    return to<JsonVariant>().set(src);
106
  }
107
108
  // Clears the document and converts it to the specified type.
109
  // https://arduinojson.org/v6/api/jsondocument/to/
110
  template <typename T>
111
0
  typename VariantTo<T>::type to() {
112
0
    clear();
113
0
    return getVariant().template to<T>();
114
0
  }
115
116
  // Creates an array and appends it to the root array.
117
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
118
0
  JsonArray createNestedArray() {
119
0
    return add().to<JsonArray>();
120
0
  }
121
122
  // Creates an array and adds it to the root object.
123
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
124
  template <typename TChar>
125
  JsonArray createNestedArray(TChar* key) {
126
    return operator[](key).template to<JsonArray>();
127
  }
128
129
  // Creates an array and adds it to the root object.
130
  // https://arduinojson.org/v6/api/jsondocument/createnestedarray/
131
  template <typename TString>
132
  JsonArray createNestedArray(const TString& key) {
133
    return operator[](key).template to<JsonArray>();
134
  }
135
136
  // Creates an object and appends it to the root array.
137
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
138
0
  JsonObject createNestedObject() {
139
0
    return add().to<JsonObject>();
140
0
  }
141
142
  // Creates an object and adds it to the root object.
143
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
144
  template <typename TChar>
145
  JsonObject createNestedObject(TChar* key) {
146
    return operator[](key).template to<JsonObject>();
147
  }
148
149
  // Creates an object and adds it to the root object.
150
  // https://arduinojson.org/v6/api/jsondocument/createnestedobject/
151
  template <typename TString>
152
  JsonObject createNestedObject(const TString& key) {
153
    return operator[](key).template to<JsonObject>();
154
  }
155
156
  // Returns true if the root object contains the specified key.
157
  // https://arduinojson.org/v6/api/jsondocument/containskey/
158
  template <typename TChar>
159
  bool containsKey(TChar* key) const {
160
    return _data.getMember(adaptString(key)) != 0;
161
  }
162
163
  // Returns true if the root object contains the specified key.
164
  // https://arduinojson.org/v6/api/jsondocument/containskey/
165
  template <typename TString>
166
  bool containsKey(const TString& key) const {
167
    return _data.getMember(adaptString(key)) != 0;
168
  }
169
170
  // Gets or sets a root object's member.
171
  // https://arduinojson.org/v6/api/jsondocument/subscript/
172
  template <typename TString>
173
  FORCE_INLINE typename enable_if<IsString<TString>::value,
174
                                  MemberProxy<JsonDocument&, TString> >::type
175
  operator[](const TString& key) {
176
    return MemberProxy<JsonDocument&, TString>(*this, key);
177
  }
178
179
  // Gets or sets a root object's member.
180
  // https://arduinojson.org/v6/api/jsondocument/subscript/
181
  template <typename TChar>
182
  FORCE_INLINE typename enable_if<IsString<TChar*>::value,
183
                                  MemberProxy<JsonDocument&, TChar*> >::type
184
  operator[](TChar* key) {
185
    return MemberProxy<JsonDocument&, TChar*>(*this, key);
186
  }
187
188
  // Gets a root object's member.
189
  // https://arduinojson.org/v6/api/jsondocument/subscript/
190
  template <typename TString>
191
  FORCE_INLINE
192
      typename enable_if<IsString<TString>::value, JsonVariantConst>::type
193
      operator[](const TString& key) const {
194
    return JsonVariantConst(_data.getMember(adaptString(key)));
195
  }
196
197
  // Gets a root object's member.
198
  // https://arduinojson.org/v6/api/jsondocument/subscript/
199
  template <typename TChar>
200
  FORCE_INLINE
201
      typename enable_if<IsString<TChar*>::value, JsonVariantConst>::type
202
      operator[](TChar* key) const {
203
    return JsonVariantConst(_data.getMember(adaptString(key)));
204
  }
205
206
  // Gets or sets a root array's element.
207
  // https://arduinojson.org/v6/api/jsondocument/subscript/
208
0
  FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
209
0
    return ElementProxy<JsonDocument&>(*this, index);
210
0
  }
211
212
  // Gets a root array's member.
213
  // https://arduinojson.org/v6/api/jsondocument/subscript/
214
0
  FORCE_INLINE JsonVariantConst operator[](size_t index) const {
215
0
    return JsonVariantConst(_data.getElement(index));
216
0
  }
217
218
  // Appends a new (null) element to the root array.
219
  // Returns a reference to the new element.
220
  // https://arduinojson.org/v6/api/jsondocument/add/
221
0
  FORCE_INLINE JsonVariant add() {
222
0
    return JsonVariant(&_pool, _data.addElement(&_pool));
223
0
  }
224
225
  // Appends a value to the root array.
226
  // https://arduinojson.org/v6/api/jsondocument/add/
227
  template <typename TValue>
228
  FORCE_INLINE bool add(const TValue& value) {
229
    return add().set(value);
230
  }
231
232
  // Appends a value to the root array.
233
  // https://arduinojson.org/v6/api/jsondocument/add/
234
  template <typename TChar>
235
  FORCE_INLINE bool add(TChar* value) {
236
    return add().set(value);
237
  }
238
239
  // Removes an element of the root array.
240
  // ⚠️ Doesn't release the memory associated with the removed element.
241
  // https://arduinojson.org/v6/api/jsondocument/remove/
242
0
  FORCE_INLINE void remove(size_t index) {
243
0
    _data.remove(index);
244
0
  }
245
246
  // Removes a member of the root object.
247
  // ⚠️ Doesn't release the memory associated with the removed element.
248
  // https://arduinojson.org/v6/api/jsondocument/remove/
249
  template <typename TChar>
250
  FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
251
      TChar* key) {
252
    _data.remove(adaptString(key));
253
  }
254
255
  // Removes a member of the root object.
256
  // ⚠️ Doesn't release the memory associated with the removed element.
257
  // https://arduinojson.org/v6/api/jsondocument/remove/
258
  template <typename TString>
259
  FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
260
      const TString& key) {
261
    _data.remove(adaptString(key));
262
  }
263
264
0
  FORCE_INLINE operator JsonVariant() {
265
0
    return getVariant();
266
0
  }
267
268
15.4k
  FORCE_INLINE operator JsonVariantConst() const {
269
15.4k
    return getVariant();
270
15.4k
  }
271
272
 protected:
273
0
  JsonDocument() : _pool(0, 0) {
274
0
    _data.init();
275
0
  }
276
277
24.1k
  JsonDocument(MemoryPool pool) : _pool(pool) {
278
24.1k
    _data.init();
279
24.1k
  }
280
281
0
  JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
282
0
    _data.init();
283
0
  }
284
285
24.1k
  ~JsonDocument() {}
286
287
0
  void replacePool(MemoryPool pool) {
288
0
    _pool = pool;
289
0
  }
290
291
0
  JsonVariant getVariant() {
292
0
    return JsonVariant(&_pool, &_data);
293
0
  }
294
295
15.4k
  JsonVariantConst getVariant() const {
296
15.4k
    return JsonVariantConst(&_data);
297
15.4k
  }
298
299
  MemoryPool _pool;
300
  VariantData _data;
301
302
 private:
303
  JsonDocument(const JsonDocument&);
304
  JsonDocument& operator=(const JsonDocument&);
305
306
 protected:
307
48.3k
  MemoryPool* getPool() {
308
48.3k
    return &_pool;
309
48.3k
  }
310
311
24.1k
  VariantData* getData() {
312
24.1k
    return &_data;
313
24.1k
  }
314
315
0
  const VariantData* getData() const {
316
0
    return &_data;
317
0
  }
318
319
0
  VariantData* getOrCreateData() {
320
0
    return &_data;
321
0
  }
322
};
323
324
0
inline void convertToJson(const JsonDocument& src, JsonVariant dst) {
325
0
  dst.set(src.as<JsonVariantConst>());
326
0
}
327
328
}  // namespace ARDUINOJSON_NAMESPACE