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