JsonCpp project page Classes Namespace JsonCpp home page

value.h
Go to the documentation of this file.
1 // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2 // Distributed under MIT license, or public domain if desired and
3 // recognized in your jurisdiction.
4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 
6 #ifndef JSON_H_INCLUDED
7 #define JSON_H_INCLUDED
8 
9 #if !defined(JSON_IS_AMALGAMATION)
10 #include "forwards.h"
11 #endif // if !defined(JSON_IS_AMALGAMATION)
12 
13 // Conditional NORETURN attribute on the throw functions would:
14 // a) suppress false positives from static code analysis
15 // b) possibly improve optimization opportunities.
16 #if !defined(JSONCPP_NORETURN)
17 #if defined(_MSC_VER) && _MSC_VER == 1800
18 #define JSONCPP_NORETURN __declspec(noreturn)
19 #else
20 #define JSONCPP_NORETURN [[noreturn]]
21 #endif
22 #endif
23 
24 // Support for '= delete' with template declarations was a late addition
25 // to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2
26 // even though these declare themselves to be c++11 compilers.
27 #if !defined(JSONCPP_TEMPLATE_DELETE)
28 #if defined(__clang__) && defined(__apple_build_version__)
29 #if __apple_build_version__ <= 8000042
30 #define JSONCPP_TEMPLATE_DELETE
31 #endif
32 #elif defined(__clang__)
33 #if __clang_major__ == 3 && __clang_minor__ <= 8
34 #define JSONCPP_TEMPLATE_DELETE
35 #endif
36 #endif
37 #if !defined(JSONCPP_TEMPLATE_DELETE)
38 #define JSONCPP_TEMPLATE_DELETE = delete
39 #endif
40 #endif
41 
42 #include <array>
43 #include <exception>
44 #include <map>
45 #include <memory>
46 #include <string>
47 #include <vector>
48 
49 // Disable warning C4251: <data member>: <type> needs to have dll-interface to
50 // be used by...
51 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
52 #pragma warning(push)
53 #pragma warning(disable : 4251)
54 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
55 
56 #pragma pack(push, 8)
57 
60 namespace Json {
61 
62 #if JSON_USE_EXCEPTION
63 
67 class JSON_API Exception : public std::exception {
68 public:
69  Exception(String msg);
70  ~Exception() noexcept override;
71  char const* what() const noexcept override;
72 
73 protected:
75 };
76 
84 public:
85  RuntimeError(String const& msg);
86 };
87 
94 class JSON_API LogicError : public Exception {
95 public:
96  LogicError(String const& msg);
97 };
98 #endif
99 
101 JSONCPP_NORETURN void throwRuntimeError(String const& msg);
103 JSONCPP_NORETURN void throwLogicError(String const& msg);
104 
107 enum ValueType {
108  nullValue = 0,
116 };
117 
124 };
125 
131 };
132 
148 public:
149  explicit StaticString(const char* czstring) : c_str_(czstring) {}
150 
151  operator const char*() const { return c_str_; }
152 
153  const char* c_str() const { return c_str_; }
154 
155 private:
156  const char* c_str_;
157 };
158 
194  friend class ValueIteratorBase;
195 
196 public:
197  using Members = std::vector<String>;
200  using UInt = Json::UInt;
201  using Int = Json::Int;
202 #if defined(JSON_HAS_INT64)
205 #endif // defined(JSON_HAS_INT64)
209 
210  // Required for boost integration, e. g. BOOST_TEST
211  using value_type = std::string;
212 
213 #if JSON_USE_NULLREF
214  // Binary compatibility kludges, do not use.
215  static const Value& null;
216  static const Value& nullRef;
217 #endif
218 
219  // null and nullRef are deprecated, use this instead.
220  static Value const& nullSingleton();
221 
223  static constexpr LargestInt minLargestInt =
224  LargestInt(~(LargestUInt(-1) / 2));
226  static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2);
228  static constexpr LargestUInt maxLargestUInt = LargestUInt(-1);
229 
231  static constexpr Int minInt = Int(~(UInt(-1) / 2));
233  static constexpr Int maxInt = Int(UInt(-1) / 2);
235  static constexpr UInt maxUInt = UInt(-1);
236 
237 #if defined(JSON_HAS_INT64)
238  static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2));
241  static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2);
243  static constexpr UInt64 maxUInt64 = UInt64(-1);
244 #endif // defined(JSON_HAS_INT64)
245  static constexpr UInt defaultRealPrecision = 17;
247  // The constant is hard-coded because some compiler have trouble
248  // converting Value::maxUInt64 to a double correctly (AIX/xlC).
249  // Assumes that UInt64 is a 64 bits integer.
250  static constexpr double maxUInt64AsDouble = 18446744073709551615.0;
251 // Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
252 // when using gcc and clang backend compilers. CZString
253 // cannot be defined as private. See issue #486
254 #ifdef __NVCC__
255 public:
256 #else
257 private:
258 #endif
259 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
260  class CZString {
261  public:
262  enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
263  CZString(ArrayIndex index);
264  CZString(char const* str, unsigned length, DuplicationPolicy allocate);
265  CZString(CZString const& other);
266  CZString(CZString&& other);
267  ~CZString();
268  CZString& operator=(const CZString& other);
269  CZString& operator=(CZString&& other);
270 
271  bool operator<(CZString const& other) const;
272  bool operator==(CZString const& other) const;
273  ArrayIndex index() const;
274  // const char* c_str() const; ///< \deprecated
275  char const* data() const;
276  unsigned length() const;
277  bool isStaticString() const;
278 
279  private:
280  void swap(CZString& other);
281 
282  struct StringStorage {
283  unsigned policy_ : 2;
284  unsigned length_ : 30; // 1GB max
285  };
286 
287  char const* cstr_; // actually, a prefixed string, unless policy is noDup
288  union {
289  ArrayIndex index_;
290  StringStorage storage_;
291  };
292  };
293 
294 public:
295  typedef std::map<CZString, Value> ObjectValues;
296 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
297 
298 public:
315  Value(ValueType type = nullValue);
316  Value(Int value);
317  Value(UInt value);
318 #if defined(JSON_HAS_INT64)
319  Value(Int64 value);
320  Value(UInt64 value);
321 #endif // if defined(JSON_HAS_INT64)
322  Value(double value);
323  Value(const char* value);
324  Value(const char* begin, const char* end);
325 
342  Value(const StaticString& value);
343  Value(const String& value);
344  Value(bool value);
345  Value(const Value& other);
346  Value(Value&& other);
347  ~Value();
348 
351  Value& operator=(const Value& other);
352  Value& operator=(Value&& other);
353 
355  void swap(Value& other);
357  void swapPayload(Value& other);
358 
360  void copy(const Value& other);
362  void copyPayload(const Value& other);
363 
364  ValueType type() const;
365 
367  bool operator<(const Value& other) const;
368  bool operator<=(const Value& other) const;
369  bool operator>=(const Value& other) const;
370  bool operator>(const Value& other) const;
371  bool operator==(const Value& other) const;
372  bool operator!=(const Value& other) const;
373  int compare(const Value& other) const;
374 
375  const char* asCString() const;
376 #if JSONCPP_USING_SECURE_MEMORY
377  unsigned getCStringLength() const; // Allows you to understand the length of
378  // the CString
379 #endif
380  String asString() const;
381 
384  bool getString(char const** begin, char const** end) const;
385  Int asInt() const;
386  UInt asUInt() const;
387 #if defined(JSON_HAS_INT64)
388  Int64 asInt64() const;
389  UInt64 asUInt64() const;
390 #endif // if defined(JSON_HAS_INT64)
391  LargestInt asLargestInt() const;
392  LargestUInt asLargestUInt() const;
393  float asFloat() const;
394  double asDouble() const;
395  bool asBool() const;
396 
397  bool isNull() const;
398  bool isBool() const;
399  bool isInt() const;
400  bool isInt64() const;
401  bool isUInt() const;
402  bool isUInt64() const;
403  bool isIntegral() const;
404  bool isDouble() const;
405  bool isNumeric() const;
406  bool isString() const;
407  bool isArray() const;
408  bool isObject() const;
409 
411  template <typename T> T as() const JSONCPP_TEMPLATE_DELETE;
412  template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE;
413 
414  bool isConvertibleTo(ValueType other) const;
415 
417  ArrayIndex size() const;
418 
421  bool empty() const;
422 
424  explicit operator bool() const;
425 
429  void clear();
430 
436  void resize(ArrayIndex newSize);
437 
439  Value& operator[](ArrayIndex index);
445  Value& operator[](int index);
447 
449  const Value& operator[](ArrayIndex index) const;
453  const Value& operator[](int index) const;
455 
458  Value get(ArrayIndex index, const Value& defaultValue) const;
460  bool isValidIndex(ArrayIndex index) const;
464  Value& append(const Value& value);
465  Value& append(Value&& value);
466 
468  bool insert(ArrayIndex index, const Value& newValue);
469  bool insert(ArrayIndex index, Value&& newValue);
470 
474  Value& operator[](const char* key);
477  const Value& operator[](const char* key) const;
480  Value& operator[](const String& key);
484  const Value& operator[](const String& key) const;
497  Value& operator[](const StaticString& key);
500  Value get(const char* key, const Value& defaultValue) const;
504  Value get(const char* begin, const char* end,
505  const Value& defaultValue) const;
509  Value get(const String& key, const Value& defaultValue) const;
513  Value const* find(char const* begin, char const* end) const;
517  Value* demand(char const* begin, char const* end);
523  void removeMember(const char* key);
526  void removeMember(const String& key);
529  bool removeMember(const char* key, Value* removed);
536  bool removeMember(String const& key, Value* removed);
538  bool removeMember(const char* begin, const char* end, Value* removed);
545  bool removeIndex(ArrayIndex index, Value* removed);
546 
549  bool isMember(const char* key) const;
552  bool isMember(const String& key) const;
554  bool isMember(const char* begin, const char* end) const;
555 
561  Members getMemberNames() const;
562 
564  JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
565  void setComment(const char* comment, CommentPlacement placement) {
566  setComment(String(comment, strlen(comment)), placement);
567  }
569  void setComment(const char* comment, size_t len, CommentPlacement placement) {
570  setComment(String(comment, len), placement);
571  }
573  void setComment(String comment, CommentPlacement placement);
574  bool hasComment(CommentPlacement placement) const;
576  String getComment(CommentPlacement placement) const;
577 
578  String toStyledString() const;
579 
580  const_iterator begin() const;
581  const_iterator end() const;
582 
583  iterator begin();
584  iterator end();
585 
586  // Accessors for the [start, limit) range of bytes within the JSON text from
587  // which this value was parsed, if any.
588  void setOffsetStart(ptrdiff_t start);
589  void setOffsetLimit(ptrdiff_t limit);
590  ptrdiff_t getOffsetStart() const;
591  ptrdiff_t getOffsetLimit() const;
592 
593 private:
594  void setType(ValueType v) {
595  bits_.value_type_ = static_cast<unsigned char>(v);
596  }
597  bool isAllocated() const { return bits_.allocated_; }
598  void setIsAllocated(bool v) { bits_.allocated_ = v; }
599 
600  void initBasic(ValueType type, bool allocated = false);
601  void dupPayload(const Value& other);
602  void releasePayload();
603  void dupMeta(const Value& other);
604 
605  Value& resolveReference(const char* key);
606  Value& resolveReference(const char* key, const char* end);
607 
608  // struct MemberNamesTransform
609  //{
610  // typedef const char *result_type;
611  // const char *operator()( const CZString &name ) const
612  // {
613  // return name.c_str();
614  // }
615  //};
616 
617  union ValueHolder {
618  LargestInt int_;
619  LargestUInt uint_;
620  double real_;
621  bool bool_;
622  char* string_; // if allocated_, ptr to { unsigned, char[] }.
623  ObjectValues* map_;
624  } value_;
625 
626  struct {
627  // Really a ValueType, but types should agree for bitfield packing.
628  unsigned int value_type_ : 8;
629  // Unless allocated_, string_ must be null-terminated.
630  unsigned int allocated_ : 1;
631  } bits_;
632 
633  class Comments {
634  public:
635  Comments() = default;
636  Comments(const Comments& that);
637  Comments(Comments&& that);
638  Comments& operator=(const Comments& that);
639  Comments& operator=(Comments&& that);
640  bool has(CommentPlacement slot) const;
641  String get(CommentPlacement slot) const;
642  void set(CommentPlacement slot, String comment);
643 
644  private:
645  using Array = std::array<String, numberOfCommentPlacement>;
646  std::unique_ptr<Array> ptr_;
647  };
648  Comments comments_;
649 
650  // [start, limit) byte offsets in the source JSON text from which this Value
651  // was extracted.
652  ptrdiff_t start_;
653  ptrdiff_t limit_;
654 };
655 
656 template <> inline bool Value::as<bool>() const { return asBool(); }
657 template <> inline bool Value::is<bool>() const { return isBool(); }
658 
659 template <> inline Int Value::as<Int>() const { return asInt(); }
660 template <> inline bool Value::is<Int>() const { return isInt(); }
661 
662 template <> inline UInt Value::as<UInt>() const { return asUInt(); }
663 template <> inline bool Value::is<UInt>() const { return isUInt(); }
664 
665 #if defined(JSON_HAS_INT64)
666 template <> inline Int64 Value::as<Int64>() const { return asInt64(); }
667 template <> inline bool Value::is<Int64>() const { return isInt64(); }
668 
669 template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); }
670 template <> inline bool Value::is<UInt64>() const { return isUInt64(); }
671 #endif
672 
673 template <> inline double Value::as<double>() const { return asDouble(); }
674 template <> inline bool Value::is<double>() const { return isDouble(); }
675 
676 template <> inline String Value::as<String>() const { return asString(); }
677 template <> inline bool Value::is<String>() const { return isString(); }
678 
681 template <> inline float Value::as<float>() const { return asFloat(); }
682 template <> inline const char* Value::as<const char*>() const {
683  return asCString();
684 }
685 
690 public:
691  friend class Path;
692 
693  PathArgument();
694  PathArgument(ArrayIndex index);
695  PathArgument(const char* key);
696  PathArgument(String key);
697 
698 private:
699  enum Kind { kindNone = 0, kindIndex, kindKey };
700  String key_;
701  ArrayIndex index_{};
702  Kind kind_{kindNone};
703 };
704 
716 class JSON_API Path {
717 public:
718  Path(const String& path, const PathArgument& a1 = PathArgument(),
719  const PathArgument& a2 = PathArgument(),
720  const PathArgument& a3 = PathArgument(),
721  const PathArgument& a4 = PathArgument(),
722  const PathArgument& a5 = PathArgument());
723 
724  const Value& resolve(const Value& root) const;
725  Value resolve(const Value& root, const Value& defaultValue) const;
728  Value& make(Value& root) const;
729 
730 private:
731  using InArgs = std::vector<const PathArgument*>;
732  using Args = std::vector<PathArgument>;
733 
734  void makePath(const String& path, const InArgs& in);
735  void addPathInArg(const String& path, const InArgs& in,
736  InArgs::const_iterator& itInArg, PathArgument::Kind kind);
737  static void invalidPath(const String& path, int location);
738 
739  Args args_;
740 };
741 
746 public:
747  using iterator_category = std::bidirectional_iterator_tag;
748  using size_t = unsigned int;
749  using difference_type = int;
751 
752  bool operator==(const SelfType& other) const { return isEqual(other); }
753 
754  bool operator!=(const SelfType& other) const { return !isEqual(other); }
755 
756  difference_type operator-(const SelfType& other) const {
757  return other.computeDistance(*this);
758  }
759 
762  Value key() const;
763 
766  UInt index() const;
767 
771  String name() const;
772 
777  JSONCPP_DEPRECATED("Use `key = name();` instead.")
778  char const* memberName() const;
782  char const* memberName(char const** end) const;
783 
784 protected:
791  const Value& deref() const;
792  Value& deref();
793 
794  void increment();
795 
796  void decrement();
797 
798  difference_type computeDistance(const SelfType& other) const;
799 
800  bool isEqual(const SelfType& other) const;
801 
802  void copy(const SelfType& other);
803 
804 private:
805  Value::ObjectValues::iterator current_;
806  // Indicates that iterator is for a null value.
807  bool isNull_{true};
808 
809 public:
810  // For some reason, BORLAND needs these at the end, rather
811  // than earlier. No idea why.
812  ValueIteratorBase();
813  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
814 };
815 
820  friend class Value;
821 
822 public:
823  using value_type = const Value;
824  // typedef unsigned int size_t;
825  // typedef int difference_type;
826  using reference = const Value&;
827  using pointer = const Value*;
829 
831  ValueConstIterator(ValueIterator const& other);
832 
833 private:
836  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
837 
838 public:
839  SelfType& operator=(const ValueIteratorBase& other);
840 
842  SelfType temp(*this);
843  ++*this;
844  return temp;
845  }
846 
848  SelfType temp(*this);
849  --*this;
850  return temp;
851  }
852 
854  decrement();
855  return *this;
856  }
857 
859  increment();
860  return *this;
861  }
862 
863  reference operator*() const { return deref(); }
864 
865  pointer operator->() const { return &deref(); }
866 };
867 
871  friend class Value;
872 
873 public:
874  using value_type = Value;
875  using size_t = unsigned int;
876  using difference_type = int;
877  using reference = Value&;
878  using pointer = Value*;
880 
881  ValueIterator();
882  explicit ValueIterator(const ValueConstIterator& other);
883  ValueIterator(const ValueIterator& other);
884 
885 private:
888  explicit ValueIterator(const Value::ObjectValues::iterator& current);
889 
890 public:
891  SelfType& operator=(const SelfType& other);
892 
894  SelfType temp(*this);
895  ++*this;
896  return temp;
897  }
898 
900  SelfType temp(*this);
901  --*this;
902  return temp;
903  }
904 
906  decrement();
907  return *this;
908  }
909 
911  increment();
912  return *this;
913  }
914 
920  reference operator*() { return deref(); }
921  pointer operator->() { return &deref(); }
922 };
923 
924 inline void swap(Value& a, Value& b) { a.swap(b); }
925 
926 } // namespace Json
927 
928 #pragma pack(pop)
929 
930 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
931 #pragma warning(pop)
932 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
933 
934 #endif // JSON_H_INCLUDED
Json::Int Int
Definition: value.h:201
Json::UInt64 UInt64
Definition: value.h:203
#define JSONCPP_DEPRECATED(message)
Definition: config.h:89
difference_type computeDistance(const SelfType &other) const
#define JSON_API
If defined, indicates that the source file is amalgamated to prevent private header inclusion...
Definition: config.h:50
bool operator!=(const SelfType &other) const
Definition: value.h:754
PrecisionType
Type of precision for formatting of real values.
Definition: value.h:128
base class for Value iterators.
Definition: value.h:745
array value (ordered list)
Definition: value.h:114
Json::Int64 Int64
Definition: value.h:204
#define JSONCPP_TEMPLATE_DELETE
Definition: value.h:38
reference operator*() const
Definition: value.h:863
Json::LargestUInt LargestUInt
Definition: value.h:207
unsigned integer value
Definition: value.h:110
Json::UInt UInt
Definition: value.h:200
bool operator==(const SelfType &other) const
Definition: value.h:752
Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
Definition: value.h:94
void setComment(const char *comment, size_t len, CommentPlacement placement)
Comments must be //... or /* ... */.
Definition: value.h:569
object value (collection of name/value pairs).
Definition: value.h:115
std::bidirectional_iterator_tag iterator_category
Definition: value.h:747
static const Value & null
Definition: value.h:215
Lightweight wrapper to tag static string.
Definition: value.h:147
pointer operator->() const
Definition: value.h:865
static const Value & nullRef
Definition: value.h:216
const iterator for object and array value.
Definition: value.h:819
int Int
Definition: config.h:108
Int64 LargestInt
Definition: config.h:123
#define JSONCPP_NORETURN
Definition: value.h:18
Experimental and untested: represents an element of the "path" to access a node.
Definition: value.h:689
unsigned int ArrayIndex
Definition: forwards.h:32
SelfType & operator--()
Definition: value.h:853
&#39;null&#39; value
Definition: value.h:108
CommentPlacement
Definition: value.h:118
SelfType & operator--()
Definition: value.h:905
StaticString(const char *czstring)
Definition: value.h:149
std::vector< String > Members
Definition: value.h:197
pointer operator->()
Definition: value.h:921
void swap(Value &a, Value &b)
Definition: value.h:924
unsigned int value_type_
Definition: value.h:628
JSON (JavaScript Object Notation).
Definition: allocator.h:14
bool operator==(const SecureAllocator< T > &, const SecureAllocator< U > &)
Definition: allocator.h:76
we set max number of digits after "." in string
Definition: value.h:130
void swap(Value &other)
Swap everything.
Definition: json_value.cpp:466
Experimental and untested: represents a "path" to access a node.
Definition: value.h:716
SelfType operator--(int)
Definition: value.h:847
const char * c_str() const
Definition: value.h:153
double value
Definition: value.h:111
SelfType operator--(int)
Definition: value.h:899
reference operator*()
Definition: value.h:920
SelfType & operator++()
Definition: value.h:910
Json::LargestInt LargestInt
Definition: value.h:206
unsigned int UInt
Definition: config.h:109
Represents a JSON value.
Definition: value.h:193
__int64 Int64
Definition: config.h:117
unsigned __int64 UInt64
Definition: config.h:118
Exceptions which the user cannot easily avoid.
Definition: value.h:83
a comment on the line after a value (only make sense for
Definition: value.h:121
we set max number of significant digits in string
Definition: value.h:129
Iterator for object and array value.
Definition: value.h:870
SelfType & operator++()
Definition: value.h:858
SelfType operator++(int)
Definition: value.h:841
difference_type operator-(const SelfType &other) const
Definition: value.h:756
ValueType
Type of the value held by a Value object.
Definition: value.h:107
bool value
Definition: value.h:113
UInt64 LargestUInt
Definition: config.h:124
signed integer value
Definition: value.h:109
Json::ArrayIndex ArrayIndex
Definition: value.h:208
String msg_
Definition: value.h:74
SelfType operator++(int)
Definition: value.h:893
bool operator!=(const SecureAllocator< T > &, const SecureAllocator< U > &)
Definition: allocator.h:81
a comment placed on the line before a value
Definition: value.h:119
UTF-8 string value.
Definition: value.h:112
a comment just after a value on the same line
Definition: value.h:120
std::string value_type
Definition: value.h:211
unsigned int allocated_
Definition: value.h:630
Base class for all exceptions we throw.
Definition: value.h:67
std::basic_string< char, std::char_traits< char >, Allocator< char > > String
Definition: config.h:132