/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 |