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