@digitalshieldfe/react-native-backup-card-sdk 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +33 -49
- package/android/libs/backupcardsdk.aar +0 -0
- package/android/src/main/AndroidManifest.xml +1 -4
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/BackupCardSdkModule.kt +244 -74
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/BackupCardSdkPackage.kt +1 -1
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/nfc/NfcExceptions.kt +11 -0
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/nfc/NfcUtils.kt +30 -0
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/utils/MiUtil.kt +74 -0
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/utils/NfcPermissionUtils.kt +23 -0
- package/lib/module/NativeBackupCardSdk.js +3 -0
- package/lib/module/NativeBackupCardSdk.js.map +1 -1
- package/lib/module/cardOperations.js +27 -0
- package/lib/module/cardOperations.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/nfc.js +75 -0
- package/lib/module/nfc.js.map +1 -0
- package/lib/typescript/src/NativeBackupCardSdk.d.ts +50 -4
- package/lib/typescript/src/NativeBackupCardSdk.d.ts.map +1 -1
- package/lib/typescript/src/cardOperations.d.ts +7 -0
- package/lib/typescript/src/cardOperations.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nfc.d.ts +28 -0
- package/lib/typescript/src/nfc.d.ts.map +1 -0
- package/package.json +7 -5
- package/src/NativeBackupCardSdk.ts +62 -4
- package/src/cardOperations.ts +61 -0
- package/src/index.tsx +22 -2
- package/src/nfc.ts +74 -0
- package/android/consumer-rules.pro +0 -0
- package/android/proguard-rules.pro +0 -21
- package/android/src/main/java/com/ziancube/backupcardsdk/BackupCardSdk.kt +0 -478
- package/android/src/main/java/com/ziancube/backupcardsdk/GPChannelNatives.java +0 -41
- package/android/src/main/java/com/ziancube/backupcardsdk/listener/ApiAsyncListener.java +0 -13
- package/android/src/main/java/com/ziancube/backupcardsdk/nfc/ApiNfc.java +0 -173
- package/android/src/main/java/com/ziancube/backupcardsdk/nfc/ImplNfc.java +0 -39
- package/android/src/main/java/com/ziancube/backupcardsdk/nfc/NfcComm.java +0 -115
- package/android/src/main/java/com/ziancube/backupcardsdk/utils/ApduParam.java +0 -67
- package/android/src/main/java/com/ziancube/backupcardsdk/utils/CommList.java +0 -41
- package/android/src/main/java/com/ziancube/backupcardsdk/utils/Utils.java +0 -109
- package/android/src/main/jni/CMakeLists.txt +0 -60
- package/android/src/main/jni/GPChannel/include/GPChannelSDK.h +0 -306
- package/android/src/main/jni/GPChannel/include/context/BaseContext.h +0 -56
- package/android/src/main/jni/GPChannel/include/device/ApduBuilder.hpp +0 -72
- package/android/src/main/jni/GPChannel/include/utility/Apdu.hpp +0 -166
- package/android/src/main/jni/GPChannel/include/utility/Debug.hpp +0 -59
- package/android/src/main/jni/GPChannel/include/utility/Singleton.h +0 -34
- package/android/src/main/jni/GPChannel/include/utility/mutex.h +0 -24
- package/android/src/main/jni/GPChannel/include/utility/trim.hpp +0 -155
- package/android/src/main/jni/GPChannel/include/utility/util.h +0 -104
- package/android/src/main/jni/GPChannel/include/utility/xFactory.hpp +0 -26
- package/android/src/main/jni/GPChannel/include/utility/xManager.hpp +0 -84
- package/android/src/main/jni/GPChannel/src/arm64-v8a/libJUB_GPC_APDU_SDK.a +0 -0
- package/android/src/main/jni/GPChannel/src/arm64-v8a/libTrezorCrypto.a +0 -0
- package/android/src/main/jni/GPChannel/src/armeabi-v7a/libJUB_GPC_APDU_SDK.a +0 -0
- package/android/src/main/jni/GPChannel/src/armeabi-v7a/libTrezorCrypto.a +0 -0
- package/android/src/main/jni/GPChannel/src/x86/libJUB_GPC_APDU_SDK.a +0 -0
- package/android/src/main/jni/GPChannel/src/x86/libTrezorCrypto.a +0 -0
- package/android/src/main/jni/src/implJni.cpp +0 -313
- package/android/src/main/jni/src/implJni.h +0 -9
- package/android/src/main/jni/utils/jsoncpp/AUTHORS +0 -111
- package/android/src/main/jni/utils/jsoncpp/CMakeLists.txt +0 -159
- package/android/src/main/jni/utils/jsoncpp/LICENSE +0 -55
- package/android/src/main/jni/utils/jsoncpp/README.md +0 -135
- package/android/src/main/jni/utils/jsoncpp/amalgamate.py +0 -155
- package/android/src/main/jni/utils/jsoncpp/appveyor.yml +0 -22
- package/android/src/main/jni/utils/jsoncpp/dev.makefile +0 -35
- package/android/src/main/jni/utils/jsoncpp/devtools/__init__.py +0 -6
- package/android/src/main/jni/utils/jsoncpp/devtools/agent_vmw7.json +0 -33
- package/android/src/main/jni/utils/jsoncpp/devtools/agent_vmxp.json +0 -26
- package/android/src/main/jni/utils/jsoncpp/devtools/antglob.py +0 -205
- package/android/src/main/jni/utils/jsoncpp/devtools/batchbuild.py +0 -278
- package/android/src/main/jni/utils/jsoncpp/devtools/fixeol.py +0 -70
- package/android/src/main/jni/utils/jsoncpp/devtools/licenseupdater.py +0 -94
- package/android/src/main/jni/utils/jsoncpp/devtools/tarball.py +0 -52
- package/android/src/main/jni/utils/jsoncpp/doxybuild.py +0 -189
- package/android/src/main/jni/utils/jsoncpp/include/CMakeLists.txt +0 -2
- package/android/src/main/jni/utils/jsoncpp/include/json/allocator.h +0 -98
- package/android/src/main/jni/utils/jsoncpp/include/json/assertions.h +0 -54
- package/android/src/main/jni/utils/jsoncpp/include/json/autolink.h +0 -25
- package/android/src/main/jni/utils/jsoncpp/include/json/config.h +0 -187
- package/android/src/main/jni/utils/jsoncpp/include/json/features.h +0 -61
- package/android/src/main/jni/utils/jsoncpp/include/json/forwards.h +0 -37
- package/android/src/main/jni/utils/jsoncpp/include/json/json.h +0 -15
- package/android/src/main/jni/utils/jsoncpp/include/json/reader.h +0 -411
- package/android/src/main/jni/utils/jsoncpp/include/json/value.h +0 -888
- package/android/src/main/jni/utils/jsoncpp/include/json/version.h +0 -20
- package/android/src/main/jni/utils/jsoncpp/include/json/writer.h +0 -357
- package/android/src/main/jni/utils/jsoncpp/makefiles/vs71/jsontest.vcproj +0 -119
- package/android/src/main/jni/utils/jsoncpp/makefiles/vs71/lib_json.vcproj +0 -205
- package/android/src/main/jni/utils/jsoncpp/makefiles/vs71/test_lib_json.vcproj +0 -130
- package/android/src/main/jni/utils/jsoncpp/makerelease.py +0 -390
- package/android/src/main/jni/utils/jsoncpp/meson.build +0 -103
- package/android/src/main/jni/utils/jsoncpp/pkg-config/jsoncpp.pc.in +0 -9
- package/android/src/main/jni/utils/jsoncpp/src/CMakeLists.txt +0 -5
- package/android/src/main/jni/utils/jsoncpp/src/jsontestrunner/CMakeLists.txt +0 -25
- package/android/src/main/jni/utils/jsoncpp/src/jsontestrunner/main.cpp +0 -333
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/CMakeLists.txt +0 -117
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_reader.cpp +0 -2060
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_tool.h +0 -114
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_value.cpp +0 -1661
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_valueiterator.inl +0 -167
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_writer.cpp +0 -1233
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/version.h.in +0 -20
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/CMakeLists.txt +0 -38
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/jsontest.cpp +0 -457
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/jsontest.h +0 -286
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/main.cpp +0 -2606
- package/android/src/main/jni/utils/jsoncpp/travis.sh +0 -23
- package/android/src/main/jni/utils/jsoncpp/version +0 -1
- package/android/src/main/jni/utils/jsoncpp/version.in +0 -1
- package/android/src/main/jni/utils/logUtils.cpp +0 -108
- package/android/src/main/jni/utils/logUtils.h +0 -87
- package/android/src/main/jni/utils/mSIGNA/stdutils/uchar_vector.h +0 -614
|
@@ -1,1661 +0,0 @@
|
|
|
1
|
-
// Copyright 2011 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
|
-
#if !defined(JSON_IS_AMALGAMATION)
|
|
7
|
-
#include <json/assertions.h>
|
|
8
|
-
#include <json/value.h>
|
|
9
|
-
#include <json/writer.h>
|
|
10
|
-
#endif // if !defined(JSON_IS_AMALGAMATION)
|
|
11
|
-
#include <math.h>
|
|
12
|
-
#include <sstream>
|
|
13
|
-
#include <utility>
|
|
14
|
-
#include <cstring>
|
|
15
|
-
#include <cassert>
|
|
16
|
-
#ifdef JSON_USE_CPPTL
|
|
17
|
-
#include <cpptl/conststring.h>
|
|
18
|
-
#endif
|
|
19
|
-
#include <cstddef> // size_t
|
|
20
|
-
#include <algorithm> // min()
|
|
21
|
-
|
|
22
|
-
#define JSON_ASSERT_UNREACHABLE assert(false)
|
|
23
|
-
|
|
24
|
-
namespace Json {
|
|
25
|
-
|
|
26
|
-
// This is a walkaround to avoid the static initialization of Value::null.
|
|
27
|
-
// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
|
|
28
|
-
// 8 (instead of 4) as a bit of future-proofing.
|
|
29
|
-
#if defined(__ARMEL__)
|
|
30
|
-
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
|
|
31
|
-
#else
|
|
32
|
-
#define ALIGNAS(byte_alignment)
|
|
33
|
-
#endif
|
|
34
|
-
//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
|
|
35
|
-
//const unsigned char& kNullRef = kNull[0];
|
|
36
|
-
//const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
|
|
37
|
-
//const Value& Value::nullRef = null;
|
|
38
|
-
|
|
39
|
-
// static
|
|
40
|
-
Value const& Value::nullSingleton()
|
|
41
|
-
{
|
|
42
|
-
static Value const nullStatic;
|
|
43
|
-
return nullStatic;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// for backwards compatibility, we'll leave these global references around, but DO NOT
|
|
47
|
-
// use them in JSONCPP library code any more!
|
|
48
|
-
Value const& Value::null = Value::nullSingleton();
|
|
49
|
-
Value const& Value::nullRef = Value::nullSingleton();
|
|
50
|
-
|
|
51
|
-
const Int Value::minInt = Int(~(UInt(-1) / 2));
|
|
52
|
-
const Int Value::maxInt = Int(UInt(-1) / 2);
|
|
53
|
-
const UInt Value::maxUInt = UInt(-1);
|
|
54
|
-
#if defined(JSON_HAS_INT64)
|
|
55
|
-
const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
|
|
56
|
-
const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
|
|
57
|
-
const UInt64 Value::maxUInt64 = UInt64(-1);
|
|
58
|
-
// The constant is hard-coded because some compiler have trouble
|
|
59
|
-
// converting Value::maxUInt64 to a double correctly (AIX/xlC).
|
|
60
|
-
// Assumes that UInt64 is a 64 bits integer.
|
|
61
|
-
static const double maxUInt64AsDouble = 18446744073709551615.0;
|
|
62
|
-
#endif // defined(JSON_HAS_INT64)
|
|
63
|
-
const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
|
|
64
|
-
const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
|
|
65
|
-
const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
|
|
66
|
-
|
|
67
|
-
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
68
|
-
template <typename T, typename U>
|
|
69
|
-
static inline bool InRange(double d, T min, U max) {
|
|
70
|
-
// The casts can lose precision, but we are looking only for
|
|
71
|
-
// an approximate range. Might fail on edge cases though. ~cdunn
|
|
72
|
-
//return d >= static_cast<double>(min) && d <= static_cast<double>(max);
|
|
73
|
-
return d >= min && d <= max;
|
|
74
|
-
}
|
|
75
|
-
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
76
|
-
static inline double integerToDouble(Json::UInt64 value) {
|
|
77
|
-
return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
template <typename T> static inline double integerToDouble(T value) {
|
|
81
|
-
return static_cast<double>(value);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
template <typename T, typename U>
|
|
85
|
-
static inline bool InRange(double d, T min, U max) {
|
|
86
|
-
return d >= integerToDouble(min) && d <= integerToDouble(max);
|
|
87
|
-
}
|
|
88
|
-
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
89
|
-
|
|
90
|
-
/** Duplicates the specified string value.
|
|
91
|
-
* @param value Pointer to the string to duplicate. Must be zero-terminated if
|
|
92
|
-
* length is "unknown".
|
|
93
|
-
* @param length Length of the value. if equals to unknown, then it will be
|
|
94
|
-
* computed using strlen(value).
|
|
95
|
-
* @return Pointer on the duplicate instance of string.
|
|
96
|
-
*/
|
|
97
|
-
static inline char* duplicateStringValue(const char* value,
|
|
98
|
-
size_t length)
|
|
99
|
-
{
|
|
100
|
-
// Avoid an integer overflow in the call to malloc below by limiting length
|
|
101
|
-
// to a sane value.
|
|
102
|
-
if (length >= static_cast<size_t>(Value::maxInt))
|
|
103
|
-
length = Value::maxInt - 1;
|
|
104
|
-
|
|
105
|
-
char* newString = static_cast<char*>(malloc(length + 1));
|
|
106
|
-
if (newString == NULL) {
|
|
107
|
-
throwRuntimeError(
|
|
108
|
-
"in Json::Value::duplicateStringValue(): "
|
|
109
|
-
"Failed to allocate string value buffer");
|
|
110
|
-
}
|
|
111
|
-
memcpy(newString, value, length);
|
|
112
|
-
newString[length] = 0;
|
|
113
|
-
return newString;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/* Record the length as a prefix.
|
|
117
|
-
*/
|
|
118
|
-
static inline char* duplicateAndPrefixStringValue(
|
|
119
|
-
const char* value,
|
|
120
|
-
unsigned int length)
|
|
121
|
-
{
|
|
122
|
-
// Avoid an integer overflow in the call to malloc below by limiting length
|
|
123
|
-
// to a sane value.
|
|
124
|
-
JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U,
|
|
125
|
-
"in Json::Value::duplicateAndPrefixStringValue(): "
|
|
126
|
-
"length too big for prefixing");
|
|
127
|
-
unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
|
|
128
|
-
char* newString = static_cast<char*>(malloc(actualLength));
|
|
129
|
-
if (newString == 0) {
|
|
130
|
-
throwRuntimeError(
|
|
131
|
-
"in Json::Value::duplicateAndPrefixStringValue(): "
|
|
132
|
-
"Failed to allocate string value buffer");
|
|
133
|
-
}
|
|
134
|
-
*reinterpret_cast<unsigned*>(newString) = length;
|
|
135
|
-
memcpy(newString + sizeof(unsigned), value, length);
|
|
136
|
-
newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
|
|
137
|
-
return newString;
|
|
138
|
-
}
|
|
139
|
-
inline static void decodePrefixedString(
|
|
140
|
-
bool isPrefixed, char const* prefixed,
|
|
141
|
-
unsigned* length, char const** value)
|
|
142
|
-
{
|
|
143
|
-
if (!isPrefixed) {
|
|
144
|
-
*length = static_cast<unsigned>(strlen(prefixed));
|
|
145
|
-
*value = prefixed;
|
|
146
|
-
} else {
|
|
147
|
-
*length = *reinterpret_cast<unsigned const*>(prefixed);
|
|
148
|
-
*value = prefixed + sizeof(unsigned);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
|
|
152
|
-
*/
|
|
153
|
-
#if JSONCPP_USING_SECURE_MEMORY
|
|
154
|
-
static inline void releasePrefixedStringValue(char* value) {
|
|
155
|
-
unsigned length = 0;
|
|
156
|
-
char const* valueDecoded;
|
|
157
|
-
decodePrefixedString(true, value, &length, &valueDecoded);
|
|
158
|
-
size_t const size = sizeof(unsigned) + length + 1U;
|
|
159
|
-
memset(value, 0, size);
|
|
160
|
-
free(value);
|
|
161
|
-
}
|
|
162
|
-
static inline void releaseStringValue(char* value, unsigned length) {
|
|
163
|
-
// length==0 => we allocated the strings memory
|
|
164
|
-
size_t size = (length==0) ? strlen(value) : length;
|
|
165
|
-
memset(value, 0, size);
|
|
166
|
-
free(value);
|
|
167
|
-
}
|
|
168
|
-
#else // !JSONCPP_USING_SECURE_MEMORY
|
|
169
|
-
static inline void releasePrefixedStringValue(char* value) {
|
|
170
|
-
free(value);
|
|
171
|
-
}
|
|
172
|
-
static inline void releaseStringValue(char* value, unsigned) {
|
|
173
|
-
free(value);
|
|
174
|
-
}
|
|
175
|
-
#endif // JSONCPP_USING_SECURE_MEMORY
|
|
176
|
-
|
|
177
|
-
} // namespace Json
|
|
178
|
-
|
|
179
|
-
// //////////////////////////////////////////////////////////////////
|
|
180
|
-
// //////////////////////////////////////////////////////////////////
|
|
181
|
-
// //////////////////////////////////////////////////////////////////
|
|
182
|
-
// ValueInternals...
|
|
183
|
-
// //////////////////////////////////////////////////////////////////
|
|
184
|
-
// //////////////////////////////////////////////////////////////////
|
|
185
|
-
// //////////////////////////////////////////////////////////////////
|
|
186
|
-
#if !defined(JSON_IS_AMALGAMATION)
|
|
187
|
-
|
|
188
|
-
#include "json_valueiterator.inl"
|
|
189
|
-
#endif // if !defined(JSON_IS_AMALGAMATION)
|
|
190
|
-
|
|
191
|
-
namespace Json {
|
|
192
|
-
|
|
193
|
-
Exception::Exception(JSONCPP_STRING const& msg)
|
|
194
|
-
: msg_(msg)
|
|
195
|
-
{}
|
|
196
|
-
Exception::~Exception() JSONCPP_NOEXCEPT
|
|
197
|
-
{}
|
|
198
|
-
char const* Exception::what() const JSONCPP_NOEXCEPT
|
|
199
|
-
{
|
|
200
|
-
return msg_.c_str();
|
|
201
|
-
}
|
|
202
|
-
RuntimeError::RuntimeError(JSONCPP_STRING const& msg)
|
|
203
|
-
: Exception(msg)
|
|
204
|
-
{}
|
|
205
|
-
LogicError::LogicError(JSONCPP_STRING const& msg)
|
|
206
|
-
: Exception(msg)
|
|
207
|
-
{}
|
|
208
|
-
JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
|
|
209
|
-
{
|
|
210
|
-
throw RuntimeError(msg);
|
|
211
|
-
}
|
|
212
|
-
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
|
|
213
|
-
{
|
|
214
|
-
throw LogicError(msg);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// //////////////////////////////////////////////////////////////////
|
|
218
|
-
// //////////////////////////////////////////////////////////////////
|
|
219
|
-
// //////////////////////////////////////////////////////////////////
|
|
220
|
-
// class Value::CommentInfo
|
|
221
|
-
// //////////////////////////////////////////////////////////////////
|
|
222
|
-
// //////////////////////////////////////////////////////////////////
|
|
223
|
-
// //////////////////////////////////////////////////////////////////
|
|
224
|
-
|
|
225
|
-
Value::CommentInfo::CommentInfo() : comment_(0)
|
|
226
|
-
{}
|
|
227
|
-
|
|
228
|
-
Value::CommentInfo::~CommentInfo() {
|
|
229
|
-
if (comment_)
|
|
230
|
-
releaseStringValue(comment_, 0u);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
void Value::CommentInfo::setComment(const char* text, size_t len) {
|
|
234
|
-
if (comment_) {
|
|
235
|
-
releaseStringValue(comment_, 0u);
|
|
236
|
-
comment_ = 0;
|
|
237
|
-
}
|
|
238
|
-
JSON_ASSERT(text != 0);
|
|
239
|
-
JSON_ASSERT_MESSAGE(
|
|
240
|
-
text[0] == '\0' || text[0] == '/',
|
|
241
|
-
"in Json::Value::setComment(): Comments must start with /");
|
|
242
|
-
// It seems that /**/ style comments are acceptable as well.
|
|
243
|
-
comment_ = duplicateStringValue(text, len);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// //////////////////////////////////////////////////////////////////
|
|
247
|
-
// //////////////////////////////////////////////////////////////////
|
|
248
|
-
// //////////////////////////////////////////////////////////////////
|
|
249
|
-
// class Value::CZString
|
|
250
|
-
// //////////////////////////////////////////////////////////////////
|
|
251
|
-
// //////////////////////////////////////////////////////////////////
|
|
252
|
-
// //////////////////////////////////////////////////////////////////
|
|
253
|
-
|
|
254
|
-
// Notes: policy_ indicates if the string was allocated when
|
|
255
|
-
// a string is stored.
|
|
256
|
-
|
|
257
|
-
Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
|
|
258
|
-
|
|
259
|
-
Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
|
|
260
|
-
: cstr_(str) {
|
|
261
|
-
// allocate != duplicate
|
|
262
|
-
storage_.policy_ = allocate & 0x3;
|
|
263
|
-
storage_.length_ = ulength & 0x3FFFFFFF;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
Value::CZString::CZString(const CZString& other) {
|
|
267
|
-
cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
|
|
268
|
-
? duplicateStringValue(other.cstr_, other.storage_.length_)
|
|
269
|
-
: other.cstr_);
|
|
270
|
-
storage_.policy_ = static_cast<unsigned>(other.cstr_
|
|
271
|
-
? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
|
|
272
|
-
? noDuplication : duplicate)
|
|
273
|
-
: static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U;
|
|
274
|
-
storage_.length_ = other.storage_.length_;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
#if JSON_HAS_RVALUE_REFERENCES
|
|
278
|
-
Value::CZString::CZString(CZString&& other)
|
|
279
|
-
: cstr_(other.cstr_), index_(other.index_) {
|
|
280
|
-
other.cstr_ = nullptr;
|
|
281
|
-
}
|
|
282
|
-
#endif
|
|
283
|
-
|
|
284
|
-
Value::CZString::~CZString() {
|
|
285
|
-
if (cstr_ && storage_.policy_ == duplicate) {
|
|
286
|
-
releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
void Value::CZString::swap(CZString& other) {
|
|
291
|
-
std::swap(cstr_, other.cstr_);
|
|
292
|
-
std::swap(index_, other.index_);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
Value::CZString& Value::CZString::operator=(const CZString& other) {
|
|
296
|
-
cstr_ = other.cstr_;
|
|
297
|
-
index_ = other.index_;
|
|
298
|
-
return *this;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
#if JSON_HAS_RVALUE_REFERENCES
|
|
302
|
-
Value::CZString& Value::CZString::operator=(CZString&& other) {
|
|
303
|
-
cstr_ = other.cstr_;
|
|
304
|
-
index_ = other.index_;
|
|
305
|
-
other.cstr_ = nullptr;
|
|
306
|
-
return *this;
|
|
307
|
-
}
|
|
308
|
-
#endif
|
|
309
|
-
|
|
310
|
-
bool Value::CZString::operator<(const CZString& other) const {
|
|
311
|
-
if (!cstr_) return index_ < other.index_;
|
|
312
|
-
//return strcmp(cstr_, other.cstr_) < 0;
|
|
313
|
-
// Assume both are strings.
|
|
314
|
-
unsigned this_len = this->storage_.length_;
|
|
315
|
-
unsigned other_len = other.storage_.length_;
|
|
316
|
-
unsigned min_len = std::min<unsigned>(this_len, other_len);
|
|
317
|
-
JSON_ASSERT(this->cstr_ && other.cstr_);
|
|
318
|
-
int comp = memcmp(this->cstr_, other.cstr_, min_len);
|
|
319
|
-
if (comp < 0) return true;
|
|
320
|
-
if (comp > 0) return false;
|
|
321
|
-
return (this_len < other_len);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
bool Value::CZString::operator==(const CZString& other) const {
|
|
325
|
-
if (!cstr_) return index_ == other.index_;
|
|
326
|
-
//return strcmp(cstr_, other.cstr_) == 0;
|
|
327
|
-
// Assume both are strings.
|
|
328
|
-
unsigned this_len = this->storage_.length_;
|
|
329
|
-
unsigned other_len = other.storage_.length_;
|
|
330
|
-
if (this_len != other_len) return false;
|
|
331
|
-
JSON_ASSERT(this->cstr_ && other.cstr_);
|
|
332
|
-
int comp = memcmp(this->cstr_, other.cstr_, this_len);
|
|
333
|
-
return comp == 0;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
ArrayIndex Value::CZString::index() const { return index_; }
|
|
337
|
-
|
|
338
|
-
//const char* Value::CZString::c_str() const { return cstr_; }
|
|
339
|
-
const char* Value::CZString::data() const { return cstr_; }
|
|
340
|
-
unsigned Value::CZString::length() const { return storage_.length_; }
|
|
341
|
-
bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
|
|
342
|
-
|
|
343
|
-
// //////////////////////////////////////////////////////////////////
|
|
344
|
-
// //////////////////////////////////////////////////////////////////
|
|
345
|
-
// //////////////////////////////////////////////////////////////////
|
|
346
|
-
// class Value::Value
|
|
347
|
-
// //////////////////////////////////////////////////////////////////
|
|
348
|
-
// //////////////////////////////////////////////////////////////////
|
|
349
|
-
// //////////////////////////////////////////////////////////////////
|
|
350
|
-
|
|
351
|
-
/*! \internal Default constructor initialization must be equivalent to:
|
|
352
|
-
* memset( this, 0, sizeof(Value) )
|
|
353
|
-
* This optimization is used in ValueInternalMap fast allocator.
|
|
354
|
-
*/
|
|
355
|
-
Value::Value(ValueType vtype) {
|
|
356
|
-
static char const emptyString[] = "";
|
|
357
|
-
initBasic(vtype);
|
|
358
|
-
switch (vtype) {
|
|
359
|
-
case nullValue:
|
|
360
|
-
break;
|
|
361
|
-
case intValue:
|
|
362
|
-
case uintValue:
|
|
363
|
-
value_.int_ = 0;
|
|
364
|
-
break;
|
|
365
|
-
case realValue:
|
|
366
|
-
value_.real_ = 0.0;
|
|
367
|
-
break;
|
|
368
|
-
case stringValue:
|
|
369
|
-
// allocated_ == false, so this is safe.
|
|
370
|
-
value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
|
|
371
|
-
break;
|
|
372
|
-
case arrayValue:
|
|
373
|
-
case objectValue:
|
|
374
|
-
value_.map_ = new ObjectValues();
|
|
375
|
-
break;
|
|
376
|
-
case booleanValue:
|
|
377
|
-
value_.bool_ = false;
|
|
378
|
-
break;
|
|
379
|
-
default:
|
|
380
|
-
JSON_ASSERT_UNREACHABLE;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
Value::Value(Int value) {
|
|
385
|
-
initBasic(intValue);
|
|
386
|
-
value_.int_ = value;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
Value::Value(UInt value) {
|
|
390
|
-
initBasic(uintValue);
|
|
391
|
-
value_.uint_ = value;
|
|
392
|
-
}
|
|
393
|
-
#if defined(JSON_HAS_INT64)
|
|
394
|
-
Value::Value(Int64 value) {
|
|
395
|
-
initBasic(intValue);
|
|
396
|
-
value_.int_ = value;
|
|
397
|
-
}
|
|
398
|
-
Value::Value(UInt64 value) {
|
|
399
|
-
initBasic(uintValue);
|
|
400
|
-
value_.uint_ = value;
|
|
401
|
-
}
|
|
402
|
-
#endif // defined(JSON_HAS_INT64)
|
|
403
|
-
|
|
404
|
-
Value::Value(double value) {
|
|
405
|
-
initBasic(realValue);
|
|
406
|
-
value_.real_ = value;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
Value::Value(const char* value) {
|
|
410
|
-
initBasic(stringValue, true);
|
|
411
|
-
JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
|
|
412
|
-
value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
Value::Value(const char* beginValue, const char* endValue) {
|
|
416
|
-
initBasic(stringValue, true);
|
|
417
|
-
value_.string_ =
|
|
418
|
-
duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
Value::Value(const JSONCPP_STRING& value) {
|
|
422
|
-
initBasic(stringValue, true);
|
|
423
|
-
value_.string_ =
|
|
424
|
-
duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
Value::Value(const StaticString& value) {
|
|
428
|
-
initBasic(stringValue);
|
|
429
|
-
value_.string_ = const_cast<char*>(value.c_str());
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
#ifdef JSON_USE_CPPTL
|
|
433
|
-
Value::Value(const CppTL::ConstString& value) {
|
|
434
|
-
initBasic(stringValue, true);
|
|
435
|
-
value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
|
|
436
|
-
}
|
|
437
|
-
#endif
|
|
438
|
-
|
|
439
|
-
Value::Value(bool value) {
|
|
440
|
-
initBasic(booleanValue);
|
|
441
|
-
value_.bool_ = value;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
Value::Value(Value const& other)
|
|
445
|
-
: type_(other.type_), allocated_(false)
|
|
446
|
-
,
|
|
447
|
-
comments_(0), start_(other.start_), limit_(other.limit_)
|
|
448
|
-
{
|
|
449
|
-
switch (type_) {
|
|
450
|
-
case nullValue:
|
|
451
|
-
case intValue:
|
|
452
|
-
case uintValue:
|
|
453
|
-
case realValue:
|
|
454
|
-
case booleanValue:
|
|
455
|
-
value_ = other.value_;
|
|
456
|
-
break;
|
|
457
|
-
case stringValue:
|
|
458
|
-
if (other.value_.string_ && other.allocated_) {
|
|
459
|
-
unsigned len;
|
|
460
|
-
char const* str;
|
|
461
|
-
decodePrefixedString(other.allocated_, other.value_.string_,
|
|
462
|
-
&len, &str);
|
|
463
|
-
value_.string_ = duplicateAndPrefixStringValue(str, len);
|
|
464
|
-
allocated_ = true;
|
|
465
|
-
} else {
|
|
466
|
-
value_.string_ = other.value_.string_;
|
|
467
|
-
allocated_ = false;
|
|
468
|
-
}
|
|
469
|
-
break;
|
|
470
|
-
case arrayValue:
|
|
471
|
-
case objectValue:
|
|
472
|
-
value_.map_ = new ObjectValues(*other.value_.map_);
|
|
473
|
-
break;
|
|
474
|
-
default:
|
|
475
|
-
JSON_ASSERT_UNREACHABLE;
|
|
476
|
-
}
|
|
477
|
-
if (other.comments_) {
|
|
478
|
-
comments_ = new CommentInfo[numberOfCommentPlacement];
|
|
479
|
-
for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
|
|
480
|
-
const CommentInfo& otherComment = other.comments_[comment];
|
|
481
|
-
if (otherComment.comment_)
|
|
482
|
-
comments_[comment].setComment(
|
|
483
|
-
otherComment.comment_, strlen(otherComment.comment_));
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
#if JSON_HAS_RVALUE_REFERENCES
|
|
489
|
-
// Move constructor
|
|
490
|
-
Value::Value(Value&& other) {
|
|
491
|
-
initBasic(nullValue);
|
|
492
|
-
swap(other);
|
|
493
|
-
}
|
|
494
|
-
#endif
|
|
495
|
-
|
|
496
|
-
Value::~Value() {
|
|
497
|
-
switch (type_) {
|
|
498
|
-
case nullValue:
|
|
499
|
-
case intValue:
|
|
500
|
-
case uintValue:
|
|
501
|
-
case realValue:
|
|
502
|
-
case booleanValue:
|
|
503
|
-
break;
|
|
504
|
-
case stringValue:
|
|
505
|
-
if (allocated_)
|
|
506
|
-
releasePrefixedStringValue(value_.string_);
|
|
507
|
-
break;
|
|
508
|
-
case arrayValue:
|
|
509
|
-
case objectValue:
|
|
510
|
-
delete value_.map_;
|
|
511
|
-
break;
|
|
512
|
-
default:
|
|
513
|
-
JSON_ASSERT_UNREACHABLE;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
delete[] comments_;
|
|
517
|
-
|
|
518
|
-
value_.uint_ = 0;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
Value& Value::operator=(Value other) {
|
|
522
|
-
swap(other);
|
|
523
|
-
return *this;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
void Value::swapPayload(Value& other) {
|
|
527
|
-
ValueType temp = type_;
|
|
528
|
-
type_ = other.type_;
|
|
529
|
-
other.type_ = temp;
|
|
530
|
-
std::swap(value_, other.value_);
|
|
531
|
-
int temp2 = allocated_;
|
|
532
|
-
allocated_ = other.allocated_;
|
|
533
|
-
other.allocated_ = temp2 & 0x1;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
void Value::copyPayload(const Value& other) {
|
|
537
|
-
type_ = other.type_;
|
|
538
|
-
value_ = other.value_;
|
|
539
|
-
allocated_ = other.allocated_;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
void Value::swap(Value& other) {
|
|
543
|
-
swapPayload(other);
|
|
544
|
-
std::swap(comments_, other.comments_);
|
|
545
|
-
std::swap(start_, other.start_);
|
|
546
|
-
std::swap(limit_, other.limit_);
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
void Value::copy(const Value& other) {
|
|
550
|
-
copyPayload(other);
|
|
551
|
-
comments_ = other.comments_;
|
|
552
|
-
start_ = other.start_;
|
|
553
|
-
limit_ = other.limit_;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
ValueType Value::type() const { return type_; }
|
|
557
|
-
|
|
558
|
-
int Value::compare(const Value& other) const {
|
|
559
|
-
if (*this < other)
|
|
560
|
-
return -1;
|
|
561
|
-
if (*this > other)
|
|
562
|
-
return 1;
|
|
563
|
-
return 0;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
bool Value::operator<(const Value& other) const {
|
|
567
|
-
int typeDelta = type_ - other.type_;
|
|
568
|
-
if (typeDelta)
|
|
569
|
-
return typeDelta < 0 ? true : false;
|
|
570
|
-
switch (type_) {
|
|
571
|
-
case nullValue:
|
|
572
|
-
return false;
|
|
573
|
-
case intValue:
|
|
574
|
-
return value_.int_ < other.value_.int_;
|
|
575
|
-
case uintValue:
|
|
576
|
-
return value_.uint_ < other.value_.uint_;
|
|
577
|
-
case realValue:
|
|
578
|
-
return value_.real_ < other.value_.real_;
|
|
579
|
-
case booleanValue:
|
|
580
|
-
return value_.bool_ < other.value_.bool_;
|
|
581
|
-
case stringValue:
|
|
582
|
-
{
|
|
583
|
-
if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
|
|
584
|
-
if (other.value_.string_) return true;
|
|
585
|
-
else return false;
|
|
586
|
-
}
|
|
587
|
-
unsigned this_len;
|
|
588
|
-
unsigned other_len;
|
|
589
|
-
char const* this_str;
|
|
590
|
-
char const* other_str;
|
|
591
|
-
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
|
592
|
-
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
|
|
593
|
-
unsigned min_len = std::min<unsigned>(this_len, other_len);
|
|
594
|
-
JSON_ASSERT(this_str && other_str);
|
|
595
|
-
int comp = memcmp(this_str, other_str, min_len);
|
|
596
|
-
if (comp < 0) return true;
|
|
597
|
-
if (comp > 0) return false;
|
|
598
|
-
return (this_len < other_len);
|
|
599
|
-
}
|
|
600
|
-
case arrayValue:
|
|
601
|
-
case objectValue: {
|
|
602
|
-
int delta = int(value_.map_->size() - other.value_.map_->size());
|
|
603
|
-
if (delta)
|
|
604
|
-
return delta < 0;
|
|
605
|
-
return (*value_.map_) < (*other.value_.map_);
|
|
606
|
-
}
|
|
607
|
-
default:
|
|
608
|
-
JSON_ASSERT_UNREACHABLE;
|
|
609
|
-
}
|
|
610
|
-
return false; // unreachable
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
bool Value::operator<=(const Value& other) const { return !(other < *this); }
|
|
614
|
-
|
|
615
|
-
bool Value::operator>=(const Value& other) const { return !(*this < other); }
|
|
616
|
-
|
|
617
|
-
bool Value::operator>(const Value& other) const { return other < *this; }
|
|
618
|
-
|
|
619
|
-
bool Value::operator==(const Value& other) const {
|
|
620
|
-
// if ( type_ != other.type_ )
|
|
621
|
-
// GCC 2.95.3 says:
|
|
622
|
-
// attempt to take address of bit-field structure member `Json::Value::type_'
|
|
623
|
-
// Beats me, but a temp solves the problem.
|
|
624
|
-
int temp = other.type_;
|
|
625
|
-
if (type_ != temp)
|
|
626
|
-
return false;
|
|
627
|
-
switch (type_) {
|
|
628
|
-
case nullValue:
|
|
629
|
-
return true;
|
|
630
|
-
case intValue:
|
|
631
|
-
return value_.int_ == other.value_.int_;
|
|
632
|
-
case uintValue:
|
|
633
|
-
return value_.uint_ == other.value_.uint_;
|
|
634
|
-
case realValue:
|
|
635
|
-
return value_.real_ == other.value_.real_;
|
|
636
|
-
case booleanValue:
|
|
637
|
-
return value_.bool_ == other.value_.bool_;
|
|
638
|
-
case stringValue:
|
|
639
|
-
{
|
|
640
|
-
if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
|
|
641
|
-
return (value_.string_ == other.value_.string_);
|
|
642
|
-
}
|
|
643
|
-
unsigned this_len;
|
|
644
|
-
unsigned other_len;
|
|
645
|
-
char const* this_str;
|
|
646
|
-
char const* other_str;
|
|
647
|
-
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
|
648
|
-
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
|
|
649
|
-
if (this_len != other_len) return false;
|
|
650
|
-
JSON_ASSERT(this_str && other_str);
|
|
651
|
-
int comp = memcmp(this_str, other_str, this_len);
|
|
652
|
-
return comp == 0;
|
|
653
|
-
}
|
|
654
|
-
case arrayValue:
|
|
655
|
-
case objectValue:
|
|
656
|
-
return value_.map_->size() == other.value_.map_->size() &&
|
|
657
|
-
(*value_.map_) == (*other.value_.map_);
|
|
658
|
-
default:
|
|
659
|
-
JSON_ASSERT_UNREACHABLE;
|
|
660
|
-
}
|
|
661
|
-
return false; // unreachable
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
bool Value::operator!=(const Value& other) const { return !(*this == other); }
|
|
665
|
-
|
|
666
|
-
const char* Value::asCString() const {
|
|
667
|
-
JSON_ASSERT_MESSAGE(type_ == stringValue,
|
|
668
|
-
"in Json::Value::asCString(): requires stringValue");
|
|
669
|
-
if (value_.string_ == 0) return 0;
|
|
670
|
-
unsigned this_len;
|
|
671
|
-
char const* this_str;
|
|
672
|
-
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
|
673
|
-
return this_str;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
#if JSONCPP_USING_SECURE_MEMORY
|
|
677
|
-
unsigned Value::getCStringLength() const {
|
|
678
|
-
JSON_ASSERT_MESSAGE(type_ == stringValue,
|
|
679
|
-
"in Json::Value::asCString(): requires stringValue");
|
|
680
|
-
if (value_.string_ == 0) return 0;
|
|
681
|
-
unsigned this_len;
|
|
682
|
-
char const* this_str;
|
|
683
|
-
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
|
684
|
-
return this_len;
|
|
685
|
-
}
|
|
686
|
-
#endif
|
|
687
|
-
|
|
688
|
-
bool Value::getString(char const** str, char const** cend) const {
|
|
689
|
-
if (type_ != stringValue) return false;
|
|
690
|
-
if (value_.string_ == 0) return false;
|
|
691
|
-
unsigned length;
|
|
692
|
-
decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
|
|
693
|
-
*cend = *str + length;
|
|
694
|
-
return true;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
JSONCPP_STRING Value::asString() const {
|
|
698
|
-
switch (type_) {
|
|
699
|
-
case nullValue:
|
|
700
|
-
return "";
|
|
701
|
-
case stringValue:
|
|
702
|
-
{
|
|
703
|
-
if (value_.string_ == 0) return "";
|
|
704
|
-
unsigned this_len;
|
|
705
|
-
char const* this_str;
|
|
706
|
-
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
|
707
|
-
return JSONCPP_STRING(this_str, this_len);
|
|
708
|
-
}
|
|
709
|
-
case booleanValue:
|
|
710
|
-
return value_.bool_ ? "true" : "false";
|
|
711
|
-
case intValue:
|
|
712
|
-
return valueToString(value_.int_);
|
|
713
|
-
case uintValue:
|
|
714
|
-
return valueToString(value_.uint_);
|
|
715
|
-
case realValue:
|
|
716
|
-
return valueToString(value_.real_);
|
|
717
|
-
default:
|
|
718
|
-
JSON_FAIL_MESSAGE("Type is not convertible to string");
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
#ifdef JSON_USE_CPPTL
|
|
723
|
-
CppTL::ConstString Value::asConstString() const {
|
|
724
|
-
unsigned len;
|
|
725
|
-
char const* str;
|
|
726
|
-
decodePrefixedString(allocated_, value_.string_,
|
|
727
|
-
&len, &str);
|
|
728
|
-
return CppTL::ConstString(str, len);
|
|
729
|
-
}
|
|
730
|
-
#endif
|
|
731
|
-
|
|
732
|
-
Value::Int Value::asInt() const {
|
|
733
|
-
switch (type_) {
|
|
734
|
-
case intValue:
|
|
735
|
-
JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
|
|
736
|
-
return Int(value_.int_);
|
|
737
|
-
case uintValue:
|
|
738
|
-
JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
|
|
739
|
-
return Int(value_.uint_);
|
|
740
|
-
case realValue:
|
|
741
|
-
JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
|
|
742
|
-
"double out of Int range");
|
|
743
|
-
return Int(value_.real_);
|
|
744
|
-
case nullValue:
|
|
745
|
-
return 0;
|
|
746
|
-
case booleanValue:
|
|
747
|
-
return value_.bool_ ? 1 : 0;
|
|
748
|
-
default:
|
|
749
|
-
break;
|
|
750
|
-
}
|
|
751
|
-
JSON_FAIL_MESSAGE("Value is not convertible to Int.");
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
Value::UInt Value::asUInt() const {
|
|
755
|
-
switch (type_) {
|
|
756
|
-
case intValue:
|
|
757
|
-
JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
|
|
758
|
-
return UInt(value_.int_);
|
|
759
|
-
case uintValue:
|
|
760
|
-
JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
|
|
761
|
-
return UInt(value_.uint_);
|
|
762
|
-
case realValue:
|
|
763
|
-
JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
|
|
764
|
-
"double out of UInt range");
|
|
765
|
-
return UInt(value_.real_);
|
|
766
|
-
case nullValue:
|
|
767
|
-
return 0;
|
|
768
|
-
case booleanValue:
|
|
769
|
-
return value_.bool_ ? 1 : 0;
|
|
770
|
-
default:
|
|
771
|
-
break;
|
|
772
|
-
}
|
|
773
|
-
JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
#if defined(JSON_HAS_INT64)
|
|
777
|
-
|
|
778
|
-
Value::Int64 Value::asInt64() const {
|
|
779
|
-
switch (type_) {
|
|
780
|
-
case intValue:
|
|
781
|
-
return Int64(value_.int_);
|
|
782
|
-
case uintValue:
|
|
783
|
-
JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
|
|
784
|
-
return Int64(value_.uint_);
|
|
785
|
-
case realValue:
|
|
786
|
-
JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
|
|
787
|
-
"double out of Int64 range");
|
|
788
|
-
return Int64(value_.real_);
|
|
789
|
-
case nullValue:
|
|
790
|
-
return 0;
|
|
791
|
-
case booleanValue:
|
|
792
|
-
return value_.bool_ ? 1 : 0;
|
|
793
|
-
default:
|
|
794
|
-
break;
|
|
795
|
-
}
|
|
796
|
-
JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
Value::UInt64 Value::asUInt64() const {
|
|
800
|
-
switch (type_) {
|
|
801
|
-
case intValue:
|
|
802
|
-
JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
|
|
803
|
-
return UInt64(value_.int_);
|
|
804
|
-
case uintValue:
|
|
805
|
-
return UInt64(value_.uint_);
|
|
806
|
-
case realValue:
|
|
807
|
-
JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
|
|
808
|
-
"double out of UInt64 range");
|
|
809
|
-
return UInt64(value_.real_);
|
|
810
|
-
case nullValue:
|
|
811
|
-
return 0;
|
|
812
|
-
case booleanValue:
|
|
813
|
-
return value_.bool_ ? 1 : 0;
|
|
814
|
-
default:
|
|
815
|
-
break;
|
|
816
|
-
}
|
|
817
|
-
JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
|
|
818
|
-
}
|
|
819
|
-
#endif // if defined(JSON_HAS_INT64)
|
|
820
|
-
|
|
821
|
-
LargestInt Value::asLargestInt() const {
|
|
822
|
-
#if defined(JSON_NO_INT64)
|
|
823
|
-
return asInt();
|
|
824
|
-
#else
|
|
825
|
-
return asInt64();
|
|
826
|
-
#endif
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
LargestUInt Value::asLargestUInt() const {
|
|
830
|
-
#if defined(JSON_NO_INT64)
|
|
831
|
-
return asUInt();
|
|
832
|
-
#else
|
|
833
|
-
return asUInt64();
|
|
834
|
-
#endif
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
double Value::asDouble() const {
|
|
838
|
-
switch (type_) {
|
|
839
|
-
case intValue:
|
|
840
|
-
return static_cast<double>(value_.int_);
|
|
841
|
-
case uintValue:
|
|
842
|
-
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
843
|
-
return static_cast<double>(value_.uint_);
|
|
844
|
-
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
845
|
-
return integerToDouble(value_.uint_);
|
|
846
|
-
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
847
|
-
case realValue:
|
|
848
|
-
return value_.real_;
|
|
849
|
-
case nullValue:
|
|
850
|
-
return 0.0;
|
|
851
|
-
case booleanValue:
|
|
852
|
-
return value_.bool_ ? 1.0 : 0.0;
|
|
853
|
-
default:
|
|
854
|
-
break;
|
|
855
|
-
}
|
|
856
|
-
JSON_FAIL_MESSAGE("Value is not convertible to double.");
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
float Value::asFloat() const {
|
|
860
|
-
switch (type_) {
|
|
861
|
-
case intValue:
|
|
862
|
-
return static_cast<float>(value_.int_);
|
|
863
|
-
case uintValue:
|
|
864
|
-
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
865
|
-
return static_cast<float>(value_.uint_);
|
|
866
|
-
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
867
|
-
// This can fail (silently?) if the value is bigger than MAX_FLOAT.
|
|
868
|
-
return static_cast<float>(integerToDouble(value_.uint_));
|
|
869
|
-
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
|
870
|
-
case realValue:
|
|
871
|
-
return static_cast<float>(value_.real_);
|
|
872
|
-
case nullValue:
|
|
873
|
-
return 0.0;
|
|
874
|
-
case booleanValue:
|
|
875
|
-
return value_.bool_ ? 1.0f : 0.0f;
|
|
876
|
-
default:
|
|
877
|
-
break;
|
|
878
|
-
}
|
|
879
|
-
JSON_FAIL_MESSAGE("Value is not convertible to float.");
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
bool Value::asBool() const {
|
|
883
|
-
switch (type_) {
|
|
884
|
-
case booleanValue:
|
|
885
|
-
return value_.bool_;
|
|
886
|
-
case nullValue:
|
|
887
|
-
return false;
|
|
888
|
-
case intValue:
|
|
889
|
-
return value_.int_ ? true : false;
|
|
890
|
-
case uintValue:
|
|
891
|
-
return value_.uint_ ? true : false;
|
|
892
|
-
case realValue:
|
|
893
|
-
// This is kind of strange. Not recommended.
|
|
894
|
-
return (value_.real_ != 0.0) ? true : false;
|
|
895
|
-
default:
|
|
896
|
-
break;
|
|
897
|
-
}
|
|
898
|
-
JSON_FAIL_MESSAGE("Value is not convertible to bool.");
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
bool Value::isConvertibleTo(ValueType other) const {
|
|
902
|
-
switch (other) {
|
|
903
|
-
case nullValue:
|
|
904
|
-
return (isNumeric() && asDouble() == 0.0) ||
|
|
905
|
-
(type_ == booleanValue && value_.bool_ == false) ||
|
|
906
|
-
(type_ == stringValue && asString().empty()) ||
|
|
907
|
-
(type_ == arrayValue && value_.map_->size() == 0) ||
|
|
908
|
-
(type_ == objectValue && value_.map_->size() == 0) ||
|
|
909
|
-
type_ == nullValue;
|
|
910
|
-
case intValue:
|
|
911
|
-
return isInt() ||
|
|
912
|
-
(type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
|
|
913
|
-
type_ == booleanValue || type_ == nullValue;
|
|
914
|
-
case uintValue:
|
|
915
|
-
return isUInt() ||
|
|
916
|
-
(type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
|
|
917
|
-
type_ == booleanValue || type_ == nullValue;
|
|
918
|
-
case realValue:
|
|
919
|
-
return isNumeric() || type_ == booleanValue || type_ == nullValue;
|
|
920
|
-
case booleanValue:
|
|
921
|
-
return isNumeric() || type_ == booleanValue || type_ == nullValue;
|
|
922
|
-
case stringValue:
|
|
923
|
-
return isNumeric() || type_ == booleanValue || type_ == stringValue ||
|
|
924
|
-
type_ == nullValue;
|
|
925
|
-
case arrayValue:
|
|
926
|
-
return type_ == arrayValue || type_ == nullValue;
|
|
927
|
-
case objectValue:
|
|
928
|
-
return type_ == objectValue || type_ == nullValue;
|
|
929
|
-
}
|
|
930
|
-
JSON_ASSERT_UNREACHABLE;
|
|
931
|
-
return false;
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
/// Number of values in array or object
|
|
935
|
-
ArrayIndex Value::size() const {
|
|
936
|
-
switch (type_) {
|
|
937
|
-
case nullValue:
|
|
938
|
-
case intValue:
|
|
939
|
-
case uintValue:
|
|
940
|
-
case realValue:
|
|
941
|
-
case booleanValue:
|
|
942
|
-
case stringValue:
|
|
943
|
-
return 0;
|
|
944
|
-
case arrayValue: // size of the array is highest index + 1
|
|
945
|
-
if (!value_.map_->empty()) {
|
|
946
|
-
ObjectValues::const_iterator itLast = value_.map_->end();
|
|
947
|
-
--itLast;
|
|
948
|
-
return (*itLast).first.index() + 1;
|
|
949
|
-
}
|
|
950
|
-
return 0;
|
|
951
|
-
case objectValue:
|
|
952
|
-
return ArrayIndex(value_.map_->size());
|
|
953
|
-
}
|
|
954
|
-
JSON_ASSERT_UNREACHABLE;
|
|
955
|
-
return 0; // unreachable;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
bool Value::empty() const {
|
|
959
|
-
if (isNull() || isArray() || isObject())
|
|
960
|
-
return size() == 0u;
|
|
961
|
-
else
|
|
962
|
-
return false;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
Value::operator bool() const { return ! isNull(); }
|
|
966
|
-
|
|
967
|
-
void Value::clear() {
|
|
968
|
-
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
|
|
969
|
-
type_ == objectValue,
|
|
970
|
-
"in Json::Value::clear(): requires complex value");
|
|
971
|
-
start_ = 0;
|
|
972
|
-
limit_ = 0;
|
|
973
|
-
switch (type_) {
|
|
974
|
-
case arrayValue:
|
|
975
|
-
case objectValue:
|
|
976
|
-
value_.map_->clear();
|
|
977
|
-
break;
|
|
978
|
-
default:
|
|
979
|
-
break;
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
void Value::resize(ArrayIndex newSize) {
|
|
984
|
-
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
|
|
985
|
-
"in Json::Value::resize(): requires arrayValue");
|
|
986
|
-
if (type_ == nullValue)
|
|
987
|
-
*this = Value(arrayValue);
|
|
988
|
-
ArrayIndex oldSize = size();
|
|
989
|
-
if (newSize == 0)
|
|
990
|
-
clear();
|
|
991
|
-
else if (newSize > oldSize)
|
|
992
|
-
(*this)[newSize - 1];
|
|
993
|
-
else {
|
|
994
|
-
for (ArrayIndex index = newSize; index < oldSize; ++index) {
|
|
995
|
-
value_.map_->erase(index);
|
|
996
|
-
}
|
|
997
|
-
JSON_ASSERT(size() == newSize);
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
Value& Value::operator[](ArrayIndex index) {
|
|
1002
|
-
JSON_ASSERT_MESSAGE(
|
|
1003
|
-
type_ == nullValue || type_ == arrayValue,
|
|
1004
|
-
"in Json::Value::operator[](ArrayIndex): requires arrayValue");
|
|
1005
|
-
if (type_ == nullValue)
|
|
1006
|
-
*this = Value(arrayValue);
|
|
1007
|
-
CZString key(index);
|
|
1008
|
-
ObjectValues::iterator it = value_.map_->lower_bound(key);
|
|
1009
|
-
if (it != value_.map_->end() && (*it).first == key)
|
|
1010
|
-
return (*it).second;
|
|
1011
|
-
|
|
1012
|
-
ObjectValues::value_type defaultValue(key, nullSingleton());
|
|
1013
|
-
it = value_.map_->insert(it, defaultValue);
|
|
1014
|
-
return (*it).second;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
Value& Value::operator[](int index) {
|
|
1018
|
-
JSON_ASSERT_MESSAGE(
|
|
1019
|
-
index >= 0,
|
|
1020
|
-
"in Json::Value::operator[](int index): index cannot be negative");
|
|
1021
|
-
return (*this)[ArrayIndex(index)];
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
const Value& Value::operator[](ArrayIndex index) const {
|
|
1025
|
-
JSON_ASSERT_MESSAGE(
|
|
1026
|
-
type_ == nullValue || type_ == arrayValue,
|
|
1027
|
-
"in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
|
|
1028
|
-
if (type_ == nullValue)
|
|
1029
|
-
return nullSingleton();
|
|
1030
|
-
CZString key(index);
|
|
1031
|
-
ObjectValues::const_iterator it = value_.map_->find(key);
|
|
1032
|
-
if (it == value_.map_->end())
|
|
1033
|
-
return nullSingleton();
|
|
1034
|
-
return (*it).second;
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
const Value& Value::operator[](int index) const {
|
|
1038
|
-
JSON_ASSERT_MESSAGE(
|
|
1039
|
-
index >= 0,
|
|
1040
|
-
"in Json::Value::operator[](int index) const: index cannot be negative");
|
|
1041
|
-
return (*this)[ArrayIndex(index)];
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
void Value::initBasic(ValueType vtype, bool allocated) {
|
|
1045
|
-
type_ = vtype;
|
|
1046
|
-
allocated_ = allocated;
|
|
1047
|
-
comments_ = 0;
|
|
1048
|
-
start_ = 0;
|
|
1049
|
-
limit_ = 0;
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
// Access an object value by name, create a null member if it does not exist.
|
|
1053
|
-
// @pre Type of '*this' is object or null.
|
|
1054
|
-
// @param key is null-terminated.
|
|
1055
|
-
Value& Value::resolveReference(const char* key) {
|
|
1056
|
-
JSON_ASSERT_MESSAGE(
|
|
1057
|
-
type_ == nullValue || type_ == objectValue,
|
|
1058
|
-
"in Json::Value::resolveReference(): requires objectValue");
|
|
1059
|
-
if (type_ == nullValue)
|
|
1060
|
-
*this = Value(objectValue);
|
|
1061
|
-
CZString actualKey(
|
|
1062
|
-
key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
|
|
1063
|
-
ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
|
|
1064
|
-
if (it != value_.map_->end() && (*it).first == actualKey)
|
|
1065
|
-
return (*it).second;
|
|
1066
|
-
|
|
1067
|
-
ObjectValues::value_type defaultValue(actualKey, nullSingleton());
|
|
1068
|
-
it = value_.map_->insert(it, defaultValue);
|
|
1069
|
-
Value& value = (*it).second;
|
|
1070
|
-
return value;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
// @param key is not null-terminated.
|
|
1074
|
-
Value& Value::resolveReference(char const* key, char const* cend)
|
|
1075
|
-
{
|
|
1076
|
-
JSON_ASSERT_MESSAGE(
|
|
1077
|
-
type_ == nullValue || type_ == objectValue,
|
|
1078
|
-
"in Json::Value::resolveReference(key, end): requires objectValue");
|
|
1079
|
-
if (type_ == nullValue)
|
|
1080
|
-
*this = Value(objectValue);
|
|
1081
|
-
CZString actualKey(
|
|
1082
|
-
key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
|
|
1083
|
-
ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
|
|
1084
|
-
if (it != value_.map_->end() && (*it).first == actualKey)
|
|
1085
|
-
return (*it).second;
|
|
1086
|
-
|
|
1087
|
-
ObjectValues::value_type defaultValue(actualKey, nullSingleton());
|
|
1088
|
-
it = value_.map_->insert(it, defaultValue);
|
|
1089
|
-
Value& value = (*it).second;
|
|
1090
|
-
return value;
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
Value Value::get(ArrayIndex index, const Value& defaultValue) const {
|
|
1094
|
-
const Value* value = &((*this)[index]);
|
|
1095
|
-
return value == &nullSingleton() ? defaultValue : *value;
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
|
|
1099
|
-
|
|
1100
|
-
Value const* Value::find(char const* key, char const* cend) const
|
|
1101
|
-
{
|
|
1102
|
-
JSON_ASSERT_MESSAGE(
|
|
1103
|
-
type_ == nullValue || type_ == objectValue,
|
|
1104
|
-
"in Json::Value::find(key, end, found): requires objectValue or nullValue");
|
|
1105
|
-
if (type_ == nullValue) return NULL;
|
|
1106
|
-
CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
|
|
1107
|
-
ObjectValues::const_iterator it = value_.map_->find(actualKey);
|
|
1108
|
-
if (it == value_.map_->end()) return NULL;
|
|
1109
|
-
return &(*it).second;
|
|
1110
|
-
}
|
|
1111
|
-
const Value& Value::operator[](const char* key) const
|
|
1112
|
-
{
|
|
1113
|
-
Value const* found = find(key, key + strlen(key));
|
|
1114
|
-
if (!found) return nullSingleton();
|
|
1115
|
-
return *found;
|
|
1116
|
-
}
|
|
1117
|
-
Value const& Value::operator[](JSONCPP_STRING const& key) const
|
|
1118
|
-
{
|
|
1119
|
-
Value const* found = find(key.data(), key.data() + key.length());
|
|
1120
|
-
if (!found) return nullSingleton();
|
|
1121
|
-
return *found;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
Value& Value::operator[](const char* key) {
|
|
1125
|
-
return resolveReference(key, key + strlen(key));
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
Value& Value::operator[](const JSONCPP_STRING& key) {
|
|
1129
|
-
return resolveReference(key.data(), key.data() + key.length());
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
|
-
Value& Value::operator[](const StaticString& key) {
|
|
1133
|
-
return resolveReference(key.c_str());
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
#ifdef JSON_USE_CPPTL
|
|
1137
|
-
Value& Value::operator[](const CppTL::ConstString& key) {
|
|
1138
|
-
return resolveReference(key.c_str(), key.end_c_str());
|
|
1139
|
-
}
|
|
1140
|
-
Value const& Value::operator[](CppTL::ConstString const& key) const
|
|
1141
|
-
{
|
|
1142
|
-
Value const* found = find(key.c_str(), key.end_c_str());
|
|
1143
|
-
if (!found) return nullSingleton();
|
|
1144
|
-
return *found;
|
|
1145
|
-
}
|
|
1146
|
-
#endif
|
|
1147
|
-
|
|
1148
|
-
Value& Value::append(const Value& value) { return (*this)[size()] = value; }
|
|
1149
|
-
|
|
1150
|
-
#if JSON_HAS_RVALUE_REFERENCES
|
|
1151
|
-
Value& Value::append(Value&& value) { return (*this)[size()] = std::move(value); }
|
|
1152
|
-
#endif
|
|
1153
|
-
|
|
1154
|
-
Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
|
|
1155
|
-
{
|
|
1156
|
-
Value const* found = find(key, cend);
|
|
1157
|
-
return !found ? defaultValue : *found;
|
|
1158
|
-
}
|
|
1159
|
-
Value Value::get(char const* key, Value const& defaultValue) const
|
|
1160
|
-
{
|
|
1161
|
-
return get(key, key + strlen(key), defaultValue);
|
|
1162
|
-
}
|
|
1163
|
-
Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const
|
|
1164
|
-
{
|
|
1165
|
-
return get(key.data(), key.data() + key.length(), defaultValue);
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
bool Value::removeMember(const char* key, const char* cend, Value* removed)
|
|
1170
|
-
{
|
|
1171
|
-
if (type_ != objectValue) {
|
|
1172
|
-
return false;
|
|
1173
|
-
}
|
|
1174
|
-
CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
|
|
1175
|
-
ObjectValues::iterator it = value_.map_->find(actualKey);
|
|
1176
|
-
if (it == value_.map_->end())
|
|
1177
|
-
return false;
|
|
1178
|
-
*removed = it->second;
|
|
1179
|
-
value_.map_->erase(it);
|
|
1180
|
-
return true;
|
|
1181
|
-
}
|
|
1182
|
-
bool Value::removeMember(const char* key, Value* removed)
|
|
1183
|
-
{
|
|
1184
|
-
return removeMember(key, key + strlen(key), removed);
|
|
1185
|
-
}
|
|
1186
|
-
bool Value::removeMember(JSONCPP_STRING const& key, Value* removed)
|
|
1187
|
-
{
|
|
1188
|
-
return removeMember(key.data(), key.data() + key.length(), removed);
|
|
1189
|
-
}
|
|
1190
|
-
void Value::removeMember(const char* key)
|
|
1191
|
-
{
|
|
1192
|
-
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
|
|
1193
|
-
"in Json::Value::removeMember(): requires objectValue");
|
|
1194
|
-
if (type_ == nullValue)
|
|
1195
|
-
return;
|
|
1196
|
-
|
|
1197
|
-
CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
|
|
1198
|
-
value_.map_->erase(actualKey);
|
|
1199
|
-
}
|
|
1200
|
-
void Value::removeMember(const JSONCPP_STRING& key)
|
|
1201
|
-
{
|
|
1202
|
-
removeMember(key.c_str());
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
bool Value::removeIndex(ArrayIndex index, Value* removed) {
|
|
1206
|
-
if (type_ != arrayValue) {
|
|
1207
|
-
return false;
|
|
1208
|
-
}
|
|
1209
|
-
CZString key(index);
|
|
1210
|
-
ObjectValues::iterator it = value_.map_->find(key);
|
|
1211
|
-
if (it == value_.map_->end()) {
|
|
1212
|
-
return false;
|
|
1213
|
-
}
|
|
1214
|
-
*removed = it->second;
|
|
1215
|
-
ArrayIndex oldSize = size();
|
|
1216
|
-
// shift left all items left, into the place of the "removed"
|
|
1217
|
-
for (ArrayIndex i = index; i < (oldSize - 1); ++i){
|
|
1218
|
-
CZString keey(i);
|
|
1219
|
-
(*value_.map_)[keey] = (*this)[i + 1];
|
|
1220
|
-
}
|
|
1221
|
-
// erase the last one ("leftover")
|
|
1222
|
-
CZString keyLast(oldSize - 1);
|
|
1223
|
-
ObjectValues::iterator itLast = value_.map_->find(keyLast);
|
|
1224
|
-
value_.map_->erase(itLast);
|
|
1225
|
-
return true;
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
#ifdef JSON_USE_CPPTL
|
|
1229
|
-
Value Value::get(const CppTL::ConstString& key,
|
|
1230
|
-
const Value& defaultValue) const {
|
|
1231
|
-
return get(key.c_str(), key.end_c_str(), defaultValue);
|
|
1232
|
-
}
|
|
1233
|
-
#endif
|
|
1234
|
-
|
|
1235
|
-
bool Value::isMember(char const* key, char const* cend) const
|
|
1236
|
-
{
|
|
1237
|
-
Value const* value = find(key, cend);
|
|
1238
|
-
return NULL != value;
|
|
1239
|
-
}
|
|
1240
|
-
bool Value::isMember(char const* key) const
|
|
1241
|
-
{
|
|
1242
|
-
return isMember(key, key + strlen(key));
|
|
1243
|
-
}
|
|
1244
|
-
bool Value::isMember(JSONCPP_STRING const& key) const
|
|
1245
|
-
{
|
|
1246
|
-
return isMember(key.data(), key.data() + key.length());
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
#ifdef JSON_USE_CPPTL
|
|
1250
|
-
bool Value::isMember(const CppTL::ConstString& key) const {
|
|
1251
|
-
return isMember(key.c_str(), key.end_c_str());
|
|
1252
|
-
}
|
|
1253
|
-
#endif
|
|
1254
|
-
|
|
1255
|
-
Value::Members Value::getMemberNames() const {
|
|
1256
|
-
JSON_ASSERT_MESSAGE(
|
|
1257
|
-
type_ == nullValue || type_ == objectValue,
|
|
1258
|
-
"in Json::Value::getMemberNames(), value must be objectValue");
|
|
1259
|
-
if (type_ == nullValue)
|
|
1260
|
-
return Value::Members();
|
|
1261
|
-
Members members;
|
|
1262
|
-
members.reserve(value_.map_->size());
|
|
1263
|
-
ObjectValues::const_iterator it = value_.map_->begin();
|
|
1264
|
-
ObjectValues::const_iterator itEnd = value_.map_->end();
|
|
1265
|
-
for (; it != itEnd; ++it) {
|
|
1266
|
-
members.push_back(JSONCPP_STRING((*it).first.data(),
|
|
1267
|
-
(*it).first.length()));
|
|
1268
|
-
}
|
|
1269
|
-
return members;
|
|
1270
|
-
}
|
|
1271
|
-
//
|
|
1272
|
-
//# ifdef JSON_USE_CPPTL
|
|
1273
|
-
// EnumMemberNames
|
|
1274
|
-
// Value::enumMemberNames() const
|
|
1275
|
-
//{
|
|
1276
|
-
// if ( type_ == objectValue )
|
|
1277
|
-
// {
|
|
1278
|
-
// return CppTL::Enum::any( CppTL::Enum::transform(
|
|
1279
|
-
// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
|
|
1280
|
-
// MemberNamesTransform() ) );
|
|
1281
|
-
// }
|
|
1282
|
-
// return EnumMemberNames();
|
|
1283
|
-
//}
|
|
1284
|
-
//
|
|
1285
|
-
//
|
|
1286
|
-
// EnumValues
|
|
1287
|
-
// Value::enumValues() const
|
|
1288
|
-
//{
|
|
1289
|
-
// if ( type_ == objectValue || type_ == arrayValue )
|
|
1290
|
-
// return CppTL::Enum::anyValues( *(value_.map_),
|
|
1291
|
-
// CppTL::Type<const Value &>() );
|
|
1292
|
-
// return EnumValues();
|
|
1293
|
-
//}
|
|
1294
|
-
//
|
|
1295
|
-
//# endif
|
|
1296
|
-
|
|
1297
|
-
static bool IsIntegral(double d) {
|
|
1298
|
-
double integral_part;
|
|
1299
|
-
return modf(d, &integral_part) == 0.0;
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
bool Value::isNull() const { return type_ == nullValue; }
|
|
1303
|
-
|
|
1304
|
-
bool Value::isBool() const { return type_ == booleanValue; }
|
|
1305
|
-
|
|
1306
|
-
bool Value::isInt() const {
|
|
1307
|
-
switch (type_) {
|
|
1308
|
-
case intValue:
|
|
1309
|
-
#if defined(JSON_HAS_INT64)
|
|
1310
|
-
return value_.int_ >= minInt && value_.int_ <= maxInt;
|
|
1311
|
-
#else
|
|
1312
|
-
return true;
|
|
1313
|
-
#endif
|
|
1314
|
-
case uintValue:
|
|
1315
|
-
return value_.uint_ <= UInt(maxInt);
|
|
1316
|
-
case realValue:
|
|
1317
|
-
return value_.real_ >= minInt && value_.real_ <= maxInt &&
|
|
1318
|
-
IsIntegral(value_.real_);
|
|
1319
|
-
default:
|
|
1320
|
-
break;
|
|
1321
|
-
}
|
|
1322
|
-
return false;
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
bool Value::isUInt() const {
|
|
1326
|
-
switch (type_) {
|
|
1327
|
-
case intValue:
|
|
1328
|
-
#if defined(JSON_HAS_INT64)
|
|
1329
|
-
return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
|
|
1330
|
-
#else
|
|
1331
|
-
return value_.int_ >= 0;
|
|
1332
|
-
#endif
|
|
1333
|
-
case uintValue:
|
|
1334
|
-
#if defined(JSON_HAS_INT64)
|
|
1335
|
-
return value_.uint_ <= maxUInt;
|
|
1336
|
-
#else
|
|
1337
|
-
return true;
|
|
1338
|
-
#endif
|
|
1339
|
-
case realValue:
|
|
1340
|
-
return value_.real_ >= 0 && value_.real_ <= maxUInt &&
|
|
1341
|
-
IsIntegral(value_.real_);
|
|
1342
|
-
default:
|
|
1343
|
-
break;
|
|
1344
|
-
}
|
|
1345
|
-
return false;
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
bool Value::isInt64() const {
|
|
1349
|
-
#if defined(JSON_HAS_INT64)
|
|
1350
|
-
switch (type_) {
|
|
1351
|
-
case intValue:
|
|
1352
|
-
return true;
|
|
1353
|
-
case uintValue:
|
|
1354
|
-
return value_.uint_ <= UInt64(maxInt64);
|
|
1355
|
-
case realValue:
|
|
1356
|
-
// Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
|
|
1357
|
-
// double, so double(maxInt64) will be rounded up to 2^63. Therefore we
|
|
1358
|
-
// require the value to be strictly less than the limit.
|
|
1359
|
-
return value_.real_ >= double(minInt64) &&
|
|
1360
|
-
value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
|
|
1361
|
-
default:
|
|
1362
|
-
break;
|
|
1363
|
-
}
|
|
1364
|
-
#endif // JSON_HAS_INT64
|
|
1365
|
-
return false;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
bool Value::isUInt64() const {
|
|
1369
|
-
#if defined(JSON_HAS_INT64)
|
|
1370
|
-
switch (type_) {
|
|
1371
|
-
case intValue:
|
|
1372
|
-
return value_.int_ >= 0;
|
|
1373
|
-
case uintValue:
|
|
1374
|
-
return true;
|
|
1375
|
-
case realValue:
|
|
1376
|
-
// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
|
|
1377
|
-
// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
|
|
1378
|
-
// require the value to be strictly less than the limit.
|
|
1379
|
-
return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
|
|
1380
|
-
IsIntegral(value_.real_);
|
|
1381
|
-
default:
|
|
1382
|
-
break;
|
|
1383
|
-
}
|
|
1384
|
-
#endif // JSON_HAS_INT64
|
|
1385
|
-
return false;
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
bool Value::isIntegral() const {
|
|
1389
|
-
switch (type_) {
|
|
1390
|
-
case intValue:
|
|
1391
|
-
case uintValue:
|
|
1392
|
-
return true;
|
|
1393
|
-
case realValue:
|
|
1394
|
-
#if defined(JSON_HAS_INT64)
|
|
1395
|
-
// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
|
|
1396
|
-
// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
|
|
1397
|
-
// require the value to be strictly less than the limit.
|
|
1398
|
-
return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
|
|
1399
|
-
#else
|
|
1400
|
-
return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_);
|
|
1401
|
-
#endif // JSON_HAS_INT64
|
|
1402
|
-
default:
|
|
1403
|
-
break;
|
|
1404
|
-
}
|
|
1405
|
-
return false;
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; }
|
|
1409
|
-
|
|
1410
|
-
bool Value::isNumeric() const { return isDouble(); }
|
|
1411
|
-
|
|
1412
|
-
bool Value::isString() const { return type_ == stringValue; }
|
|
1413
|
-
|
|
1414
|
-
bool Value::isArray() const { return type_ == arrayValue; }
|
|
1415
|
-
|
|
1416
|
-
bool Value::isObject() const { return type_ == objectValue; }
|
|
1417
|
-
|
|
1418
|
-
void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
|
|
1419
|
-
if (!comments_)
|
|
1420
|
-
comments_ = new CommentInfo[numberOfCommentPlacement];
|
|
1421
|
-
if ((len > 0) && (comment[len-1] == '\n')) {
|
|
1422
|
-
// Always discard trailing newline, to aid indentation.
|
|
1423
|
-
len -= 1;
|
|
1424
|
-
}
|
|
1425
|
-
comments_[placement].setComment(comment, len);
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
void Value::setComment(const char* comment, CommentPlacement placement) {
|
|
1429
|
-
setComment(comment, strlen(comment), placement);
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) {
|
|
1433
|
-
setComment(comment.c_str(), comment.length(), placement);
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
bool Value::hasComment(CommentPlacement placement) const {
|
|
1437
|
-
return comments_ != 0 && comments_[placement].comment_ != 0;
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
|
|
1441
|
-
if (hasComment(placement))
|
|
1442
|
-
return comments_[placement].comment_;
|
|
1443
|
-
return "";
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
|
|
1447
|
-
|
|
1448
|
-
void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
|
|
1449
|
-
|
|
1450
|
-
ptrdiff_t Value::getOffsetStart() const { return start_; }
|
|
1451
|
-
|
|
1452
|
-
ptrdiff_t Value::getOffsetLimit() const { return limit_; }
|
|
1453
|
-
|
|
1454
|
-
JSONCPP_STRING Value::toStyledString() const {
|
|
1455
|
-
StreamWriterBuilder builder;
|
|
1456
|
-
|
|
1457
|
-
JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : "";
|
|
1458
|
-
out += Json::writeString(builder, *this);
|
|
1459
|
-
out += "\n";
|
|
1460
|
-
|
|
1461
|
-
return out;
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
Value::const_iterator Value::begin() const {
|
|
1465
|
-
switch (type_) {
|
|
1466
|
-
case arrayValue:
|
|
1467
|
-
case objectValue:
|
|
1468
|
-
if (value_.map_)
|
|
1469
|
-
return const_iterator(value_.map_->begin());
|
|
1470
|
-
break;
|
|
1471
|
-
default:
|
|
1472
|
-
break;
|
|
1473
|
-
}
|
|
1474
|
-
return const_iterator();
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
Value::const_iterator Value::end() const {
|
|
1478
|
-
switch (type_) {
|
|
1479
|
-
case arrayValue:
|
|
1480
|
-
case objectValue:
|
|
1481
|
-
if (value_.map_)
|
|
1482
|
-
return const_iterator(value_.map_->end());
|
|
1483
|
-
break;
|
|
1484
|
-
default:
|
|
1485
|
-
break;
|
|
1486
|
-
}
|
|
1487
|
-
return const_iterator();
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
Value::iterator Value::begin() {
|
|
1491
|
-
switch (type_) {
|
|
1492
|
-
case arrayValue:
|
|
1493
|
-
case objectValue:
|
|
1494
|
-
if (value_.map_)
|
|
1495
|
-
return iterator(value_.map_->begin());
|
|
1496
|
-
break;
|
|
1497
|
-
default:
|
|
1498
|
-
break;
|
|
1499
|
-
}
|
|
1500
|
-
return iterator();
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
Value::iterator Value::end() {
|
|
1504
|
-
switch (type_) {
|
|
1505
|
-
case arrayValue:
|
|
1506
|
-
case objectValue:
|
|
1507
|
-
if (value_.map_)
|
|
1508
|
-
return iterator(value_.map_->end());
|
|
1509
|
-
break;
|
|
1510
|
-
default:
|
|
1511
|
-
break;
|
|
1512
|
-
}
|
|
1513
|
-
return iterator();
|
|
1514
|
-
}
|
|
1515
|
-
|
|
1516
|
-
// class PathArgument
|
|
1517
|
-
// //////////////////////////////////////////////////////////////////
|
|
1518
|
-
|
|
1519
|
-
PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
|
|
1520
|
-
|
|
1521
|
-
PathArgument::PathArgument(ArrayIndex index)
|
|
1522
|
-
: key_(), index_(index), kind_(kindIndex) {}
|
|
1523
|
-
|
|
1524
|
-
PathArgument::PathArgument(const char* key)
|
|
1525
|
-
: key_(key), index_(), kind_(kindKey) {}
|
|
1526
|
-
|
|
1527
|
-
PathArgument::PathArgument(const JSONCPP_STRING& key)
|
|
1528
|
-
: key_(key.c_str()), index_(), kind_(kindKey) {}
|
|
1529
|
-
|
|
1530
|
-
// class Path
|
|
1531
|
-
// //////////////////////////////////////////////////////////////////
|
|
1532
|
-
|
|
1533
|
-
Path::Path(const JSONCPP_STRING& path,
|
|
1534
|
-
const PathArgument& a1,
|
|
1535
|
-
const PathArgument& a2,
|
|
1536
|
-
const PathArgument& a3,
|
|
1537
|
-
const PathArgument& a4,
|
|
1538
|
-
const PathArgument& a5) {
|
|
1539
|
-
InArgs in;
|
|
1540
|
-
in.reserve(5);
|
|
1541
|
-
in.push_back(&a1);
|
|
1542
|
-
in.push_back(&a2);
|
|
1543
|
-
in.push_back(&a3);
|
|
1544
|
-
in.push_back(&a4);
|
|
1545
|
-
in.push_back(&a5);
|
|
1546
|
-
makePath(path, in);
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) {
|
|
1550
|
-
const char* current = path.c_str();
|
|
1551
|
-
const char* end = current + path.length();
|
|
1552
|
-
InArgs::const_iterator itInArg = in.begin();
|
|
1553
|
-
while (current != end) {
|
|
1554
|
-
if (*current == '[') {
|
|
1555
|
-
++current;
|
|
1556
|
-
if (*current == '%')
|
|
1557
|
-
addPathInArg(path, in, itInArg, PathArgument::kindIndex);
|
|
1558
|
-
else {
|
|
1559
|
-
ArrayIndex index = 0;
|
|
1560
|
-
for (; current != end && *current >= '0' && *current <= '9'; ++current)
|
|
1561
|
-
index = index * 10 + ArrayIndex(*current - '0');
|
|
1562
|
-
args_.push_back(index);
|
|
1563
|
-
}
|
|
1564
|
-
if (current == end || *++current != ']')
|
|
1565
|
-
invalidPath(path, int(current - path.c_str()));
|
|
1566
|
-
} else if (*current == '%') {
|
|
1567
|
-
addPathInArg(path, in, itInArg, PathArgument::kindKey);
|
|
1568
|
-
++current;
|
|
1569
|
-
} else if (*current == '.' || *current == ']') {
|
|
1570
|
-
++current;
|
|
1571
|
-
} else {
|
|
1572
|
-
const char* beginName = current;
|
|
1573
|
-
while (current != end && !strchr("[.", *current))
|
|
1574
|
-
++current;
|
|
1575
|
-
args_.push_back(JSONCPP_STRING(beginName, current));
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
void Path::addPathInArg(const JSONCPP_STRING& /*path*/,
|
|
1581
|
-
const InArgs& in,
|
|
1582
|
-
InArgs::const_iterator& itInArg,
|
|
1583
|
-
PathArgument::Kind kind) {
|
|
1584
|
-
if (itInArg == in.end()) {
|
|
1585
|
-
// Error: missing argument %d
|
|
1586
|
-
} else if ((*itInArg)->kind_ != kind) {
|
|
1587
|
-
// Error: bad argument type
|
|
1588
|
-
} else {
|
|
1589
|
-
args_.push_back(**itInArg++);
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) {
|
|
1594
|
-
// Error: invalid path.
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
const Value& Path::resolve(const Value& root) const {
|
|
1598
|
-
const Value* node = &root;
|
|
1599
|
-
for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
|
|
1600
|
-
const PathArgument& arg = *it;
|
|
1601
|
-
if (arg.kind_ == PathArgument::kindIndex) {
|
|
1602
|
-
if (!node->isArray() || !node->isValidIndex(arg.index_)) {
|
|
1603
|
-
// Error: unable to resolve path (array value expected at position...
|
|
1604
|
-
return Value::null;
|
|
1605
|
-
}
|
|
1606
|
-
node = &((*node)[arg.index_]);
|
|
1607
|
-
} else if (arg.kind_ == PathArgument::kindKey) {
|
|
1608
|
-
if (!node->isObject()) {
|
|
1609
|
-
// Error: unable to resolve path (object value expected at position...)
|
|
1610
|
-
return Value::null;
|
|
1611
|
-
}
|
|
1612
|
-
node = &((*node)[arg.key_]);
|
|
1613
|
-
if (node == &Value::nullSingleton()) {
|
|
1614
|
-
// Error: unable to resolve path (object has no member named '' at
|
|
1615
|
-
// position...)
|
|
1616
|
-
return Value::null;
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
return *node;
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
Value Path::resolve(const Value& root, const Value& defaultValue) const {
|
|
1624
|
-
const Value* node = &root;
|
|
1625
|
-
for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
|
|
1626
|
-
const PathArgument& arg = *it;
|
|
1627
|
-
if (arg.kind_ == PathArgument::kindIndex) {
|
|
1628
|
-
if (!node->isArray() || !node->isValidIndex(arg.index_))
|
|
1629
|
-
return defaultValue;
|
|
1630
|
-
node = &((*node)[arg.index_]);
|
|
1631
|
-
} else if (arg.kind_ == PathArgument::kindKey) {
|
|
1632
|
-
if (!node->isObject())
|
|
1633
|
-
return defaultValue;
|
|
1634
|
-
node = &((*node)[arg.key_]);
|
|
1635
|
-
if (node == &Value::nullSingleton())
|
|
1636
|
-
return defaultValue;
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
return *node;
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
Value& Path::make(Value& root) const {
|
|
1643
|
-
Value* node = &root;
|
|
1644
|
-
for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
|
|
1645
|
-
const PathArgument& arg = *it;
|
|
1646
|
-
if (arg.kind_ == PathArgument::kindIndex) {
|
|
1647
|
-
if (!node->isArray()) {
|
|
1648
|
-
// Error: node is not an array at position ...
|
|
1649
|
-
}
|
|
1650
|
-
node = &((*node)[arg.index_]);
|
|
1651
|
-
} else if (arg.kind_ == PathArgument::kindKey) {
|
|
1652
|
-
if (!node->isObject()) {
|
|
1653
|
-
// Error: node is not an object at position...
|
|
1654
|
-
}
|
|
1655
|
-
node = &((*node)[arg.key_]);
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
return *node;
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
|
-
} // namespace Json
|