JsonCpp project page | Classes | Namespace | JsonCpp home page

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