1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors |
2 | // Distributed under MIT license, or public domain if desired and |
3 | // recognized in your jurisdiction. |
4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE |
5 | |
6 | #ifndef JSON_H_INCLUDED |
7 | #define JSON_H_INCLUDED |
8 | |
9 | #if !defined(JSON_IS_AMALGAMATION) |
10 | #include "forwards.h" |
11 | #endif // if !defined(JSON_IS_AMALGAMATION) |
12 | |
13 | // Conditional NORETURN attribute on the throw functions would: |
14 | // a) suppress false positives from static code analysis |
15 | // b) possibly improve optimization opportunities. |
16 | #if !defined(JSONCPP_NORETURN) |
17 | #if defined(_MSC_VER) && _MSC_VER == 1800 |
18 | #define JSONCPP_NORETURN __declspec(noreturn) |
19 | #else |
20 | #define JSONCPP_NORETURN [[noreturn]] |
21 | #endif |
22 | #endif |
23 | |
24 | // Support for '= delete' with template declarations was a late addition |
25 | // to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2 |
26 | // even though these declare themselves to be c++11 compilers. |
27 | #if !defined(JSONCPP_TEMPLATE_DELETE) |
28 | #if defined(__clang__) && defined(__apple_build_version__) |
29 | #if __apple_build_version__ <= 8000042 |
30 | #define JSONCPP_TEMPLATE_DELETE |
31 | #endif |
32 | #elif defined(__clang__) |
33 | #if __clang_major__ == 3 && __clang_minor__ <= 8 |
34 | #define JSONCPP_TEMPLATE_DELETE |
35 | #endif |
36 | #endif |
37 | #if !defined(JSONCPP_TEMPLATE_DELETE) |
38 | #define JSONCPP_TEMPLATE_DELETE = delete |
39 | #endif |
40 | #endif |
41 | |
42 | #include <array> |
43 | #include <exception> |
44 | #include <map> |
45 | #include <memory> |
46 | #include <string> |
47 | #include <vector> |
48 | |
49 | // Disable warning C4251: <data member>: <type> needs to have dll-interface to |
50 | // be used by... |
51 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) |
52 | #pragma warning(push) |
53 | #pragma warning(disable : 4251) |
54 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) |
55 | |
56 | #pragma pack(push, 8) |
57 | |
58 | /** \brief JSON (JavaScript Object Notation). |
59 | */ |
60 | namespace Json { |
61 | |
62 | #if JSON_USE_EXCEPTION |
63 | /** Base class for all exceptions we throw. |
64 | * |
65 | * We use nothing but these internally. Of course, STL can throw others. |
66 | */ |
67 | class JSON_API Exception : public std::exception { |
68 | public: |
69 | Exception(String msg); |
70 | ~Exception() noexcept override; |
71 | char const* what() const noexcept override; |
72 | |
73 | protected: |
74 | String msg_; |
75 | }; |
76 | |
77 | /** Exceptions which the user cannot easily avoid. |
78 | * |
79 | * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input |
80 | * |
81 | * \remark derived from Json::Exception |
82 | */ |
83 | class JSON_API RuntimeError : public Exception { |
84 | public: |
85 | RuntimeError(String const& msg); |
86 | }; |
87 | |
88 | /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. |
89 | * |
90 | * These are precondition-violations (user bugs) and internal errors (our bugs). |
91 | * |
92 | * \remark derived from Json::Exception |
93 | */ |
94 | class JSON_API LogicError : public Exception { |
95 | public: |
96 | LogicError(String const& msg); |
97 | }; |
98 | #endif |
99 | |
100 | /// used internally |
101 | JSONCPP_NORETURN void throwRuntimeError(String const& msg); |
102 | /// used internally |
103 | JSONCPP_NORETURN void throwLogicError(String const& msg); |
104 | |
105 | /** \brief Type of the value held by a Value object. |
106 | */ |
107 | enum ValueType { |
108 | nullValue = 0, ///< 'null' value |
109 | intValue, ///< signed integer value |
110 | uintValue, ///< unsigned integer value |
111 | realValue, ///< double value |
112 | stringValue, ///< UTF-8 string value |
113 | booleanValue, ///< bool value |
114 | arrayValue, ///< array value (ordered list) |
115 | objectValue ///< object value (collection of name/value pairs). |
116 | }; |
117 | |
118 | enum { |
119 | = 0, ///< a comment placed on the line before a value |
120 | , ///< a comment just after a value on the same line |
121 | , ///< a comment on the line after a value (only make sense for |
122 | /// root value) |
123 | |
124 | }; |
125 | |
126 | /** \brief Type of precision for formatting of real values. |
127 | */ |
128 | enum PrecisionType { |
129 | significantDigits = 0, ///< we set max number of significant digits in string |
130 | decimalPlaces ///< we set max number of digits after "." in string |
131 | }; |
132 | |
133 | /** \brief Lightweight wrapper to tag static string. |
134 | * |
135 | * Value constructor and objectValue member assignment takes advantage of the |
136 | * StaticString and avoid the cost of string duplication when storing the |
137 | * string or the member name. |
138 | * |
139 | * Example of usage: |
140 | * \code |
141 | * Json::Value aValue( StaticString("some text") ); |
142 | * Json::Value object; |
143 | * static const StaticString code("code"); |
144 | * object[code] = 1234; |
145 | * \endcode |
146 | */ |
147 | class JSON_API StaticString { |
148 | public: |
149 | explicit StaticString(const char* czstring) : c_str_(czstring) {} |
150 | |
151 | operator const char*() const { return c_str_; } |
152 | |
153 | const char* c_str() const { return c_str_; } |
154 | |
155 | private: |
156 | const char* c_str_; |
157 | }; |
158 | |
159 | /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value. |
160 | * |
161 | * This class is a discriminated union wrapper that can represents a: |
162 | * - signed integer [range: Value::minInt - Value::maxInt] |
163 | * - unsigned integer (range: 0 - Value::maxUInt) |
164 | * - double |
165 | * - UTF-8 string |
166 | * - boolean |
167 | * - 'null' |
168 | * - an ordered list of Value |
169 | * - collection of name/value pairs (javascript object) |
170 | * |
171 | * The type of the held value is represented by a #ValueType and |
172 | * can be obtained using type(). |
173 | * |
174 | * Values of an #objectValue or #arrayValue can be accessed using operator[]() |
175 | * methods. |
176 | * Non-const methods will automatically create the a #nullValue element |
177 | * if it does not exist. |
178 | * The sequence of an #arrayValue will be automatically resized and initialized |
179 | * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. |
180 | * |
181 | * The get() methods can be used to obtain default value in the case the |
182 | * required element does not exist. |
183 | * |
184 | * It is possible to iterate over the list of member keys of an object using |
185 | * the getMemberNames() method. |
186 | * |
187 | * \note #Value string-length fit in size_t, but keys must be < 2^30. |
188 | * (The reason is an implementation detail.) A #CharReader will raise an |
189 | * exception if a bound is exceeded to avoid security holes in your app, |
190 | * but the Value API does *not* check bounds. That is the responsibility |
191 | * of the caller. |
192 | */ |
193 | class JSON_API Value { |
194 | friend class ValueIteratorBase; |
195 | |
196 | public: |
197 | using Members = std::vector<String>; |
198 | using iterator = ValueIterator; |
199 | using const_iterator = ValueConstIterator; |
200 | using UInt = Json::UInt; |
201 | using Int = Json::Int; |
202 | #if defined(JSON_HAS_INT64) |
203 | using UInt64 = Json::UInt64; |
204 | using Int64 = Json::Int64; |
205 | #endif // defined(JSON_HAS_INT64) |
206 | using LargestInt = Json::LargestInt; |
207 | using LargestUInt = Json::LargestUInt; |
208 | using ArrayIndex = Json::ArrayIndex; |
209 | |
210 | // Required for boost integration, e. g. BOOST_TEST |
211 | using value_type = std::string; |
212 | |
213 | #if JSON_USE_NULLREF |
214 | // Binary compatibility kludges, do not use. |
215 | static const Value& null; |
216 | static const Value& nullRef; |
217 | #endif |
218 | |
219 | // null and nullRef are deprecated, use this instead. |
220 | static Value const& nullSingleton(); |
221 | |
222 | /// Minimum signed integer value that can be stored in a Json::Value. |
223 | static constexpr LargestInt minLargestInt = |
224 | LargestInt(~(LargestUInt(-1) / 2)); |
225 | /// Maximum signed integer value that can be stored in a Json::Value. |
226 | static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2); |
227 | /// Maximum unsigned integer value that can be stored in a Json::Value. |
228 | static constexpr LargestUInt maxLargestUInt = LargestUInt(-1); |
229 | |
230 | /// Minimum signed int value that can be stored in a Json::Value. |
231 | static constexpr Int minInt = Int(~(UInt(-1) / 2)); |
232 | /// Maximum signed int value that can be stored in a Json::Value. |
233 | static constexpr Int maxInt = Int(UInt(-1) / 2); |
234 | /// Maximum unsigned int value that can be stored in a Json::Value. |
235 | static constexpr UInt maxUInt = UInt(-1); |
236 | |
237 | #if defined(JSON_HAS_INT64) |
238 | /// Minimum signed 64 bits int value that can be stored in a Json::Value. |
239 | static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2)); |
240 | /// Maximum signed 64 bits int value that can be stored in a Json::Value. |
241 | static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2); |
242 | /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. |
243 | static constexpr UInt64 maxUInt64 = UInt64(-1); |
244 | #endif // defined(JSON_HAS_INT64) |
245 | /// Default precision for real value for string representation. |
246 | static constexpr UInt defaultRealPrecision = 17; |
247 | // The constant is hard-coded because some compiler have trouble |
248 | // converting Value::maxUInt64 to a double correctly (AIX/xlC). |
249 | // Assumes that UInt64 is a 64 bits integer. |
250 | static constexpr double maxUInt64AsDouble = 18446744073709551615.0; |
251 | // Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler |
252 | // when using gcc and clang backend compilers. CZString |
253 | // cannot be defined as private. See issue #486 |
254 | #ifdef __NVCC__ |
255 | public: |
256 | #else |
257 | private: |
258 | #endif |
259 | #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION |
260 | class CZString { |
261 | public: |
262 | enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy }; |
263 | CZString(ArrayIndex index); |
264 | CZString(char const* str, unsigned length, DuplicationPolicy allocate); |
265 | CZString(CZString const& other); |
266 | CZString(CZString&& other); |
267 | ~CZString(); |
268 | CZString& operator=(const CZString& other); |
269 | CZString& operator=(CZString&& other); |
270 | |
271 | bool operator<(CZString const& other) const; |
272 | bool operator==(CZString const& other) const; |
273 | ArrayIndex index() const; |
274 | // const char* c_str() const; ///< \deprecated |
275 | char const* data() const; |
276 | unsigned length() const; |
277 | bool isStaticString() const; |
278 | |
279 | private: |
280 | void swap(CZString& other); |
281 | |
282 | struct StringStorage { |
283 | unsigned policy_ : 2; |
284 | unsigned length_ : 30; // 1GB max |
285 | }; |
286 | |
287 | char const* cstr_; // actually, a prefixed string, unless policy is noDup |
288 | union { |
289 | ArrayIndex index_; |
290 | StringStorage storage_; |
291 | }; |
292 | }; |
293 | |
294 | public: |
295 | typedef std::map<CZString, Value> ObjectValues; |
296 | #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION |
297 | |
298 | public: |
299 | /** |
300 | * \brief Create a default Value of the given type. |
301 | * |
302 | * This is a very useful constructor. |
303 | * To create an empty array, pass arrayValue. |
304 | * To create an empty object, pass objectValue. |
305 | * Another Value can then be set to this one by assignment. |
306 | * This is useful since clear() and resize() will not alter types. |
307 | * |
308 | * Examples: |
309 | * \code |
310 | * Json::Value null_value; // null |
311 | * Json::Value arr_value(Json::arrayValue); // [] |
312 | * Json::Value obj_value(Json::objectValue); // {} |
313 | * \endcode |
314 | */ |
315 | Value(ValueType type = nullValue); |
316 | Value(Int value); |
317 | Value(UInt value); |
318 | #if defined(JSON_HAS_INT64) |
319 | Value(Int64 value); |
320 | Value(UInt64 value); |
321 | #endif // if defined(JSON_HAS_INT64) |
322 | Value(double value); |
323 | Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) |
324 | Value(const char* begin, const char* end); ///< Copy all, incl zeroes. |
325 | /** |
326 | * \brief Constructs a value from a static string. |
327 | * |
328 | * Like other value string constructor but do not duplicate the string for |
329 | * internal storage. The given string must remain alive after the call to |
330 | * this constructor. |
331 | * |
332 | * \note This works only for null-terminated strings. (We cannot change the |
333 | * size of this class, so we have nowhere to store the length, which might be |
334 | * computed later for various operations.) |
335 | * |
336 | * Example of usage: |
337 | * \code |
338 | * static StaticString foo("some text"); |
339 | * Json::Value aValue(foo); |
340 | * \endcode |
341 | */ |
342 | Value(const StaticString& value); |
343 | Value(const String& value); |
344 | Value(bool value); |
345 | Value(std::nullptr_t ptr) = delete; |
346 | Value(const Value& other); |
347 | Value(Value&& other); |
348 | ~Value(); |
349 | |
350 | /// \note Overwrite existing comments. To preserve comments, use |
351 | /// #swapPayload(). |
352 | Value& operator=(const Value& other); |
353 | Value& operator=(Value&& other); |
354 | |
355 | /// Swap everything. |
356 | void swap(Value& other); |
357 | /// Swap values but leave comments and source offsets in place. |
358 | void swapPayload(Value& other); |
359 | |
360 | /// copy everything. |
361 | void copy(const Value& other); |
362 | /// copy values but leave comments and source offsets in place. |
363 | void copyPayload(const Value& other); |
364 | |
365 | ValueType type() const; |
366 | |
367 | /// Compare payload only, not comments etc. |
368 | bool operator<(const Value& other) const; |
369 | bool operator<=(const Value& other) const; |
370 | bool operator>=(const Value& other) const; |
371 | bool operator>(const Value& other) const; |
372 | bool operator==(const Value& other) const; |
373 | bool operator!=(const Value& other) const; |
374 | int compare(const Value& other) const; |
375 | |
376 | const char* asCString() const; ///< Embedded zeroes could cause you trouble! |
377 | #if JSONCPP_USING_SECURE_MEMORY |
378 | unsigned getCStringLength() const; // Allows you to understand the length of |
379 | // the CString |
380 | #endif |
381 | String asString() const; ///< Embedded zeroes are possible. |
382 | /** Get raw char* of string-value. |
383 | * \return false if !string. (Seg-fault if str or end are NULL.) |
384 | */ |
385 | bool getString(char const** begin, char const** end) const; |
386 | Int asInt() const; |
387 | UInt asUInt() const; |
388 | #if defined(JSON_HAS_INT64) |
389 | Int64 asInt64() const; |
390 | UInt64 asUInt64() const; |
391 | #endif // if defined(JSON_HAS_INT64) |
392 | LargestInt asLargestInt() const; |
393 | LargestUInt asLargestUInt() const; |
394 | float asFloat() const; |
395 | double asDouble() const; |
396 | bool asBool() const; |
397 | |
398 | bool isNull() const; |
399 | bool isBool() const; |
400 | bool isInt() const; |
401 | bool isInt64() const; |
402 | bool isUInt() const; |
403 | bool isUInt64() const; |
404 | bool isIntegral() const; |
405 | bool isDouble() const; |
406 | bool isNumeric() const; |
407 | bool isString() const; |
408 | bool isArray() const; |
409 | bool isObject() const; |
410 | |
411 | /// The `as<T>` and `is<T>` member function templates and specializations. |
412 | template <typename T> T as() const JSONCPP_TEMPLATE_DELETE; |
413 | template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE; |
414 | |
415 | bool isConvertibleTo(ValueType other) const; |
416 | |
417 | /// Number of values in array or object |
418 | ArrayIndex size() const; |
419 | |
420 | /// \brief Return true if empty array, empty object, or null; |
421 | /// otherwise, false. |
422 | bool empty() const; |
423 | |
424 | /// Return !isNull() |
425 | explicit operator bool() const; |
426 | |
427 | /// Remove all object members and array elements. |
428 | /// \pre type() is arrayValue, objectValue, or nullValue |
429 | /// \post type() is unchanged |
430 | void clear(); |
431 | |
432 | /// Resize the array to newSize elements. |
433 | /// New elements are initialized to null. |
434 | /// May only be called on nullValue or arrayValue. |
435 | /// \pre type() is arrayValue or nullValue |
436 | /// \post type() is arrayValue |
437 | void resize(ArrayIndex newSize); |
438 | |
439 | //@{ |
440 | /// Access an array element (zero based index). If the array contains less |
441 | /// than index element, then null value are inserted in the array so that |
442 | /// its size is index+1. |
443 | /// (You may need to say 'value[0u]' to get your compiler to distinguish |
444 | /// this from the operator[] which takes a string.) |
445 | Value& operator[](ArrayIndex index); |
446 | Value& operator[](int index); |
447 | //@} |
448 | |
449 | //@{ |
450 | /// Access an array element (zero based index). |
451 | /// (You may need to say 'value[0u]' to get your compiler to distinguish |
452 | /// this from the operator[] which takes a string.) |
453 | const Value& operator[](ArrayIndex index) const; |
454 | const Value& operator[](int index) const; |
455 | //@} |
456 | |
457 | /// If the array contains at least index+1 elements, returns the element |
458 | /// value, otherwise returns defaultValue. |
459 | Value get(ArrayIndex index, const Value& defaultValue) const; |
460 | /// Return true if index < size(). |
461 | bool isValidIndex(ArrayIndex index) const; |
462 | /// \brief Append value to array at the end. |
463 | /// |
464 | /// Equivalent to jsonvalue[jsonvalue.size()] = value; |
465 | Value& append(const Value& value); |
466 | Value& append(Value&& value); |
467 | |
468 | /// \brief Insert value in array at specific index |
469 | bool insert(ArrayIndex index, const Value& newValue); |
470 | bool insert(ArrayIndex index, Value&& newValue); |
471 | |
472 | /// Access an object value by name, create a null member if it does not exist. |
473 | /// \note Because of our implementation, keys are limited to 2^30 -1 chars. |
474 | /// Exceeding that will cause an exception. |
475 | Value& operator[](const char* key); |
476 | /// Access an object value by name, returns null if there is no member with |
477 | /// that name. |
478 | const Value& operator[](const char* key) const; |
479 | /// Access an object value by name, create a null member if it does not exist. |
480 | /// \param key may contain embedded nulls. |
481 | Value& operator[](const String& key); |
482 | /// Access an object value by name, returns null if there is no member with |
483 | /// that name. |
484 | /// \param key may contain embedded nulls. |
485 | const Value& operator[](const String& key) const; |
486 | /** \brief Access an object value by name, create a null member if it does not |
487 | * exist. |
488 | * |
489 | * If the object has no entry for that name, then the member name used to |
490 | * store the new entry is not duplicated. |
491 | * Example of use: |
492 | * \code |
493 | * Json::Value object; |
494 | * static const StaticString code("code"); |
495 | * object[code] = 1234; |
496 | * \endcode |
497 | */ |
498 | Value& operator[](const StaticString& key); |
499 | /// Return the member named key if it exist, defaultValue otherwise. |
500 | /// \note deep copy |
501 | Value get(const char* key, const Value& defaultValue) const; |
502 | /// Return the member named key if it exist, defaultValue otherwise. |
503 | /// \note deep copy |
504 | /// \note key may contain embedded nulls. |
505 | Value get(const char* begin, const char* end, |
506 | const Value& defaultValue) const; |
507 | /// Return the member named key if it exist, defaultValue otherwise. |
508 | /// \note deep copy |
509 | /// \param key may contain embedded nulls. |
510 | Value get(const String& key, const Value& defaultValue) const; |
511 | /// Most general and efficient version of isMember()const, get()const, |
512 | /// and operator[]const |
513 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 |
514 | Value const* find(char const* begin, char const* end) const; |
515 | /// Most general and efficient version of object-mutators. |
516 | /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 |
517 | /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. |
518 | Value* demand(char const* begin, char const* end); |
519 | /// \brief Remove and return the named member. |
520 | /// |
521 | /// Do nothing if it did not exist. |
522 | /// \pre type() is objectValue or nullValue |
523 | /// \post type() is unchanged |
524 | void removeMember(const char* key); |
525 | /// Same as removeMember(const char*) |
526 | /// \param key may contain embedded nulls. |
527 | void removeMember(const String& key); |
528 | /// Same as removeMember(const char* begin, const char* end, Value* removed), |
529 | /// but 'key' is null-terminated. |
530 | bool removeMember(const char* key, Value* removed); |
531 | /** \brief Remove the named map member. |
532 | * |
533 | * Update 'removed' iff removed. |
534 | * \param key may contain embedded nulls. |
535 | * \return true iff removed (no exceptions) |
536 | */ |
537 | bool removeMember(String const& key, Value* removed); |
538 | /// Same as removeMember(String const& key, Value* removed) |
539 | bool removeMember(const char* begin, const char* end, Value* removed); |
540 | /** \brief Remove the indexed array element. |
541 | * |
542 | * O(n) expensive operations. |
543 | * Update 'removed' iff removed. |
544 | * \return true if removed (no exceptions) |
545 | */ |
546 | bool removeIndex(ArrayIndex index, Value* removed); |
547 | |
548 | /// Return true if the object has a member named key. |
549 | /// \note 'key' must be null-terminated. |
550 | bool isMember(const char* key) const; |
551 | /// Return true if the object has a member named key. |
552 | /// \param key may contain embedded nulls. |
553 | bool isMember(const String& key) const; |
554 | /// Same as isMember(String const& key)const |
555 | bool isMember(const char* begin, const char* end) const; |
556 | |
557 | /// \brief Return a list of the member names. |
558 | /// |
559 | /// If null, return an empty list. |
560 | /// \pre type() is objectValue or nullValue |
561 | /// \post if type() was nullValue, it remains nullValue |
562 | Members getMemberNames() const; |
563 | |
564 | /// \deprecated Always pass len. |
565 | JSONCPP_DEPRECATED("Use setComment(String const&) instead." ) |
566 | void (const char* , CommentPlacement placement) { |
567 | setComment(String(comment, strlen(comment)), placement); |
568 | } |
569 | /// Comments must be //... or /* ... */ |
570 | void (const char* , size_t len, CommentPlacement placement) { |
571 | setComment(String(comment, len), placement); |
572 | } |
573 | /// Comments must be //... or /* ... */ |
574 | void (String , CommentPlacement placement); |
575 | bool (CommentPlacement placement) const; |
576 | /// Include delimiters and embedded newlines. |
577 | String (CommentPlacement placement) const; |
578 | |
579 | String toStyledString() const; |
580 | |
581 | const_iterator begin() const; |
582 | const_iterator end() const; |
583 | |
584 | iterator begin(); |
585 | iterator end(); |
586 | |
587 | // Accessors for the [start, limit) range of bytes within the JSON text from |
588 | // which this value was parsed, if any. |
589 | void setOffsetStart(ptrdiff_t start); |
590 | void setOffsetLimit(ptrdiff_t limit); |
591 | ptrdiff_t getOffsetStart() const; |
592 | ptrdiff_t getOffsetLimit() const; |
593 | |
594 | private: |
595 | void setType(ValueType v) { |
596 | bits_.value_type_ = static_cast<unsigned char>(v); |
597 | } |
598 | bool isAllocated() const { return bits_.allocated_; } |
599 | void setIsAllocated(bool v) { bits_.allocated_ = v; } |
600 | |
601 | void initBasic(ValueType type, bool allocated = false); |
602 | void dupPayload(const Value& other); |
603 | void releasePayload(); |
604 | void dupMeta(const Value& other); |
605 | |
606 | Value& resolveReference(const char* key); |
607 | Value& resolveReference(const char* key, const char* end); |
608 | |
609 | // struct MemberNamesTransform |
610 | //{ |
611 | // typedef const char *result_type; |
612 | // const char *operator()( const CZString &name ) const |
613 | // { |
614 | // return name.c_str(); |
615 | // } |
616 | //}; |
617 | |
618 | union ValueHolder { |
619 | LargestInt int_; |
620 | LargestUInt uint_; |
621 | double real_; |
622 | bool bool_; |
623 | char* string_; // if allocated_, ptr to { unsigned, char[] }. |
624 | ObjectValues* map_; |
625 | } value_; |
626 | |
627 | struct { |
628 | // Really a ValueType, but types should agree for bitfield packing. |
629 | unsigned int value_type_ : 8; |
630 | // Unless allocated_, string_ must be null-terminated. |
631 | unsigned int allocated_ : 1; |
632 | } bits_; |
633 | |
634 | class { |
635 | public: |
636 | () = default; |
637 | (const Comments& that); |
638 | (Comments&& that); |
639 | Comments& (const Comments& that); |
640 | Comments& (Comments&& that); |
641 | bool (CommentPlacement slot) const; |
642 | String (CommentPlacement slot) const; |
643 | void (CommentPlacement slot, String ); |
644 | |
645 | private: |
646 | using = std::array<String, numberOfCommentPlacement>; |
647 | std::unique_ptr<Array> ; |
648 | }; |
649 | Comments ; |
650 | |
651 | // [start, limit) byte offsets in the source JSON text from which this Value |
652 | // was extracted. |
653 | ptrdiff_t start_; |
654 | ptrdiff_t limit_; |
655 | }; |
656 | |
657 | template <> inline bool Value::as<bool>() const { return asBool(); } |
658 | template <> inline bool Value::is<bool>() const { return isBool(); } |
659 | |
660 | template <> inline Int Value::as<Int>() const { return asInt(); } |
661 | template <> inline bool Value::is<Int>() const { return isInt(); } |
662 | |
663 | template <> inline UInt Value::as<UInt>() const { return asUInt(); } |
664 | template <> inline bool Value::is<UInt>() const { return isUInt(); } |
665 | |
666 | #if defined(JSON_HAS_INT64) |
667 | template <> inline Int64 Value::as<Int64>() const { return asInt64(); } |
668 | template <> inline bool Value::is<Int64>() const { return isInt64(); } |
669 | |
670 | template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); } |
671 | template <> inline bool Value::is<UInt64>() const { return isUInt64(); } |
672 | #endif |
673 | |
674 | template <> inline double Value::as<double>() const { return asDouble(); } |
675 | template <> inline bool Value::is<double>() const { return isDouble(); } |
676 | |
677 | template <> inline String Value::as<String>() const { return asString(); } |
678 | template <> inline bool Value::is<String>() const { return isString(); } |
679 | |
680 | /// These `as` specializations are type conversions, and do not have a |
681 | /// corresponding `is`. |
682 | template <> inline float Value::as<float>() const { return asFloat(); } |
683 | template <> inline const char* Value::as<const char*>() const { |
684 | return asCString(); |
685 | } |
686 | |
687 | /** \brief Experimental and untested: represents an element of the "path" to |
688 | * access a node. |
689 | */ |
690 | class JSON_API PathArgument { |
691 | public: |
692 | friend class Path; |
693 | |
694 | PathArgument(); |
695 | PathArgument(ArrayIndex index); |
696 | PathArgument(const char* key); |
697 | PathArgument(String key); |
698 | |
699 | private: |
700 | enum Kind { kindNone = 0, kindIndex, kindKey }; |
701 | String key_; |
702 | ArrayIndex index_{}; |
703 | Kind kind_{kindNone}; |
704 | }; |
705 | |
706 | /** \brief Experimental and untested: represents a "path" to access a node. |
707 | * |
708 | * Syntax: |
709 | * - "." => root node |
710 | * - ".[n]" => elements at index 'n' of root node (an array value) |
711 | * - ".name" => member named 'name' of root node (an object value) |
712 | * - ".name1.name2.name3" |
713 | * - ".[0][1][2].name1[3]" |
714 | * - ".%" => member name is provided as parameter |
715 | * - ".[%]" => index is provided as parameter |
716 | */ |
717 | class JSON_API Path { |
718 | public: |
719 | Path(const String& path, const PathArgument& a1 = PathArgument(), |
720 | const PathArgument& a2 = PathArgument(), |
721 | const PathArgument& a3 = PathArgument(), |
722 | const PathArgument& a4 = PathArgument(), |
723 | const PathArgument& a5 = PathArgument()); |
724 | |
725 | const Value& resolve(const Value& root) const; |
726 | Value resolve(const Value& root, const Value& defaultValue) const; |
727 | /// Creates the "path" to access the specified node and returns a reference on |
728 | /// the node. |
729 | Value& make(Value& root) const; |
730 | |
731 | private: |
732 | using InArgs = std::vector<const PathArgument*>; |
733 | using Args = std::vector<PathArgument>; |
734 | |
735 | void makePath(const String& path, const InArgs& in); |
736 | void addPathInArg(const String& path, const InArgs& in, |
737 | InArgs::const_iterator& itInArg, PathArgument::Kind kind); |
738 | static void invalidPath(const String& path, int location); |
739 | |
740 | Args args_; |
741 | }; |
742 | |
743 | /** \brief base class for Value iterators. |
744 | * |
745 | */ |
746 | class JSON_API ValueIteratorBase { |
747 | public: |
748 | using iterator_category = std::bidirectional_iterator_tag; |
749 | using size_t = unsigned int; |
750 | using difference_type = int; |
751 | using SelfType = ValueIteratorBase; |
752 | |
753 | bool operator==(const SelfType& other) const { return isEqual(other); } |
754 | |
755 | bool operator!=(const SelfType& other) const { return !isEqual(other); } |
756 | |
757 | difference_type operator-(const SelfType& other) const { |
758 | return other.computeDistance(*this); |
759 | } |
760 | |
761 | /// Return either the index or the member name of the referenced value as a |
762 | /// Value. |
763 | Value key() const; |
764 | |
765 | /// Return the index of the referenced Value, or -1 if it is not an |
766 | /// arrayValue. |
767 | UInt index() const; |
768 | |
769 | /// Return the member name of the referenced Value, or "" if it is not an |
770 | /// objectValue. |
771 | /// \note Avoid `c_str()` on result, as embedded zeroes are possible. |
772 | String name() const; |
773 | |
774 | /// Return the member name of the referenced Value. "" if it is not an |
775 | /// objectValue. |
776 | /// \deprecated This cannot be used for UTF-8 strings, since there can be |
777 | /// embedded nulls. |
778 | JSONCPP_DEPRECATED("Use `key = name();` instead." ) |
779 | char const* memberName() const; |
780 | /// Return the member name of the referenced Value, or NULL if it is not an |
781 | /// objectValue. |
782 | /// \note Better version than memberName(). Allows embedded nulls. |
783 | char const* memberName(char const** end) const; |
784 | |
785 | protected: |
786 | /*! Internal utility functions to assist with implementing |
787 | * other iterator functions. The const and non-const versions |
788 | * of the "deref" protected methods expose the protected |
789 | * current_ member variable in a way that can often be |
790 | * optimized away by the compiler. |
791 | */ |
792 | const Value& deref() const; |
793 | Value& deref(); |
794 | |
795 | void increment(); |
796 | |
797 | void decrement(); |
798 | |
799 | difference_type computeDistance(const SelfType& other) const; |
800 | |
801 | bool isEqual(const SelfType& other) const; |
802 | |
803 | void copy(const SelfType& other); |
804 | |
805 | private: |
806 | Value::ObjectValues::iterator current_; |
807 | // Indicates that iterator is for a null value. |
808 | bool isNull_{true}; |
809 | |
810 | public: |
811 | // For some reason, BORLAND needs these at the end, rather |
812 | // than earlier. No idea why. |
813 | ValueIteratorBase(); |
814 | explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); |
815 | }; |
816 | |
817 | /** \brief const iterator for object and array value. |
818 | * |
819 | */ |
820 | class JSON_API ValueConstIterator : public ValueIteratorBase { |
821 | friend class Value; |
822 | |
823 | public: |
824 | using value_type = const Value; |
825 | // typedef unsigned int size_t; |
826 | // typedef int difference_type; |
827 | using reference = const Value&; |
828 | using pointer = const Value*; |
829 | using SelfType = ValueConstIterator; |
830 | |
831 | ValueConstIterator(); |
832 | ValueConstIterator(ValueIterator const& other); |
833 | |
834 | private: |
835 | /*! \internal Use by Value to create an iterator. |
836 | */ |
837 | explicit ValueConstIterator(const Value::ObjectValues::iterator& current); |
838 | |
839 | public: |
840 | SelfType& operator=(const ValueIteratorBase& other); |
841 | |
842 | SelfType operator++(int) { |
843 | SelfType temp(*this); |
844 | ++*this; |
845 | return temp; |
846 | } |
847 | |
848 | SelfType operator--(int) { |
849 | SelfType temp(*this); |
850 | --*this; |
851 | return temp; |
852 | } |
853 | |
854 | SelfType& operator--() { |
855 | decrement(); |
856 | return *this; |
857 | } |
858 | |
859 | SelfType& operator++() { |
860 | increment(); |
861 | return *this; |
862 | } |
863 | |
864 | reference operator*() const { return deref(); } |
865 | |
866 | pointer operator->() const { return &deref(); } |
867 | }; |
868 | |
869 | /** \brief Iterator for object and array value. |
870 | */ |
871 | class JSON_API ValueIterator : public ValueIteratorBase { |
872 | friend class Value; |
873 | |
874 | public: |
875 | using value_type = Value; |
876 | using size_t = unsigned int; |
877 | using difference_type = int; |
878 | using reference = Value&; |
879 | using pointer = Value*; |
880 | using SelfType = ValueIterator; |
881 | |
882 | ValueIterator(); |
883 | explicit ValueIterator(const ValueConstIterator& other); |
884 | ValueIterator(const ValueIterator& other); |
885 | |
886 | private: |
887 | /*! \internal Use by Value to create an iterator. |
888 | */ |
889 | explicit ValueIterator(const Value::ObjectValues::iterator& current); |
890 | |
891 | public: |
892 | SelfType& operator=(const SelfType& other); |
893 | |
894 | SelfType operator++(int) { |
895 | SelfType temp(*this); |
896 | ++*this; |
897 | return temp; |
898 | } |
899 | |
900 | SelfType operator--(int) { |
901 | SelfType temp(*this); |
902 | --*this; |
903 | return temp; |
904 | } |
905 | |
906 | SelfType& operator--() { |
907 | decrement(); |
908 | return *this; |
909 | } |
910 | |
911 | SelfType& operator++() { |
912 | increment(); |
913 | return *this; |
914 | } |
915 | |
916 | /*! The return value of non-const iterators can be |
917 | * changed, so the these functions are not const |
918 | * because the returned references/pointers can be used |
919 | * to change state of the base class. |
920 | */ |
921 | reference operator*() { return deref(); } |
922 | pointer operator->() { return &deref(); } |
923 | }; |
924 | |
925 | inline void swap(Value& a, Value& b) { a.swap(b); } |
926 | |
927 | } // namespace Json |
928 | |
929 | #pragma pack(pop) |
930 | |
931 | #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) |
932 | #pragma warning(pop) |
933 | #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) |
934 | |
935 | #endif // JSON_H_INCLUDED |
936 | |