• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) noexcept
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) noexcept {
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) noexcept {
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) noexcept {
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     for (ArrayIndex i = oldSize; i < newSize; ++i)
916       (*this)[i];
917   else {
918     for (ArrayIndex index = newSize; index < oldSize; ++index) {
919       value_.map_->erase(index);
920     }
921     JSON_ASSERT(size() == newSize);
922   }
923 }
924 
operator [](ArrayIndex index)925 Value& Value::operator[](ArrayIndex index) {
926   JSON_ASSERT_MESSAGE(
927       type() == nullValue || type() == arrayValue,
928       "in Json::Value::operator[](ArrayIndex): requires arrayValue");
929   if (type() == nullValue)
930     *this = Value(arrayValue);
931   CZString key(index);
932   auto it = value_.map_->lower_bound(key);
933   if (it != value_.map_->end() && (*it).first == key)
934     return (*it).second;
935 
936   ObjectValues::value_type defaultValue(key, nullSingleton());
937   it = value_.map_->insert(it, defaultValue);
938   return (*it).second;
939 }
940 
operator [](int index)941 Value& Value::operator[](int index) {
942   JSON_ASSERT_MESSAGE(
943       index >= 0,
944       "in Json::Value::operator[](int index): index cannot be negative");
945   return (*this)[ArrayIndex(index)];
946 }
947 
operator [](ArrayIndex index) const948 const Value& Value::operator[](ArrayIndex index) const {
949   JSON_ASSERT_MESSAGE(
950       type() == nullValue || type() == arrayValue,
951       "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
952   if (type() == nullValue)
953     return nullSingleton();
954   CZString key(index);
955   ObjectValues::const_iterator it = value_.map_->find(key);
956   if (it == value_.map_->end())
957     return nullSingleton();
958   return (*it).second;
959 }
960 
operator [](int index) const961 const Value& Value::operator[](int index) const {
962   JSON_ASSERT_MESSAGE(
963       index >= 0,
964       "in Json::Value::operator[](int index) const: index cannot be negative");
965   return (*this)[ArrayIndex(index)];
966 }
967 
initBasic(ValueType type,bool allocated)968 void Value::initBasic(ValueType type, bool allocated) {
969   setType(type);
970   setIsAllocated(allocated);
971   comments_ = Comments{};
972   start_ = 0;
973   limit_ = 0;
974 }
975 
dupPayload(const Value & other)976 void Value::dupPayload(const Value& other) {
977   setType(other.type());
978   setIsAllocated(false);
979   switch (type()) {
980   case nullValue:
981   case intValue:
982   case uintValue:
983   case realValue:
984   case booleanValue:
985     value_ = other.value_;
986     break;
987   case stringValue:
988     if (other.value_.string_ && other.isAllocated()) {
989       unsigned len;
990       char const* str;
991       decodePrefixedString(other.isAllocated(), other.value_.string_, &len,
992                            &str);
993       value_.string_ = duplicateAndPrefixStringValue(str, len);
994       setIsAllocated(true);
995     } else {
996       value_.string_ = other.value_.string_;
997     }
998     break;
999   case arrayValue:
1000   case objectValue:
1001     value_.map_ = new ObjectValues(*other.value_.map_);
1002     break;
1003   default:
1004     JSON_ASSERT_UNREACHABLE;
1005   }
1006 }
1007 
releasePayload()1008 void Value::releasePayload() {
1009   switch (type()) {
1010   case nullValue:
1011   case intValue:
1012   case uintValue:
1013   case realValue:
1014   case booleanValue:
1015     break;
1016   case stringValue:
1017     if (isAllocated())
1018       releasePrefixedStringValue(value_.string_);
1019     break;
1020   case arrayValue:
1021   case objectValue:
1022     delete value_.map_;
1023     break;
1024   default:
1025     JSON_ASSERT_UNREACHABLE;
1026   }
1027 }
1028 
dupMeta(const Value & other)1029 void Value::dupMeta(const Value& other) {
1030   comments_ = other.comments_;
1031   start_ = other.start_;
1032   limit_ = other.limit_;
1033 }
1034 
1035 // Access an object value by name, create a null member if it does not exist.
1036 // @pre Type of '*this' is object or null.
1037 // @param key is null-terminated.
resolveReference(const char * key)1038 Value& Value::resolveReference(const char* key) {
1039   JSON_ASSERT_MESSAGE(
1040       type() == nullValue || type() == objectValue,
1041       "in Json::Value::resolveReference(): requires objectValue");
1042   if (type() == nullValue)
1043     *this = Value(objectValue);
1044   CZString actualKey(key, static_cast<unsigned>(strlen(key)),
1045                      CZString::noDuplication); // NOTE!
1046   auto it = value_.map_->lower_bound(actualKey);
1047   if (it != value_.map_->end() && (*it).first == actualKey)
1048     return (*it).second;
1049 
1050   ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1051   it = value_.map_->insert(it, defaultValue);
1052   Value& value = (*it).second;
1053   return value;
1054 }
1055 
1056 // @param key is not null-terminated.
resolveReference(char const * key,char const * end)1057 Value& Value::resolveReference(char const* key, char const* end) {
1058   JSON_ASSERT_MESSAGE(
1059       type() == nullValue || type() == objectValue,
1060       "in Json::Value::resolveReference(key, end): requires objectValue");
1061   if (type() == nullValue)
1062     *this = Value(objectValue);
1063   CZString actualKey(key, static_cast<unsigned>(end - key),
1064                      CZString::duplicateOnCopy);
1065   auto it = value_.map_->lower_bound(actualKey);
1066   if (it != value_.map_->end() && (*it).first == actualKey)
1067     return (*it).second;
1068 
1069   ObjectValues::value_type defaultValue(actualKey, nullSingleton());
1070   it = value_.map_->insert(it, defaultValue);
1071   Value& value = (*it).second;
1072   return value;
1073 }
1074 
get(ArrayIndex index,const Value & defaultValue) const1075 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
1076   const Value* value = &((*this)[index]);
1077   return value == &nullSingleton() ? defaultValue : *value;
1078 }
1079 
isValidIndex(ArrayIndex index) const1080 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
1081 
find(char const * begin,char const * end) const1082 Value const* Value::find(char const* begin, char const* end) const {
1083   JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1084                       "in Json::Value::find(begin, end): requires "
1085                       "objectValue or nullValue");
1086   if (type() == nullValue)
1087     return nullptr;
1088   CZString actualKey(begin, static_cast<unsigned>(end - begin),
1089                      CZString::noDuplication);
1090   ObjectValues::const_iterator it = value_.map_->find(actualKey);
1091   if (it == value_.map_->end())
1092     return nullptr;
1093   return &(*it).second;
1094 }
demand(char const * begin,char const * end)1095 Value* Value::demand(char const* begin, char const* end) {
1096   JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1097                       "in Json::Value::demand(begin, end): requires "
1098                       "objectValue or nullValue");
1099   return &resolveReference(begin, end);
1100 }
operator [](const char * key) const1101 const Value& Value::operator[](const char* key) const {
1102   Value const* found = find(key, key + strlen(key));
1103   if (!found)
1104     return nullSingleton();
1105   return *found;
1106 }
operator [](const String & key) const1107 Value const& Value::operator[](const String& key) const {
1108   Value const* found = find(key.data(), key.data() + key.length());
1109   if (!found)
1110     return nullSingleton();
1111   return *found;
1112 }
1113 
operator [](const char * key)1114 Value& Value::operator[](const char* key) {
1115   return resolveReference(key, key + strlen(key));
1116 }
1117 
operator [](const String & key)1118 Value& Value::operator[](const String& key) {
1119   return resolveReference(key.data(), key.data() + key.length());
1120 }
1121 
operator [](const StaticString & key)1122 Value& Value::operator[](const StaticString& key) {
1123   return resolveReference(key.c_str());
1124 }
1125 
append(const Value & value)1126 Value& Value::append(const Value& value) { return append(Value(value)); }
1127 
append(Value && value)1128 Value& Value::append(Value&& value) {
1129   JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
1130                       "in Json::Value::append: requires arrayValue");
1131   if (type() == nullValue) {
1132     *this = Value(arrayValue);
1133   }
1134   return this->value_.map_->emplace(size(), std::move(value)).first->second;
1135 }
1136 
insert(ArrayIndex index,const Value & newValue)1137 bool Value::insert(ArrayIndex index, const Value& newValue) {
1138   return insert(index, Value(newValue));
1139 }
1140 
insert(ArrayIndex index,Value && newValue)1141 bool Value::insert(ArrayIndex index, Value&& newValue) {
1142   JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
1143                       "in Json::Value::insert: requires arrayValue");
1144   ArrayIndex length = size();
1145   if (index > length) {
1146     return false;
1147   }
1148   for (ArrayIndex i = length; i > index; i--) {
1149     (*this)[i] = std::move((*this)[i - 1]);
1150   }
1151   (*this)[index] = std::move(newValue);
1152   return true;
1153 }
1154 
get(char const * begin,char const * end,Value const & defaultValue) const1155 Value Value::get(char const* begin, char const* end,
1156                  Value const& defaultValue) const {
1157   Value const* found = find(begin, end);
1158   return !found ? defaultValue : *found;
1159 }
get(char const * key,Value const & defaultValue) const1160 Value Value::get(char const* key, Value const& defaultValue) const {
1161   return get(key, key + strlen(key), defaultValue);
1162 }
get(String const & key,Value const & defaultValue) const1163 Value Value::get(String const& key, Value const& defaultValue) const {
1164   return get(key.data(), key.data() + key.length(), defaultValue);
1165 }
1166 
removeMember(const char * begin,const char * end,Value * removed)1167 bool Value::removeMember(const char* begin, const char* end, Value* removed) {
1168   if (type() != objectValue) {
1169     return false;
1170   }
1171   CZString actualKey(begin, static_cast<unsigned>(end - begin),
1172                      CZString::noDuplication);
1173   auto it = value_.map_->find(actualKey);
1174   if (it == value_.map_->end())
1175     return false;
1176   if (removed)
1177     *removed = std::move(it->second);
1178   value_.map_->erase(it);
1179   return true;
1180 }
removeMember(const char * key,Value * removed)1181 bool Value::removeMember(const char* key, Value* removed) {
1182   return removeMember(key, key + strlen(key), removed);
1183 }
removeMember(String const & key,Value * removed)1184 bool Value::removeMember(String const& key, Value* removed) {
1185   return removeMember(key.data(), key.data() + key.length(), removed);
1186 }
removeMember(const char * key)1187 void Value::removeMember(const char* key) {
1188   JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
1189                       "in Json::Value::removeMember(): requires objectValue");
1190   if (type() == nullValue)
1191     return;
1192 
1193   CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
1194   value_.map_->erase(actualKey);
1195 }
removeMember(const String & key)1196 void Value::removeMember(const String& key) { removeMember(key.c_str()); }
1197 
removeIndex(ArrayIndex index,Value * removed)1198 bool Value::removeIndex(ArrayIndex index, Value* removed) {
1199   if (type() != arrayValue) {
1200     return false;
1201   }
1202   CZString key(index);
1203   auto it = value_.map_->find(key);
1204   if (it == value_.map_->end()) {
1205     return false;
1206   }
1207   if (removed)
1208     *removed = it->second;
1209   ArrayIndex oldSize = size();
1210   // shift left all items left, into the place of the "removed"
1211   for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
1212     CZString keey(i);
1213     (*value_.map_)[keey] = (*this)[i + 1];
1214   }
1215   // erase the last one ("leftover")
1216   CZString keyLast(oldSize - 1);
1217   auto itLast = value_.map_->find(keyLast);
1218   value_.map_->erase(itLast);
1219   return true;
1220 }
1221 
isMember(char const * begin,char const * end) const1222 bool Value::isMember(char const* begin, char const* end) const {
1223   Value const* value = find(begin, end);
1224   return nullptr != value;
1225 }
isMember(char const * key) const1226 bool Value::isMember(char const* key) const {
1227   return isMember(key, key + strlen(key));
1228 }
isMember(String const & key) const1229 bool Value::isMember(String const& key) const {
1230   return isMember(key.data(), key.data() + key.length());
1231 }
1232 
getMemberNames() const1233 Value::Members Value::getMemberNames() const {
1234   JSON_ASSERT_MESSAGE(
1235       type() == nullValue || type() == objectValue,
1236       "in Json::Value::getMemberNames(), value must be objectValue");
1237   if (type() == nullValue)
1238     return Value::Members();
1239   Members members;
1240   members.reserve(value_.map_->size());
1241   ObjectValues::const_iterator it = value_.map_->begin();
1242   ObjectValues::const_iterator itEnd = value_.map_->end();
1243   for (; it != itEnd; ++it) {
1244     members.push_back(String((*it).first.data(), (*it).first.length()));
1245   }
1246   return members;
1247 }
1248 
IsIntegral(double d)1249 static bool IsIntegral(double d) {
1250   double integral_part;
1251   return modf(d, &integral_part) == 0.0;
1252 }
1253 
isNull() const1254 bool Value::isNull() const { return type() == nullValue; }
1255 
isBool() const1256 bool Value::isBool() const { return type() == booleanValue; }
1257 
isInt() const1258 bool Value::isInt() const {
1259   switch (type()) {
1260   case intValue:
1261 #if defined(JSON_HAS_INT64)
1262     return value_.int_ >= minInt && value_.int_ <= maxInt;
1263 #else
1264     return true;
1265 #endif
1266   case uintValue:
1267     return value_.uint_ <= UInt(maxInt);
1268   case realValue:
1269     return value_.real_ >= minInt && value_.real_ <= maxInt &&
1270            IsIntegral(value_.real_);
1271   default:
1272     break;
1273   }
1274   return false;
1275 }
1276 
isUInt() const1277 bool Value::isUInt() const {
1278   switch (type()) {
1279   case intValue:
1280 #if defined(JSON_HAS_INT64)
1281     return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
1282 #else
1283     return value_.int_ >= 0;
1284 #endif
1285   case uintValue:
1286 #if defined(JSON_HAS_INT64)
1287     return value_.uint_ <= maxUInt;
1288 #else
1289     return true;
1290 #endif
1291   case realValue:
1292     return value_.real_ >= 0 && value_.real_ <= maxUInt &&
1293            IsIntegral(value_.real_);
1294   default:
1295     break;
1296   }
1297   return false;
1298 }
1299 
isInt64() const1300 bool Value::isInt64() const {
1301 #if defined(JSON_HAS_INT64)
1302   switch (type()) {
1303   case intValue:
1304     return true;
1305   case uintValue:
1306     return value_.uint_ <= UInt64(maxInt64);
1307   case realValue:
1308     // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
1309     // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
1310     // require the value to be strictly less than the limit.
1311     return value_.real_ >= double(minInt64) &&
1312            value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
1313   default:
1314     break;
1315   }
1316 #endif // JSON_HAS_INT64
1317   return false;
1318 }
1319 
isUInt64() const1320 bool Value::isUInt64() const {
1321 #if defined(JSON_HAS_INT64)
1322   switch (type()) {
1323   case intValue:
1324     return value_.int_ >= 0;
1325   case uintValue:
1326     return true;
1327   case realValue:
1328     // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1329     // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1330     // require the value to be strictly less than the limit.
1331     return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
1332            IsIntegral(value_.real_);
1333   default:
1334     break;
1335   }
1336 #endif // JSON_HAS_INT64
1337   return false;
1338 }
1339 
isIntegral() const1340 bool Value::isIntegral() const {
1341   switch (type()) {
1342   case intValue:
1343   case uintValue:
1344     return true;
1345   case realValue:
1346 #if defined(JSON_HAS_INT64)
1347     // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
1348     // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
1349     // require the value to be strictly less than the limit.
1350     return value_.real_ >= double(minInt64) &&
1351            value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
1352 #else
1353     return value_.real_ >= minInt && value_.real_ <= maxUInt &&
1354            IsIntegral(value_.real_);
1355 #endif // JSON_HAS_INT64
1356   default:
1357     break;
1358   }
1359   return false;
1360 }
1361 
isDouble() const1362 bool Value::isDouble() const {
1363   return type() == intValue || type() == uintValue || type() == realValue;
1364 }
1365 
isNumeric() const1366 bool Value::isNumeric() const { return isDouble(); }
1367 
isString() const1368 bool Value::isString() const { return type() == stringValue; }
1369 
isArray() const1370 bool Value::isArray() const { return type() == arrayValue; }
1371 
isObject() const1372 bool Value::isObject() const { return type() == objectValue; }
1373 
Comments(const Comments & that)1374 Value::Comments::Comments(const Comments& that)
1375     : ptr_{cloneUnique(that.ptr_)} {}
1376 
Comments(Comments && that)1377 Value::Comments::Comments(Comments&& that) noexcept
1378     : ptr_{std::move(that.ptr_)} {}
1379 
operator =(const Comments & that)1380 Value::Comments& Value::Comments::operator=(const Comments& that) {
1381   ptr_ = cloneUnique(that.ptr_);
1382   return *this;
1383 }
1384 
operator =(Comments && that)1385 Value::Comments& Value::Comments::operator=(Comments&& that) noexcept {
1386   ptr_ = std::move(that.ptr_);
1387   return *this;
1388 }
1389 
has(CommentPlacement slot) const1390 bool Value::Comments::has(CommentPlacement slot) const {
1391   return ptr_ && !(*ptr_)[slot].empty();
1392 }
1393 
get(CommentPlacement slot) const1394 String Value::Comments::get(CommentPlacement slot) const {
1395   if (!ptr_)
1396     return {};
1397   return (*ptr_)[slot];
1398 }
1399 
set(CommentPlacement slot,String comment)1400 void Value::Comments::set(CommentPlacement slot, String comment) {
1401   if (slot >= CommentPlacement::numberOfCommentPlacement)
1402     return;
1403   if (!ptr_)
1404     ptr_ = std::unique_ptr<Array>(new Array());
1405   (*ptr_)[slot] = std::move(comment);
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