NIM PC Cross Platform SDK
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 NIM_CPP_WRAPPER_UTIL_JSON_H_INCLUDED
7#define NIM_CPP_WRAPPER_UTIL_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
60namespace nim_cpp_wrapper_util {
61namespace Json {
62
63#if JSON_USE_EXCEPTION
68class JSON_API Exception : public std::exception {
69public:
70 Exception(String msg);
71 ~Exception() noexcept override;
72 char const* what() const noexcept override;
73
74protected:
75 String msg_;
76};
77
84class JSON_API RuntimeError : public Exception {
85public:
86 RuntimeError(String const& msg);
87};
88
95class JSON_API LogicError : public Exception {
96public:
97 LogicError(String const& msg);
98};
99#endif
100
102JSONCPP_NORETURN void throwRuntimeError(String const& msg);
104JSONCPP_NORETURN void throwLogicError(String const& msg);
105
108enum ValueType {
109 nullValue = 0,
110 intValue,
111 uintValue,
112 realValue,
113 stringValue,
114 booleanValue,
115 arrayValue,
116 objectValue
117};
118
120enum CommentPlacement {
121 commentBefore = 0,
122 commentAfterOnSameLine,
123 commentAfter,
125 numberOfCommentPlacement
126};
127
130enum PrecisionType {
131 significantDigits = 0,
132 decimalPlaces
133};
134
149class JSON_API StaticString {
150public:
151 explicit StaticString(const char* czstring)
152 : c_str_(czstring) {}
153
154 operator const char*() const { return c_str_; }
155
156 const char* c_str() const { return c_str_; }
157
158private:
159 const char* c_str_;
160};
161
196class JSON_API Value {
197 friend class ValueIteratorBase;
198
199public:
200 using Members = std::vector<String>;
201 using iterator = ValueIterator;
203 using UInt = nim_cpp_wrapper_util::Json::UInt;
204 using Int = nim_cpp_wrapper_util::Json::Int;
205#if defined(JSON_HAS_INT64)
206 using UInt64 = nim_cpp_wrapper_util::Json::UInt64;
207 using Int64 = nim_cpp_wrapper_util::Json::Int64;
208#endif // defined(JSON_HAS_INT64)
209 using LargestInt = nim_cpp_wrapper_util::Json::LargestInt;
210 using LargestUInt = nim_cpp_wrapper_util::Json::LargestUInt;
211 using ArrayIndex = nim_cpp_wrapper_util::Json::ArrayIndex;
212
213 // Required for boost integration, e. g. BOOST_TEST
214 using value_type = std::string;
215
216#if JSON_USE_NULLREF
217 // Binary compatibility kludges, do not use.
218 static const Value& null;
219 static const Value& nullRef;
220#endif
221
222 // null and nullRef are deprecated, use this instead.
223 static Value const& nullSingleton();
224
226 static constexpr LargestInt minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
228 static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2);
230 static constexpr LargestUInt maxLargestUInt = LargestUInt(-1);
231
233 static constexpr Int minInt = Int(~(UInt(-1) / 2));
235 static constexpr Int maxInt = Int(UInt(-1) / 2);
237 static constexpr UInt maxUInt = UInt(-1);
238
239#if defined(JSON_HAS_INT64)
241 static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2));
243 static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2);
245 static constexpr UInt64 maxUInt64 = UInt64(-1);
246#endif // defined(JSON_HAS_INT64)
248 static constexpr UInt defaultRealPrecision = 17;
249 // The constant is hard-coded because some compiler have trouble
250 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
251 // Assumes that UInt64 is a 64 bits integer.
252 static constexpr double maxUInt64AsDouble = 18446744073709551615.0;
253// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
254// when using gcc and clang backend compilers. CZString
255// cannot be defined as private. See issue #486
256#ifdef __NVCC__
257public:
258#else
259private:
260#endif
261#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
262 class CZString {
263 public:
264 enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
265 CZString(ArrayIndex index);
266 CZString(char const* str, unsigned length, DuplicationPolicy allocate);
267 CZString(CZString const& other);
268 CZString(CZString&& other);
269 ~CZString();
270 CZString& operator=(const CZString& other);
271 CZString& operator=(CZString&& other);
272
273 bool operator<(CZString const& other) const;
274 bool operator==(CZString const& other) const;
275 ArrayIndex index() const;
276 // const char* c_str() const; ///< \deprecated
277 char const* data() const;
278 unsigned length() const;
279 bool isStaticString() const;
280
281 private:
282 void swap(CZString& other);
283
284 struct StringStorage {
285 unsigned policy_ : 2;
286 unsigned length_ : 30; // 1GB max
287 };
288
289 char const* cstr_; // actually, a prefixed string, unless policy is noDup
290 union {
291 ArrayIndex index_;
292 StringStorage storage_;
293 };
294 };
295
296public:
297 typedef std::map<CZString, Value> ObjectValues;
298#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
299
300public:
317 Value(ValueType type = nullValue);
318 Value(Int value);
319 Value(UInt value);
320#if defined(JSON_HAS_INT64)
321 Value(Int64 value);
322 Value(UInt64 value);
323#endif // if defined(JSON_HAS_INT64)
324 Value(double value);
325 Value(const char* value);
326 Value(const char* begin, const char* end);
344 Value(const StaticString& value);
345 Value(const String& value);
346 Value(bool value);
347 Value(std::nullptr_t ptr) = delete;
348 Value(const Value& other);
349 Value(Value&& other);
350 ~Value();
351
354 Value& operator=(const Value& other);
355 Value& operator=(Value&& other);
356
358 void swap(Value& other);
360 void swapPayload(Value& other);
361
363 void copy(const Value& other);
365 void copyPayload(const Value& other);
366
367 ValueType type() const;
368
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 bool operator!=(const Value& other) const;
376 int compare(const Value& other) const;
377
378 const char* asCString() const;
379#if JSONCPP_USING_SECURE_MEMORY
380 unsigned getCStringLength() const; // Allows you to understand the length of
381 // the CString
382#endif
383 String asString() const;
387 bool getString(char const** begin, char const** end) const;
388 Int asInt() const;
389 UInt asUInt() const;
390#if defined(JSON_HAS_INT64)
391 Int64 asInt64() const;
392 UInt64 asUInt64() const;
393#endif // if defined(JSON_HAS_INT64)
394 LargestInt asLargestInt() const;
395 LargestUInt asLargestUInt() const;
396 float asFloat() const;
397 double asDouble() const;
398 bool asBool() const;
399
400 bool isNull() const;
401 bool isBool() const;
402 bool isInt() const;
403 bool isInt64() const;
404 bool isUInt() const;
405 bool isUInt64() const;
406 bool isIntegral() const;
407 bool isDouble() const;
408 bool isNumeric() const;
409 bool isString() const;
410 bool isArray() const;
411 bool isObject() const;
412
414 template <typename T>
415 T as() const JSONCPP_TEMPLATE_DELETE;
416 template <typename T>
417 bool is() const JSONCPP_TEMPLATE_DELETE;
418
419 bool isConvertibleTo(ValueType other) const;
420
422 ArrayIndex size() const;
423
426 bool empty() const;
427
429 explicit operator bool() const;
430
434 void clear();
435
441 void resize(ArrayIndex newSize);
442
444
449 Value& operator[](ArrayIndex index);
450 Value& operator[](int index);
452
454
457 const Value& operator[](ArrayIndex index) const;
458 const Value& operator[](int index) const;
460
463 Value get(ArrayIndex index, const Value& defaultValue) const;
465 bool isValidIndex(ArrayIndex index) const;
469 Value& append(const Value& value);
470 Value& append(Value&& value);
471
473 bool insert(ArrayIndex index, const Value& newValue);
474 bool insert(ArrayIndex index, Value&& newValue);
475
479 Value& operator[](const char* key);
482 const Value& operator[](const char* key) const;
485 Value& operator[](const String& key);
489 const Value& operator[](const String& key) const;
502 Value& operator[](const StaticString& key);
505 Value get(const char* key, const Value& defaultValue) const;
509 Value get(const char* begin, const char* end, const Value& defaultValue) const;
513 Value get(const String& key, const Value& defaultValue) const;
517 Value const* find(char const* begin, char const* end) const;
521 Value* demand(char const* begin, char const* end);
527 void removeMember(const char* key);
530 void removeMember(const String& key);
533 bool removeMember(const char* key, Value* removed);
540 bool removeMember(String const& key, Value* removed);
542 bool removeMember(const char* begin, const char* end, Value* removed);
549 bool removeIndex(ArrayIndex index, Value* removed);
550
553 bool isMember(const char* key) const;
556 bool isMember(const String& key) const;
558 bool isMember(const char* begin, const char* end) const;
559
565 Members getMemberNames() const;
566
568 void setComment(const char* comment, CommentPlacement placement) {
569 setComment(String(comment, strlen(comment)), placement);
570 }
572 void setComment(const char* comment, size_t len, CommentPlacement placement) {
573 setComment(String(comment, len), placement);
574 }
576 void setComment(String comment, CommentPlacement placement);
577 bool hasComment(CommentPlacement placement) const;
579 String getComment(CommentPlacement placement) const;
580
581 String toStyledString() const;
582
583 const_iterator begin() const;
584 const_iterator end() const;
585
586 iterator begin();
587 iterator end();
588
589 // Accessors for the [start, limit) range of bytes within the JSON text from
590 // which this value was parsed, if any.
591 void setOffsetStart(ptrdiff_t start);
592 void setOffsetLimit(ptrdiff_t limit);
593 ptrdiff_t getOffsetStart() const;
594 ptrdiff_t getOffsetLimit() const;
595
596private:
597 void setType(ValueType v) {
598 bits_.value_type_ = static_cast<unsigned char>(v);
599 }
600 bool isAllocated() const {
601 return bits_.allocated_;
602 }
603 void setIsAllocated(bool v) {
604 bits_.allocated_ = v;
605 }
606
607 void initBasic(ValueType type, bool allocated = false);
608 void dupPayload(const Value& other);
609 void releasePayload();
610 void dupMeta(const Value& other);
611
612 Value& resolveReference(const char* key);
613 Value& resolveReference(const char* key, const char* end);
614
615 // struct MemberNamesTransform
616 //{
617 // typedef const char *result_type;
618 // const char *operator()( const CZString &name ) const
619 // {
620 // return name.c_str();
621 // }
622 //};
623
624 union ValueHolder {
625 LargestInt int_;
626 LargestUInt uint_;
627 double real_;
628 bool bool_;
629 char* string_; // if allocated_, ptr to { unsigned, char[] }.
630 ObjectValues* map_;
631 } value_;
632
633 struct {
634 // Really a ValueType, but types should agree for bitfield packing.
635 unsigned int value_type_ : 8;
636 // Unless allocated_, string_ must be null-terminated.
637 unsigned int allocated_ : 1;
638 } bits_;
639
640 class Comments {
641 public:
642 Comments() = default;
643 Comments(const Comments& that);
644 Comments(Comments&& that);
645 Comments& operator=(const Comments& that);
646 Comments& operator=(Comments&& that);
647 bool has(CommentPlacement slot) const;
648 String get(CommentPlacement slot) const;
649 void set(CommentPlacement slot, String comment);
650
651 private:
652 using Array = std::array<String, numberOfCommentPlacement>;
653 std::unique_ptr<Array> ptr_;
654 };
655 Comments comments_;
656
657 // [start, limit) byte offsets in the source JSON text from which this Value
658 // was extracted.
659 ptrdiff_t start_;
660 ptrdiff_t limit_;
661};
662
663template <>
664inline bool Value::as<bool>() const {
665 return asBool();
666}
667template <>
668inline bool Value::is<bool>() const {
669 return isBool();
670}
671
672template <>
673inline Int Value::as<Int>() const {
674 return asInt();
675}
676template <>
677inline bool Value::is<Int>() const {
678 return isInt();
679}
680
681template <>
682inline UInt Value::as<UInt>() const {
683 return asUInt();
684}
685template <>
686inline bool Value::is<UInt>() const {
687 return isUInt();
688}
689
690#if defined(JSON_HAS_INT64)
691template <>
692inline Int64 Value::as<Int64>() const {
693 return asInt64();
694}
695template <>
696inline bool Value::is<Int64>() const {
697 return isInt64();
698}
699
700template <>
701inline UInt64 Value::as<UInt64>() const {
702 return asUInt64();
703}
704template <>
705inline bool Value::is<UInt64>() const {
706 return isUInt64();
707}
708#endif
709
710template <>
711inline double Value::as<double>() const {
712 return asDouble();
713}
714template <>
715inline bool Value::is<double>() const {
716 return isDouble();
717}
718
719template <>
720inline String Value::as<String>() const {
721 return asString();
722}
723template <>
724inline bool Value::is<String>() const {
725 return isString();
726}
727
730template <>
731inline float Value::as<float>() const {
732 return asFloat();
733}
734template <>
735inline const char* Value::as<const char*>() const {
736 return asCString();
737}
738
742class JSON_API PathArgument {
743public:
744 friend class Path;
745
746 PathArgument();
747 PathArgument(ArrayIndex index);
748 PathArgument(const char* key);
749 PathArgument(String key);
750
751private:
752 enum Kind { kindNone = 0, kindIndex, kindKey };
753 String key_;
754 ArrayIndex index_{};
755 Kind kind_{kindNone};
756};
757
769class JSON_API Path {
770public:
771 Path(const String& path,
772 const PathArgument& a1 = PathArgument(),
773 const PathArgument& a2 = PathArgument(),
774 const PathArgument& a3 = PathArgument(),
775 const PathArgument& a4 = PathArgument(),
776 const PathArgument& a5 = PathArgument());
777
778 const Value& resolve(const Value& root) const;
779 Value resolve(const Value& root, const Value& defaultValue) const;
782 Value& make(Value& root) const;
783
784private:
785 using InArgs = std::vector<const PathArgument*>;
786 using Args = std::vector<PathArgument>;
787
788 void makePath(const String& path, const InArgs& in);
789 void addPathInArg(const String& path, const InArgs& in, InArgs::const_iterator& itInArg, PathArgument::Kind kind);
790 static void invalidPath(const String& path, int location);
791
792 Args args_;
793};
794
798class JSON_API ValueIteratorBase {
799public:
800 using iterator_category = std::bidirectional_iterator_tag;
801 using size_t = unsigned int;
802 using difference_type = int;
804
805 bool operator==(const SelfType& other) const { return isEqual(other); }
806
807 bool operator!=(const SelfType& other) const { return !isEqual(other); }
808
809 difference_type operator-(const SelfType& other) const { return other.computeDistance(*this); }
810
813 Value key() const;
814
817 UInt index() const;
818
822 String name() const;
823
828 char const* memberName() const;
832 char const* memberName(char const** end) const;
833
834protected:
841 const Value& deref() const;
842 Value& deref();
843
844 void increment();
845
846 void decrement();
847
848 difference_type computeDistance(const SelfType& other) const;
849
850 bool isEqual(const SelfType& other) const;
851
852 void copy(const SelfType& other);
853
854private:
855 Value::ObjectValues::iterator current_;
856 // Indicates that iterator is for a null value.
857 bool isNull_{true};
858
859public:
860 // For some reason, BORLAND needs these at the end, rather
861 // than earlier. No idea why.
863 explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
864};
865
869class JSON_API ValueConstIterator : public ValueIteratorBase {
870 friend class Value;
871
872public:
873 using value_type = const Value;
874 // typedef unsigned int size_t;
875 // typedef int difference_type;
876 using reference = const Value&;
877 using pointer = const Value*;
879
881 ValueConstIterator(ValueIterator const& other);
882
883private:
886 explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
887
888public:
889 SelfType& operator=(const ValueIteratorBase& other);
890
891 SelfType operator++(int) {
892 SelfType temp(*this);
893 ++*this;
894 return temp;
895 }
896
897 SelfType operator--(int) {
898 SelfType temp(*this);
899 --*this;
900 return temp;
901 }
902
903 SelfType& operator--() {
904 decrement();
905 return *this;
906 }
907
908 SelfType& operator++() {
909 increment();
910 return *this;
911 }
912
913 reference operator*() const { return deref(); }
914
915 pointer operator->() const { return &deref(); }
916};
917
920class JSON_API ValueIterator : public ValueIteratorBase {
921 friend class Value;
922
923public:
924 using value_type = Value;
925 using size_t = unsigned int;
926 using difference_type = int;
927 using reference = Value&;
928 using pointer = Value*;
929 using SelfType = ValueIterator;
930
932 explicit ValueIterator(const ValueConstIterator& other);
933 ValueIterator(const ValueIterator& other);
934
935private:
938 explicit ValueIterator(const Value::ObjectValues::iterator& current);
939
940public:
941 SelfType& operator=(const SelfType& other);
942
943 SelfType operator++(int) {
944 SelfType temp(*this);
945 ++*this;
946 return temp;
947 }
948
949 SelfType operator--(int) {
950 SelfType temp(*this);
951 --*this;
952 return temp;
953 }
954
955 SelfType& operator--() {
956 decrement();
957 return *this;
958 }
959
960 SelfType& operator++() {
961 increment();
962 return *this;
963 }
964
970 reference operator*() { return deref(); }
971 pointer operator->() { return &deref(); }
972};
973
974inline void swap(Value& a, Value& b) {
975 a.swap(b);
976}
977
978} // namespace Json
979} // namespace nim_cpp_wrapper_util
980
981#pragma pack(pop)
982
983#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
984#pragma warning(pop)
985#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
986
987#endif // JSON_H_INCLUDED
Experimental and untested: represents an element of the "path" to access a node.
Definition: value.h:742
Experimental and untested: represents a "path" to access a node.
Definition: value.h:769
Lightweight wrapper to tag static string.
Definition: value.h:149
const iterator for object and array value.
Definition: value.h:869
Represents a JSON value.
Definition: value.h:196
void setComment(const char *comment, size_t len, CommentPlacement placement)
Comments must be //... or /* ... *‍/.
Definition: value.h:572
const char * asCString() const
Embedded zeroes could cause you trouble!
Definition: json_value.cpp:599
T as() const JSONCPP_TEMPLATE_DELETE
The as<T> and is<T> member function templates and specializations.
String asString() const
Embedded zeroes are possible.
Definition: json_value.cpp:632
base class for Value iterators.
Definition: value.h:798
Iterator for object and array value.
Definition: value.h:920
reference operator*()
Definition: value.h:970
bool operator==(const NIMChatRoomExitReasonInfo &info, NIMChatRoomExitReason code)
Definition: nim_chatroom_helper.cpp:13
JSON (JavaScript Object Notation).
Definition: allocator.h:14