Home | History | Annotate | Download | only in lib_json
      1 // Copyright 2011 Baptiste Lepilleur
      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 #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
     11 #include "json_batchallocator.h"
     12 #endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
     13 #endif // if !defined(JSON_IS_AMALGAMATION)
     14 #include <math.h>
     15 #include <sstream>
     16 #include <utility>
     17 #include <cstring>
     18 #include <cassert>
     19 #ifdef JSON_USE_CPPTL
     20 #include <cpptl/conststring.h>
     21 #endif
     22 #include <cstddef> // size_t
     23 
     24 #define JSON_ASSERT_UNREACHABLE assert(false)
     25 
     26 namespace Json {
     27 
     28 // This is a walkaround to avoid the static initialization of Value::null.
     29 // kNull must be word-aligned to avoid crashing on ARM.  We use an alignment of
     30 // 8 (instead of 4) as a bit of future-proofing.
     31 #if defined(__ARMEL__)
     32 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
     33 #else
     34 #define ALIGNAS(byte_alignment)
     35 #endif
     36 static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
     37 const unsigned char& kNullRef = kNull[0];
     38 const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
     39 
     40 const Int Value::minInt = Int(~(UInt(-1) / 2));
     41 const Int Value::maxInt = Int(UInt(-1) / 2);
     42 const UInt Value::maxUInt = UInt(-1);
     43 #if defined(JSON_HAS_INT64)
     44 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
     45 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
     46 const UInt64 Value::maxUInt64 = UInt64(-1);
     47 // The constant is hard-coded because some compiler have trouble
     48 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
     49 // Assumes that UInt64 is a 64 bits integer.
     50 static const double maxUInt64AsDouble = 18446744073709551615.0;
     51 #endif // defined(JSON_HAS_INT64)
     52 const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
     53 const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
     54 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
     55 
     56 /// Unknown size marker
     57 static const unsigned int unknown = (unsigned)-1;
     58 
     59 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
     60 template <typename T, typename U>
     61 static inline bool InRange(double d, T min, U max) {
     62   return d >= min && d <= max;
     63 }
     64 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
     65 static inline double integerToDouble(Json::UInt64 value) {
     66   return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
     67 }
     68 
     69 template <typename T> static inline double integerToDouble(T value) {
     70   return static_cast<double>(value);
     71 }
     72 
     73 template <typename T, typename U>
     74 static inline bool InRange(double d, T min, U max) {
     75   return d >= integerToDouble(min) && d <= integerToDouble(max);
     76 }
     77 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
     78 
     79 /** Duplicates the specified string value.
     80  * @param value Pointer to the string to duplicate. Must be zero-terminated if
     81  *              length is "unknown".
     82  * @param length Length of the value. if equals to unknown, then it will be
     83  *               computed using strlen(value).
     84  * @return Pointer on the duplicate instance of string.
     85  */
     86 static inline char* duplicateStringValue(const char* value,
     87                                          unsigned int length = unknown) {
     88   if (length == unknown)
     89     length = (unsigned int)strlen(value);
     90 
     91   // Avoid an integer overflow in the call to malloc below by limiting length
     92   // to a sane value.
     93   if (length >= (unsigned)Value::maxInt)
     94     length = Value::maxInt - 1;
     95 
     96   char* newString = static_cast<char*>(malloc(length + 1));
     97   JSON_ASSERT_MESSAGE(newString != 0,
     98                       "in Json::Value::duplicateStringValue(): "
     99                       "Failed to allocate string value buffer");
    100   memcpy(newString, value, length);
    101   newString[length] = 0;
    102   return newString;
    103 }
    104 
    105 /** Free the string duplicated by duplicateStringValue().
    106  */
    107 static inline void releaseStringValue(char* value) { free(value); }
    108 
    109 } // namespace Json
    110 
    111 // //////////////////////////////////////////////////////////////////
    112 // //////////////////////////////////////////////////////////////////
    113 // //////////////////////////////////////////////////////////////////
    114 // ValueInternals...
    115 // //////////////////////////////////////////////////////////////////
    116 // //////////////////////////////////////////////////////////////////
    117 // //////////////////////////////////////////////////////////////////
    118 #if !defined(JSON_IS_AMALGAMATION)
    119 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    120 #include "json_internalarray.inl"
    121 #include "json_internalmap.inl"
    122 #endif // JSON_VALUE_USE_INTERNAL_MAP
    123 
    124 #include "json_valueiterator.inl"
    125 #endif // if !defined(JSON_IS_AMALGAMATION)
    126 
    127 namespace Json {
    128 
    129 // //////////////////////////////////////////////////////////////////
    130 // //////////////////////////////////////////////////////////////////
    131 // //////////////////////////////////////////////////////////////////
    132 // class Value::CommentInfo
    133 // //////////////////////////////////////////////////////////////////
    134 // //////////////////////////////////////////////////////////////////
    135 // //////////////////////////////////////////////////////////////////
    136 
    137 Value::CommentInfo::CommentInfo() : comment_(0) {}
    138 
    139 Value::CommentInfo::~CommentInfo() {
    140   if (comment_)
    141     releaseStringValue(comment_);
    142 }
    143 
    144 void Value::CommentInfo::setComment(const char* text) {
    145   if (comment_)
    146     releaseStringValue(comment_);
    147   JSON_ASSERT(text != 0);
    148   JSON_ASSERT_MESSAGE(
    149       text[0] == '\0' || text[0] == '/',
    150       "in Json::Value::setComment(): Comments must start with /");
    151   // It seems that /**/ style comments are acceptable as well.
    152   comment_ = duplicateStringValue(text);
    153 }
    154 
    155 // //////////////////////////////////////////////////////////////////
    156 // //////////////////////////////////////////////////////////////////
    157 // //////////////////////////////////////////////////////////////////
    158 // class Value::CZString
    159 // //////////////////////////////////////////////////////////////////
    160 // //////////////////////////////////////////////////////////////////
    161 // //////////////////////////////////////////////////////////////////
    162 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    163 
    164 // Notes: index_ indicates if the string was allocated when
    165 // a string is stored.
    166 
    167 Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {}
    168 
    169 Value::CZString::CZString(const char* cstr, DuplicationPolicy allocate)
    170     : cstr_(allocate == duplicate ? duplicateStringValue(cstr) : cstr),
    171       index_(allocate) {}
    172 
    173 Value::CZString::CZString(const CZString& other)
    174     : cstr_(other.index_ != noDuplication && other.cstr_ != 0
    175                 ? duplicateStringValue(other.cstr_)
    176                 : other.cstr_),
    177       index_(other.cstr_
    178                  ? static_cast<ArrayIndex>(other.index_ == noDuplication
    179                      ? noDuplication : duplicate)
    180                  : other.index_) {}
    181 
    182 Value::CZString::~CZString() {
    183   if (cstr_ && index_ == duplicate)
    184     releaseStringValue(const_cast<char*>(cstr_));
    185 }
    186 
    187 void Value::CZString::swap(CZString& other) {
    188   std::swap(cstr_, other.cstr_);
    189   std::swap(index_, other.index_);
    190 }
    191 
    192 Value::CZString& Value::CZString::operator=(CZString other) {
    193   swap(other);
    194   return *this;
    195 }
    196 
    197 bool Value::CZString::operator<(const CZString& other) const {
    198   if (cstr_)
    199     return strcmp(cstr_, other.cstr_) < 0;
    200   return index_ < other.index_;
    201 }
    202 
    203 bool Value::CZString::operator==(const CZString& other) const {
    204   if (cstr_)
    205     return strcmp(cstr_, other.cstr_) == 0;
    206   return index_ == other.index_;
    207 }
    208 
    209 ArrayIndex Value::CZString::index() const { return index_; }
    210 
    211 const char* Value::CZString::c_str() const { return cstr_; }
    212 
    213 bool Value::CZString::isStaticString() const { return index_ == noDuplication; }
    214 
    215 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
    216 
    217 // //////////////////////////////////////////////////////////////////
    218 // //////////////////////////////////////////////////////////////////
    219 // //////////////////////////////////////////////////////////////////
    220 // class Value::Value
    221 // //////////////////////////////////////////////////////////////////
    222 // //////////////////////////////////////////////////////////////////
    223 // //////////////////////////////////////////////////////////////////
    224 
    225 /*! \internal Default constructor initialization must be equivalent to:
    226  * memset( this, 0, sizeof(Value) )
    227  * This optimization is used in ValueInternalMap fast allocator.
    228  */
    229 Value::Value(ValueType type) {
    230   initBasic(type);
    231   switch (type) {
    232   case nullValue:
    233     break;
    234   case intValue:
    235   case uintValue:
    236     value_.int_ = 0;
    237     break;
    238   case realValue:
    239     value_.real_ = 0.0;
    240     break;
    241   case stringValue:
    242     value_.string_ = 0;
    243     break;
    244 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    245   case arrayValue:
    246   case objectValue:
    247     value_.map_ = new ObjectValues();
    248     break;
    249 #else
    250   case arrayValue:
    251     value_.array_ = arrayAllocator()->newArray();
    252     break;
    253   case objectValue:
    254     value_.map_ = mapAllocator()->newMap();
    255     break;
    256 #endif
    257   case booleanValue:
    258     value_.bool_ = false;
    259     break;
    260   default:
    261     JSON_ASSERT_UNREACHABLE;
    262   }
    263 }
    264 
    265 Value::Value(Int value) {
    266   initBasic(intValue);
    267   value_.int_ = value;
    268 }
    269 
    270 Value::Value(UInt value) {
    271   initBasic(uintValue);
    272   value_.uint_ = value;
    273 }
    274 #if defined(JSON_HAS_INT64)
    275 Value::Value(Int64 value) {
    276   initBasic(intValue);
    277   value_.int_ = value;
    278 }
    279 Value::Value(UInt64 value) {
    280   initBasic(uintValue);
    281   value_.uint_ = value;
    282 }
    283 #endif // defined(JSON_HAS_INT64)
    284 
    285 Value::Value(double value) {
    286   initBasic(realValue);
    287   value_.real_ = value;
    288 }
    289 
    290 Value::Value(const char* value) {
    291   initBasic(stringValue, true);
    292   value_.string_ = duplicateStringValue(value);
    293 }
    294 
    295 Value::Value(const char* beginValue, const char* endValue) {
    296   initBasic(stringValue, true);
    297   value_.string_ =
    298       duplicateStringValue(beginValue, (unsigned int)(endValue - beginValue));
    299 }
    300 
    301 Value::Value(const std::string& value) {
    302   initBasic(stringValue, true);
    303   value_.string_ =
    304       duplicateStringValue(value.c_str(), (unsigned int)value.length());
    305 }
    306 
    307 Value::Value(const StaticString& value) {
    308   initBasic(stringValue);
    309   value_.string_ = const_cast<char*>(value.c_str());
    310 }
    311 
    312 #ifdef JSON_USE_CPPTL
    313 Value::Value(const CppTL::ConstString& value) {
    314   initBasic(stringValue, true);
    315   value_.string_ = duplicateStringValue(value, value.length());
    316 }
    317 #endif
    318 
    319 Value::Value(bool value) {
    320   initBasic(booleanValue);
    321   value_.bool_ = value;
    322 }
    323 
    324 Value::Value(const Value& other)
    325     : type_(other.type_), allocated_(false)
    326 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    327       ,
    328       itemIsUsed_(0)
    329 #endif
    330       ,
    331       comments_(0), start_(other.start_), limit_(other.limit_) {
    332   switch (type_) {
    333   case nullValue:
    334   case intValue:
    335   case uintValue:
    336   case realValue:
    337   case booleanValue:
    338     value_ = other.value_;
    339     break;
    340   case stringValue:
    341     if (other.value_.string_) {
    342       value_.string_ = duplicateStringValue(other.value_.string_);
    343       allocated_ = true;
    344     } else {
    345       value_.string_ = 0;
    346       allocated_ = false;
    347     }
    348     break;
    349 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    350   case arrayValue:
    351   case objectValue:
    352     value_.map_ = new ObjectValues(*other.value_.map_);
    353     break;
    354 #else
    355   case arrayValue:
    356     value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_);
    357     break;
    358   case objectValue:
    359     value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_);
    360     break;
    361 #endif
    362   default:
    363     JSON_ASSERT_UNREACHABLE;
    364   }
    365   if (other.comments_) {
    366     comments_ = new CommentInfo[numberOfCommentPlacement];
    367     for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
    368       const CommentInfo& otherComment = other.comments_[comment];
    369       if (otherComment.comment_)
    370         comments_[comment].setComment(otherComment.comment_);
    371     }
    372   }
    373 }
    374 
    375 Value::~Value() {
    376   switch (type_) {
    377   case nullValue:
    378   case intValue:
    379   case uintValue:
    380   case realValue:
    381   case booleanValue:
    382     break;
    383   case stringValue:
    384     if (allocated_)
    385       releaseStringValue(value_.string_);
    386     break;
    387 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    388   case arrayValue:
    389   case objectValue:
    390     delete value_.map_;
    391     break;
    392 #else
    393   case arrayValue:
    394     arrayAllocator()->destructArray(value_.array_);
    395     break;
    396   case objectValue:
    397     mapAllocator()->destructMap(value_.map_);
    398     break;
    399 #endif
    400   default:
    401     JSON_ASSERT_UNREACHABLE;
    402   }
    403 
    404   if (comments_)
    405     delete[] comments_;
    406 }
    407 
    408 Value& Value::operator=(Value other) {
    409   swap(other);
    410   return *this;
    411 }
    412 
    413 void Value::swap(Value& other) {
    414   ValueType temp = type_;
    415   type_ = other.type_;
    416   other.type_ = temp;
    417   std::swap(value_, other.value_);
    418   int temp2 = allocated_;
    419   allocated_ = other.allocated_;
    420   other.allocated_ = temp2;
    421   std::swap(start_, other.start_);
    422   std::swap(limit_, other.limit_);
    423 }
    424 
    425 ValueType Value::type() const { return type_; }
    426 
    427 int Value::compare(const Value& other) const {
    428   if (*this < other)
    429     return -1;
    430   if (*this > other)
    431     return 1;
    432   return 0;
    433 }
    434 
    435 bool Value::operator<(const Value& other) const {
    436   int typeDelta = type_ - other.type_;
    437   if (typeDelta)
    438     return typeDelta < 0 ? true : false;
    439   switch (type_) {
    440   case nullValue:
    441     return false;
    442   case intValue:
    443     return value_.int_ < other.value_.int_;
    444   case uintValue:
    445     return value_.uint_ < other.value_.uint_;
    446   case realValue:
    447     return value_.real_ < other.value_.real_;
    448   case booleanValue:
    449     return value_.bool_ < other.value_.bool_;
    450   case stringValue:
    451     return (value_.string_ == 0 && other.value_.string_) ||
    452            (other.value_.string_ && value_.string_ &&
    453             strcmp(value_.string_, other.value_.string_) < 0);
    454 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    455   case arrayValue:
    456   case objectValue: {
    457     int delta = int(value_.map_->size() - other.value_.map_->size());
    458     if (delta)
    459       return delta < 0;
    460     return (*value_.map_) < (*other.value_.map_);
    461   }
    462 #else
    463   case arrayValue:
    464     return value_.array_->compare(*(other.value_.array_)) < 0;
    465   case objectValue:
    466     return value_.map_->compare(*(other.value_.map_)) < 0;
    467 #endif
    468   default:
    469     JSON_ASSERT_UNREACHABLE;
    470   }
    471   return false; // unreachable
    472 }
    473 
    474 bool Value::operator<=(const Value& other) const { return !(other < *this); }
    475 
    476 bool Value::operator>=(const Value& other) const { return !(*this < other); }
    477 
    478 bool Value::operator>(const Value& other) const { return other < *this; }
    479 
    480 bool Value::operator==(const Value& other) const {
    481   // if ( type_ != other.type_ )
    482   // GCC 2.95.3 says:
    483   // attempt to take address of bit-field structure member `Json::Value::type_'
    484   // Beats me, but a temp solves the problem.
    485   int temp = other.type_;
    486   if (type_ != temp)
    487     return false;
    488   switch (type_) {
    489   case nullValue:
    490     return true;
    491   case intValue:
    492     return value_.int_ == other.value_.int_;
    493   case uintValue:
    494     return value_.uint_ == other.value_.uint_;
    495   case realValue:
    496     return value_.real_ == other.value_.real_;
    497   case booleanValue:
    498     return value_.bool_ == other.value_.bool_;
    499   case stringValue:
    500     return (value_.string_ == other.value_.string_) ||
    501            (other.value_.string_ && value_.string_ &&
    502             strcmp(value_.string_, other.value_.string_) == 0);
    503 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    504   case arrayValue:
    505   case objectValue:
    506     return value_.map_->size() == other.value_.map_->size() &&
    507            (*value_.map_) == (*other.value_.map_);
    508 #else
    509   case arrayValue:
    510     return value_.array_->compare(*(other.value_.array_)) == 0;
    511   case objectValue:
    512     return value_.map_->compare(*(other.value_.map_)) == 0;
    513 #endif
    514   default:
    515     JSON_ASSERT_UNREACHABLE;
    516   }
    517   return false; // unreachable
    518 }
    519 
    520 bool Value::operator!=(const Value& other) const { return !(*this == other); }
    521 
    522 const char* Value::asCString() const {
    523   JSON_ASSERT_MESSAGE(type_ == stringValue,
    524                       "in Json::Value::asCString(): requires stringValue");
    525   return value_.string_;
    526 }
    527 
    528 std::string Value::asString() const {
    529   switch (type_) {
    530   case nullValue:
    531     return "";
    532   case stringValue:
    533     return value_.string_ ? value_.string_ : "";
    534   case booleanValue:
    535     return value_.bool_ ? "true" : "false";
    536   case intValue:
    537     return valueToString(value_.int_);
    538   case uintValue:
    539     return valueToString(value_.uint_);
    540   case realValue:
    541     return valueToString(value_.real_);
    542   default:
    543     JSON_FAIL_MESSAGE("Type is not convertible to string");
    544   }
    545 }
    546 
    547 #ifdef JSON_USE_CPPTL
    548 CppTL::ConstString Value::asConstString() const {
    549   return CppTL::ConstString(asString().c_str());
    550 }
    551 #endif
    552 
    553 Value::Int Value::asInt() const {
    554   switch (type_) {
    555   case intValue:
    556     JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
    557     return Int(value_.int_);
    558   case uintValue:
    559     JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
    560     return Int(value_.uint_);
    561   case realValue:
    562     JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
    563                         "double out of Int range");
    564     return Int(value_.real_);
    565   case nullValue:
    566     return 0;
    567   case booleanValue:
    568     return value_.bool_ ? 1 : 0;
    569   default:
    570     break;
    571   }
    572   JSON_FAIL_MESSAGE("Value is not convertible to Int.");
    573 }
    574 
    575 Value::UInt Value::asUInt() const {
    576   switch (type_) {
    577   case intValue:
    578     JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
    579     return UInt(value_.int_);
    580   case uintValue:
    581     JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
    582     return UInt(value_.uint_);
    583   case realValue:
    584     JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
    585                         "double out of UInt range");
    586     return UInt(value_.real_);
    587   case nullValue:
    588     return 0;
    589   case booleanValue:
    590     return value_.bool_ ? 1 : 0;
    591   default:
    592     break;
    593   }
    594   JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
    595 }
    596 
    597 #if defined(JSON_HAS_INT64)
    598 
    599 Value::Int64 Value::asInt64() const {
    600   switch (type_) {
    601   case intValue:
    602     return Int64(value_.int_);
    603   case uintValue:
    604     JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
    605     return Int64(value_.uint_);
    606   case realValue:
    607     JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
    608                         "double out of Int64 range");
    609     return Int64(value_.real_);
    610   case nullValue:
    611     return 0;
    612   case booleanValue:
    613     return value_.bool_ ? 1 : 0;
    614   default:
    615     break;
    616   }
    617   JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
    618 }
    619 
    620 Value::UInt64 Value::asUInt64() const {
    621   switch (type_) {
    622   case intValue:
    623     JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
    624     return UInt64(value_.int_);
    625   case uintValue:
    626     return UInt64(value_.uint_);
    627   case realValue:
    628     JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
    629                         "double out of UInt64 range");
    630     return UInt64(value_.real_);
    631   case nullValue:
    632     return 0;
    633   case booleanValue:
    634     return value_.bool_ ? 1 : 0;
    635   default:
    636     break;
    637   }
    638   JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
    639 }
    640 #endif // if defined(JSON_HAS_INT64)
    641 
    642 LargestInt Value::asLargestInt() const {
    643 #if defined(JSON_NO_INT64)
    644   return asInt();
    645 #else
    646   return asInt64();
    647 #endif
    648 }
    649 
    650 LargestUInt Value::asLargestUInt() const {
    651 #if defined(JSON_NO_INT64)
    652   return asUInt();
    653 #else
    654   return asUInt64();
    655 #endif
    656 }
    657 
    658 double Value::asDouble() const {
    659   switch (type_) {
    660   case intValue:
    661     return static_cast<double>(value_.int_);
    662   case uintValue:
    663 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    664     return static_cast<double>(value_.uint_);
    665 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    666     return integerToDouble(value_.uint_);
    667 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    668   case realValue:
    669     return value_.real_;
    670   case nullValue:
    671     return 0.0;
    672   case booleanValue:
    673     return value_.bool_ ? 1.0 : 0.0;
    674   default:
    675     break;
    676   }
    677   JSON_FAIL_MESSAGE("Value is not convertible to double.");
    678 }
    679 
    680 float Value::asFloat() const {
    681   switch (type_) {
    682   case intValue:
    683     return static_cast<float>(value_.int_);
    684   case uintValue:
    685 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    686     return static_cast<float>(value_.uint_);
    687 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    688     return integerToDouble(value_.uint_);
    689 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    690   case realValue:
    691     return static_cast<float>(value_.real_);
    692   case nullValue:
    693     return 0.0;
    694   case booleanValue:
    695     return value_.bool_ ? 1.0f : 0.0f;
    696   default:
    697     break;
    698   }
    699   JSON_FAIL_MESSAGE("Value is not convertible to float.");
    700 }
    701 
    702 bool Value::asBool() const {
    703   switch (type_) {
    704   case booleanValue:
    705     return value_.bool_;
    706   case nullValue:
    707     return false;
    708   case intValue:
    709     return value_.int_ ? true : false;
    710   case uintValue:
    711     return value_.uint_ ? true : false;
    712   case realValue:
    713     return value_.real_ ? true : false;
    714   default:
    715     break;
    716   }
    717   JSON_FAIL_MESSAGE("Value is not convertible to bool.");
    718 }
    719 
    720 bool Value::isConvertibleTo(ValueType other) const {
    721   switch (other) {
    722   case nullValue:
    723     return (isNumeric() && asDouble() == 0.0) ||
    724            (type_ == booleanValue && value_.bool_ == false) ||
    725            (type_ == stringValue && asString() == "") ||
    726            (type_ == arrayValue && value_.map_->size() == 0) ||
    727            (type_ == objectValue && value_.map_->size() == 0) ||
    728            type_ == nullValue;
    729   case intValue:
    730     return isInt() ||
    731            (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
    732            type_ == booleanValue || type_ == nullValue;
    733   case uintValue:
    734     return isUInt() ||
    735            (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
    736            type_ == booleanValue || type_ == nullValue;
    737   case realValue:
    738     return isNumeric() || type_ == booleanValue || type_ == nullValue;
    739   case booleanValue:
    740     return isNumeric() || type_ == booleanValue || type_ == nullValue;
    741   case stringValue:
    742     return isNumeric() || type_ == booleanValue || type_ == stringValue ||
    743            type_ == nullValue;
    744   case arrayValue:
    745     return type_ == arrayValue || type_ == nullValue;
    746   case objectValue:
    747     return type_ == objectValue || type_ == nullValue;
    748   }
    749   JSON_ASSERT_UNREACHABLE;
    750   return false;
    751 }
    752 
    753 /// Number of values in array or object
    754 ArrayIndex Value::size() const {
    755   switch (type_) {
    756   case nullValue:
    757   case intValue:
    758   case uintValue:
    759   case realValue:
    760   case booleanValue:
    761   case stringValue:
    762     return 0;
    763 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    764   case arrayValue: // size of the array is highest index + 1
    765     if (!value_.map_->empty()) {
    766       ObjectValues::const_iterator itLast = value_.map_->end();
    767       --itLast;
    768       return (*itLast).first.index() + 1;
    769     }
    770     return 0;
    771   case objectValue:
    772     return ArrayIndex(value_.map_->size());
    773 #else
    774   case arrayValue:
    775     return Int(value_.array_->size());
    776   case objectValue:
    777     return Int(value_.map_->size());
    778 #endif
    779   }
    780   JSON_ASSERT_UNREACHABLE;
    781   return 0; // unreachable;
    782 }
    783 
    784 bool Value::empty() const {
    785   if (isNull() || isArray() || isObject())
    786     return size() == 0u;
    787   else
    788     return false;
    789 }
    790 
    791 bool Value::operator!() const { return isNull(); }
    792 
    793 void Value::clear() {
    794   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
    795                           type_ == objectValue,
    796                       "in Json::Value::clear(): requires complex value");
    797   start_ = 0;
    798   limit_ = 0;
    799   switch (type_) {
    800 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    801   case arrayValue:
    802   case objectValue:
    803     value_.map_->clear();
    804     break;
    805 #else
    806   case arrayValue:
    807     value_.array_->clear();
    808     break;
    809   case objectValue:
    810     value_.map_->clear();
    811     break;
    812 #endif
    813   default:
    814     break;
    815   }
    816 }
    817 
    818 void Value::resize(ArrayIndex newSize) {
    819   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
    820                       "in Json::Value::resize(): requires arrayValue");
    821   if (type_ == nullValue)
    822     *this = Value(arrayValue);
    823 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    824   ArrayIndex oldSize = size();
    825   if (newSize == 0)
    826     clear();
    827   else if (newSize > oldSize)
    828     (*this)[newSize - 1];
    829   else {
    830     for (ArrayIndex index = newSize; index < oldSize; ++index) {
    831       value_.map_->erase(index);
    832     }
    833     assert(size() == newSize);
    834   }
    835 #else
    836   value_.array_->resize(newSize);
    837 #endif
    838 }
    839 
    840 Value& Value::operator[](ArrayIndex index) {
    841   JSON_ASSERT_MESSAGE(
    842       type_ == nullValue || type_ == arrayValue,
    843       "in Json::Value::operator[](ArrayIndex): requires arrayValue");
    844   if (type_ == nullValue)
    845     *this = Value(arrayValue);
    846 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    847   CZString key(index);
    848   ObjectValues::iterator it = value_.map_->lower_bound(key);
    849   if (it != value_.map_->end() && (*it).first == key)
    850     return (*it).second;
    851 
    852   ObjectValues::value_type defaultValue(key, null);
    853   it = value_.map_->insert(it, defaultValue);
    854   return (*it).second;
    855 #else
    856   return value_.array_->resolveReference(index);
    857 #endif
    858 }
    859 
    860 Value& Value::operator[](int index) {
    861   JSON_ASSERT_MESSAGE(
    862       index >= 0,
    863       "in Json::Value::operator[](int index): index cannot be negative");
    864   return (*this)[ArrayIndex(index)];
    865 }
    866 
    867 const Value& Value::operator[](ArrayIndex index) const {
    868   JSON_ASSERT_MESSAGE(
    869       type_ == nullValue || type_ == arrayValue,
    870       "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
    871   if (type_ == nullValue)
    872     return null;
    873 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    874   CZString key(index);
    875   ObjectValues::const_iterator it = value_.map_->find(key);
    876   if (it == value_.map_->end())
    877     return null;
    878   return (*it).second;
    879 #else
    880   Value* value = value_.array_->find(index);
    881   return value ? *value : null;
    882 #endif
    883 }
    884 
    885 const Value& Value::operator[](int index) const {
    886   JSON_ASSERT_MESSAGE(
    887       index >= 0,
    888       "in Json::Value::operator[](int index) const: index cannot be negative");
    889   return (*this)[ArrayIndex(index)];
    890 }
    891 
    892 Value& Value::operator[](const char* key) {
    893   return resolveReference(key, false);
    894 }
    895 
    896 void Value::initBasic(ValueType type, bool allocated) {
    897   type_ = type;
    898   allocated_ = allocated;
    899 #ifdef JSON_VALUE_USE_INTERNAL_MAP
    900   itemIsUsed_ = 0;
    901 #endif
    902   comments_ = 0;
    903   start_ = 0;
    904   limit_ = 0;
    905 }
    906 
    907 Value& Value::resolveReference(const char* key, bool isStatic) {
    908   JSON_ASSERT_MESSAGE(
    909       type_ == nullValue || type_ == objectValue,
    910       "in Json::Value::resolveReference(): requires objectValue");
    911   if (type_ == nullValue)
    912     *this = Value(objectValue);
    913 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    914   CZString actualKey(
    915       key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
    916   ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
    917   if (it != value_.map_->end() && (*it).first == actualKey)
    918     return (*it).second;
    919 
    920   ObjectValues::value_type defaultValue(actualKey, null);
    921   it = value_.map_->insert(it, defaultValue);
    922   Value& value = (*it).second;
    923   return value;
    924 #else
    925   return value_.map_->resolveReference(key, isStatic);
    926 #endif
    927 }
    928 
    929 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
    930   const Value* value = &((*this)[index]);
    931   return value == &null ? defaultValue : *value;
    932 }
    933 
    934 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
    935 
    936 const Value& Value::operator[](const char* key) const {
    937   JSON_ASSERT_MESSAGE(
    938       type_ == nullValue || type_ == objectValue,
    939       "in Json::Value::operator[](char const*)const: requires objectValue");
    940   if (type_ == nullValue)
    941     return null;
    942 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    943   CZString actualKey(key, CZString::noDuplication);
    944   ObjectValues::const_iterator it = value_.map_->find(actualKey);
    945   if (it == value_.map_->end())
    946     return null;
    947   return (*it).second;
    948 #else
    949   const Value* value = value_.map_->find(key);
    950   return value ? *value : null;
    951 #endif
    952 }
    953 
    954 Value& Value::operator[](const std::string& key) {
    955   return (*this)[key.c_str()];
    956 }
    957 
    958 const Value& Value::operator[](const std::string& key) const {
    959   return (*this)[key.c_str()];
    960 }
    961 
    962 Value& Value::operator[](const StaticString& key) {
    963   return resolveReference(key, true);
    964 }
    965 
    966 #ifdef JSON_USE_CPPTL
    967 Value& Value::operator[](const CppTL::ConstString& key) {
    968   return (*this)[key.c_str()];
    969 }
    970 
    971 const Value& Value::operator[](const CppTL::ConstString& key) const {
    972   return (*this)[key.c_str()];
    973 }
    974 #endif
    975 
    976 Value& Value::append(const Value& value) { return (*this)[size()] = value; }
    977 
    978 Value Value::get(const char* key, const Value& defaultValue) const {
    979   const Value* value = &((*this)[key]);
    980   return value == &null ? defaultValue : *value;
    981 }
    982 
    983 Value Value::get(const std::string& key, const Value& defaultValue) const {
    984   return get(key.c_str(), defaultValue);
    985 }
    986 
    987 Value Value::removeMember(const char* key) {
    988   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
    989                       "in Json::Value::removeMember(): requires objectValue");
    990   if (type_ == nullValue)
    991     return null;
    992 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    993   CZString actualKey(key, CZString::noDuplication);
    994   ObjectValues::iterator it = value_.map_->find(actualKey);
    995   if (it == value_.map_->end())
    996     return null;
    997   Value old(it->second);
    998   value_.map_->erase(it);
    999   return old;
   1000 #else
   1001   Value* value = value_.map_->find(key);
   1002   if (value) {
   1003     Value old(*value);
   1004     value_.map_.remove(key);
   1005     return old;
   1006   } else {
   1007     return null;
   1008   }
   1009 #endif
   1010 }
   1011 
   1012 Value Value::removeMember(const std::string& key) {
   1013   return removeMember(key.c_str());
   1014 }
   1015 
   1016 #ifdef JSON_USE_CPPTL
   1017 Value Value::get(const CppTL::ConstString& key,
   1018                  const Value& defaultValue) const {
   1019   return get(key.c_str(), defaultValue);
   1020 }
   1021 #endif
   1022 
   1023 bool Value::isMember(const char* key) const {
   1024   const Value* value = &((*this)[key]);
   1025   return value != &null;
   1026 }
   1027 
   1028 bool Value::isMember(const std::string& key) const {
   1029   return isMember(key.c_str());
   1030 }
   1031 
   1032 #ifdef JSON_USE_CPPTL
   1033 bool Value::isMember(const CppTL::ConstString& key) const {
   1034   return isMember(key.c_str());
   1035 }
   1036 #endif
   1037 
   1038 Value::Members Value::getMemberNames() const {
   1039   JSON_ASSERT_MESSAGE(
   1040       type_ == nullValue || type_ == objectValue,
   1041       "in Json::Value::getMemberNames(), value must be objectValue");
   1042   if (type_ == nullValue)
   1043     return Value::Members();
   1044   Members members;
   1045   members.reserve(value_.map_->size());
   1046 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1047   ObjectValues::const_iterator it = value_.map_->begin();
   1048   ObjectValues::const_iterator itEnd = value_.map_->end();
   1049   for (; it != itEnd; ++it)
   1050     members.push_back(std::string((*it).first.c_str()));
   1051 #else
   1052   ValueInternalMap::IteratorState it;
   1053   ValueInternalMap::IteratorState itEnd;
   1054   value_.map_->makeBeginIterator(it);
   1055   value_.map_->makeEndIterator(itEnd);
   1056   for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it))
   1057     members.push_back(std::string(ValueInternalMap::key(it)));
   1058 #endif
   1059   return members;
   1060 }
   1061 //
   1062 //# ifdef JSON_USE_CPPTL
   1063 // EnumMemberNames
   1064 // Value::enumMemberNames() const
   1065 //{
   1066 //   if ( type_ == objectValue )
   1067 //   {
   1068 //      return CppTL::Enum::any(  CppTL::Enum::transform(
   1069 //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
   1070 //         MemberNamesTransform() ) );
   1071 //   }
   1072 //   return EnumMemberNames();
   1073 //}
   1074 //
   1075 //
   1076 // EnumValues
   1077 // Value::enumValues() const
   1078 //{
   1079 //   if ( type_ == objectValue  ||  type_ == arrayValue )
   1080 //      return CppTL::Enum::anyValues( *(value_.map_),
   1081 //                                     CppTL::Type<const Value &>() );
   1082 //   return EnumValues();
   1083 //}
   1084 //
   1085 //# endif
   1086 
   1087 static bool IsIntegral(double d) {
   1088   double integral_part;
   1089   return modf(d, &integral_part) == 0.0;
   1090 }
   1091 
   1092 bool Value::isNull() const { return type_ == nullValue; }
   1093 
   1094 bool Value::isBool() const { return type_ == booleanValue; }
   1095 
   1096 bool Value::isInt() const {
   1097   switch (type_) {
   1098   case intValue:
   1099     return value_.int_ >= minInt && value_.int_ <= maxInt;
   1100   case uintValue:
   1101     return value_.uint_ <= UInt(maxInt);
   1102   case realValue:
   1103     return value_.real_ >= minInt && value_.real_ <= maxInt &&
   1104            IsIntegral(value_.real_);
   1105   default:
   1106     break;
   1107   }
   1108   return false;
   1109 }
   1110 
   1111 bool Value::isUInt() const {
   1112   switch (type_) {
   1113   case intValue:
   1114     return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
   1115   case uintValue:
   1116     return value_.uint_ <= maxUInt;
   1117   case realValue:
   1118     return value_.real_ >= 0 && value_.real_ <= maxUInt &&
   1119            IsIntegral(value_.real_);
   1120   default:
   1121     break;
   1122   }
   1123   return false;
   1124 }
   1125 
   1126 bool Value::isInt64() const {
   1127 #if defined(JSON_HAS_INT64)
   1128   switch (type_) {
   1129   case intValue:
   1130     return true;
   1131   case uintValue:
   1132     return value_.uint_ <= UInt64(maxInt64);
   1133   case realValue:
   1134     // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
   1135     // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
   1136     // require the value to be strictly less than the limit.
   1137     return value_.real_ >= double(minInt64) &&
   1138            value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
   1139   default:
   1140     break;
   1141   }
   1142 #endif // JSON_HAS_INT64
   1143   return false;
   1144 }
   1145 
   1146 bool Value::isUInt64() const {
   1147 #if defined(JSON_HAS_INT64)
   1148   switch (type_) {
   1149   case intValue:
   1150     return value_.int_ >= 0;
   1151   case uintValue:
   1152     return true;
   1153   case realValue:
   1154     // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
   1155     // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
   1156     // require the value to be strictly less than the limit.
   1157     return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
   1158            IsIntegral(value_.real_);
   1159   default:
   1160     break;
   1161   }
   1162 #endif // JSON_HAS_INT64
   1163   return false;
   1164 }
   1165 
   1166 bool Value::isIntegral() const {
   1167 #if defined(JSON_HAS_INT64)
   1168   return isInt64() || isUInt64();
   1169 #else
   1170   return isInt() || isUInt();
   1171 #endif
   1172 }
   1173 
   1174 bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
   1175 
   1176 bool Value::isNumeric() const { return isIntegral() || isDouble(); }
   1177 
   1178 bool Value::isString() const { return type_ == stringValue; }
   1179 
   1180 bool Value::isArray() const { return type_ == arrayValue; }
   1181 
   1182 bool Value::isObject() const { return type_ == objectValue; }
   1183 
   1184 void Value::setComment(const char* comment, CommentPlacement placement) {
   1185   if (!comments_)
   1186     comments_ = new CommentInfo[numberOfCommentPlacement];
   1187   comments_[placement].setComment(comment);
   1188 }
   1189 
   1190 void Value::setComment(const std::string& comment, CommentPlacement placement) {
   1191   setComment(comment.c_str(), placement);
   1192 }
   1193 
   1194 bool Value::hasComment(CommentPlacement placement) const {
   1195   return comments_ != 0 && comments_[placement].comment_ != 0;
   1196 }
   1197 
   1198 std::string Value::getComment(CommentPlacement placement) const {
   1199   if (hasComment(placement))
   1200     return comments_[placement].comment_;
   1201   return "";
   1202 }
   1203 
   1204 void Value::setOffsetStart(size_t start) { start_ = start; }
   1205 
   1206 void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
   1207 
   1208 size_t Value::getOffsetStart() const { return start_; }
   1209 
   1210 size_t Value::getOffsetLimit() const { return limit_; }
   1211 
   1212 std::string Value::toStyledString() const {
   1213   StyledWriter writer;
   1214   return writer.write(*this);
   1215 }
   1216 
   1217 Value::const_iterator Value::begin() const {
   1218   switch (type_) {
   1219 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1220   case arrayValue:
   1221     if (value_.array_) {
   1222       ValueInternalArray::IteratorState it;
   1223       value_.array_->makeBeginIterator(it);
   1224       return const_iterator(it);
   1225     }
   1226     break;
   1227   case objectValue:
   1228     if (value_.map_) {
   1229       ValueInternalMap::IteratorState it;
   1230       value_.map_->makeBeginIterator(it);
   1231       return const_iterator(it);
   1232     }
   1233     break;
   1234 #else
   1235   case arrayValue:
   1236   case objectValue:
   1237     if (value_.map_)
   1238       return const_iterator(value_.map_->begin());
   1239     break;
   1240 #endif
   1241   default:
   1242     break;
   1243   }
   1244   return const_iterator();
   1245 }
   1246 
   1247 Value::const_iterator Value::end() const {
   1248   switch (type_) {
   1249 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1250   case arrayValue:
   1251     if (value_.array_) {
   1252       ValueInternalArray::IteratorState it;
   1253       value_.array_->makeEndIterator(it);
   1254       return const_iterator(it);
   1255     }
   1256     break;
   1257   case objectValue:
   1258     if (value_.map_) {
   1259       ValueInternalMap::IteratorState it;
   1260       value_.map_->makeEndIterator(it);
   1261       return const_iterator(it);
   1262     }
   1263     break;
   1264 #else
   1265   case arrayValue:
   1266   case objectValue:
   1267     if (value_.map_)
   1268       return const_iterator(value_.map_->end());
   1269     break;
   1270 #endif
   1271   default:
   1272     break;
   1273   }
   1274   return const_iterator();
   1275 }
   1276 
   1277 Value::iterator Value::begin() {
   1278   switch (type_) {
   1279 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1280   case arrayValue:
   1281     if (value_.array_) {
   1282       ValueInternalArray::IteratorState it;
   1283       value_.array_->makeBeginIterator(it);
   1284       return iterator(it);
   1285     }
   1286     break;
   1287   case objectValue:
   1288     if (value_.map_) {
   1289       ValueInternalMap::IteratorState it;
   1290       value_.map_->makeBeginIterator(it);
   1291       return iterator(it);
   1292     }
   1293     break;
   1294 #else
   1295   case arrayValue:
   1296   case objectValue:
   1297     if (value_.map_)
   1298       return iterator(value_.map_->begin());
   1299     break;
   1300 #endif
   1301   default:
   1302     break;
   1303   }
   1304   return iterator();
   1305 }
   1306 
   1307 Value::iterator Value::end() {
   1308   switch (type_) {
   1309 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1310   case arrayValue:
   1311     if (value_.array_) {
   1312       ValueInternalArray::IteratorState it;
   1313       value_.array_->makeEndIterator(it);
   1314       return iterator(it);
   1315     }
   1316     break;
   1317   case objectValue:
   1318     if (value_.map_) {
   1319       ValueInternalMap::IteratorState it;
   1320       value_.map_->makeEndIterator(it);
   1321       return iterator(it);
   1322     }
   1323     break;
   1324 #else
   1325   case arrayValue:
   1326   case objectValue:
   1327     if (value_.map_)
   1328       return iterator(value_.map_->end());
   1329     break;
   1330 #endif
   1331   default:
   1332     break;
   1333   }
   1334   return iterator();
   1335 }
   1336 
   1337 // class PathArgument
   1338 // //////////////////////////////////////////////////////////////////
   1339 
   1340 PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
   1341 
   1342 PathArgument::PathArgument(ArrayIndex index)
   1343     : key_(), index_(index), kind_(kindIndex) {}
   1344 
   1345 PathArgument::PathArgument(const char* key)
   1346     : key_(key), index_(), kind_(kindKey) {}
   1347 
   1348 PathArgument::PathArgument(const std::string& key)
   1349     : key_(key.c_str()), index_(), kind_(kindKey) {}
   1350 
   1351 // class Path
   1352 // //////////////////////////////////////////////////////////////////
   1353 
   1354 Path::Path(const std::string& path,
   1355            const PathArgument& a1,
   1356            const PathArgument& a2,
   1357            const PathArgument& a3,
   1358            const PathArgument& a4,
   1359            const PathArgument& a5) {
   1360   InArgs in;
   1361   in.push_back(&a1);
   1362   in.push_back(&a2);
   1363   in.push_back(&a3);
   1364   in.push_back(&a4);
   1365   in.push_back(&a5);
   1366   makePath(path, in);
   1367 }
   1368 
   1369 void Path::makePath(const std::string& path, const InArgs& in) {
   1370   const char* current = path.c_str();
   1371   const char* end = current + path.length();
   1372   InArgs::const_iterator itInArg = in.begin();
   1373   while (current != end) {
   1374     if (*current == '[') {
   1375       ++current;
   1376       if (*current == '%')
   1377         addPathInArg(path, in, itInArg, PathArgument::kindIndex);
   1378       else {
   1379         ArrayIndex index = 0;
   1380         for (; current != end && *current >= '0' && *current <= '9'; ++current)
   1381           index = index * 10 + ArrayIndex(*current - '0');
   1382         args_.push_back(index);
   1383       }
   1384       if (current == end || *current++ != ']')
   1385         invalidPath(path, int(current - path.c_str()));
   1386     } else if (*current == '%') {
   1387       addPathInArg(path, in, itInArg, PathArgument::kindKey);
   1388       ++current;
   1389     } else if (*current == '.') {
   1390       ++current;
   1391     } else {
   1392       const char* beginName = current;
   1393       while (current != end && !strchr("[.", *current))
   1394         ++current;
   1395       args_.push_back(std::string(beginName, current));
   1396     }
   1397   }
   1398 }
   1399 
   1400 void Path::addPathInArg(const std::string& /*path*/,
   1401                         const InArgs& in,
   1402                         InArgs::const_iterator& itInArg,
   1403                         PathArgument::Kind kind) {
   1404   if (itInArg == in.end()) {
   1405     // Error: missing argument %d
   1406   } else if ((*itInArg)->kind_ != kind) {
   1407     // Error: bad argument type
   1408   } else {
   1409     args_.push_back(**itInArg);
   1410   }
   1411 }
   1412 
   1413 void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
   1414   // Error: invalid path.
   1415 }
   1416 
   1417 const Value& Path::resolve(const Value& root) const {
   1418   const Value* node = &root;
   1419   for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
   1420     const PathArgument& arg = *it;
   1421     if (arg.kind_ == PathArgument::kindIndex) {
   1422       if (!node->isArray() || !node->isValidIndex(arg.index_)) {
   1423         // Error: unable to resolve path (array value expected at position...
   1424       }
   1425       node = &((*node)[arg.index_]);
   1426     } else if (arg.kind_ == PathArgument::kindKey) {
   1427       if (!node->isObject()) {
   1428         // Error: unable to resolve path (object value expected at position...)
   1429       }
   1430       node = &((*node)[arg.key_]);
   1431       if (node == &Value::null) {
   1432         // Error: unable to resolve path (object has no member named '' at
   1433         // position...)
   1434       }
   1435     }
   1436   }
   1437   return *node;
   1438 }
   1439 
   1440 Value Path::resolve(const Value& root, const Value& defaultValue) const {
   1441   const Value* node = &root;
   1442   for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
   1443     const PathArgument& arg = *it;
   1444     if (arg.kind_ == PathArgument::kindIndex) {
   1445       if (!node->isArray() || !node->isValidIndex(arg.index_))
   1446         return defaultValue;
   1447       node = &((*node)[arg.index_]);
   1448     } else if (arg.kind_ == PathArgument::kindKey) {
   1449       if (!node->isObject())
   1450         return defaultValue;
   1451       node = &((*node)[arg.key_]);
   1452       if (node == &Value::null)
   1453         return defaultValue;
   1454     }
   1455   }
   1456   return *node;
   1457 }
   1458 
   1459 Value& Path::make(Value& root) const {
   1460   Value* node = &root;
   1461   for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
   1462     const PathArgument& arg = *it;
   1463     if (arg.kind_ == PathArgument::kindIndex) {
   1464       if (!node->isArray()) {
   1465         // Error: node is not an array at position ...
   1466       }
   1467       node = &((*node)[arg.index_]);
   1468     } else if (arg.kind_ == PathArgument::kindKey) {
   1469       if (!node->isObject()) {
   1470         // Error: node is not an object at position...
   1471       }
   1472       node = &((*node)[arg.key_]);
   1473     }
   1474   }
   1475   return *node;
   1476 }
   1477 
   1478 } // namespace Json
   1479