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