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