blob: 0872ff548727558825d6165798301c7b50be350e [file] [log] [blame]
Haibo Huangb0bee822021-02-24 15:40:15 -08001// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04002// 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)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05007#include <json/assertions.h>
8#include <json/value.h>
9#include <json/writer.h>
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040010#endif // if !defined(JSON_IS_AMALGAMATION)
Haibo Huangb0bee822021-02-24 15:40:15 -080011#include <algorithm>
12#include <cassert>
13#include <cmath>
14#include <cstddef>
15#include <cstring>
16#include <iostream>
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040017#include <sstream>
18#include <utility>
Haibo Huangb0bee822021-02-24 15:40:15 -080019
20// Provide implementation equivalent of std::snprintf for older _MSC compilers
21#if defined(_MSC_VER) && _MSC_VER < 1900
22#include <stdarg.h>
23static int msvc_pre1900_c99_vsnprintf(char* outBuf, size_t size,
24 const char* format, va_list ap) {
25 int count = -1;
26 if (size != 0)
27 count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
28 if (count == -1)
29 count = _vscprintf(format, ap);
30 return count;
31}
32
33int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
34 const char* format, ...) {
35 va_list ap;
36 va_start(ap, format);
37 const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap);
38 va_end(ap);
39 return count;
40}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040041#endif
Haibo Huangb0bee822021-02-24 15:40:15 -080042
43// Disable warning C4702 : unreachable code
44#if defined(_MSC_VER)
45#pragma warning(disable : 4702)
46#endif
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040047
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050048#define JSON_ASSERT_UNREACHABLE assert(false)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040049
50namespace Json {
Haibo Huangb0bee822021-02-24 15:40:15 -080051template <typename T>
52static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) {
53 std::unique_ptr<T> r;
54 if (p) {
55 r = std::unique_ptr<T>(new T(*p));
56 }
57 return r;
58}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040059
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050060// This is a walkaround to avoid the static initialization of Value::null.
61// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
62// 8 (instead of 4) as a bit of future-proofing.
63#if defined(__ARMEL__)
64#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
65#else
66#define ALIGNAS(byte_alignment)
67#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050068
Haibo Huangb0bee822021-02-24 15:40:15 -080069// static
70Value const& Value::nullSingleton() {
71 static Value const nullStatic;
72 return nullStatic;
73}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040074
Haibo Huangb0bee822021-02-24 15:40:15 -080075#if JSON_USE_NULLREF
76// for backwards compatibility, we'll leave these global references around, but
77// DO NOT use them in JSONCPP library code any more!
78// static
79Value const& Value::null = Value::nullSingleton();
80
81// static
82Value const& Value::nullRef = Value::nullSingleton();
83#endif
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040084
85#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
86template <typename T, typename U>
87static inline bool InRange(double d, T min, U max) {
Haibo Huangb0bee822021-02-24 15:40:15 -080088 // The casts can lose precision, but we are looking only for
89 // an approximate range. Might fail on edge cases though. ~cdunn
90 return d >= static_cast<double>(min) && d <= static_cast<double>(max);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040091}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050092#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
93static inline double integerToDouble(Json::UInt64 value) {
Haibo Huangb0bee822021-02-24 15:40:15 -080094 return static_cast<double>(Int64(value / 2)) * 2.0 +
95 static_cast<double>(Int64(value & 1));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040096}
97
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050098template <typename T> static inline double integerToDouble(T value) {
99 return static_cast<double>(value);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400100}
101
102template <typename T, typename U>
103static inline bool InRange(double d, T min, U max) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500104 return d >= integerToDouble(min) && d <= integerToDouble(max);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400105}
106#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
107
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400108/** Duplicates the specified string value.
109 * @param value Pointer to the string to duplicate. Must be zero-terminated if
110 * length is "unknown".
111 * @param length Length of the value. if equals to unknown, then it will be
112 * computed using strlen(value).
113 * @return Pointer on the duplicate instance of string.
114 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800115static inline char* duplicateStringValue(const char* value, size_t length) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500116 // Avoid an integer overflow in the call to malloc below by limiting length
117 // to a sane value.
Haibo Huangb0bee822021-02-24 15:40:15 -0800118 if (length >= static_cast<size_t>(Value::maxInt))
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500119 length = Value::maxInt - 1;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400120
Haibo Huangb0bee822021-02-24 15:40:15 -0800121 auto newString = static_cast<char*>(malloc(length + 1));
122 if (newString == nullptr) {
123 throwRuntimeError("in Json::Value::duplicateStringValue(): "
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500124 "Failed to allocate string value buffer");
Haibo Huangb0bee822021-02-24 15:40:15 -0800125 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500126 memcpy(newString, value, length);
127 newString[length] = 0;
128 return newString;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400129}
130
Haibo Huangb0bee822021-02-24 15:40:15 -0800131/* Record the length as a prefix.
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400132 */
Haibo Huangb0bee822021-02-24 15:40:15 -0800133static inline char* duplicateAndPrefixStringValue(const char* value,
134 unsigned int length) {
135 // Avoid an integer overflow in the call to malloc below by limiting length
136 // to a sane value.
137 JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) -
138 sizeof(unsigned) - 1U,
139 "in Json::Value::duplicateAndPrefixStringValue(): "
140 "length too big for prefixing");
141 size_t actualLength = sizeof(length) + length + 1;
142 auto newString = static_cast<char*>(malloc(actualLength));
143 if (newString == nullptr) {
144 throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): "
145 "Failed to allocate string value buffer");
146 }
147 *reinterpret_cast<unsigned*>(newString) = length;
148 memcpy(newString + sizeof(unsigned), value, length);
149 newString[actualLength - 1U] =
150 0; // to avoid buffer over-run accidents by users later
151 return newString;
152}
153inline static void decodePrefixedString(bool isPrefixed, char const* prefixed,
154 unsigned* length, char const** value) {
155 if (!isPrefixed) {
156 *length = static_cast<unsigned>(strlen(prefixed));
157 *value = prefixed;
158 } else {
159 *length = *reinterpret_cast<unsigned const*>(prefixed);
160 *value = prefixed + sizeof(unsigned);
161 }
162}
163/** Free the string duplicated by
164 * duplicateStringValue()/duplicateAndPrefixStringValue().
165 */
166#if JSONCPP_USING_SECURE_MEMORY
167static inline void releasePrefixedStringValue(char* value) {
168 unsigned length = 0;
169 char const* valueDecoded;
170 decodePrefixedString(true, value, &length, &valueDecoded);
171 size_t const size = sizeof(unsigned) + length + 1U;
172 memset(value, 0, size);
173 free(value);
174}
175static inline void releaseStringValue(char* value, unsigned length) {
176 // length==0 => we allocated the strings memory
177 size_t size = (length == 0) ? strlen(value) : length;
178 memset(value, 0, size);
179 free(value);
180}
181#else // !JSONCPP_USING_SECURE_MEMORY
182static inline void releasePrefixedStringValue(char* value) { free(value); }
183static inline void releaseStringValue(char* value, unsigned) { free(value); }
184#endif // JSONCPP_USING_SECURE_MEMORY
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400185
186} // namespace Json
187
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400188// //////////////////////////////////////////////////////////////////
189// //////////////////////////////////////////////////////////////////
190// //////////////////////////////////////////////////////////////////
191// ValueInternals...
192// //////////////////////////////////////////////////////////////////
193// //////////////////////////////////////////////////////////////////
194// //////////////////////////////////////////////////////////////////
195#if !defined(JSON_IS_AMALGAMATION)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400196
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500197#include "json_valueiterator.inl"
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400198#endif // if !defined(JSON_IS_AMALGAMATION)
199
200namespace Json {
201
Haibo Huangb0bee822021-02-24 15:40:15 -0800202#if JSON_USE_EXCEPTION
203Exception::Exception(String msg) : msg_(std::move(msg)) {}
204Exception::~Exception() noexcept = default;
205char const* Exception::what() const noexcept { return msg_.c_str(); }
206RuntimeError::RuntimeError(String const& msg) : Exception(msg) {}
207LogicError::LogicError(String const& msg) : Exception(msg) {}
208JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
209 throw RuntimeError(msg);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400210}
Haibo Huangb0bee822021-02-24 15:40:15 -0800211JSONCPP_NORETURN void throwLogicError(String const& msg) {
212 throw LogicError(msg);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400213}
Haibo Huangb0bee822021-02-24 15:40:15 -0800214#else // !JSON_USE_EXCEPTION
215JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
216 std::cerr << msg << std::endl;
217 abort();
218}
219JSONCPP_NORETURN void throwLogicError(String const& msg) {
220 std::cerr << msg << std::endl;
221 abort();
222}
223#endif
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400224
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400225// //////////////////////////////////////////////////////////////////
226// //////////////////////////////////////////////////////////////////
227// //////////////////////////////////////////////////////////////////
228// class Value::CZString
229// //////////////////////////////////////////////////////////////////
230// //////////////////////////////////////////////////////////////////
231// //////////////////////////////////////////////////////////////////
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400232
Haibo Huangb0bee822021-02-24 15:40:15 -0800233// Notes: policy_ indicates if the string was allocated when
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400234// a string is stored.
235
Haibo Huangb0bee822021-02-24 15:40:15 -0800236Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500237
Haibo Huangb0bee822021-02-24 15:40:15 -0800238Value::CZString::CZString(char const* str, unsigned length,
239 DuplicationPolicy allocate)
240 : cstr_(str) {
241 // allocate != duplicate
242 storage_.policy_ = allocate & 0x3;
243 storage_.length_ = length & 0x3FFFFFFF;
244}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500245
Haibo Huangb0bee822021-02-24 15:40:15 -0800246Value::CZString::CZString(const CZString& other) {
247 cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr
248 ? duplicateStringValue(other.cstr_, other.storage_.length_)
249 : other.cstr_);
250 storage_.policy_ =
251 static_cast<unsigned>(
252 other.cstr_
253 ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
254 noDuplication
255 ? noDuplication
256 : duplicate)
257 : static_cast<DuplicationPolicy>(other.storage_.policy_)) &
258 3U;
259 storage_.length_ = other.storage_.length_;
260}
261
262Value::CZString::CZString(CZString&& other)
263 : cstr_(other.cstr_), index_(other.index_) {
264 other.cstr_ = nullptr;
265}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500266
267Value::CZString::~CZString() {
Haibo Huangb0bee822021-02-24 15:40:15 -0800268 if (cstr_ && storage_.policy_ == duplicate) {
269 releaseStringValue(const_cast<char*>(cstr_),
270 storage_.length_ + 1U); // +1 for null terminating
271 // character for sake of
272 // completeness but not actually
273 // necessary
274 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400275}
276
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500277void Value::CZString::swap(CZString& other) {
278 std::swap(cstr_, other.cstr_);
279 std::swap(index_, other.index_);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400280}
281
Haibo Huangb0bee822021-02-24 15:40:15 -0800282Value::CZString& Value::CZString::operator=(const CZString& other) {
283 cstr_ = other.cstr_;
284 index_ = other.index_;
285 return *this;
286}
287
288Value::CZString& Value::CZString::operator=(CZString&& other) {
289 cstr_ = other.cstr_;
290 index_ = other.index_;
291 other.cstr_ = nullptr;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500292 return *this;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400293}
294
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500295bool Value::CZString::operator<(const CZString& other) const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800296 if (!cstr_)
297 return index_ < other.index_;
298 // return strcmp(cstr_, other.cstr_) < 0;
299 // Assume both are strings.
300 unsigned this_len = this->storage_.length_;
301 unsigned other_len = other.storage_.length_;
302 unsigned min_len = std::min<unsigned>(this_len, other_len);
303 JSON_ASSERT(this->cstr_ && other.cstr_);
304 int comp = memcmp(this->cstr_, other.cstr_, min_len);
305 if (comp < 0)
306 return true;
307 if (comp > 0)
308 return false;
309 return (this_len < other_len);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400310}
311
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500312bool Value::CZString::operator==(const CZString& other) const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800313 if (!cstr_)
314 return index_ == other.index_;
315 // return strcmp(cstr_, other.cstr_) == 0;
316 // Assume both are strings.
317 unsigned this_len = this->storage_.length_;
318 unsigned other_len = other.storage_.length_;
319 if (this_len != other_len)
320 return false;
321 JSON_ASSERT(this->cstr_ && other.cstr_);
322 int comp = memcmp(this->cstr_, other.cstr_, this_len);
323 return comp == 0;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400324}
325
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500326ArrayIndex Value::CZString::index() const { return index_; }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400327
Haibo Huangb0bee822021-02-24 15:40:15 -0800328// const char* Value::CZString::c_str() const { return cstr_; }
329const char* Value::CZString::data() const { return cstr_; }
330unsigned Value::CZString::length() const { return storage_.length_; }
331bool Value::CZString::isStaticString() const {
332 return storage_.policy_ == noDuplication;
333}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400334
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400335// //////////////////////////////////////////////////////////////////
336// //////////////////////////////////////////////////////////////////
337// //////////////////////////////////////////////////////////////////
338// class Value::Value
339// //////////////////////////////////////////////////////////////////
340// //////////////////////////////////////////////////////////////////
341// //////////////////////////////////////////////////////////////////
342
343/*! \internal Default constructor initialization must be equivalent to:
344 * memset( this, 0, sizeof(Value) )
345 * This optimization is used in ValueInternalMap fast allocator.
346 */
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500347Value::Value(ValueType type) {
Haibo Huangb0bee822021-02-24 15:40:15 -0800348 static char const emptyString[] = "";
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500349 initBasic(type);
350 switch (type) {
351 case nullValue:
352 break;
353 case intValue:
354 case uintValue:
355 value_.int_ = 0;
356 break;
357 case realValue:
358 value_.real_ = 0.0;
359 break;
360 case stringValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800361 // allocated_ == false, so this is safe.
362 value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500363 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500364 case arrayValue:
365 case objectValue:
366 value_.map_ = new ObjectValues();
367 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500368 case booleanValue:
369 value_.bool_ = false;
370 break;
371 default:
372 JSON_ASSERT_UNREACHABLE;
373 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400374}
375
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500376Value::Value(Int value) {
377 initBasic(intValue);
378 value_.int_ = value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400379}
380
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500381Value::Value(UInt value) {
382 initBasic(uintValue);
383 value_.uint_ = value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400384}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500385#if defined(JSON_HAS_INT64)
386Value::Value(Int64 value) {
387 initBasic(intValue);
388 value_.int_ = value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400389}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500390Value::Value(UInt64 value) {
391 initBasic(uintValue);
392 value_.uint_ = value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400393}
394#endif // defined(JSON_HAS_INT64)
395
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500396Value::Value(double value) {
397 initBasic(realValue);
398 value_.real_ = value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400399}
400
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500401Value::Value(const char* value) {
402 initBasic(stringValue, true);
Haibo Huangb0bee822021-02-24 15:40:15 -0800403 JSON_ASSERT_MESSAGE(value != nullptr,
404 "Null Value Passed to Value Constructor");
405 value_.string_ = duplicateAndPrefixStringValue(
406 value, static_cast<unsigned>(strlen(value)));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400407}
408
Haibo Huangb0bee822021-02-24 15:40:15 -0800409Value::Value(const char* begin, const char* end) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500410 initBasic(stringValue, true);
411 value_.string_ =
Haibo Huangb0bee822021-02-24 15:40:15 -0800412 duplicateAndPrefixStringValue(begin, static_cast<unsigned>(end - begin));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400413}
414
Haibo Huangb0bee822021-02-24 15:40:15 -0800415Value::Value(const String& value) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500416 initBasic(stringValue, true);
Haibo Huangb0bee822021-02-24 15:40:15 -0800417 value_.string_ = duplicateAndPrefixStringValue(
418 value.data(), static_cast<unsigned>(value.length()));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400419}
420
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500421Value::Value(const StaticString& value) {
422 initBasic(stringValue);
423 value_.string_ = const_cast<char*>(value.c_str());
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400424}
425
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500426Value::Value(bool value) {
427 initBasic(booleanValue);
428 value_.bool_ = value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400429}
430
Haibo Huangb0bee822021-02-24 15:40:15 -0800431Value::Value(const Value& other) {
432 dupPayload(other);
433 dupMeta(other);
434}
435
436Value::Value(Value&& other) {
437 initBasic(nullValue);
438 swap(other);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400439}
440
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500441Value::~Value() {
Haibo Huangb0bee822021-02-24 15:40:15 -0800442 releasePayload();
443 value_.uint_ = 0;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400444}
445
Haibo Huangb0bee822021-02-24 15:40:15 -0800446Value& Value::operator=(const Value& other) {
447 Value(other).swap(*this);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500448 return *this;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400449}
450
Haibo Huangb0bee822021-02-24 15:40:15 -0800451Value& Value::operator=(Value&& other) {
452 other.swap(*this);
453 return *this;
454}
455
456void Value::swapPayload(Value& other) {
457 std::swap(bits_, other.bits_);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500458 std::swap(value_, other.value_);
Haibo Huangb0bee822021-02-24 15:40:15 -0800459}
460
461void Value::copyPayload(const Value& other) {
462 releasePayload();
463 dupPayload(other);
464}
465
466void Value::swap(Value& other) {
467 swapPayload(other);
468 std::swap(comments_, other.comments_);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500469 std::swap(start_, other.start_);
470 std::swap(limit_, other.limit_);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400471}
472
Haibo Huangb0bee822021-02-24 15:40:15 -0800473void Value::copy(const Value& other) {
474 copyPayload(other);
475 dupMeta(other);
476}
477
478ValueType Value::type() const {
479 return static_cast<ValueType>(bits_.value_type_);
480}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500481
482int Value::compare(const Value& other) const {
483 if (*this < other)
484 return -1;
485 if (*this > other)
486 return 1;
487 return 0;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400488}
489
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500490bool Value::operator<(const Value& other) const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800491 int typeDelta = type() - other.type();
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500492 if (typeDelta)
Haibo Huangb0bee822021-02-24 15:40:15 -0800493 return typeDelta < 0;
494 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500495 case nullValue:
496 return false;
497 case intValue:
498 return value_.int_ < other.value_.int_;
499 case uintValue:
500 return value_.uint_ < other.value_.uint_;
501 case realValue:
502 return value_.real_ < other.value_.real_;
503 case booleanValue:
504 return value_.bool_ < other.value_.bool_;
Haibo Huangb0bee822021-02-24 15:40:15 -0800505 case stringValue: {
506 if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
507 return other.value_.string_ != nullptr;
508 }
509 unsigned this_len;
510 unsigned other_len;
511 char const* this_str;
512 char const* other_str;
513 decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
514 &this_str);
515 decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
516 &other_str);
517 unsigned min_len = std::min<unsigned>(this_len, other_len);
518 JSON_ASSERT(this_str && other_str);
519 int comp = memcmp(this_str, other_str, min_len);
520 if (comp < 0)
521 return true;
522 if (comp > 0)
523 return false;
524 return (this_len < other_len);
525 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500526 case arrayValue:
527 case objectValue: {
Haibo Huangb0bee822021-02-24 15:40:15 -0800528 auto thisSize = value_.map_->size();
529 auto otherSize = other.value_.map_->size();
530 if (thisSize != otherSize)
531 return thisSize < otherSize;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500532 return (*value_.map_) < (*other.value_.map_);
533 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500534 default:
535 JSON_ASSERT_UNREACHABLE;
536 }
537 return false; // unreachable
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400538}
539
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500540bool Value::operator<=(const Value& other) const { return !(other < *this); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400541
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500542bool Value::operator>=(const Value& other) const { return !(*this < other); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400543
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500544bool Value::operator>(const Value& other) const { return other < *this; }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400545
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500546bool Value::operator==(const Value& other) const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800547 if (type() != other.type())
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500548 return false;
Haibo Huangb0bee822021-02-24 15:40:15 -0800549 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500550 case nullValue:
551 return true;
552 case intValue:
553 return value_.int_ == other.value_.int_;
554 case uintValue:
555 return value_.uint_ == other.value_.uint_;
556 case realValue:
557 return value_.real_ == other.value_.real_;
558 case booleanValue:
559 return value_.bool_ == other.value_.bool_;
Haibo Huangb0bee822021-02-24 15:40:15 -0800560 case stringValue: {
561 if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
562 return (value_.string_ == other.value_.string_);
563 }
564 unsigned this_len;
565 unsigned other_len;
566 char const* this_str;
567 char const* other_str;
568 decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
569 &this_str);
570 decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
571 &other_str);
572 if (this_len != other_len)
573 return false;
574 JSON_ASSERT(this_str && other_str);
575 int comp = memcmp(this_str, other_str, this_len);
576 return comp == 0;
577 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500578 case arrayValue:
579 case objectValue:
580 return value_.map_->size() == other.value_.map_->size() &&
581 (*value_.map_) == (*other.value_.map_);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500582 default:
583 JSON_ASSERT_UNREACHABLE;
584 }
585 return false; // unreachable
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400586}
587
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500588bool Value::operator!=(const Value& other) const { return !(*this == other); }
589
590const char* Value::asCString() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800591 JSON_ASSERT_MESSAGE(type() == stringValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500592 "in Json::Value::asCString(): requires stringValue");
Haibo Huangb0bee822021-02-24 15:40:15 -0800593 if (value_.string_ == nullptr)
594 return nullptr;
595 unsigned this_len;
596 char const* this_str;
597 decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
598 &this_str);
599 return this_str;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400600}
601
Haibo Huangb0bee822021-02-24 15:40:15 -0800602#if JSONCPP_USING_SECURE_MEMORY
603unsigned Value::getCStringLength() const {
604 JSON_ASSERT_MESSAGE(type() == stringValue,
605 "in Json::Value::asCString(): requires stringValue");
606 if (value_.string_ == 0)
607 return 0;
608 unsigned this_len;
609 char const* this_str;
610 decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
611 &this_str);
612 return this_len;
613}
614#endif
615
616bool Value::getString(char const** begin, char const** end) const {
617 if (type() != stringValue)
618 return false;
619 if (value_.string_ == nullptr)
620 return false;
621 unsigned length;
622 decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
623 begin);
624 *end = *begin + length;
625 return true;
626}
627
628String Value::asString() const {
629 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500630 case nullValue:
631 return "";
Haibo Huangb0bee822021-02-24 15:40:15 -0800632 case stringValue: {
633 if (value_.string_ == nullptr)
634 return "";
635 unsigned this_len;
636 char const* this_str;
637 decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
638 &this_str);
639 return String(this_str, this_len);
640 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500641 case booleanValue:
642 return value_.bool_ ? "true" : "false";
643 case intValue:
644 return valueToString(value_.int_);
645 case uintValue:
646 return valueToString(value_.uint_);
647 case realValue:
648 return valueToString(value_.real_);
649 default:
650 JSON_FAIL_MESSAGE("Type is not convertible to string");
651 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400652}
653
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500654Value::Int Value::asInt() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800655 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500656 case intValue:
657 JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
658 return Int(value_.int_);
659 case uintValue:
660 JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
661 return Int(value_.uint_);
662 case realValue:
663 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
664 "double out of Int range");
665 return Int(value_.real_);
666 case nullValue:
667 return 0;
668 case booleanValue:
669 return value_.bool_ ? 1 : 0;
670 default:
671 break;
672 }
673 JSON_FAIL_MESSAGE("Value is not convertible to Int.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400674}
675
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500676Value::UInt Value::asUInt() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800677 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500678 case intValue:
679 JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
680 return UInt(value_.int_);
681 case uintValue:
682 JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
683 return UInt(value_.uint_);
684 case realValue:
685 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
686 "double out of UInt range");
687 return UInt(value_.real_);
688 case nullValue:
689 return 0;
690 case booleanValue:
691 return value_.bool_ ? 1 : 0;
692 default:
693 break;
694 }
695 JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400696}
697
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500698#if defined(JSON_HAS_INT64)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400699
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500700Value::Int64 Value::asInt64() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800701 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500702 case intValue:
703 return Int64(value_.int_);
704 case uintValue:
705 JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
706 return Int64(value_.uint_);
707 case realValue:
708 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
709 "double out of Int64 range");
710 return Int64(value_.real_);
711 case nullValue:
712 return 0;
713 case booleanValue:
714 return value_.bool_ ? 1 : 0;
715 default:
716 break;
717 }
718 JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400719}
720
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500721Value::UInt64 Value::asUInt64() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800722 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500723 case intValue:
724 JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
725 return UInt64(value_.int_);
726 case uintValue:
727 return UInt64(value_.uint_);
728 case realValue:
729 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
730 "double out of UInt64 range");
731 return UInt64(value_.real_);
732 case nullValue:
733 return 0;
734 case booleanValue:
735 return value_.bool_ ? 1 : 0;
736 default:
737 break;
738 }
739 JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400740}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500741#endif // if defined(JSON_HAS_INT64)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400742
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500743LargestInt Value::asLargestInt() const {
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400744#if defined(JSON_NO_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500745 return asInt();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400746#else
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500747 return asInt64();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400748#endif
749}
750
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500751LargestUInt Value::asLargestUInt() const {
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400752#if defined(JSON_NO_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500753 return asUInt();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400754#else
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500755 return asUInt64();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400756#endif
757}
758
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500759double Value::asDouble() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800760 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500761 case intValue:
762 return static_cast<double>(value_.int_);
763 case uintValue:
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400764#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500765 return static_cast<double>(value_.uint_);
766#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
767 return integerToDouble(value_.uint_);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400768#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500769 case realValue:
770 return value_.real_;
771 case nullValue:
772 return 0.0;
773 case booleanValue:
774 return value_.bool_ ? 1.0 : 0.0;
775 default:
776 break;
777 }
778 JSON_FAIL_MESSAGE("Value is not convertible to double.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400779}
780
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500781float Value::asFloat() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800782 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500783 case intValue:
784 return static_cast<float>(value_.int_);
785 case uintValue:
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400786#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500787 return static_cast<float>(value_.uint_);
788#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
Haibo Huangb0bee822021-02-24 15:40:15 -0800789 // This can fail (silently?) if the value is bigger than MAX_FLOAT.
790 return static_cast<float>(integerToDouble(value_.uint_));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400791#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500792 case realValue:
793 return static_cast<float>(value_.real_);
794 case nullValue:
795 return 0.0;
796 case booleanValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800797 return value_.bool_ ? 1.0F : 0.0F;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500798 default:
799 break;
800 }
801 JSON_FAIL_MESSAGE("Value is not convertible to float.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400802}
803
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500804bool Value::asBool() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800805 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500806 case booleanValue:
807 return value_.bool_;
808 case nullValue:
809 return false;
810 case intValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800811 return value_.int_ != 0;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500812 case uintValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800813 return value_.uint_ != 0;
814 case realValue: {
815 // According to JavaScript language zero or NaN is regarded as false
816 const auto value_classification = std::fpclassify(value_.real_);
817 return value_classification != FP_ZERO && value_classification != FP_NAN;
818 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500819 default:
820 break;
821 }
822 JSON_FAIL_MESSAGE("Value is not convertible to bool.");
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400823}
824
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500825bool Value::isConvertibleTo(ValueType other) const {
826 switch (other) {
827 case nullValue:
828 return (isNumeric() && asDouble() == 0.0) ||
Haibo Huangb0bee822021-02-24 15:40:15 -0800829 (type() == booleanValue && !value_.bool_) ||
830 (type() == stringValue && asString().empty()) ||
831 (type() == arrayValue && value_.map_->empty()) ||
832 (type() == objectValue && value_.map_->empty()) ||
833 type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500834 case intValue:
835 return isInt() ||
Haibo Huangb0bee822021-02-24 15:40:15 -0800836 (type() == realValue && InRange(value_.real_, minInt, maxInt)) ||
837 type() == booleanValue || type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500838 case uintValue:
839 return isUInt() ||
Haibo Huangb0bee822021-02-24 15:40:15 -0800840 (type() == realValue && InRange(value_.real_, 0, maxUInt)) ||
841 type() == booleanValue || type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500842 case realValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800843 return isNumeric() || type() == booleanValue || type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500844 case booleanValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800845 return isNumeric() || type() == booleanValue || type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500846 case stringValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800847 return isNumeric() || type() == booleanValue || type() == stringValue ||
848 type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500849 case arrayValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800850 return type() == arrayValue || type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500851 case objectValue:
Haibo Huangb0bee822021-02-24 15:40:15 -0800852 return type() == objectValue || type() == nullValue;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500853 }
854 JSON_ASSERT_UNREACHABLE;
855 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400856}
857
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400858/// Number of values in array or object
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500859ArrayIndex Value::size() const {
Haibo Huangb0bee822021-02-24 15:40:15 -0800860 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500861 case nullValue:
862 case intValue:
863 case uintValue:
864 case realValue:
865 case booleanValue:
866 case stringValue:
867 return 0;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500868 case arrayValue: // size of the array is highest index + 1
869 if (!value_.map_->empty()) {
870 ObjectValues::const_iterator itLast = value_.map_->end();
871 --itLast;
872 return (*itLast).first.index() + 1;
873 }
874 return 0;
875 case objectValue:
876 return ArrayIndex(value_.map_->size());
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500877 }
878 JSON_ASSERT_UNREACHABLE;
879 return 0; // unreachable;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400880}
881
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500882bool Value::empty() const {
883 if (isNull() || isArray() || isObject())
Haibo Huangb0bee822021-02-24 15:40:15 -0800884 return size() == 0U;
885 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400886}
887
Haibo Huangb0bee822021-02-24 15:40:15 -0800888Value::operator bool() const { return !isNull(); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400889
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500890void Value::clear() {
Haibo Huangb0bee822021-02-24 15:40:15 -0800891 JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue ||
892 type() == objectValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500893 "in Json::Value::clear(): requires complex value");
894 start_ = 0;
895 limit_ = 0;
Haibo Huangb0bee822021-02-24 15:40:15 -0800896 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500897 case arrayValue:
898 case objectValue:
899 value_.map_->clear();
900 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500901 default:
902 break;
903 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400904}
905
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500906void Value::resize(ArrayIndex newSize) {
Haibo Huangb0bee822021-02-24 15:40:15 -0800907 JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500908 "in Json::Value::resize(): requires arrayValue");
Haibo Huangb0bee822021-02-24 15:40:15 -0800909 if (type() == nullValue)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500910 *this = Value(arrayValue);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500911 ArrayIndex oldSize = size();
912 if (newSize == 0)
913 clear();
914 else if (newSize > oldSize)
Haibo Huangb0bee822021-02-24 15:40:15 -0800915 this->operator[](newSize - 1);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500916 else {
917 for (ArrayIndex index = newSize; index < oldSize; ++index) {
918 value_.map_->erase(index);
919 }
Haibo Huangb0bee822021-02-24 15:40:15 -0800920 JSON_ASSERT(size() == newSize);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500921 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400922}
923
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500924Value& Value::operator[](ArrayIndex index) {
925 JSON_ASSERT_MESSAGE(
Haibo Huangb0bee822021-02-24 15:40:15 -0800926 type() == nullValue || type() == arrayValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500927 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
Haibo Huangb0bee822021-02-24 15:40:15 -0800928 if (type() == nullValue)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500929 *this = Value(arrayValue);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500930 CZString key(index);
Haibo Huangb0bee822021-02-24 15:40:15 -0800931 auto it = value_.map_->lower_bound(key);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500932 if (it != value_.map_->end() && (*it).first == key)
933 return (*it).second;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400934
Haibo Huangb0bee822021-02-24 15:40:15 -0800935 ObjectValues::value_type defaultValue(key, nullSingleton());
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500936 it = value_.map_->insert(it, defaultValue);
937 return (*it).second;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400938}
939
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500940Value& Value::operator[](int index) {
941 JSON_ASSERT_MESSAGE(
942 index >= 0,
943 "in Json::Value::operator[](int index): index cannot be negative");
944 return (*this)[ArrayIndex(index)];
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400945}
946
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500947const Value& Value::operator[](ArrayIndex index) const {
948 JSON_ASSERT_MESSAGE(
Haibo Huangb0bee822021-02-24 15:40:15 -0800949 type() == nullValue || type() == arrayValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500950 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
Haibo Huangb0bee822021-02-24 15:40:15 -0800951 if (type() == nullValue)
952 return nullSingleton();
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500953 CZString key(index);
954 ObjectValues::const_iterator it = value_.map_->find(key);
955 if (it == value_.map_->end())
Haibo Huangb0bee822021-02-24 15:40:15 -0800956 return nullSingleton();
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500957 return (*it).second;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400958}
959
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500960const Value& Value::operator[](int index) const {
961 JSON_ASSERT_MESSAGE(
962 index >= 0,
963 "in Json::Value::operator[](int index) const: index cannot be negative");
964 return (*this)[ArrayIndex(index)];
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400965}
966
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500967void Value::initBasic(ValueType type, bool allocated) {
Haibo Huangb0bee822021-02-24 15:40:15 -0800968 setType(type);
969 setIsAllocated(allocated);
970 comments_ = Comments{};
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500971 start_ = 0;
972 limit_ = 0;
973}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400974
Haibo Huangb0bee822021-02-24 15:40:15 -0800975void Value::dupPayload(const Value& other) {
976 setType(other.type());
977 setIsAllocated(false);
978 switch (type()) {
979 case nullValue:
980 case intValue:
981 case uintValue:
982 case realValue:
983 case booleanValue:
984 value_ = other.value_;
985 break;
986 case stringValue:
987 if (other.value_.string_ && other.isAllocated()) {
988 unsigned len;
989 char const* str;
990 decodePrefixedString(other.isAllocated(), other.value_.string_, &len,
991 &str);
992 value_.string_ = duplicateAndPrefixStringValue(str, len);
993 setIsAllocated(true);
994 } else {
995 value_.string_ = other.value_.string_;
996 }
997 break;
998 case arrayValue:
999 case objectValue:
1000 value_.map_ = new ObjectValues(*other.value_.map_);
1001 break;
1002 default:
1003 JSON_ASSERT_UNREACHABLE;
1004 }
1005}
1006
1007void Value::releasePayload() {
1008 switch (type()) {
1009 case nullValue:
1010 case intValue:
1011 case uintValue:
1012 case realValue:
1013 case booleanValue:
1014 break;
1015 case stringValue:
1016 if (isAllocated())
1017 releasePrefixedStringValue(value_.string_);
1018 break;
1019 case arrayValue:
1020 case objectValue:
1021 delete value_.map_;
1022 break;
1023 default:
1024 JSON_ASSERT_UNREACHABLE;
1025 }
1026}
1027
1028void Value::dupMeta(const Value& other) {
1029 comments_ = other.comments_;
1030 start_ = other.start_;
1031 limit_ = other.limit_;
1032}
1033
1034// Access an object value by name, create a null member if it does not exist.
1035// @pre Type of '*this' is object or null.
1036// @param key is null-terminated.
1037Value& Value::resolveReference(const char* key) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001038 JSON_ASSERT_MESSAGE(
Haibo Huangb0bee822021-02-24 15:40:15 -08001039 type() == nullValue || type() == objectValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001040 "in Json::Value::resolveReference(): requires objectValue");
Haibo Huangb0bee822021-02-24 15:40:15 -08001041 if (type() == nullValue)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001042 *this = Value(objectValue);
Haibo Huangb0bee822021-02-24 15:40:15 -08001043 CZString actualKey(key, static_cast<unsigned>(strlen(key)),
1044 CZString::noDuplication); // NOTE!
1045 auto it = value_.map_->lower_bound(actualKey);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001046 if (it != value_.map_->end() && (*it).first == actualKey)
1047 return (*it).second;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001048
Haibo Huangb0bee822021-02-24 15:40:15 -08001049 ObjectValues::value_type defaultValue(actualKey, nullSingleton());
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001050 it = value_.map_->insert(it, defaultValue);
1051 Value& value = (*it).second;
1052 return value;
Haibo Huangb0bee822021-02-24 15:40:15 -08001053}
1054
1055// @param key is not null-terminated.
1056Value& Value::resolveReference(char const* key, char const* end) {
1057 JSON_ASSERT_MESSAGE(
1058 type() == nullValue || type() == objectValue,
1059 "in Json::Value::resolveReference(key, end): requires objectValue");
1060 if (type() == nullValue)
1061 *this = Value(objectValue);
1062 CZString actualKey(key, static_cast<unsigned>(end - key),
1063 CZString::duplicateOnCopy);
1064 auto it = value_.map_->lower_bound(actualKey);
1065 if (it != value_.map_->end() && (*it).first == actualKey)
1066 return (*it).second;
1067
1068 ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1069 it = value_.map_->insert(it, defaultValue);
1070 Value& value = (*it).second;
1071 return value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001072}
1073
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001074Value Value::get(ArrayIndex index, const Value& defaultValue) const {
1075 const Value* value = &((*this)[index]);
Haibo Huangb0bee822021-02-24 15:40:15 -08001076 return value == &nullSingleton() ? defaultValue : *value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001077}
1078
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001079bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001080
Haibo Huangb0bee822021-02-24 15:40:15 -08001081Value const* Value::find(char const* begin, char const* end) const {
1082 JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1083 "in Json::Value::find(begin, end): requires "
1084 "objectValue or nullValue");
1085 if (type() == nullValue)
1086 return nullptr;
1087 CZString actualKey(begin, static_cast<unsigned>(end - begin),
1088 CZString::noDuplication);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001089 ObjectValues::const_iterator it = value_.map_->find(actualKey);
1090 if (it == value_.map_->end())
Haibo Huangb0bee822021-02-24 15:40:15 -08001091 return nullptr;
1092 return &(*it).second;
1093}
1094Value* Value::demand(char const* begin, char const* end) {
1095 JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1096 "in Json::Value::demand(begin, end): requires "
1097 "objectValue or nullValue");
1098 return &resolveReference(begin, end);
1099}
1100const Value& Value::operator[](const char* key) const {
1101 Value const* found = find(key, key + strlen(key));
1102 if (!found)
1103 return nullSingleton();
1104 return *found;
1105}
1106Value const& Value::operator[](const String& key) const {
1107 Value const* found = find(key.data(), key.data() + key.length());
1108 if (!found)
1109 return nullSingleton();
1110 return *found;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001111}
1112
Haibo Huangb0bee822021-02-24 15:40:15 -08001113Value& Value::operator[](const char* key) {
1114 return resolveReference(key, key + strlen(key));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001115}
1116
Haibo Huangb0bee822021-02-24 15:40:15 -08001117Value& Value::operator[](const String& key) {
1118 return resolveReference(key.data(), key.data() + key.length());
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001119}
1120
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001121Value& Value::operator[](const StaticString& key) {
Haibo Huangb0bee822021-02-24 15:40:15 -08001122 return resolveReference(key.c_str());
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001123}
1124
Haibo Huangb0bee822021-02-24 15:40:15 -08001125Value& Value::append(const Value& value) { return append(Value(value)); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001126
Haibo Huangb0bee822021-02-24 15:40:15 -08001127Value& Value::append(Value&& value) {
1128 JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
1129 "in Json::Value::append: requires arrayValue");
1130 if (type() == nullValue) {
1131 *this = Value(arrayValue);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001132 }
Haibo Huangb0bee822021-02-24 15:40:15 -08001133 return this->value_.map_->emplace(size(), std::move(value)).first->second;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001134}
1135
Haibo Huangb0bee822021-02-24 15:40:15 -08001136bool Value::insert(ArrayIndex index, const Value& newValue) {
1137 return insert(index, Value(newValue));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001138}
1139
Haibo Huangb0bee822021-02-24 15:40:15 -08001140bool Value::insert(ArrayIndex index, Value&& newValue) {
1141 JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
1142 "in Json::Value::insert: requires arrayValue");
1143 ArrayIndex length = size();
1144 if (index > length) {
1145 return false;
1146 }
1147 for (ArrayIndex i = length; i > index; i--) {
1148 (*this)[i] = std::move((*this)[i - 1]);
1149 }
1150 (*this)[index] = std::move(newValue);
1151 return true;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001152}
1153
Haibo Huangb0bee822021-02-24 15:40:15 -08001154Value Value::get(char const* begin, char const* end,
1155 Value const& defaultValue) const {
1156 Value const* found = find(begin, end);
1157 return !found ? defaultValue : *found;
1158}
1159Value Value::get(char const* key, Value const& defaultValue) const {
1160 return get(key, key + strlen(key), defaultValue);
1161}
1162Value Value::get(String const& key, Value const& defaultValue) const {
1163 return get(key.data(), key.data() + key.length(), defaultValue);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001164}
1165
Haibo Huangb0bee822021-02-24 15:40:15 -08001166bool Value::removeMember(const char* begin, const char* end, Value* removed) {
1167 if (type() != objectValue) {
1168 return false;
1169 }
1170 CZString actualKey(begin, static_cast<unsigned>(end - begin),
1171 CZString::noDuplication);
1172 auto it = value_.map_->find(actualKey);
1173 if (it == value_.map_->end())
1174 return false;
1175 if (removed)
1176 *removed = std::move(it->second);
1177 value_.map_->erase(it);
1178 return true;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001179}
Haibo Huangb0bee822021-02-24 15:40:15 -08001180bool Value::removeMember(const char* key, Value* removed) {
1181 return removeMember(key, key + strlen(key), removed);
1182}
1183bool Value::removeMember(String const& key, Value* removed) {
1184 return removeMember(key.data(), key.data() + key.length(), removed);
1185}
1186void Value::removeMember(const char* key) {
1187 JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1188 "in Json::Value::removeMember(): requires objectValue");
1189 if (type() == nullValue)
1190 return;
1191
1192 CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
1193 value_.map_->erase(actualKey);
1194}
1195void Value::removeMember(const String& key) { removeMember(key.c_str()); }
1196
1197bool Value::removeIndex(ArrayIndex index, Value* removed) {
1198 if (type() != arrayValue) {
1199 return false;
1200 }
1201 CZString key(index);
1202 auto it = value_.map_->find(key);
1203 if (it == value_.map_->end()) {
1204 return false;
1205 }
1206 if (removed)
1207 *removed = it->second;
1208 ArrayIndex oldSize = size();
1209 // shift left all items left, into the place of the "removed"
1210 for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
1211 CZString keey(i);
1212 (*value_.map_)[keey] = (*this)[i + 1];
1213 }
1214 // erase the last one ("leftover")
1215 CZString keyLast(oldSize - 1);
1216 auto itLast = value_.map_->find(keyLast);
1217 value_.map_->erase(itLast);
1218 return true;
1219}
1220
1221bool Value::isMember(char const* begin, char const* end) const {
1222 Value const* value = find(begin, end);
1223 return nullptr != value;
1224}
1225bool Value::isMember(char const* key) const {
1226 return isMember(key, key + strlen(key));
1227}
1228bool Value::isMember(String const& key) const {
1229 return isMember(key.data(), key.data() + key.length());
1230}
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001231
1232Value::Members Value::getMemberNames() const {
1233 JSON_ASSERT_MESSAGE(
Haibo Huangb0bee822021-02-24 15:40:15 -08001234 type() == nullValue || type() == objectValue,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001235 "in Json::Value::getMemberNames(), value must be objectValue");
Haibo Huangb0bee822021-02-24 15:40:15 -08001236 if (type() == nullValue)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001237 return Value::Members();
1238 Members members;
1239 members.reserve(value_.map_->size());
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001240 ObjectValues::const_iterator it = value_.map_->begin();
1241 ObjectValues::const_iterator itEnd = value_.map_->end();
Haibo Huangb0bee822021-02-24 15:40:15 -08001242 for (; it != itEnd; ++it) {
1243 members.push_back(String((*it).first.data(), (*it).first.length()));
1244 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001245 return members;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001246}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001247
1248static bool IsIntegral(double d) {
1249 double integral_part;
1250 return modf(d, &integral_part) == 0.0;
1251}
1252
Haibo Huangb0bee822021-02-24 15:40:15 -08001253bool Value::isNull() const { return type() == nullValue; }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001254
Haibo Huangb0bee822021-02-24 15:40:15 -08001255bool Value::isBool() const { return type() == booleanValue; }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001256
1257bool Value::isInt() const {
Haibo Huangb0bee822021-02-24 15:40:15 -08001258 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001259 case intValue:
Haibo Huangb0bee822021-02-24 15:40:15 -08001260#if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001261 return value_.int_ >= minInt && value_.int_ <= maxInt;
Haibo Huangb0bee822021-02-24 15:40:15 -08001262#else
1263 return true;
1264#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001265 case uintValue:
1266 return value_.uint_ <= UInt(maxInt);
1267 case realValue:
1268 return value_.real_ >= minInt && value_.real_ <= maxInt &&
1269 IsIntegral(value_.real_);
1270 default:
1271 break;
1272 }
1273 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001274}
1275
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001276bool Value::isUInt() const {
Haibo Huangb0bee822021-02-24 15:40:15 -08001277 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001278 case intValue:
Haibo Huangb0bee822021-02-24 15:40:15 -08001279#if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001280 return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
Haibo Huangb0bee822021-02-24 15:40:15 -08001281#else
1282 return value_.int_ >= 0;
1283#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001284 case uintValue:
Haibo Huangb0bee822021-02-24 15:40:15 -08001285#if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001286 return value_.uint_ <= maxUInt;
Haibo Huangb0bee822021-02-24 15:40:15 -08001287#else
1288 return true;
1289#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001290 case realValue:
1291 return value_.real_ >= 0 && value_.real_ <= maxUInt &&
1292 IsIntegral(value_.real_);
1293 default:
1294 break;
1295 }
1296 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001297}
1298
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001299bool Value::isInt64() const {
1300#if defined(JSON_HAS_INT64)
Haibo Huangb0bee822021-02-24 15:40:15 -08001301 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001302 case intValue:
1303 return true;
1304 case uintValue:
1305 return value_.uint_ <= UInt64(maxInt64);
1306 case realValue:
1307 // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
1308 // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
1309 // require the value to be strictly less than the limit.
1310 return value_.real_ >= double(minInt64) &&
1311 value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
1312 default:
1313 break;
1314 }
1315#endif // JSON_HAS_INT64
1316 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001317}
1318
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001319bool Value::isUInt64() const {
1320#if defined(JSON_HAS_INT64)
Haibo Huangb0bee822021-02-24 15:40:15 -08001321 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001322 case intValue:
1323 return value_.int_ >= 0;
1324 case uintValue:
1325 return true;
1326 case realValue:
1327 // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1328 // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1329 // require the value to be strictly less than the limit.
1330 return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
1331 IsIntegral(value_.real_);
1332 default:
1333 break;
1334 }
1335#endif // JSON_HAS_INT64
1336 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001337}
1338
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001339bool Value::isIntegral() const {
Haibo Huangb0bee822021-02-24 15:40:15 -08001340 switch (type()) {
1341 case intValue:
1342 case uintValue:
1343 return true;
1344 case realValue:
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001345#if defined(JSON_HAS_INT64)
Haibo Huangb0bee822021-02-24 15:40:15 -08001346 // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1347 // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1348 // require the value to be strictly less than the limit.
1349 return value_.real_ >= double(minInt64) &&
1350 value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001351#else
Haibo Huangb0bee822021-02-24 15:40:15 -08001352 return value_.real_ >= minInt && value_.real_ <= maxUInt &&
1353 IsIntegral(value_.real_);
1354#endif // JSON_HAS_INT64
1355 default:
1356 break;
1357 }
1358 return false;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001359}
1360
Haibo Huangb0bee822021-02-24 15:40:15 -08001361bool Value::isDouble() const {
1362 return type() == intValue || type() == uintValue || type() == realValue;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001363}
1364
Haibo Huangb0bee822021-02-24 15:40:15 -08001365bool Value::isNumeric() const { return isDouble(); }
1366
1367bool Value::isString() const { return type() == stringValue; }
1368
1369bool Value::isArray() const { return type() == arrayValue; }
1370
1371bool Value::isObject() const { return type() == objectValue; }
1372
1373Value::Comments::Comments(const Comments& that)
1374 : ptr_{cloneUnique(that.ptr_)} {}
1375
1376Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {}
1377
1378Value::Comments& Value::Comments::operator=(const Comments& that) {
1379 ptr_ = cloneUnique(that.ptr_);
1380 return *this;
1381}
1382
1383Value::Comments& Value::Comments::operator=(Comments&& that) {
1384 ptr_ = std::move(that.ptr_);
1385 return *this;
1386}
1387
1388bool Value::Comments::has(CommentPlacement slot) const {
1389 return ptr_ && !(*ptr_)[slot].empty();
1390}
1391
1392String Value::Comments::get(CommentPlacement slot) const {
1393 if (!ptr_)
1394 return {};
1395 return (*ptr_)[slot];
1396}
1397
1398void Value::Comments::set(CommentPlacement slot, String comment) {
1399 if (!ptr_) {
1400 ptr_ = std::unique_ptr<Array>(new Array());
1401 }
1402 // check comments array boundry.
1403 if (slot < CommentPlacement::numberOfCommentPlacement) {
1404 (*ptr_)[slot] = std::move(comment);
1405 }
1406}
1407
1408void Value::setComment(String comment, CommentPlacement placement) {
1409 if (!comment.empty() && (comment.back() == '\n')) {
1410 // Always discard trailing newline, to aid indentation.
1411 comment.pop_back();
1412 }
1413 JSON_ASSERT(!comment.empty());
1414 JSON_ASSERT_MESSAGE(
1415 comment[0] == '\0' || comment[0] == '/',
1416 "in Json::Value::setComment(): Comments must start with /");
1417 comments_.set(placement, std::move(comment));
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001418}
1419
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001420bool Value::hasComment(CommentPlacement placement) const {
Haibo Huangb0bee822021-02-24 15:40:15 -08001421 return comments_.has(placement);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001422}
1423
Haibo Huangb0bee822021-02-24 15:40:15 -08001424String Value::getComment(CommentPlacement placement) const {
1425 return comments_.get(placement);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001426}
1427
Haibo Huangb0bee822021-02-24 15:40:15 -08001428void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001429
Haibo Huangb0bee822021-02-24 15:40:15 -08001430void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001431
Haibo Huangb0bee822021-02-24 15:40:15 -08001432ptrdiff_t Value::getOffsetStart() const { return start_; }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001433
Haibo Huangb0bee822021-02-24 15:40:15 -08001434ptrdiff_t Value::getOffsetLimit() const { return limit_; }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001435
Haibo Huangb0bee822021-02-24 15:40:15 -08001436String Value::toStyledString() const {
1437 StreamWriterBuilder builder;
1438
1439 String out = this->hasComment(commentBefore) ? "\n" : "";
1440 out += Json::writeString(builder, *this);
1441 out += '\n';
1442
1443 return out;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001444}
1445
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001446Value::const_iterator Value::begin() const {
Haibo Huangb0bee822021-02-24 15:40:15 -08001447 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001448 case arrayValue:
1449 case objectValue:
1450 if (value_.map_)
1451 return const_iterator(value_.map_->begin());
1452 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001453 default:
1454 break;
1455 }
Haibo Huangb0bee822021-02-24 15:40:15 -08001456 return {};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001457}
1458
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001459Value::const_iterator Value::end() const {
Haibo Huangb0bee822021-02-24 15:40:15 -08001460 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001461 case arrayValue:
1462 case objectValue:
1463 if (value_.map_)
1464 return const_iterator(value_.map_->end());
1465 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001466 default:
1467 break;
1468 }
Haibo Huangb0bee822021-02-24 15:40:15 -08001469 return {};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001470}
1471
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001472Value::iterator Value::begin() {
Haibo Huangb0bee822021-02-24 15:40:15 -08001473 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001474 case arrayValue:
1475 case objectValue:
1476 if (value_.map_)
1477 return iterator(value_.map_->begin());
1478 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001479 default:
1480 break;
1481 }
1482 return iterator();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001483}
1484
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001485Value::iterator Value::end() {
Haibo Huangb0bee822021-02-24 15:40:15 -08001486 switch (type()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001487 case arrayValue:
1488 case objectValue:
1489 if (value_.map_)
1490 return iterator(value_.map_->end());
1491 break;
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001492 default:
1493 break;
1494 }
1495 return iterator();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001496}
1497
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001498// class PathArgument
1499// //////////////////////////////////////////////////////////////////
1500
Haibo Huangb0bee822021-02-24 15:40:15 -08001501PathArgument::PathArgument() = default;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001502
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001503PathArgument::PathArgument(ArrayIndex index)
Haibo Huangb0bee822021-02-24 15:40:15 -08001504 : index_(index), kind_(kindIndex) {}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001505
Haibo Huangb0bee822021-02-24 15:40:15 -08001506PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001507
Haibo Huangb0bee822021-02-24 15:40:15 -08001508PathArgument::PathArgument(String key) : key_(std::move(key)), kind_(kindKey) {}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001509
1510// class Path
1511// //////////////////////////////////////////////////////////////////
1512
Haibo Huangb0bee822021-02-24 15:40:15 -08001513Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2,
1514 const PathArgument& a3, const PathArgument& a4,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001515 const PathArgument& a5) {
1516 InArgs in;
Haibo Huangb0bee822021-02-24 15:40:15 -08001517 in.reserve(5);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001518 in.push_back(&a1);
1519 in.push_back(&a2);
1520 in.push_back(&a3);
1521 in.push_back(&a4);
1522 in.push_back(&a5);
1523 makePath(path, in);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001524}
1525
Haibo Huangb0bee822021-02-24 15:40:15 -08001526void Path::makePath(const String& path, const InArgs& in) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001527 const char* current = path.c_str();
1528 const char* end = current + path.length();
Haibo Huangb0bee822021-02-24 15:40:15 -08001529 auto itInArg = in.begin();
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001530 while (current != end) {
1531 if (*current == '[') {
1532 ++current;
1533 if (*current == '%')
1534 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1535 else {
1536 ArrayIndex index = 0;
1537 for (; current != end && *current >= '0' && *current <= '9'; ++current)
1538 index = index * 10 + ArrayIndex(*current - '0');
1539 args_.push_back(index);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001540 }
Haibo Huangb0bee822021-02-24 15:40:15 -08001541 if (current == end || *++current != ']')
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001542 invalidPath(path, int(current - path.c_str()));
1543 } else if (*current == '%') {
1544 addPathInArg(path, in, itInArg, PathArgument::kindKey);
1545 ++current;
Haibo Huangb0bee822021-02-24 15:40:15 -08001546 } else if (*current == '.' || *current == ']') {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001547 ++current;
1548 } else {
1549 const char* beginName = current;
1550 while (current != end && !strchr("[.", *current))
1551 ++current;
Haibo Huangb0bee822021-02-24 15:40:15 -08001552 args_.push_back(String(beginName, current));
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001553 }
1554 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001555}
1556
Haibo Huangb0bee822021-02-24 15:40:15 -08001557void Path::addPathInArg(const String& /*path*/, const InArgs& in,
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001558 InArgs::const_iterator& itInArg,
1559 PathArgument::Kind kind) {
1560 if (itInArg == in.end()) {
1561 // Error: missing argument %d
1562 } else if ((*itInArg)->kind_ != kind) {
1563 // Error: bad argument type
1564 } else {
Haibo Huangb0bee822021-02-24 15:40:15 -08001565 args_.push_back(**itInArg++);
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001566 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001567}
1568
Haibo Huangb0bee822021-02-24 15:40:15 -08001569void Path::invalidPath(const String& /*path*/, int /*location*/) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001570 // Error: invalid path.
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001571}
1572
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001573const Value& Path::resolve(const Value& root) const {
1574 const Value* node = &root;
Haibo Huangb0bee822021-02-24 15:40:15 -08001575 for (const auto& arg : args_) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001576 if (arg.kind_ == PathArgument::kindIndex) {
1577 if (!node->isArray() || !node->isValidIndex(arg.index_)) {
Haibo Huangb0bee822021-02-24 15:40:15 -08001578 // Error: unable to resolve path (array value expected at position... )
1579 return Value::nullSingleton();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001580 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001581 node = &((*node)[arg.index_]);
1582 } else if (arg.kind_ == PathArgument::kindKey) {
1583 if (!node->isObject()) {
1584 // Error: unable to resolve path (object value expected at position...)
Haibo Huangb0bee822021-02-24 15:40:15 -08001585 return Value::nullSingleton();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001586 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001587 node = &((*node)[arg.key_]);
Haibo Huangb0bee822021-02-24 15:40:15 -08001588 if (node == &Value::nullSingleton()) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001589 // Error: unable to resolve path (object has no member named '' at
1590 // position...)
Haibo Huangb0bee822021-02-24 15:40:15 -08001591 return Value::nullSingleton();
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001592 }
1593 }
1594 }
1595 return *node;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001596}
1597
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001598Value Path::resolve(const Value& root, const Value& defaultValue) const {
1599 const Value* node = &root;
Haibo Huangb0bee822021-02-24 15:40:15 -08001600 for (const auto& arg : args_) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001601 if (arg.kind_ == PathArgument::kindIndex) {
1602 if (!node->isArray() || !node->isValidIndex(arg.index_))
1603 return defaultValue;
1604 node = &((*node)[arg.index_]);
1605 } else if (arg.kind_ == PathArgument::kindKey) {
1606 if (!node->isObject())
1607 return defaultValue;
1608 node = &((*node)[arg.key_]);
Haibo Huangb0bee822021-02-24 15:40:15 -08001609 if (node == &Value::nullSingleton())
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001610 return defaultValue;
1611 }
1612 }
1613 return *node;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001614}
1615
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001616Value& Path::make(Value& root) const {
1617 Value* node = &root;
Haibo Huangb0bee822021-02-24 15:40:15 -08001618 for (const auto& arg : args_) {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001619 if (arg.kind_ == PathArgument::kindIndex) {
1620 if (!node->isArray()) {
1621 // Error: node is not an array at position ...
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001622 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001623 node = &((*node)[arg.index_]);
1624 } else if (arg.kind_ == PathArgument::kindKey) {
1625 if (!node->isObject()) {
1626 // Error: node is not an object at position...
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001627 }
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001628 node = &((*node)[arg.key_]);
1629 }
1630 }
1631 return *node;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001632}
1633
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001634} // namespace Json