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