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 4275)
54#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
55
56#pragma pack(push, 8)
57
60namespace Json {
61
62#if JSON_USE_EXCEPTION
67class JSON_API Exception : public std::exception {
68public:
69 Exception(String msg);
70 ~Exception() noexcept override;
71 char const* what() const noexcept override;
72
73protected:
74 String msg_;
75};
76
84public:
85 RuntimeError(String const& msg);
86};
87
95public:
96 LogicError(String const& msg);
97};
98#endif
99
101JSONCPP_NORETURN void throwRuntimeError(String const& msg);
103JSONCPP_NORETURN void throwLogicError(String const& msg);
104
117
125
132
148public:
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
155private:
156 const char* c_str_;
157};
158
194 friend class ValueIteratorBase;
195
196public:
197 using Members = std::vector<String>;
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)
239 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)
246 static constexpr UInt defaultRealPrecision = 17;
247 // The constant is hard-coded because some compiler have trouble
248 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
249 // Assumes that UInt64 is a 64 bits integer.
250 static constexpr double maxUInt64AsDouble = 18446744073709551615.0;
251// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
252// when using gcc and clang backend compilers. CZString
253// cannot be defined as private. See issue #486
254#ifdef __NVCC__
255public:
256#else
257private:
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) noexcept;
267 ~CZString();
268 CZString& operator=(const CZString& other);
269 CZString& operator=(CZString&& other) noexcept;
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
294public:
295 typedef std::map<CZString, Value> ObjectValues;
296#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
297
298public:
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);
342 Value(const StaticString& value);
343 Value(const String& value);
344 Value(bool value);
345 Value(std::nullptr_t ptr) = delete;
346 Value(const Value& other);
347 Value(Value&& other) noexcept;
348 ~Value();
349
352 Value& operator=(const Value& other);
353 Value& operator=(Value&& other) noexcept;
354
356 void swap(Value& other);
358 void swapPayload(Value& other);
359
361 void copy(const Value& other);
363 void copyPayload(const Value& other);
364
365 ValueType type() const;
366
368 bool operator<(const Value& other) const;
369 bool operator<=(const Value& other) const;
370 bool operator>=(const Value& other) const;
371 bool operator>(const Value& other) const;
372 bool operator==(const Value& other) const;
373 bool operator!=(const Value& other) const;
374 int compare(const Value& other) const;
375
376 const char* asCString() const;
377#if JSONCPP_USING_SECURE_MEMORY
378 unsigned getCStringLength() const; // Allows you to understand the length of
379 // the CString
380#endif
381 String asString() const;
385 bool getString(char const** begin, char const** end) const;
386 Int asInt() const;
387 UInt asUInt() const;
388#if defined(JSON_HAS_INT64)
389 Int64 asInt64() const;
390 UInt64 asUInt64() const;
391#endif // if defined(JSON_HAS_INT64)
392 LargestInt asLargestInt() const;
393 LargestUInt asLargestUInt() const;
394 float asFloat() const;
395 double asDouble() const;
396 bool asBool() const;
397
398 bool isNull() const;
399 bool isBool() const;
400 bool isInt() const;
401 bool isInt64() const;
402 bool isUInt() const;
403 bool isUInt64() const;
404 bool isIntegral() const;
405 bool isDouble() const;
406 bool isNumeric() const;
407 bool isString() const;
408 bool isArray() const;
409 bool isObject() const;
410
412 template <typename T> T as() const JSONCPP_TEMPLATE_DELETE;
413 template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE;
414
415 bool isConvertibleTo(ValueType other) const;
416
418 ArrayIndex size() const;
419
422 bool empty() const;
423
425 explicit operator bool() const;
426
430 void clear();
431
437 void resize(ArrayIndex newSize);
438
440
445 Value& operator[](ArrayIndex index);
446 Value& operator[](int index);
448
450
453 const Value& operator[](ArrayIndex index) const;
454 const Value& operator[](int index) const;
456
459 Value get(ArrayIndex index, const Value& defaultValue) const;
461 bool isValidIndex(ArrayIndex index) const;
465 Value& append(const Value& value);
466 Value& append(Value&& value);
467
469 bool insert(ArrayIndex index, const Value& newValue);
470 bool insert(ArrayIndex index, Value&& newValue);
471
475 Value& operator[](const char* key);
478 const Value& operator[](const char* key) const;
481 Value& operator[](const String& key);
485 const Value& operator[](const String& key) const;
498 Value& operator[](const StaticString& key);
501 Value get(const char* key, const Value& defaultValue) const;
505 Value get(const char* begin, const char* end,
506 const Value& defaultValue) const;
510 Value get(const String& key, const Value& defaultValue) const;
514 Value const* find(char const* begin, char const* end) const;
518 Value* demand(char const* begin, char const* end);
524 void removeMember(const char* key);
527 void removeMember(const String& key);
530 bool removeMember(const char* key, Value* removed);
537 bool removeMember(String const& key, Value* removed);
539 bool removeMember(const char* begin, const char* end, Value* removed);
546 bool removeIndex(ArrayIndex index, Value* removed);
547
550 bool isMember(const char* key) const;
553 bool isMember(const String& key) const;
555 bool isMember(const char* begin, const char* end) const;
556
562 Members getMemberNames() const;
563
565 JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
566 void setComment(const char* comment, CommentPlacement placement) {
567 setComment(String(comment, strlen(comment)), placement);
568 }
570 void setComment(const char* comment, size_t len, CommentPlacement placement) {
571 setComment(String(comment, len), placement);
572 }
574 void setComment(String comment, CommentPlacement placement);
575 bool hasComment(CommentPlacement placement) const;
577 String getComment(CommentPlacement placement) const;
578
579 String toStyledString() const;
580
581 const_iterator begin() const;
582 const_iterator end() const;
583
584 iterator begin();
585 iterator end();
586
587 // Accessors for the [start, limit) range of bytes within the JSON text from
588 // which this value was parsed, if any.
589 void setOffsetStart(ptrdiff_t start);
590 void setOffsetLimit(ptrdiff_t limit);
591 ptrdiff_t getOffsetStart() const;
592 ptrdiff_t getOffsetLimit() const;
593
594private:
595 void setType(ValueType v) {
596 bits_.value_type_ = static_cast<unsigned char>(v);
597 }
598 bool isAllocated() const { return bits_.allocated_; }
599 void setIsAllocated(bool v) { bits_.allocated_ = v; }
600
601 void initBasic(ValueType type, bool allocated = false);
602 void dupPayload(const Value& other);
603 void releasePayload();
604 void dupMeta(const Value& other);
605
606 Value& resolveReference(const char* key);
607 Value& resolveReference(const char* key, const char* end);
608
609 // struct MemberNamesTransform
610 //{
611 // typedef const char *result_type;
612 // const char *operator()( const CZString &name ) const
613 // {
614 // return name.c_str();
615 // }
616 //};
617
618 union ValueHolder {
619 LargestInt int_;
620 LargestUInt uint_;
621 double real_;
622 bool bool_;
623 char* string_; // if allocated_, ptr to { unsigned, char[] }.
624 ObjectValues* map_;
625 } value_;
626
627 struct {
628 // Really a ValueType, but types should agree for bitfield packing.
629 unsigned int value_type_ : 8;
630 // Unless allocated_, string_ must be null-terminated.
631 unsigned int allocated_ : 1;
632 } bits_;
633
634 class Comments {
635 public:
636 Comments() = default;
637 Comments(const Comments& that);
638 Comments(Comments&& that) noexcept;
639 Comments& operator=(const Comments& that);
640 Comments& operator=(Comments&& that) noexcept;
641 bool has(CommentPlacement slot) const;
642 String get(CommentPlacement slot) const;
643 void set(CommentPlacement slot, String comment);
644
645 private:
646 using Array = std::array<String, numberOfCommentPlacement>;
647 std::unique_ptr<Array> ptr_;
648 };
649 Comments comments_;
650
651 // [start, limit) byte offsets in the source JSON text from which this Value
652 // was extracted.
653 ptrdiff_t start_;
654 ptrdiff_t limit_;
655};
656
657template <> inline bool Value::as<bool>() const { return asBool(); }
658template <> inline bool Value::is<bool>() const { return isBool(); }
659
660template <> inline Int Value::as<Int>() const { return asInt(); }
661template <> inline bool Value::is<Int>() const { return isInt(); }
662
663template <> inline UInt Value::as<UInt>() const { return asUInt(); }
664template <> inline bool Value::is<UInt>() const { return isUInt(); }
665
666#if defined(JSON_HAS_INT64)
667template <> inline Int64 Value::as<Int64>() const { return asInt64(); }
668template <> inline bool Value::is<Int64>() const { return isInt64(); }
669
670template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); }
671template <> inline bool Value::is<UInt64>() const { return isUInt64(); }
672#endif
673
674template <> inline double Value::as<double>() const { return asDouble(); }
675template <> inline bool Value::is<double>() const { return isDouble(); }
676
677template <> inline String Value::as<String>() const { return asString(); }
678template <> inline bool Value::is<String>() const { return isString(); }
679
682template <> inline float Value::as<float>() const { return asFloat(); }
683template <> inline const char* Value::as<const char*>() const {
684 return asCString();
685}
686
691public:
692 friend class Path;
693
696 PathArgument(const char* key);
697 PathArgument(String key);
698
699private:
700 enum Kind { kindNone = 0, kindIndex, kindKey };
701 String key_;
702 ArrayIndex index_{};
703 Kind kind_{kindNone};
704};
705
718public:
719 Path(const String& path, const PathArgument& a1 = PathArgument(),
720 const PathArgument& a2 = PathArgument(),
721 const PathArgument& a3 = PathArgument(),
722 const PathArgument& a4 = PathArgument(),
723 const PathArgument& a5 = PathArgument());
724
725 const Value& resolve(const Value& root) const;
726 Value resolve(const Value& root, const Value& defaultValue) const;
729 Value& make(Value& root) const;
730
731private:
732 using InArgs = std::vector<const PathArgument*>;
733 using Args = std::vector<PathArgument>;
734
735 void makePath(const String& path, const InArgs& in);
736 void addPathInArg(const String& path, const InArgs& in,
737 InArgs::const_iterator& itInArg, PathArgument::Kind kind);
738 static void invalidPath(const String& path, int location);
739
740 Args args_;
741};
742
747public:
748 using iterator_category = std::bidirectional_iterator_tag;
749 using size_t = unsigned int;
750 using difference_type = int;
752
753 bool operator==(const SelfType& other) const { return isEqual(other); }
754
755 bool operator!=(const SelfType& other) const { return !isEqual(other); }
756
757 difference_type operator-(const SelfType& other) const {
758 return other.computeDistance(*this);
759 }
760
763 Value key() const;
764
767 UInt index() const;
768
772 String name() const;
773
778 JSONCPP_DEPRECATED("Use `key = name();` instead.")
779 char const* memberName() const;
783 char const* memberName(char const** end) const;
784
785protected:
792 const Value& deref() const;
793 Value& deref();
794
795 void increment();
796
797 void decrement();
798
799 difference_type computeDistance(const SelfType& other) const;
800
801 bool isEqual(const SelfType& other) const;
802
803 void copy(const SelfType& other);
804
805private:
806 Value::ObjectValues::iterator current_;
807 // Indicates that iterator is for a null value.
808 bool isNull_{true};
809
810public:
811 // For some reason, BORLAND needs these at the end, rather
812 // than earlier. No idea why.
814 explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
815};
816
821 friend class Value;
822
823public:
824 using value_type = const Value;
825 // typedef unsigned int size_t;
826 // typedef int difference_type;
827 using reference = const Value&;
828 using pointer = const Value*;
830
832 ValueConstIterator(ValueIterator const& other);
833
834private:
837 explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
838
839public:
840 SelfType& operator=(const ValueIteratorBase& other);
841
843 SelfType temp(*this);
844 ++*this;
845 return temp;
846 }
847
849 SelfType temp(*this);
850 --*this;
851 return temp;
852 }
853
855 decrement();
856 return *this;
857 }
858
860 increment();
861 return *this;
862 }
863
864 reference operator*() const { return deref(); }
865
866 pointer operator->() const { return &deref(); }
867};
868
872 friend class Value;
873
874public:
876 using size_t = unsigned int;
877 using difference_type = int;
878 using reference = Value&;
879 using pointer = Value*;
881
883 explicit ValueIterator(const ValueConstIterator& other);
885
886private:
889 explicit ValueIterator(const Value::ObjectValues::iterator& current);
890
891public:
892 SelfType& operator=(const SelfType& other);
893
895 SelfType temp(*this);
896 ++*this;
897 return temp;
898 }
899
901 SelfType temp(*this);
902 --*this;
903 return temp;
904 }
905
907 decrement();
908 return *this;
909 }
910
912 increment();
913 return *this;
914 }
915
921 reference operator*() const { return const_cast<reference>(deref()); }
922 pointer operator->() const { return const_cast<pointer>(&deref()); }
923};
924
925inline void swap(Value& a, Value& b) { a.swap(b); }
926
927} // namespace Json
928
929#pragma pack(pop)
930
931#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
932#pragma warning(pop)
933#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
934
935#endif // JSON_H_INCLUDED
Base class for all exceptions we throw.
Definition: value.h:67
~Exception() noexcept override
Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
Definition: value.h:94
Experimental and untested: represents an element of the "path" to access a node.
Definition: value.h:690
Experimental and untested: represents a "path" to access a node.
Definition: value.h:717
Exceptions which the user cannot easily avoid.
Definition: value.h:83
Lightweight wrapper to tag static string.
Definition: value.h:147
const char * c_str() const
Definition: value.h:153
StaticString(const char *czstring)
Definition: value.h:149
const iterator for object and array value.
Definition: value.h:820
SelfType & operator--()
Definition: value.h:854
pointer operator->() const
Definition: value.h:866
SelfType operator--(int)
Definition: value.h:848
SelfType & operator++()
Definition: value.h:859
SelfType operator++(int)
Definition: value.h:842
reference operator*() const
Definition: value.h:864
Represents a JSON value.
Definition: value.h:193
Value(std::nullptr_t ptr)=delete
Json::ArrayIndex ArrayIndex
Definition: value.h:208
Json::UInt UInt
Definition: value.h:200
static const Value & null
Definition: value.h:215
void setComment(const char *comment, size_t len, CommentPlacement placement)
Comments must be //... or /* ... *‍/.
Definition: value.h:570
T as() const =delete
The as<T> and is<T> member function templates and specializations.
std::vector< String > Members
Definition: value.h:197
Json::LargestInt LargestInt
Definition: value.h:206
Json::LargestUInt LargestUInt
Definition: value.h:207
Json::UInt64 UInt64
Definition: value.h:203
void swap(Value &other)
Swap everything.
Definition: json_value.cpp:466
Json::Int Int
Definition: value.h:201
static const Value & nullRef
Definition: value.h:216
unsigned int value_type_
Definition: value.h:629
Json::Int64 Int64
Definition: value.h:204
unsigned int allocated_
Definition: value.h:631
std::string value_type
Definition: value.h:211
base class for Value iterators.
Definition: value.h:746
bool operator==(const SelfType &other) const
Definition: value.h:753
unsigned int size_t
Definition: value.h:749
std::bidirectional_iterator_tag iterator_category
Definition: value.h:748
difference_type operator-(const SelfType &other) const
Definition: value.h:757
bool operator!=(const SelfType &other) const
Definition: value.h:755
difference_type computeDistance(const SelfType &other) const
Iterator for object and array value.
Definition: value.h:871
SelfType operator--(int)
Definition: value.h:900
SelfType & operator--()
Definition: value.h:906
reference operator*() const
Definition: value.h:921
SelfType & operator++()
Definition: value.h:911
ValueIterator(const ValueIterator &other)
pointer operator->() const
Definition: value.h:922
SelfType operator++(int)
Definition: value.h:894
#define JSON_API
If defined, indicates that the source file is amalgamated to prevent private header inclusion.
Definition: config.h:50
#define JSONCPP_DEPRECATED(message)
Definition: config.h:89
JSON (JavaScript Object Notation).
Definition: allocator.h:14
unsigned int ArrayIndex
Definition: forwards.h:32
std::basic_string< char, std::char_traits< char >, Allocator< char > > String
Definition: config.h:132
CommentPlacement
Definition: value.h:118
@ commentAfterOnSameLine
a comment just after a value on the same line
Definition: value.h:120
@ commentBefore
a comment placed on the line before a value
Definition: value.h:119
@ numberOfCommentPlacement
root value)
Definition: value.h:123
@ commentAfter
a comment on the line after a value (only make sense for
Definition: value.h:121
Int64 LargestInt
Definition: config.h:123
ValueType
Type of the value held by a Value object.
Definition: value.h:107
@ booleanValue
bool value
Definition: value.h:113
@ nullValue
'null' value
Definition: value.h:108
@ stringValue
UTF-8 string value.
Definition: value.h:112
@ realValue
double value
Definition: value.h:111
@ arrayValue
array value (ordered list)
Definition: value.h:114
@ intValue
signed integer value
Definition: value.h:109
@ objectValue
object value (collection of name/value pairs).
Definition: value.h:115
@ uintValue
unsigned integer value
Definition: value.h:110
bool operator==(const SecureAllocator< T > &, const SecureAllocator< U > &)
Definition: allocator.h:75
bool operator!=(const SecureAllocator< T > &, const SecureAllocator< U > &)
Definition: allocator.h:80
int Int
Definition: config.h:108
UInt64 LargestUInt
Definition: config.h:124
unsigned __int64 UInt64
Definition: config.h:118
unsigned int UInt
Definition: config.h:109
__int64 Int64
Definition: config.h:117
PrecisionType
Type of precision for formatting of real values.
Definition: value.h:128
@ decimalPlaces
we set max number of digits after "." in string
Definition: value.h:130
@ significantDigits
we set max number of significant digits in string
Definition: value.h:129
void swap(Value &a, Value &b)
Definition: value.h:925
#define JSONCPP_TEMPLATE_DELETE
Definition: value.h:38
#define JSONCPP_NORETURN
Definition: value.h:18