00001
00002
00003
00004
00005
00006 #if !defined(JSON_IS_AMALGAMATION)
00007 #include <json/assertions.h>
00008 #include <json/value.h>
00009 #include <json/writer.h>
00010 #endif // if !defined(JSON_IS_AMALGAMATION)
00011 #include <math.h>
00012 #include <sstream>
00013 #include <utility>
00014 #include <cstring>
00015 #include <cassert>
00016 #ifdef JSON_USE_CPPTL
00017 #include <cpptl/conststring.h>
00018 #endif
00019 #include <cstddef>
00020 #include <algorithm>
00021
00022 #define JSON_ASSERT_UNREACHABLE assert(false)
00023
00024 namespace Json {
00025
00026
00027
00028
00029 #if defined(__ARMEL__)
00030 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
00031 #else
00032 #define ALIGNAS(byte_alignment)
00033 #endif
00034 static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
00035 const unsigned char& kNullRef = kNull[0];
00036 const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
00037 const Value& Value::nullRef = null;
00038
00039 const Int Value::minInt = Int(~(UInt(-1) / 2));
00040 const Int Value::maxInt = Int(UInt(-1) / 2);
00041 const UInt Value::maxUInt = UInt(-1);
00042 #if defined(JSON_HAS_INT64)
00043 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
00044 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
00045 const UInt64 Value::maxUInt64 = UInt64(-1);
00046
00047
00048
00049 static const double maxUInt64AsDouble = 18446744073709551615.0;
00050 #endif // defined(JSON_HAS_INT64)
00051 const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
00052 const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
00053 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
00054
00055 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00056 template <typename T, typename U>
00057 static inline bool InRange(double d, T min, U max) {
00058 return d >= min && d <= max;
00059 }
00060 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00061 static inline double integerToDouble(Json::UInt64 value) {
00062 return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
00063 }
00064
00065 template <typename T> static inline double integerToDouble(T value) {
00066 return static_cast<double>(value);
00067 }
00068
00069 template <typename T, typename U>
00070 static inline bool InRange(double d, T min, U max) {
00071 return d >= integerToDouble(min) && d <= integerToDouble(max);
00072 }
00073 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00074
00082 static inline char* duplicateStringValue(const char* value,
00083 size_t length) {
00084
00085
00086 if (length >= (size_t)Value::maxInt)
00087 length = Value::maxInt - 1;
00088
00089 char* newString = static_cast<char*>(malloc(length + 1));
00090 if (newString == NULL) {
00091 throwRuntimeError(
00092 "in Json::Value::duplicateStringValue(): "
00093 "Failed to allocate string value buffer");
00094 }
00095 memcpy(newString, value, length);
00096 newString[length] = 0;
00097 return newString;
00098 }
00099
00100
00101
00102 static inline char* duplicateAndPrefixStringValue(
00103 const char* value,
00104 unsigned int length)
00105 {
00106
00107
00108 JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U,
00109 "in Json::Value::duplicateAndPrefixStringValue(): "
00110 "length too big for prefixing");
00111 unsigned actualLength = length + sizeof(unsigned) + 1U;
00112 char* newString = static_cast<char*>(malloc(actualLength));
00113 if (newString == 0) {
00114 throwRuntimeError(
00115 "in Json::Value::duplicateAndPrefixStringValue(): "
00116 "Failed to allocate string value buffer");
00117 }
00118 *reinterpret_cast<unsigned*>(newString) = length;
00119 memcpy(newString + sizeof(unsigned), value, length);
00120 newString[actualLength - 1U] = 0;
00121 return newString;
00122 }
00123 inline static void decodePrefixedString(
00124 bool isPrefixed, char const* prefixed,
00125 unsigned* length, char const** value)
00126 {
00127 if (!isPrefixed) {
00128 *length = strlen(prefixed);
00129 *value = prefixed;
00130 } else {
00131 *length = *reinterpret_cast<unsigned const*>(prefixed);
00132 *value = prefixed + sizeof(unsigned);
00133 }
00134 }
00137 static inline void releaseStringValue(char* value) { free(value); }
00138
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148 #if !defined(JSON_IS_AMALGAMATION)
00149
00150 #include "json_valueiterator.inl"
00151 #endif // if !defined(JSON_IS_AMALGAMATION)
00152
00153 namespace Json {
00154
00155 class JSON_API Exception : public std::exception {
00156 public:
00157 Exception(std::string const& msg);
00158 virtual ~Exception() throw();
00159 virtual char const* what() const throw();
00160 protected:
00161 std::string const msg_;
00162 };
00163 class JSON_API RuntimeError : public Exception {
00164 public:
00165 RuntimeError(std::string const& msg);
00166 };
00167 class JSON_API LogicError : public Exception {
00168 public:
00169 LogicError(std::string const& msg);
00170 };
00171
00172 Exception::Exception(std::string const& msg)
00173 : msg_(msg)
00174 {}
00175 Exception::~Exception() throw()
00176 {}
00177 char const* Exception::what() const throw()
00178 {
00179 return msg_.c_str();
00180 }
00181 RuntimeError::RuntimeError(std::string const& msg)
00182 : Exception(msg)
00183 {}
00184 LogicError::LogicError(std::string const& msg)
00185 : Exception(msg)
00186 {}
00187 void throwRuntimeError(std::string const& msg)
00188 {
00189 throw RuntimeError(msg);
00190 }
00191 void throwLogicError(std::string const& msg)
00192 {
00193 throw LogicError(msg);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 Value::CommentInfo::CommentInfo() : comment_(0) {}
00205
00206 Value::CommentInfo::~CommentInfo() {
00207 if (comment_)
00208 releaseStringValue(comment_);
00209 }
00210
00211 void Value::CommentInfo::setComment(const char* text, size_t len) {
00212 if (comment_) {
00213 releaseStringValue(comment_);
00214 comment_ = 0;
00215 }
00216 JSON_ASSERT(text != 0);
00217 JSON_ASSERT_MESSAGE(
00218 text[0] == '\0' || text[0] == '/',
00219 "in Json::Value::setComment(): Comments must start with /");
00220
00221 comment_ = duplicateStringValue(text, len);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {}
00236
00237 Value::CZString::CZString(char const* str, unsigned length, DuplicationPolicy allocate)
00238 : cstr_(str)
00239 {
00240
00241 storage_.policy_ = allocate;
00242 storage_.length_ = length;
00243 }
00244
00245 Value::CZString::CZString(const CZString& other)
00246 : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
00247 ? duplicateStringValue(other.cstr_, other.storage_.length_)
00248 : other.cstr_)
00249 {
00250 storage_.policy_ = (other.cstr_
00251 ? (other.storage_.policy_ == noDuplication
00252 ? noDuplication : duplicate)
00253 : other.storage_.policy_);
00254 storage_.length_ = other.storage_.length_;
00255 }
00256
00257 Value::CZString::~CZString() {
00258 if (cstr_ && storage_.policy_ == duplicate)
00259 releaseStringValue(const_cast<char*>(cstr_));
00260 }
00261
00262 void Value::CZString::swap(CZString& other) {
00263 std::swap(cstr_, other.cstr_);
00264 std::swap(index_, other.index_);
00265 }
00266
00267 Value::CZString& Value::CZString::operator=(CZString other) {
00268 swap(other);
00269 return *this;
00270 }
00271
00272 bool Value::CZString::operator<(const CZString& other) const {
00273 if (!cstr_) return index_ < other.index_;
00274
00275
00276 unsigned this_len = this->storage_.length_;
00277 unsigned other_len = other.storage_.length_;
00278 unsigned min_len = std::min(this_len, other_len);
00279 int comp = memcmp(this->cstr_, other.cstr_, min_len);
00280 if (comp < 0) return true;
00281 if (comp > 0) return false;
00282 return (this_len < other_len);
00283 }
00284
00285 bool Value::CZString::operator==(const CZString& other) const {
00286 if (!cstr_) return index_ == other.index_;
00287
00288
00289 unsigned this_len = this->storage_.length_;
00290 unsigned other_len = other.storage_.length_;
00291 if (this_len != other_len) return false;
00292 int comp = memcmp(this->cstr_, other.cstr_, this_len);
00293 return comp == 0;
00294 }
00295
00296 ArrayIndex Value::CZString::index() const { return index_; }
00297
00298
00299 const char* Value::CZString::data() const { return cstr_; }
00300 unsigned Value::CZString::length() const { return storage_.length_; }
00301 bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00315 Value::Value(ValueType type) {
00316 initBasic(type);
00317 switch (type) {
00318 case nullValue:
00319 break;
00320 case intValue:
00321 case uintValue:
00322 value_.int_ = 0;
00323 break;
00324 case realValue:
00325 value_.real_ = 0.0;
00326 break;
00327 case stringValue:
00328 value_.string_ = 0;
00329 break;
00330 case arrayValue:
00331 case objectValue:
00332 value_.map_ = new ObjectValues();
00333 break;
00334 case booleanValue:
00335 value_.bool_ = false;
00336 break;
00337 default:
00338 JSON_ASSERT_UNREACHABLE;
00339 }
00340 }
00341
00342 Value::Value(Int value) {
00343 initBasic(intValue);
00344 value_.int_ = value;
00345 }
00346
00347 Value::Value(UInt value) {
00348 initBasic(uintValue);
00349 value_.uint_ = value;
00350 }
00351 #if defined(JSON_HAS_INT64)
00352 Value::Value(Int64 value) {
00353 initBasic(intValue);
00354 value_.int_ = value;
00355 }
00356 Value::Value(UInt64 value) {
00357 initBasic(uintValue);
00358 value_.uint_ = value;
00359 }
00360 #endif // defined(JSON_HAS_INT64)
00361
00362 Value::Value(double value) {
00363 initBasic(realValue);
00364 value_.real_ = value;
00365 }
00366
00367 Value::Value(const char* value) {
00368 initBasic(stringValue, true);
00369 value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
00370 }
00371
00372 Value::Value(const char* beginValue, const char* endValue) {
00373 initBasic(stringValue, true);
00374 value_.string_ =
00375 duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
00376 }
00377
00378 Value::Value(const std::string& value) {
00379 initBasic(stringValue, true);
00380 value_.string_ =
00381 duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
00382 }
00383
00384 Value::Value(const StaticString& value) {
00385 initBasic(stringValue);
00386 value_.string_ = const_cast<char*>(value.c_str());
00387 }
00388
00389 #ifdef JSON_USE_CPPTL
00390 Value::Value(const CppTL::ConstString& value) {
00391 initBasic(stringValue, true);
00392 value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
00393 }
00394 #endif
00395
00396 Value::Value(bool value) {
00397 initBasic(booleanValue);
00398 value_.bool_ = value;
00399 }
00400
00401 Value::Value(Value const& other)
00402 : type_(other.type_), allocated_(false)
00403 ,
00404 comments_(0), start_(other.start_), limit_(other.limit_)
00405 {
00406 switch (type_) {
00407 case nullValue:
00408 case intValue:
00409 case uintValue:
00410 case realValue:
00411 case booleanValue:
00412 value_ = other.value_;
00413 break;
00414 case stringValue:
00415 if (other.value_.string_ && other.allocated_) {
00416 unsigned len;
00417 char const* str;
00418 decodePrefixedString(other.allocated_, other.value_.string_,
00419 &len, &str);
00420 value_.string_ = duplicateAndPrefixStringValue(str, len);
00421 allocated_ = true;
00422 } else {
00423 value_.string_ = other.value_.string_;
00424 allocated_ = false;
00425 }
00426 break;
00427 case arrayValue:
00428 case objectValue:
00429 value_.map_ = new ObjectValues(*other.value_.map_);
00430 break;
00431 default:
00432 JSON_ASSERT_UNREACHABLE;
00433 }
00434 if (other.comments_) {
00435 comments_ = new CommentInfo[numberOfCommentPlacement];
00436 for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
00437 const CommentInfo& otherComment = other.comments_[comment];
00438 if (otherComment.comment_)
00439 comments_[comment].setComment(
00440 otherComment.comment_, strlen(otherComment.comment_));
00441 }
00442 }
00443 }
00444
00445 Value::~Value() {
00446 switch (type_) {
00447 case nullValue:
00448 case intValue:
00449 case uintValue:
00450 case realValue:
00451 case booleanValue:
00452 break;
00453 case stringValue:
00454 if (allocated_)
00455 releaseStringValue(value_.string_);
00456 break;
00457 case arrayValue:
00458 case objectValue:
00459 delete value_.map_;
00460 break;
00461 default:
00462 JSON_ASSERT_UNREACHABLE;
00463 }
00464
00465 if (comments_)
00466 delete[] comments_;
00467 }
00468
00469 Value& Value::operator=(Value other) {
00470 swap(other);
00471 return *this;
00472 }
00473
00474 void Value::swapPayload(Value& other) {
00475 ValueType temp = type_;
00476 type_ = other.type_;
00477 other.type_ = temp;
00478 std::swap(value_, other.value_);
00479 int temp2 = allocated_;
00480 allocated_ = other.allocated_;
00481 other.allocated_ = temp2;
00482 }
00483
00484 void Value::swap(Value& other) {
00485 swapPayload(other);
00486 std::swap(comments_, other.comments_);
00487 std::swap(start_, other.start_);
00488 std::swap(limit_, other.limit_);
00489 }
00490
00491 ValueType Value::type() const { return type_; }
00492
00493 int Value::compare(const Value& other) const {
00494 if (*this < other)
00495 return -1;
00496 if (*this > other)
00497 return 1;
00498 return 0;
00499 }
00500
00501 bool Value::operator<(const Value& other) const {
00502 int typeDelta = type_ - other.type_;
00503 if (typeDelta)
00504 return typeDelta < 0 ? true : false;
00505 switch (type_) {
00506 case nullValue:
00507 return false;
00508 case intValue:
00509 return value_.int_ < other.value_.int_;
00510 case uintValue:
00511 return value_.uint_ < other.value_.uint_;
00512 case realValue:
00513 return value_.real_ < other.value_.real_;
00514 case booleanValue:
00515 return value_.bool_ < other.value_.bool_;
00516 case stringValue:
00517 {
00518 if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
00519 if (other.value_.string_) return true;
00520 else return false;
00521 }
00522 unsigned this_len;
00523 unsigned other_len;
00524 char const* this_str;
00525 char const* other_str;
00526 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
00527 decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
00528 unsigned min_len = std::min(this_len, other_len);
00529 int comp = memcmp(this_str, other_str, min_len);
00530 if (comp < 0) return true;
00531 if (comp > 0) return false;
00532 return (this_len < other_len);
00533 }
00534 case arrayValue:
00535 case objectValue: {
00536 int delta = int(value_.map_->size() - other.value_.map_->size());
00537 if (delta)
00538 return delta < 0;
00539 return (*value_.map_) < (*other.value_.map_);
00540 }
00541 default:
00542 JSON_ASSERT_UNREACHABLE;
00543 }
00544 return false;
00545 }
00546
00547 bool Value::operator<=(const Value& other) const { return !(other < *this); }
00548
00549 bool Value::operator>=(const Value& other) const { return !(*this < other); }
00550
00551 bool Value::operator>(const Value& other) const { return other < *this; }
00552
00553 bool Value::operator==(const Value& other) const {
00554
00555
00556
00557
00558 int temp = other.type_;
00559 if (type_ != temp)
00560 return false;
00561 switch (type_) {
00562 case nullValue:
00563 return true;
00564 case intValue:
00565 return value_.int_ == other.value_.int_;
00566 case uintValue:
00567 return value_.uint_ == other.value_.uint_;
00568 case realValue:
00569 return value_.real_ == other.value_.real_;
00570 case booleanValue:
00571 return value_.bool_ == other.value_.bool_;
00572 case stringValue:
00573 {
00574 if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
00575 return (value_.string_ == other.value_.string_);
00576 }
00577 unsigned this_len;
00578 unsigned other_len;
00579 char const* this_str;
00580 char const* other_str;
00581 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
00582 decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
00583 if (this_len != other_len) return false;
00584 int comp = memcmp(this_str, other_str, this_len);
00585 return comp == 0;
00586 }
00587 case arrayValue:
00588 case objectValue:
00589 return value_.map_->size() == other.value_.map_->size() &&
00590 (*value_.map_) == (*other.value_.map_);
00591 default:
00592 JSON_ASSERT_UNREACHABLE;
00593 }
00594 return false;
00595 }
00596
00597 bool Value::operator!=(const Value& other) const { return !(*this == other); }
00598
00599 const char* Value::asCString() const {
00600 JSON_ASSERT_MESSAGE(type_ == stringValue,
00601 "in Json::Value::asCString(): requires stringValue");
00602 if (value_.string_ == 0) return 0;
00603 unsigned this_len;
00604 char const* this_str;
00605 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
00606 return this_str;
00607 }
00608
00609 bool Value::getString(char const** str, char const** end) const {
00610 if (type_ != stringValue) return false;
00611 if (value_.string_ == 0) return false;
00612 unsigned length;
00613 decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
00614 *end = *str + length;
00615 return true;
00616 }
00617
00618 std::string Value::asString() const {
00619 switch (type_) {
00620 case nullValue:
00621 return "";
00622 case stringValue:
00623 {
00624 if (value_.string_ == 0) return "";
00625 unsigned this_len;
00626 char const* this_str;
00627 decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
00628 return std::string(this_str, this_len);
00629 }
00630 case booleanValue:
00631 return value_.bool_ ? "true" : "false";
00632 case intValue:
00633 return valueToString(value_.int_);
00634 case uintValue:
00635 return valueToString(value_.uint_);
00636 case realValue:
00637 return valueToString(value_.real_);
00638 default:
00639 JSON_FAIL_MESSAGE("Type is not convertible to string");
00640 }
00641 }
00642
00643 #ifdef JSON_USE_CPPTL
00644 CppTL::ConstString Value::asConstString() const {
00645 unsigned len;
00646 char const* str;
00647 decodePrefixedString(allocated_, value_.string_,
00648 &len, &str);
00649 return CppTL::ConstString(str, len);
00650 }
00651 #endif
00652
00653 Value::Int Value::asInt() const {
00654 switch (type_) {
00655 case intValue:
00656 JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
00657 return Int(value_.int_);
00658 case uintValue:
00659 JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
00660 return Int(value_.uint_);
00661 case realValue:
00662 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
00663 "double out of Int range");
00664 return Int(value_.real_);
00665 case nullValue:
00666 return 0;
00667 case booleanValue:
00668 return value_.bool_ ? 1 : 0;
00669 default:
00670 break;
00671 }
00672 JSON_FAIL_MESSAGE("Value is not convertible to Int.");
00673 }
00674
00675 Value::UInt Value::asUInt() const {
00676 switch (type_) {
00677 case intValue:
00678 JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
00679 return UInt(value_.int_);
00680 case uintValue:
00681 JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
00682 return UInt(value_.uint_);
00683 case realValue:
00684 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
00685 "double out of UInt range");
00686 return UInt(value_.real_);
00687 case nullValue:
00688 return 0;
00689 case booleanValue:
00690 return value_.bool_ ? 1 : 0;
00691 default:
00692 break;
00693 }
00694 JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
00695 }
00696
00697 #if defined(JSON_HAS_INT64)
00698
00699 Value::Int64 Value::asInt64() const {
00700 switch (type_) {
00701 case intValue:
00702 return Int64(value_.int_);
00703 case uintValue:
00704 JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
00705 return Int64(value_.uint_);
00706 case realValue:
00707 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
00708 "double out of Int64 range");
00709 return Int64(value_.real_);
00710 case nullValue:
00711 return 0;
00712 case booleanValue:
00713 return value_.bool_ ? 1 : 0;
00714 default:
00715 break;
00716 }
00717 JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
00718 }
00719
00720 Value::UInt64 Value::asUInt64() const {
00721 switch (type_) {
00722 case intValue:
00723 JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
00724 return UInt64(value_.int_);
00725 case uintValue:
00726 return UInt64(value_.uint_);
00727 case realValue:
00728 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
00729 "double out of UInt64 range");
00730 return UInt64(value_.real_);
00731 case nullValue:
00732 return 0;
00733 case booleanValue:
00734 return value_.bool_ ? 1 : 0;
00735 default:
00736 break;
00737 }
00738 JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
00739 }
00740 #endif // if defined(JSON_HAS_INT64)
00741
00742 LargestInt Value::asLargestInt() const {
00743 #if defined(JSON_NO_INT64)
00744 return asInt();
00745 #else
00746 return asInt64();
00747 #endif
00748 }
00749
00750 LargestUInt Value::asLargestUInt() const {
00751 #if defined(JSON_NO_INT64)
00752 return asUInt();
00753 #else
00754 return asUInt64();
00755 #endif
00756 }
00757
00758 double Value::asDouble() const {
00759 switch (type_) {
00760 case intValue:
00761 return static_cast<double>(value_.int_);
00762 case uintValue:
00763 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00764 return static_cast<double>(value_.uint_);
00765 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00766 return integerToDouble(value_.uint_);
00767 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00768 case realValue:
00769 return value_.real_;
00770 case nullValue:
00771 return 0.0;
00772 case booleanValue:
00773 return value_.bool_ ? 1.0 : 0.0;
00774 default:
00775 break;
00776 }
00777 JSON_FAIL_MESSAGE("Value is not convertible to double.");
00778 }
00779
00780 float Value::asFloat() const {
00781 switch (type_) {
00782 case intValue:
00783 return static_cast<float>(value_.int_);
00784 case uintValue:
00785 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00786 return static_cast<float>(value_.uint_);
00787 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00788 return integerToDouble(value_.uint_);
00789 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00790 case realValue:
00791 return static_cast<float>(value_.real_);
00792 case nullValue:
00793 return 0.0;
00794 case booleanValue:
00795 return value_.bool_ ? 1.0f : 0.0f;
00796 default:
00797 break;
00798 }
00799 JSON_FAIL_MESSAGE("Value is not convertible to float.");
00800 }
00801
00802 bool Value::asBool() const {
00803 switch (type_) {
00804 case booleanValue:
00805 return value_.bool_;
00806 case nullValue:
00807 return false;
00808 case intValue:
00809 return value_.int_ ? true : false;
00810 case uintValue:
00811 return value_.uint_ ? true : false;
00812 case realValue:
00813 return value_.real_ ? true : false;
00814 default:
00815 break;
00816 }
00817 JSON_FAIL_MESSAGE("Value is not convertible to bool.");
00818 }
00819
00820 bool Value::isConvertibleTo(ValueType other) const {
00821 switch (other) {
00822 case nullValue:
00823 return (isNumeric() && asDouble() == 0.0) ||
00824 (type_ == booleanValue && value_.bool_ == false) ||
00825 (type_ == stringValue && asString() == "") ||
00826 (type_ == arrayValue && value_.map_->size() == 0) ||
00827 (type_ == objectValue && value_.map_->size() == 0) ||
00828 type_ == nullValue;
00829 case intValue:
00830 return isInt() ||
00831 (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
00832 type_ == booleanValue || type_ == nullValue;
00833 case uintValue:
00834 return isUInt() ||
00835 (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
00836 type_ == booleanValue || type_ == nullValue;
00837 case realValue:
00838 return isNumeric() || type_ == booleanValue || type_ == nullValue;
00839 case booleanValue:
00840 return isNumeric() || type_ == booleanValue || type_ == nullValue;
00841 case stringValue:
00842 return isNumeric() || type_ == booleanValue || type_ == stringValue ||
00843 type_ == nullValue;
00844 case arrayValue:
00845 return type_ == arrayValue || type_ == nullValue;
00846 case objectValue:
00847 return type_ == objectValue || type_ == nullValue;
00848 }
00849 JSON_ASSERT_UNREACHABLE;
00850 return false;
00851 }
00852
00854 ArrayIndex Value::size() const {
00855 switch (type_) {
00856 case nullValue:
00857 case intValue:
00858 case uintValue:
00859 case realValue:
00860 case booleanValue:
00861 case stringValue:
00862 return 0;
00863 case arrayValue:
00864 if (!value_.map_->empty()) {
00865 ObjectValues::const_iterator itLast = value_.map_->end();
00866 --itLast;
00867 return (*itLast).first.index() + 1;
00868 }
00869 return 0;
00870 case objectValue:
00871 return ArrayIndex(value_.map_->size());
00872 }
00873 JSON_ASSERT_UNREACHABLE;
00874 return 0;
00875 }
00876
00877 bool Value::empty() const {
00878 if (isNull() || isArray() || isObject())
00879 return size() == 0u;
00880 else
00881 return false;
00882 }
00883
00884 bool Value::operator!() const { return isNull(); }
00885
00886 void Value::clear() {
00887 JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
00888 type_ == objectValue,
00889 "in Json::Value::clear(): requires complex value");
00890 start_ = 0;
00891 limit_ = 0;
00892 switch (type_) {
00893 case arrayValue:
00894 case objectValue:
00895 value_.map_->clear();
00896 break;
00897 default:
00898 break;
00899 }
00900 }
00901
00902 void Value::resize(ArrayIndex newSize) {
00903 JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
00904 "in Json::Value::resize(): requires arrayValue");
00905 if (type_ == nullValue)
00906 *this = Value(arrayValue);
00907 ArrayIndex oldSize = size();
00908 if (newSize == 0)
00909 clear();
00910 else if (newSize > oldSize)
00911 (*this)[newSize - 1];
00912 else {
00913 for (ArrayIndex index = newSize; index < oldSize; ++index) {
00914 value_.map_->erase(index);
00915 }
00916 assert(size() == newSize);
00917 }
00918 }
00919
00920 Value& Value::operator[](ArrayIndex index) {
00921 JSON_ASSERT_MESSAGE(
00922 type_ == nullValue || type_ == arrayValue,
00923 "in Json::Value::operator[](ArrayIndex): requires arrayValue");
00924 if (type_ == nullValue)
00925 *this = Value(arrayValue);
00926 CZString key(index);
00927 ObjectValues::iterator it = value_.map_->lower_bound(key);
00928 if (it != value_.map_->end() && (*it).first == key)
00929 return (*it).second;
00930
00931 ObjectValues::value_type defaultValue(key, nullRef);
00932 it = value_.map_->insert(it, defaultValue);
00933 return (*it).second;
00934 }
00935
00936 Value& Value::operator[](int index) {
00937 JSON_ASSERT_MESSAGE(
00938 index >= 0,
00939 "in Json::Value::operator[](int index): index cannot be negative");
00940 return (*this)[ArrayIndex(index)];
00941 }
00942
00943 const Value& Value::operator[](ArrayIndex index) const {
00944 JSON_ASSERT_MESSAGE(
00945 type_ == nullValue || type_ == arrayValue,
00946 "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
00947 if (type_ == nullValue)
00948 return nullRef;
00949 CZString key(index);
00950 ObjectValues::const_iterator it = value_.map_->find(key);
00951 if (it == value_.map_->end())
00952 return nullRef;
00953 return (*it).second;
00954 }
00955
00956 const Value& Value::operator[](int index) const {
00957 JSON_ASSERT_MESSAGE(
00958 index >= 0,
00959 "in Json::Value::operator[](int index) const: index cannot be negative");
00960 return (*this)[ArrayIndex(index)];
00961 }
00962
00963 void Value::initBasic(ValueType type, bool allocated) {
00964 type_ = type;
00965 allocated_ = allocated;
00966 comments_ = 0;
00967 start_ = 0;
00968 limit_ = 0;
00969 }
00970
00971
00972
00973
00974 Value& Value::resolveReference(const char* key) {
00975 JSON_ASSERT_MESSAGE(
00976 type_ == nullValue || type_ == objectValue,
00977 "in Json::Value::resolveReference(): requires objectValue");
00978 if (type_ == nullValue)
00979 *this = Value(objectValue);
00980 CZString actualKey(
00981 key, static_cast<unsigned>(strlen(key)), CZString::noDuplication);
00982 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
00983 if (it != value_.map_->end() && (*it).first == actualKey)
00984 return (*it).second;
00985
00986 ObjectValues::value_type defaultValue(actualKey, nullRef);
00987 it = value_.map_->insert(it, defaultValue);
00988 Value& value = (*it).second;
00989 return value;
00990 }
00991
00992
00993 Value& Value::resolveReference(char const* key, char const* end)
00994 {
00995 JSON_ASSERT_MESSAGE(
00996 type_ == nullValue || type_ == objectValue,
00997 "in Json::Value::resolveReference(key, end): requires objectValue");
00998 if (type_ == nullValue)
00999 *this = Value(objectValue);
01000 CZString actualKey(
01001 key, static_cast<unsigned>(end-key), CZString::duplicateOnCopy);
01002 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
01003 if (it != value_.map_->end() && (*it).first == actualKey)
01004 return (*it).second;
01005
01006 ObjectValues::value_type defaultValue(actualKey, nullRef);
01007 it = value_.map_->insert(it, defaultValue);
01008 Value& value = (*it).second;
01009 return value;
01010 }
01011
01012 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
01013 const Value* value = &((*this)[index]);
01014 return value == &nullRef ? defaultValue : *value;
01015 }
01016
01017 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
01018
01019 Value const* Value::find(char const* key, char const* end) const
01020 {
01021 JSON_ASSERT_MESSAGE(
01022 type_ == nullValue || type_ == objectValue,
01023 "in Json::Value::find(key, end, found): requires objectValue or nullValue");
01024 if (type_ == nullValue) return NULL;
01025 CZString actualKey(key, static_cast<unsigned>(end-key), CZString::noDuplication);
01026 ObjectValues::const_iterator it = value_.map_->find(actualKey);
01027 if (it == value_.map_->end()) return NULL;
01028 return &(*it).second;
01029 }
01030 const Value& Value::operator[](const char* key) const
01031 {
01032 Value const* found = find(key, key + strlen(key));
01033 if (!found) return nullRef;
01034 return *found;
01035 }
01036 Value const& Value::operator[](std::string const& key) const
01037 {
01038 Value const* found = find(key.data(), key.data() + key.length());
01039 if (!found) return nullRef;
01040 return *found;
01041 }
01042
01043 Value& Value::operator[](const char* key) {
01044 return resolveReference(key, key + strlen(key));
01045 }
01046
01047 Value& Value::operator[](const std::string& key) {
01048 return resolveReference(key.data(), key.data() + key.length());
01049 }
01050
01051 Value& Value::operator[](const StaticString& key) {
01052 return resolveReference(key.c_str());
01053 }
01054
01055 #ifdef JSON_USE_CPPTL
01056 Value& Value::operator[](const CppTL::ConstString& key) {
01057 return resolveReference(key.c_str(), key.end_c_str());
01058 }
01059 Value const& Value::operator[](CppTL::ConstString const& key) const
01060 {
01061 Value const* found = find(key.c_str(), key.end_c_str());
01062 if (!found) return nullRef;
01063 return *found;
01064 }
01065 #endif
01066
01067 Value& Value::append(const Value& value) { return (*this)[size()] = value; }
01068
01069 Value Value::get(char const* key, char const* end, Value const& defaultValue) const
01070 {
01071 Value const* found = find(key, end);
01072 return !found ? defaultValue : *found;
01073 }
01074 Value Value::get(char const* key, Value const& defaultValue) const
01075 {
01076 return get(key, key + strlen(key), defaultValue);
01077 }
01078 Value Value::get(std::string const& key, Value const& defaultValue) const
01079 {
01080 return get(key.data(), key.data() + key.length(), defaultValue);
01081 }
01082
01083
01084 bool Value::removeMember(const char* key, const char* end, Value* removed)
01085 {
01086 if (type_ != objectValue) {
01087 return false;
01088 }
01089 CZString actualKey(key, static_cast<unsigned>(end-key), CZString::noDuplication);
01090 ObjectValues::iterator it = value_.map_->find(actualKey);
01091 if (it == value_.map_->end())
01092 return false;
01093 *removed = it->second;
01094 value_.map_->erase(it);
01095 return true;
01096 }
01097 bool Value::removeMember(const char* key, Value* removed)
01098 {
01099 return removeMember(key, key + strlen(key), removed);
01100 }
01101 bool Value::removeMember(std::string const& key, Value* removed)
01102 {
01103 return removeMember(key.data(), key.data() + key.length(), removed);
01104 }
01105 Value Value::removeMember(const char* key)
01106 {
01107 JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
01108 "in Json::Value::removeMember(): requires objectValue");
01109 if (type_ == nullValue)
01110 return nullRef;
01111
01112 Value removed;
01113 removeMember(key, key + strlen(key), &removed);
01114 return removed;
01115 }
01116 Value Value::removeMember(const std::string& key)
01117 {
01118 return removeMember(key.c_str());
01119 }
01120
01121 bool Value::removeIndex(ArrayIndex index, Value* removed) {
01122 if (type_ != arrayValue) {
01123 return false;
01124 }
01125 CZString key(index);
01126 ObjectValues::iterator it = value_.map_->find(key);
01127 if (it == value_.map_->end()) {
01128 return false;
01129 }
01130 *removed = it->second;
01131 ArrayIndex oldSize = size();
01132
01133 for (ArrayIndex i = index; i < (oldSize - 1); ++i){
01134 CZString key(i);
01135 (*value_.map_)[key] = (*this)[i + 1];
01136 }
01137
01138 CZString keyLast(oldSize - 1);
01139 ObjectValues::iterator itLast = value_.map_->find(keyLast);
01140 value_.map_->erase(itLast);
01141 return true;
01142 }
01143
01144 #ifdef JSON_USE_CPPTL
01145 Value Value::get(const CppTL::ConstString& key,
01146 const Value& defaultValue) const {
01147 return get(key.c_str(), key.end_c_str(), defaultValue);
01148 }
01149 #endif
01150
01151 bool Value::isMember(char const* key, char const* end) const
01152 {
01153 Value const* value = find(key, end);
01154 return NULL != value;
01155 }
01156 bool Value::isMember(char const* key) const
01157 {
01158 return isMember(key, key + strlen(key));
01159 }
01160 bool Value::isMember(std::string const& key) const
01161 {
01162 return isMember(key.data(), key.data() + key.length());
01163 }
01164
01165 #ifdef JSON_USE_CPPTL
01166 bool Value::isMember(const CppTL::ConstString& key) const {
01167 return isMember(key.c_str(), key.end_c_str());
01168 }
01169 #endif
01170
01171 Value::Members Value::getMemberNames() const {
01172 JSON_ASSERT_MESSAGE(
01173 type_ == nullValue || type_ == objectValue,
01174 "in Json::Value::getMemberNames(), value must be objectValue");
01175 if (type_ == nullValue)
01176 return Value::Members();
01177 Members members;
01178 members.reserve(value_.map_->size());
01179 ObjectValues::const_iterator it = value_.map_->begin();
01180 ObjectValues::const_iterator itEnd = value_.map_->end();
01181 for (; it != itEnd; ++it) {
01182 members.push_back(std::string((*it).first.data(),
01183 (*it).first.length()));
01184 }
01185 return members;
01186 }
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 static bool IsIntegral(double d) {
01214 double integral_part;
01215 return modf(d, &integral_part) == 0.0;
01216 }
01217
01218 bool Value::isNull() const { return type_ == nullValue; }
01219
01220 bool Value::isBool() const { return type_ == booleanValue; }
01221
01222 bool Value::isInt() const {
01223 switch (type_) {
01224 case intValue:
01225 return value_.int_ >= minInt && value_.int_ <= maxInt;
01226 case uintValue:
01227 return value_.uint_ <= UInt(maxInt);
01228 case realValue:
01229 return value_.real_ >= minInt && value_.real_ <= maxInt &&
01230 IsIntegral(value_.real_);
01231 default:
01232 break;
01233 }
01234 return false;
01235 }
01236
01237 bool Value::isUInt() const {
01238 switch (type_) {
01239 case intValue:
01240 return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
01241 case uintValue:
01242 return value_.uint_ <= maxUInt;
01243 case realValue:
01244 return value_.real_ >= 0 && value_.real_ <= maxUInt &&
01245 IsIntegral(value_.real_);
01246 default:
01247 break;
01248 }
01249 return false;
01250 }
01251
01252 bool Value::isInt64() const {
01253 #if defined(JSON_HAS_INT64)
01254 switch (type_) {
01255 case intValue:
01256 return true;
01257 case uintValue:
01258 return value_.uint_ <= UInt64(maxInt64);
01259 case realValue:
01260
01261
01262
01263 return value_.real_ >= double(minInt64) &&
01264 value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
01265 default:
01266 break;
01267 }
01268 #endif // JSON_HAS_INT64
01269 return false;
01270 }
01271
01272 bool Value::isUInt64() const {
01273 #if defined(JSON_HAS_INT64)
01274 switch (type_) {
01275 case intValue:
01276 return value_.int_ >= 0;
01277 case uintValue:
01278 return true;
01279 case realValue:
01280
01281
01282
01283 return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
01284 IsIntegral(value_.real_);
01285 default:
01286 break;
01287 }
01288 #endif // JSON_HAS_INT64
01289 return false;
01290 }
01291
01292 bool Value::isIntegral() const {
01293 #if defined(JSON_HAS_INT64)
01294 return isInt64() || isUInt64();
01295 #else
01296 return isInt() || isUInt();
01297 #endif
01298 }
01299
01300 bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
01301
01302 bool Value::isNumeric() const { return isIntegral() || isDouble(); }
01303
01304 bool Value::isString() const { return type_ == stringValue; }
01305
01306 bool Value::isArray() const { return type_ == arrayValue; }
01307
01308 bool Value::isObject() const { return type_ == objectValue; }
01309
01310 void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
01311 if (!comments_)
01312 comments_ = new CommentInfo[numberOfCommentPlacement];
01313 if ((len > 0) && (comment[len-1] == '\n')) {
01314
01315 len -= 1;
01316 }
01317 comments_[placement].setComment(comment, len);
01318 }
01319
01320 void Value::setComment(const char* comment, CommentPlacement placement) {
01321 setComment(comment, strlen(comment), placement);
01322 }
01323
01324 void Value::setComment(const std::string& comment, CommentPlacement placement) {
01325 setComment(comment.c_str(), comment.length(), placement);
01326 }
01327
01328 bool Value::hasComment(CommentPlacement placement) const {
01329 return comments_ != 0 && comments_[placement].comment_ != 0;
01330 }
01331
01332 std::string Value::getComment(CommentPlacement placement) const {
01333 if (hasComment(placement))
01334 return comments_[placement].comment_;
01335 return "";
01336 }
01337
01338 void Value::setOffsetStart(size_t start) { start_ = start; }
01339
01340 void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
01341
01342 size_t Value::getOffsetStart() const { return start_; }
01343
01344 size_t Value::getOffsetLimit() const { return limit_; }
01345
01346 std::string Value::toStyledString() const {
01347 StyledWriter writer;
01348 return writer.write(*this);
01349 }
01350
01351 Value::const_iterator Value::begin() const {
01352 switch (type_) {
01353 case arrayValue:
01354 case objectValue:
01355 if (value_.map_)
01356 return const_iterator(value_.map_->begin());
01357 break;
01358 default:
01359 break;
01360 }
01361 return const_iterator();
01362 }
01363
01364 Value::const_iterator Value::end() const {
01365 switch (type_) {
01366 case arrayValue:
01367 case objectValue:
01368 if (value_.map_)
01369 return const_iterator(value_.map_->end());
01370 break;
01371 default:
01372 break;
01373 }
01374 return const_iterator();
01375 }
01376
01377 Value::iterator Value::begin() {
01378 switch (type_) {
01379 case arrayValue:
01380 case objectValue:
01381 if (value_.map_)
01382 return iterator(value_.map_->begin());
01383 break;
01384 default:
01385 break;
01386 }
01387 return iterator();
01388 }
01389
01390 Value::iterator Value::end() {
01391 switch (type_) {
01392 case arrayValue:
01393 case objectValue:
01394 if (value_.map_)
01395 return iterator(value_.map_->end());
01396 break;
01397 default:
01398 break;
01399 }
01400 return iterator();
01401 }
01402
01403
01404
01405
01406 PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
01407
01408 PathArgument::PathArgument(ArrayIndex index)
01409 : key_(), index_(index), kind_(kindIndex) {}
01410
01411 PathArgument::PathArgument(const char* key)
01412 : key_(key), index_(), kind_(kindKey) {}
01413
01414 PathArgument::PathArgument(const std::string& key)
01415 : key_(key.c_str()), index_(), kind_(kindKey) {}
01416
01417
01418
01419
01420 Path::Path(const std::string& path,
01421 const PathArgument& a1,
01422 const PathArgument& a2,
01423 const PathArgument& a3,
01424 const PathArgument& a4,
01425 const PathArgument& a5) {
01426 InArgs in;
01427 in.push_back(&a1);
01428 in.push_back(&a2);
01429 in.push_back(&a3);
01430 in.push_back(&a4);
01431 in.push_back(&a5);
01432 makePath(path, in);
01433 }
01434
01435 void Path::makePath(const std::string& path, const InArgs& in) {
01436 const char* current = path.c_str();
01437 const char* end = current + path.length();
01438 InArgs::const_iterator itInArg = in.begin();
01439 while (current != end) {
01440 if (*current == '[') {
01441 ++current;
01442 if (*current == '%')
01443 addPathInArg(path, in, itInArg, PathArgument::kindIndex);
01444 else {
01445 ArrayIndex index = 0;
01446 for (; current != end && *current >= '0' && *current <= '9'; ++current)
01447 index = index * 10 + ArrayIndex(*current - '0');
01448 args_.push_back(index);
01449 }
01450 if (current == end || *current++ != ']')
01451 invalidPath(path, int(current - path.c_str()));
01452 } else if (*current == '%') {
01453 addPathInArg(path, in, itInArg, PathArgument::kindKey);
01454 ++current;
01455 } else if (*current == '.') {
01456 ++current;
01457 } else {
01458 const char* beginName = current;
01459 while (current != end && !strchr("[.", *current))
01460 ++current;
01461 args_.push_back(std::string(beginName, current));
01462 }
01463 }
01464 }
01465
01466 void Path::addPathInArg(const std::string& ,
01467 const InArgs& in,
01468 InArgs::const_iterator& itInArg,
01469 PathArgument::Kind kind) {
01470 if (itInArg == in.end()) {
01471
01472 } else if ((*itInArg)->kind_ != kind) {
01473
01474 } else {
01475 args_.push_back(**itInArg);
01476 }
01477 }
01478
01479 void Path::invalidPath(const std::string& , int ) {
01480
01481 }
01482
01483 const Value& Path::resolve(const Value& root) const {
01484 const Value* node = &root;
01485 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
01486 const PathArgument& arg = *it;
01487 if (arg.kind_ == PathArgument::kindIndex) {
01488 if (!node->isArray() || !node->isValidIndex(arg.index_)) {
01489
01490 }
01491 node = &((*node)[arg.index_]);
01492 } else if (arg.kind_ == PathArgument::kindKey) {
01493 if (!node->isObject()) {
01494
01495 }
01496 node = &((*node)[arg.key_]);
01497 if (node == &Value::nullRef) {
01498
01499
01500 }
01501 }
01502 }
01503 return *node;
01504 }
01505
01506 Value Path::resolve(const Value& root, const Value& defaultValue) const {
01507 const Value* node = &root;
01508 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
01509 const PathArgument& arg = *it;
01510 if (arg.kind_ == PathArgument::kindIndex) {
01511 if (!node->isArray() || !node->isValidIndex(arg.index_))
01512 return defaultValue;
01513 node = &((*node)[arg.index_]);
01514 } else if (arg.kind_ == PathArgument::kindKey) {
01515 if (!node->isObject())
01516 return defaultValue;
01517 node = &((*node)[arg.key_]);
01518 if (node == &Value::nullRef)
01519 return defaultValue;
01520 }
01521 }
01522 return *node;
01523 }
01524
01525 Value& Path::make(Value& root) const {
01526 Value* node = &root;
01527 for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
01528 const PathArgument& arg = *it;
01529 if (arg.kind_ == PathArgument::kindIndex) {
01530 if (!node->isArray()) {
01531
01532 }
01533 node = &((*node)[arg.index_]);
01534 } else if (arg.kind_ == PathArgument::kindKey) {
01535 if (!node->isObject()) {
01536
01537 }
01538 node = &((*node)[arg.key_]);
01539 }
01540 }
01541 return *node;
01542 }
01543
01544 }