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