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