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