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 <stdexcept> 18 #include <cstring> 19 #include <cassert> 20 #ifdef JSON_USE_CPPTL 21 # include <cpptl/conststring.h> 22 #endif 23 #include <cstddef> // size_t 24 25 #define JSON_ASSERT_UNREACHABLE assert( false ) 26 27 namespace Json { 28 29 // This is a walkaround to avoid the static initialization of Value::null. 30 // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of 31 // 8 (instead of 4) as a bit of future-proofing. 32 #if defined(__ARMEL__) 33 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) 34 #else 35 #define ALIGNAS(byte_alignment) 36 #endif 37 static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = {0}; 38 const Value& Value::null = reinterpret_cast<const Value&>(kNull); 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 57 /// Unknown size marker 58 static const unsigned int unknown = (unsigned)-1; 59 60 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 61 template <typename T, typename U> 62 static inline bool InRange(double d, T min, U max) { 63 return d >= min && d <= max; 64 } 65 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 66 static inline double integerToDouble( Json::UInt64 value ) 67 { 68 return static_cast<double>( Int64(value/2) ) * 2.0 + Int64(value & 1); 69 } 70 71 template<typename T> 72 static inline double integerToDouble( T value ) 73 { 74 return static_cast<double>( value ); 75 } 76 77 template <typename T, typename U> 78 static inline bool InRange(double d, T min, U max) { 79 return d >= integerToDouble(min) && d <= integerToDouble(max); 80 } 81 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 82 83 84 /** Duplicates the specified string value. 85 * @param value Pointer to the string to duplicate. Must be zero-terminated if 86 * length is "unknown". 87 * @param length Length of the value. if equals to unknown, then it will be 88 * computed using strlen(value). 89 * @return Pointer on the duplicate instance of string. 90 */ 91 static inline char * 92 duplicateStringValue( const char *value, 93 unsigned int length = unknown ) 94 { 95 if ( length == unknown ) 96 length = (unsigned int)strlen(value); 97 98 // Avoid an integer overflow in the call to malloc below by limiting length 99 // to a sane value. 100 if (length >= (unsigned)Value::maxInt) 101 length = Value::maxInt - 1; 102 103 char *newString = static_cast<char *>( malloc( length + 1 ) ); 104 JSON_ASSERT_MESSAGE( newString != 0, "Failed to allocate string value buffer" ); 105 memcpy( newString, value, length ); 106 newString[length] = 0; 107 return newString; 108 } 109 110 111 /** Free the string duplicated by duplicateStringValue(). 112 */ 113 static inline void 114 releaseStringValue( char *value ) 115 { 116 if ( value ) 117 free( value ); 118 } 119 120 } // namespace Json 121 122 123 // ////////////////////////////////////////////////////////////////// 124 // ////////////////////////////////////////////////////////////////// 125 // ////////////////////////////////////////////////////////////////// 126 // ValueInternals... 127 // ////////////////////////////////////////////////////////////////// 128 // ////////////////////////////////////////////////////////////////// 129 // ////////////////////////////////////////////////////////////////// 130 #if !defined(JSON_IS_AMALGAMATION) 131 # ifdef JSON_VALUE_USE_INTERNAL_MAP 132 # include "json_internalarray.inl" 133 # include "json_internalmap.inl" 134 # endif // JSON_VALUE_USE_INTERNAL_MAP 135 136 # include "json_valueiterator.inl" 137 #endif // if !defined(JSON_IS_AMALGAMATION) 138 139 namespace Json { 140 141 // ////////////////////////////////////////////////////////////////// 142 // ////////////////////////////////////////////////////////////////// 143 // ////////////////////////////////////////////////////////////////// 144 // class Value::CommentInfo 145 // ////////////////////////////////////////////////////////////////// 146 // ////////////////////////////////////////////////////////////////// 147 // ////////////////////////////////////////////////////////////////// 148 149 150 Value::CommentInfo::CommentInfo() 151 : comment_( 0 ) 152 { 153 } 154 155 Value::CommentInfo::~CommentInfo() 156 { 157 if ( comment_ ) 158 releaseStringValue( comment_ ); 159 } 160 161 162 void 163 Value::CommentInfo::setComment( const char *text ) 164 { 165 if ( comment_ ) 166 releaseStringValue( comment_ ); 167 JSON_ASSERT( text != 0 ); 168 JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /"); 169 // It seems that /**/ style comments are acceptable as well. 170 comment_ = duplicateStringValue( text ); 171 } 172 173 174 // ////////////////////////////////////////////////////////////////// 175 // ////////////////////////////////////////////////////////////////// 176 // ////////////////////////////////////////////////////////////////// 177 // class Value::CZString 178 // ////////////////////////////////////////////////////////////////// 179 // ////////////////////////////////////////////////////////////////// 180 // ////////////////////////////////////////////////////////////////// 181 # ifndef JSON_VALUE_USE_INTERNAL_MAP 182 183 // Notes: index_ indicates if the string was allocated when 184 // a string is stored. 185 186 Value::CZString::CZString( ArrayIndex index ) 187 : cstr_( 0 ) 188 , index_( index ) 189 { 190 } 191 192 Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) 193 : cstr_( allocate == duplicate ? duplicateStringValue(cstr) 194 : cstr ) 195 , index_( allocate ) 196 { 197 } 198 199 Value::CZString::CZString( const CZString &other ) 200 : cstr_( other.index_ != noDuplication && other.cstr_ != 0 201 ? duplicateStringValue( other.cstr_ ) 202 : other.cstr_ ) 203 , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) 204 : other.index_ ) 205 { 206 } 207 208 Value::CZString::~CZString() 209 { 210 if ( cstr_ && index_ == duplicate ) 211 releaseStringValue( const_cast<char *>( cstr_ ) ); 212 } 213 214 void 215 Value::CZString::swap( CZString &other ) 216 { 217 std::swap( cstr_, other.cstr_ ); 218 std::swap( index_, other.index_ ); 219 } 220 221 Value::CZString & 222 Value::CZString::operator =( const CZString &other ) 223 { 224 CZString temp( other ); 225 swap( temp ); 226 return *this; 227 } 228 229 bool 230 Value::CZString::operator<( const CZString &other ) const 231 { 232 if ( cstr_ ) 233 return strcmp( cstr_, other.cstr_ ) < 0; 234 return index_ < other.index_; 235 } 236 237 bool 238 Value::CZString::operator==( const CZString &other ) const 239 { 240 if ( cstr_ ) 241 return strcmp( cstr_, other.cstr_ ) == 0; 242 return index_ == other.index_; 243 } 244 245 246 ArrayIndex 247 Value::CZString::index() const 248 { 249 return index_; 250 } 251 252 253 const char * 254 Value::CZString::c_str() const 255 { 256 return cstr_; 257 } 258 259 bool 260 Value::CZString::isStaticString() const 261 { 262 return index_ == noDuplication; 263 } 264 265 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP 266 267 268 // ////////////////////////////////////////////////////////////////// 269 // ////////////////////////////////////////////////////////////////// 270 // ////////////////////////////////////////////////////////////////// 271 // class Value::Value 272 // ////////////////////////////////////////////////////////////////// 273 // ////////////////////////////////////////////////////////////////// 274 // ////////////////////////////////////////////////////////////////// 275 276 /*! \internal Default constructor initialization must be equivalent to: 277 * memset( this, 0, sizeof(Value) ) 278 * This optimization is used in ValueInternalMap fast allocator. 279 */ 280 Value::Value( ValueType type ) 281 : type_( type ) 282 , allocated_( false ) 283 # ifdef JSON_VALUE_USE_INTERNAL_MAP 284 , itemIsUsed_( 0 ) 285 #endif 286 , comments_( 0 ) 287 { 288 switch ( type ) 289 { 290 case nullValue: 291 break; 292 case intValue: 293 case uintValue: 294 value_.int_ = 0; 295 break; 296 case realValue: 297 value_.real_ = 0.0; 298 break; 299 case stringValue: 300 value_.string_ = 0; 301 break; 302 #ifndef JSON_VALUE_USE_INTERNAL_MAP 303 case arrayValue: 304 case objectValue: 305 value_.map_ = new ObjectValues(); 306 break; 307 #else 308 case arrayValue: 309 value_.array_ = arrayAllocator()->newArray(); 310 break; 311 case objectValue: 312 value_.map_ = mapAllocator()->newMap(); 313 break; 314 #endif 315 case booleanValue: 316 value_.bool_ = false; 317 break; 318 default: 319 JSON_ASSERT_UNREACHABLE; 320 } 321 } 322 323 324 Value::Value( UInt value ) 325 : type_( uintValue ) 326 , allocated_( false ) 327 # ifdef JSON_VALUE_USE_INTERNAL_MAP 328 , itemIsUsed_( 0 ) 329 #endif 330 , comments_( 0 ) 331 { 332 value_.uint_ = value; 333 } 334 335 Value::Value( Int value ) 336 : type_( intValue ) 337 , allocated_( false ) 338 # ifdef JSON_VALUE_USE_INTERNAL_MAP 339 , itemIsUsed_( 0 ) 340 #endif 341 , comments_( 0 ) 342 { 343 value_.int_ = value; 344 } 345 346 347 # if defined(JSON_HAS_INT64) 348 Value::Value( Int64 value ) 349 : type_( intValue ) 350 , allocated_( false ) 351 # ifdef JSON_VALUE_USE_INTERNAL_MAP 352 , itemIsUsed_( 0 ) 353 #endif 354 , comments_( 0 ) 355 { 356 value_.int_ = value; 357 } 358 359 360 Value::Value( UInt64 value ) 361 : type_( uintValue ) 362 , allocated_( false ) 363 # ifdef JSON_VALUE_USE_INTERNAL_MAP 364 , itemIsUsed_( 0 ) 365 #endif 366 , comments_( 0 ) 367 { 368 value_.uint_ = value; 369 } 370 #endif // defined(JSON_HAS_INT64) 371 372 Value::Value( double value ) 373 : type_( realValue ) 374 , allocated_( false ) 375 # ifdef JSON_VALUE_USE_INTERNAL_MAP 376 , itemIsUsed_( 0 ) 377 #endif 378 , comments_( 0 ) 379 { 380 value_.real_ = value; 381 } 382 383 Value::Value( const char *value ) 384 : type_( stringValue ) 385 , allocated_( true ) 386 # ifdef JSON_VALUE_USE_INTERNAL_MAP 387 , itemIsUsed_( 0 ) 388 #endif 389 , comments_( 0 ) 390 { 391 value_.string_ = duplicateStringValue( value ); 392 } 393 394 395 Value::Value( const char *beginValue, 396 const char *endValue ) 397 : type_( stringValue ) 398 , allocated_( true ) 399 # ifdef JSON_VALUE_USE_INTERNAL_MAP 400 , itemIsUsed_( 0 ) 401 #endif 402 , comments_( 0 ) 403 { 404 value_.string_ = duplicateStringValue( beginValue, 405 (unsigned int)(endValue - beginValue) ); 406 } 407 408 409 Value::Value( const std::string &value ) 410 : type_( stringValue ) 411 , allocated_( true ) 412 # ifdef JSON_VALUE_USE_INTERNAL_MAP 413 , itemIsUsed_( 0 ) 414 #endif 415 , comments_( 0 ) 416 { 417 value_.string_ = duplicateStringValue( value.c_str(), 418 (unsigned int)value.length() ); 419 420 } 421 422 Value::Value( const StaticString &value ) 423 : type_( stringValue ) 424 , allocated_( false ) 425 # ifdef JSON_VALUE_USE_INTERNAL_MAP 426 , itemIsUsed_( 0 ) 427 #endif 428 , comments_( 0 ) 429 { 430 value_.string_ = const_cast<char *>( value.c_str() ); 431 } 432 433 434 # ifdef JSON_USE_CPPTL 435 Value::Value( const CppTL::ConstString &value ) 436 : type_( stringValue ) 437 , allocated_( true ) 438 # ifdef JSON_VALUE_USE_INTERNAL_MAP 439 , itemIsUsed_( 0 ) 440 #endif 441 , comments_( 0 ) 442 { 443 value_.string_ = duplicateStringValue( value, value.length() ); 444 } 445 # endif 446 447 Value::Value( bool value ) 448 : type_( booleanValue ) 449 , allocated_( false ) 450 # ifdef JSON_VALUE_USE_INTERNAL_MAP 451 , itemIsUsed_( 0 ) 452 #endif 453 , comments_( 0 ) 454 { 455 value_.bool_ = value; 456 } 457 458 459 Value::Value( const Value &other ) 460 : type_( other.type_ ) 461 , allocated_( false ) 462 # ifdef JSON_VALUE_USE_INTERNAL_MAP 463 , itemIsUsed_( 0 ) 464 #endif 465 , comments_( 0 ) 466 { 467 switch ( type_ ) 468 { 469 case nullValue: 470 case intValue: 471 case uintValue: 472 case realValue: 473 case booleanValue: 474 value_ = other.value_; 475 break; 476 case stringValue: 477 if ( other.value_.string_ ) 478 { 479 value_.string_ = duplicateStringValue( other.value_.string_ ); 480 allocated_ = true; 481 } 482 else 483 value_.string_ = 0; 484 break; 485 #ifndef JSON_VALUE_USE_INTERNAL_MAP 486 case arrayValue: 487 case objectValue: 488 value_.map_ = new ObjectValues( *other.value_.map_ ); 489 break; 490 #else 491 case arrayValue: 492 value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ ); 493 break; 494 case objectValue: 495 value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ ); 496 break; 497 #endif 498 default: 499 JSON_ASSERT_UNREACHABLE; 500 } 501 if ( other.comments_ ) 502 { 503 comments_ = new CommentInfo[numberOfCommentPlacement]; 504 for ( int comment =0; comment < numberOfCommentPlacement; ++comment ) 505 { 506 const CommentInfo &otherComment = other.comments_[comment]; 507 if ( otherComment.comment_ ) 508 comments_[comment].setComment( otherComment.comment_ ); 509 } 510 } 511 } 512 513 514 Value::~Value() 515 { 516 switch ( type_ ) 517 { 518 case nullValue: 519 case intValue: 520 case uintValue: 521 case realValue: 522 case booleanValue: 523 break; 524 case stringValue: 525 if ( allocated_ ) 526 releaseStringValue( value_.string_ ); 527 break; 528 #ifndef JSON_VALUE_USE_INTERNAL_MAP 529 case arrayValue: 530 case objectValue: 531 delete value_.map_; 532 break; 533 #else 534 case arrayValue: 535 arrayAllocator()->destructArray( value_.array_ ); 536 break; 537 case objectValue: 538 mapAllocator()->destructMap( value_.map_ ); 539 break; 540 #endif 541 default: 542 JSON_ASSERT_UNREACHABLE; 543 } 544 545 if ( comments_ ) 546 delete[] comments_; 547 } 548 549 Value & 550 Value::operator=( const Value &other ) 551 { 552 Value temp( other ); 553 swap( temp ); 554 return *this; 555 } 556 557 void 558 Value::swap( Value &other ) 559 { 560 ValueType temp = type_; 561 type_ = other.type_; 562 other.type_ = temp; 563 std::swap( value_, other.value_ ); 564 int temp2 = allocated_; 565 allocated_ = other.allocated_; 566 other.allocated_ = temp2; 567 } 568 569 ValueType 570 Value::type() const 571 { 572 return type_; 573 } 574 575 576 int 577 Value::compare( const Value &other ) const 578 { 579 if ( *this < other ) 580 return -1; 581 if ( *this > other ) 582 return 1; 583 return 0; 584 } 585 586 587 bool 588 Value::operator <( const Value &other ) const 589 { 590 int typeDelta = type_ - other.type_; 591 if ( typeDelta ) 592 return typeDelta < 0 ? true : false; 593 switch ( type_ ) 594 { 595 case nullValue: 596 return false; 597 case intValue: 598 return value_.int_ < other.value_.int_; 599 case uintValue: 600 return value_.uint_ < other.value_.uint_; 601 case realValue: 602 return value_.real_ < other.value_.real_; 603 case booleanValue: 604 return value_.bool_ < other.value_.bool_; 605 case stringValue: 606 return ( value_.string_ == 0 && other.value_.string_ ) 607 || ( other.value_.string_ 608 && value_.string_ 609 && strcmp( value_.string_, other.value_.string_ ) < 0 ); 610 #ifndef JSON_VALUE_USE_INTERNAL_MAP 611 case arrayValue: 612 case objectValue: 613 { 614 int delta = int( value_.map_->size() - other.value_.map_->size() ); 615 if ( delta ) 616 return delta < 0; 617 return (*value_.map_) < (*other.value_.map_); 618 } 619 #else 620 case arrayValue: 621 return value_.array_->compare( *(other.value_.array_) ) < 0; 622 case objectValue: 623 return value_.map_->compare( *(other.value_.map_) ) < 0; 624 #endif 625 default: 626 JSON_ASSERT_UNREACHABLE; 627 } 628 return false; // unreachable 629 } 630 631 bool 632 Value::operator <=( const Value &other ) const 633 { 634 return !(other < *this); 635 } 636 637 bool 638 Value::operator >=( const Value &other ) const 639 { 640 return !(*this < other); 641 } 642 643 bool 644 Value::operator >( const Value &other ) const 645 { 646 return other < *this; 647 } 648 649 bool 650 Value::operator ==( const Value &other ) const 651 { 652 //if ( type_ != other.type_ ) 653 // GCC 2.95.3 says: 654 // attempt to take address of bit-field structure member `Json::Value::type_' 655 // Beats me, but a temp solves the problem. 656 int temp = other.type_; 657 if ( type_ != temp ) 658 return false; 659 switch ( type_ ) 660 { 661 case nullValue: 662 return true; 663 case intValue: 664 return value_.int_ == other.value_.int_; 665 case uintValue: 666 return value_.uint_ == other.value_.uint_; 667 case realValue: 668 return value_.real_ == other.value_.real_; 669 case booleanValue: 670 return value_.bool_ == other.value_.bool_; 671 case stringValue: 672 return ( value_.string_ == other.value_.string_ ) 673 || ( other.value_.string_ 674 && value_.string_ 675 && strcmp( value_.string_, other.value_.string_ ) == 0 ); 676 #ifndef JSON_VALUE_USE_INTERNAL_MAP 677 case arrayValue: 678 case objectValue: 679 return value_.map_->size() == other.value_.map_->size() 680 && (*value_.map_) == (*other.value_.map_); 681 #else 682 case arrayValue: 683 return value_.array_->compare( *(other.value_.array_) ) == 0; 684 case objectValue: 685 return value_.map_->compare( *(other.value_.map_) ) == 0; 686 #endif 687 default: 688 JSON_ASSERT_UNREACHABLE; 689 } 690 return false; // unreachable 691 } 692 693 bool 694 Value::operator !=( const Value &other ) const 695 { 696 return !( *this == other ); 697 } 698 699 const char * 700 Value::asCString() const 701 { 702 JSON_ASSERT( type_ == stringValue ); 703 return value_.string_; 704 } 705 706 707 std::string 708 Value::asString() const 709 { 710 switch ( type_ ) 711 { 712 case nullValue: 713 return ""; 714 case stringValue: 715 return value_.string_ ? value_.string_ : ""; 716 case booleanValue: 717 return value_.bool_ ? "true" : "false"; 718 case intValue: 719 return valueToString( value_.int_ ); 720 case uintValue: 721 return valueToString( value_.uint_ ); 722 case realValue: 723 return valueToString( value_.real_ ); 724 default: 725 JSON_FAIL_MESSAGE( "Type is not convertible to string" ); 726 } 727 } 728 729 # ifdef JSON_USE_CPPTL 730 CppTL::ConstString 731 Value::asConstString() const 732 { 733 return CppTL::ConstString( asString().c_str() ); 734 } 735 # endif 736 737 738 Value::Int 739 Value::asInt() const 740 { 741 switch ( type_ ) 742 { 743 case intValue: 744 JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); 745 return Int(value_.int_); 746 case uintValue: 747 JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); 748 return Int(value_.uint_); 749 case realValue: 750 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), "double out of Int range"); 751 return Int(value_.real_); 752 case nullValue: 753 return 0; 754 case booleanValue: 755 return value_.bool_ ? 1 : 0; 756 default: 757 break; 758 } 759 JSON_FAIL_MESSAGE("Value is not convertible to Int."); 760 } 761 762 763 Value::UInt 764 Value::asUInt() const 765 { 766 switch ( type_ ) 767 { 768 case intValue: 769 JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); 770 return UInt(value_.int_); 771 case uintValue: 772 JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); 773 return UInt(value_.uint_); 774 case realValue: 775 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), "double out of UInt range"); 776 return UInt( value_.real_ ); 777 case nullValue: 778 return 0; 779 case booleanValue: 780 return value_.bool_ ? 1 : 0; 781 default: 782 break; 783 } 784 JSON_FAIL_MESSAGE("Value is not convertible to UInt."); 785 } 786 787 788 # if defined(JSON_HAS_INT64) 789 790 Value::Int64 791 Value::asInt64() const 792 { 793 switch ( type_ ) 794 { 795 case intValue: 796 return Int64(value_.int_); 797 case uintValue: 798 JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); 799 return Int64(value_.uint_); 800 case realValue: 801 JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), "double out of Int64 range"); 802 return Int64(value_.real_); 803 case nullValue: 804 return 0; 805 case booleanValue: 806 return value_.bool_ ? 1 : 0; 807 default: 808 break; 809 } 810 JSON_FAIL_MESSAGE("Value is not convertible to Int64."); 811 } 812 813 814 Value::UInt64 815 Value::asUInt64() const 816 { 817 switch ( type_ ) 818 { 819 case intValue: 820 JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); 821 return UInt64(value_.int_); 822 case uintValue: 823 return UInt64(value_.uint_); 824 case realValue: 825 JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), "double out of UInt64 range"); 826 return UInt64( value_.real_ ); 827 case nullValue: 828 return 0; 829 case booleanValue: 830 return value_.bool_ ? 1 : 0; 831 default: 832 break; 833 } 834 JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); 835 } 836 # endif // if defined(JSON_HAS_INT64) 837 838 839 LargestInt 840 Value::asLargestInt() const 841 { 842 #if defined(JSON_NO_INT64) 843 return asInt(); 844 #else 845 return asInt64(); 846 #endif 847 } 848 849 850 LargestUInt 851 Value::asLargestUInt() const 852 { 853 #if defined(JSON_NO_INT64) 854 return asUInt(); 855 #else 856 return asUInt64(); 857 #endif 858 } 859 860 861 double 862 Value::asDouble() const 863 { 864 switch ( type_ ) 865 { 866 case intValue: 867 return static_cast<double>( value_.int_ ); 868 case uintValue: 869 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 870 return static_cast<double>( value_.uint_ ); 871 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 872 return integerToDouble( value_.uint_ ); 873 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 874 case realValue: 875 return value_.real_; 876 case nullValue: 877 return 0.0; 878 case booleanValue: 879 return value_.bool_ ? 1.0 : 0.0; 880 default: 881 break; 882 } 883 JSON_FAIL_MESSAGE("Value is not convertible to double."); 884 } 885 886 float 887 Value::asFloat() const 888 { 889 switch ( type_ ) 890 { 891 case intValue: 892 return static_cast<float>( value_.int_ ); 893 case uintValue: 894 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 895 return static_cast<float>( value_.uint_ ); 896 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 897 return integerToDouble( value_.uint_ ); 898 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 899 case realValue: 900 return static_cast<float>( value_.real_ ); 901 case nullValue: 902 return 0.0; 903 case booleanValue: 904 return value_.bool_ ? 1.0f : 0.0f; 905 default: 906 break; 907 } 908 JSON_FAIL_MESSAGE("Value is not convertible to float."); 909 } 910 911 bool 912 Value::asBool() const 913 { 914 switch ( type_ ) 915 { 916 case booleanValue: 917 return value_.bool_; 918 case nullValue: 919 return false; 920 case intValue: 921 return value_.int_ ? true : false; 922 case uintValue: 923 return value_.uint_ ? true : false; 924 case realValue: 925 return value_.real_ ? true : false; 926 default: 927 break; 928 } 929 JSON_FAIL_MESSAGE("Value is not convertible to bool."); 930 } 931 932 933 bool 934 Value::isConvertibleTo( ValueType other ) const 935 { 936 switch ( other ) 937 { 938 case nullValue: 939 return ( isNumeric() && asDouble() == 0.0 ) 940 || ( type_ == booleanValue && value_.bool_ == false ) 941 || ( type_ == stringValue && asString() == "" ) 942 || ( type_ == arrayValue && value_.map_->size() == 0 ) 943 || ( type_ == objectValue && value_.map_->size() == 0 ) 944 || type_ == nullValue; 945 case intValue: 946 return isInt() 947 || (type_ == realValue && InRange(value_.real_, minInt, maxInt)) 948 || type_ == booleanValue 949 || type_ == nullValue; 950 case uintValue: 951 return isUInt() 952 || (type_ == realValue && InRange(value_.real_, 0, maxUInt)) 953 || type_ == booleanValue 954 || type_ == nullValue; 955 case realValue: 956 return isNumeric() 957 || type_ == booleanValue 958 || type_ == nullValue; 959 case booleanValue: 960 return isNumeric() 961 || type_ == booleanValue 962 || type_ == nullValue; 963 case stringValue: 964 return isNumeric() 965 || type_ == booleanValue 966 || type_ == stringValue 967 || type_ == nullValue; 968 case arrayValue: 969 return type_ == arrayValue 970 || type_ == nullValue; 971 case objectValue: 972 return type_ == objectValue 973 || type_ == nullValue; 974 } 975 JSON_ASSERT_UNREACHABLE; 976 return false; 977 } 978 979 980 /// Number of values in array or object 981 ArrayIndex 982 Value::size() const 983 { 984 switch ( type_ ) 985 { 986 case nullValue: 987 case intValue: 988 case uintValue: 989 case realValue: 990 case booleanValue: 991 case stringValue: 992 return 0; 993 #ifndef JSON_VALUE_USE_INTERNAL_MAP 994 case arrayValue: // size of the array is highest index + 1 995 if ( !value_.map_->empty() ) 996 { 997 ObjectValues::const_iterator itLast = value_.map_->end(); 998 --itLast; 999 return (*itLast).first.index()+1; 1000 } 1001 return 0; 1002 case objectValue: 1003 return ArrayIndex( value_.map_->size() ); 1004 #else 1005 case arrayValue: 1006 return Int( value_.array_->size() ); 1007 case objectValue: 1008 return Int( value_.map_->size() ); 1009 #endif 1010 } 1011 JSON_ASSERT_UNREACHABLE; 1012 return 0; // unreachable; 1013 } 1014 1015 1016 bool 1017 Value::empty() const 1018 { 1019 if ( isNull() || isArray() || isObject() ) 1020 return size() == 0u; 1021 else 1022 return false; 1023 } 1024 1025 1026 bool 1027 Value::operator!() const 1028 { 1029 return isNull(); 1030 } 1031 1032 1033 void 1034 Value::clear() 1035 { 1036 JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue ); 1037 1038 switch ( type_ ) 1039 { 1040 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1041 case arrayValue: 1042 case objectValue: 1043 value_.map_->clear(); 1044 break; 1045 #else 1046 case arrayValue: 1047 value_.array_->clear(); 1048 break; 1049 case objectValue: 1050 value_.map_->clear(); 1051 break; 1052 #endif 1053 default: 1054 break; 1055 } 1056 } 1057 1058 void 1059 Value::resize( ArrayIndex newSize ) 1060 { 1061 JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); 1062 if ( type_ == nullValue ) 1063 *this = Value( arrayValue ); 1064 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1065 ArrayIndex oldSize = size(); 1066 if ( newSize == 0 ) 1067 clear(); 1068 else if ( newSize > oldSize ) 1069 (*this)[ newSize - 1 ]; 1070 else 1071 { 1072 for ( ArrayIndex index = newSize; index < oldSize; ++index ) 1073 { 1074 value_.map_->erase( index ); 1075 } 1076 assert( size() == newSize ); 1077 } 1078 #else 1079 value_.array_->resize( newSize ); 1080 #endif 1081 } 1082 1083 1084 Value & 1085 Value::operator[]( ArrayIndex index ) 1086 { 1087 JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); 1088 if ( type_ == nullValue ) 1089 *this = Value( arrayValue ); 1090 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1091 CZString key( index ); 1092 ObjectValues::iterator it = value_.map_->lower_bound( key ); 1093 if ( it != value_.map_->end() && (*it).first == key ) 1094 return (*it).second; 1095 1096 ObjectValues::value_type defaultValue( key, null ); 1097 it = value_.map_->insert( it, defaultValue ); 1098 return (*it).second; 1099 #else 1100 return value_.array_->resolveReference( index ); 1101 #endif 1102 } 1103 1104 1105 Value & 1106 Value::operator[]( int index ) 1107 { 1108 JSON_ASSERT( index >= 0 ); 1109 return (*this)[ ArrayIndex(index) ]; 1110 } 1111 1112 1113 const Value & 1114 Value::operator[]( ArrayIndex index ) const 1115 { 1116 JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); 1117 if ( type_ == nullValue ) 1118 return null; 1119 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1120 CZString key( index ); 1121 ObjectValues::const_iterator it = value_.map_->find( key ); 1122 if ( it == value_.map_->end() ) 1123 return null; 1124 return (*it).second; 1125 #else 1126 Value *value = value_.array_->find( index ); 1127 return value ? *value : null; 1128 #endif 1129 } 1130 1131 1132 const Value & 1133 Value::operator[]( int index ) const 1134 { 1135 JSON_ASSERT( index >= 0 ); 1136 return (*this)[ ArrayIndex(index) ]; 1137 } 1138 1139 1140 Value & 1141 Value::operator[]( const char *key ) 1142 { 1143 return resolveReference( key, false ); 1144 } 1145 1146 1147 Value & 1148 Value::resolveReference( const char *key, 1149 bool isStatic ) 1150 { 1151 JSON_ASSERT( type_ == nullValue || type_ == objectValue ); 1152 if ( type_ == nullValue ) 1153 *this = Value( objectValue ); 1154 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1155 CZString actualKey( key, isStatic ? CZString::noDuplication 1156 : CZString::duplicateOnCopy ); 1157 ObjectValues::iterator it = value_.map_->lower_bound( actualKey ); 1158 if ( it != value_.map_->end() && (*it).first == actualKey ) 1159 return (*it).second; 1160 1161 ObjectValues::value_type defaultValue( actualKey, null ); 1162 it = value_.map_->insert( it, defaultValue ); 1163 Value &value = (*it).second; 1164 return value; 1165 #else 1166 return value_.map_->resolveReference( key, isStatic ); 1167 #endif 1168 } 1169 1170 1171 Value 1172 Value::get( ArrayIndex index, 1173 const Value &defaultValue ) const 1174 { 1175 const Value *value = &((*this)[index]); 1176 return value == &null ? defaultValue : *value; 1177 } 1178 1179 1180 bool 1181 Value::isValidIndex( ArrayIndex index ) const 1182 { 1183 return index < size(); 1184 } 1185 1186 1187 1188 const Value & 1189 Value::operator[]( const char *key ) const 1190 { 1191 JSON_ASSERT( type_ == nullValue || type_ == objectValue ); 1192 if ( type_ == nullValue ) 1193 return null; 1194 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1195 CZString actualKey( key, CZString::noDuplication ); 1196 ObjectValues::const_iterator it = value_.map_->find( actualKey ); 1197 if ( it == value_.map_->end() ) 1198 return null; 1199 return (*it).second; 1200 #else 1201 const Value *value = value_.map_->find( key ); 1202 return value ? *value : null; 1203 #endif 1204 } 1205 1206 1207 Value & 1208 Value::operator[]( const std::string &key ) 1209 { 1210 return (*this)[ key.c_str() ]; 1211 } 1212 1213 1214 const Value & 1215 Value::operator[]( const std::string &key ) const 1216 { 1217 return (*this)[ key.c_str() ]; 1218 } 1219 1220 Value & 1221 Value::operator[]( const StaticString &key ) 1222 { 1223 return resolveReference( key, true ); 1224 } 1225 1226 1227 # ifdef JSON_USE_CPPTL 1228 Value & 1229 Value::operator[]( const CppTL::ConstString &key ) 1230 { 1231 return (*this)[ key.c_str() ]; 1232 } 1233 1234 1235 const Value & 1236 Value::operator[]( const CppTL::ConstString &key ) const 1237 { 1238 return (*this)[ key.c_str() ]; 1239 } 1240 # endif 1241 1242 1243 Value & 1244 Value::append( const Value &value ) 1245 { 1246 return (*this)[size()] = value; 1247 } 1248 1249 1250 Value 1251 Value::get( const char *key, 1252 const Value &defaultValue ) const 1253 { 1254 const Value *value = &((*this)[key]); 1255 return value == &null ? defaultValue : *value; 1256 } 1257 1258 1259 Value 1260 Value::get( const std::string &key, 1261 const Value &defaultValue ) const 1262 { 1263 return get( key.c_str(), defaultValue ); 1264 } 1265 1266 Value 1267 Value::removeMember( const char* key ) 1268 { 1269 JSON_ASSERT( type_ == nullValue || type_ == objectValue ); 1270 if ( type_ == nullValue ) 1271 return null; 1272 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1273 CZString actualKey( key, CZString::noDuplication ); 1274 ObjectValues::iterator it = value_.map_->find( actualKey ); 1275 if ( it == value_.map_->end() ) 1276 return null; 1277 Value old(it->second); 1278 value_.map_->erase(it); 1279 return old; 1280 #else 1281 Value *value = value_.map_->find( key ); 1282 if (value){ 1283 Value old(*value); 1284 value_.map_.remove( key ); 1285 return old; 1286 } else { 1287 return null; 1288 } 1289 #endif 1290 } 1291 1292 Value 1293 Value::removeMember( const std::string &key ) 1294 { 1295 return removeMember( key.c_str() ); 1296 } 1297 1298 # ifdef JSON_USE_CPPTL 1299 Value 1300 Value::get( const CppTL::ConstString &key, 1301 const Value &defaultValue ) const 1302 { 1303 return get( key.c_str(), defaultValue ); 1304 } 1305 # endif 1306 1307 bool 1308 Value::isMember( const char *key ) const 1309 { 1310 const Value *value = &((*this)[key]); 1311 return value != &null; 1312 } 1313 1314 1315 bool 1316 Value::isMember( const std::string &key ) const 1317 { 1318 return isMember( key.c_str() ); 1319 } 1320 1321 1322 # ifdef JSON_USE_CPPTL 1323 bool 1324 Value::isMember( const CppTL::ConstString &key ) const 1325 { 1326 return isMember( key.c_str() ); 1327 } 1328 #endif 1329 1330 Value::Members 1331 Value::getMemberNames() const 1332 { 1333 JSON_ASSERT( type_ == nullValue || type_ == objectValue ); 1334 if ( type_ == nullValue ) 1335 return Value::Members(); 1336 Members members; 1337 members.reserve( value_.map_->size() ); 1338 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1339 ObjectValues::const_iterator it = value_.map_->begin(); 1340 ObjectValues::const_iterator itEnd = value_.map_->end(); 1341 for ( ; it != itEnd; ++it ) 1342 members.push_back( std::string( (*it).first.c_str() ) ); 1343 #else 1344 ValueInternalMap::IteratorState it; 1345 ValueInternalMap::IteratorState itEnd; 1346 value_.map_->makeBeginIterator( it ); 1347 value_.map_->makeEndIterator( itEnd ); 1348 for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) ) 1349 members.push_back( std::string( ValueInternalMap::key( it ) ) ); 1350 #endif 1351 return members; 1352 } 1353 // 1354 //# ifdef JSON_USE_CPPTL 1355 //EnumMemberNames 1356 //Value::enumMemberNames() const 1357 //{ 1358 // if ( type_ == objectValue ) 1359 // { 1360 // return CppTL::Enum::any( CppTL::Enum::transform( 1361 // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), 1362 // MemberNamesTransform() ) ); 1363 // } 1364 // return EnumMemberNames(); 1365 //} 1366 // 1367 // 1368 //EnumValues 1369 //Value::enumValues() const 1370 //{ 1371 // if ( type_ == objectValue || type_ == arrayValue ) 1372 // return CppTL::Enum::anyValues( *(value_.map_), 1373 // CppTL::Type<const Value &>() ); 1374 // return EnumValues(); 1375 //} 1376 // 1377 //# endif 1378 1379 static bool IsIntegral(double d) { 1380 double integral_part; 1381 return modf(d, &integral_part) == 0.0; 1382 } 1383 1384 1385 bool 1386 Value::isNull() const 1387 { 1388 return type_ == nullValue; 1389 } 1390 1391 1392 bool 1393 Value::isBool() const 1394 { 1395 return type_ == booleanValue; 1396 } 1397 1398 1399 bool 1400 Value::isInt() const 1401 { 1402 switch ( type_ ) 1403 { 1404 case intValue: 1405 return value_.int_ >= minInt && value_.int_ <= maxInt; 1406 case uintValue: 1407 return value_.uint_ <= UInt(maxInt); 1408 case realValue: 1409 return value_.real_ >= minInt && 1410 value_.real_ <= maxInt && 1411 IsIntegral(value_.real_); 1412 default: 1413 break; 1414 } 1415 return false; 1416 } 1417 1418 1419 bool 1420 Value::isUInt() const 1421 { 1422 switch ( type_ ) 1423 { 1424 case intValue: 1425 return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); 1426 case uintValue: 1427 return value_.uint_ <= maxUInt; 1428 case realValue: 1429 return value_.real_ >= 0 && 1430 value_.real_ <= maxUInt && 1431 IsIntegral(value_.real_); 1432 default: 1433 break; 1434 } 1435 return false; 1436 } 1437 1438 bool 1439 Value::isInt64() const 1440 { 1441 # if defined(JSON_HAS_INT64) 1442 switch ( type_ ) 1443 { 1444 case intValue: 1445 return true; 1446 case uintValue: 1447 return value_.uint_ <= UInt64(maxInt64); 1448 case realValue: 1449 // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a 1450 // double, so double(maxInt64) will be rounded up to 2^63. Therefore we 1451 // require the value to be strictly less than the limit. 1452 return value_.real_ >= double(minInt64) && 1453 value_.real_ < double(maxInt64) && 1454 IsIntegral(value_.real_); 1455 default: 1456 break; 1457 } 1458 # endif // JSON_HAS_INT64 1459 return false; 1460 } 1461 1462 bool 1463 Value::isUInt64() const 1464 { 1465 # if defined(JSON_HAS_INT64) 1466 switch ( type_ ) 1467 { 1468 case intValue: 1469 return value_.int_ >= 0; 1470 case uintValue: 1471 return true; 1472 case realValue: 1473 // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a 1474 // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we 1475 // require the value to be strictly less than the limit. 1476 return value_.real_ >= 0 && 1477 value_.real_ < maxUInt64AsDouble && 1478 IsIntegral(value_.real_); 1479 default: 1480 break; 1481 } 1482 # endif // JSON_HAS_INT64 1483 return false; 1484 } 1485 1486 1487 bool 1488 Value::isIntegral() const 1489 { 1490 #if defined(JSON_HAS_INT64) 1491 return isInt64() || isUInt64(); 1492 #else 1493 return isInt() || isUInt(); 1494 #endif 1495 } 1496 1497 1498 bool 1499 Value::isDouble() const 1500 { 1501 return type_ == realValue || isIntegral(); 1502 } 1503 1504 1505 bool 1506 Value::isNumeric() const 1507 { 1508 return isIntegral() || isDouble(); 1509 } 1510 1511 1512 bool 1513 Value::isString() const 1514 { 1515 return type_ == stringValue; 1516 } 1517 1518 1519 bool 1520 Value::isArray() const 1521 { 1522 return type_ == arrayValue; 1523 } 1524 1525 1526 bool 1527 Value::isObject() const 1528 { 1529 return type_ == objectValue; 1530 } 1531 1532 1533 void 1534 Value::setComment( const char *comment, 1535 CommentPlacement placement ) 1536 { 1537 if ( !comments_ ) 1538 comments_ = new CommentInfo[numberOfCommentPlacement]; 1539 comments_[placement].setComment( comment ); 1540 } 1541 1542 1543 void 1544 Value::setComment( const std::string &comment, 1545 CommentPlacement placement ) 1546 { 1547 setComment( comment.c_str(), placement ); 1548 } 1549 1550 1551 bool 1552 Value::hasComment( CommentPlacement placement ) const 1553 { 1554 return comments_ != 0 && comments_[placement].comment_ != 0; 1555 } 1556 1557 std::string 1558 Value::getComment( CommentPlacement placement ) const 1559 { 1560 if ( hasComment(placement) ) 1561 return comments_[placement].comment_; 1562 return ""; 1563 } 1564 1565 1566 std::string 1567 Value::toStyledString() const 1568 { 1569 StyledWriter writer; 1570 return writer.write( *this ); 1571 } 1572 1573 1574 Value::const_iterator 1575 Value::begin() const 1576 { 1577 switch ( type_ ) 1578 { 1579 #ifdef JSON_VALUE_USE_INTERNAL_MAP 1580 case arrayValue: 1581 if ( value_.array_ ) 1582 { 1583 ValueInternalArray::IteratorState it; 1584 value_.array_->makeBeginIterator( it ); 1585 return const_iterator( it ); 1586 } 1587 break; 1588 case objectValue: 1589 if ( value_.map_ ) 1590 { 1591 ValueInternalMap::IteratorState it; 1592 value_.map_->makeBeginIterator( it ); 1593 return const_iterator( it ); 1594 } 1595 break; 1596 #else 1597 case arrayValue: 1598 case objectValue: 1599 if ( value_.map_ ) 1600 return const_iterator( value_.map_->begin() ); 1601 break; 1602 #endif 1603 default: 1604 break; 1605 } 1606 return const_iterator(); 1607 } 1608 1609 Value::const_iterator 1610 Value::end() const 1611 { 1612 switch ( type_ ) 1613 { 1614 #ifdef JSON_VALUE_USE_INTERNAL_MAP 1615 case arrayValue: 1616 if ( value_.array_ ) 1617 { 1618 ValueInternalArray::IteratorState it; 1619 value_.array_->makeEndIterator( it ); 1620 return const_iterator( it ); 1621 } 1622 break; 1623 case objectValue: 1624 if ( value_.map_ ) 1625 { 1626 ValueInternalMap::IteratorState it; 1627 value_.map_->makeEndIterator( it ); 1628 return const_iterator( it ); 1629 } 1630 break; 1631 #else 1632 case arrayValue: 1633 case objectValue: 1634 if ( value_.map_ ) 1635 return const_iterator( value_.map_->end() ); 1636 break; 1637 #endif 1638 default: 1639 break; 1640 } 1641 return const_iterator(); 1642 } 1643 1644 1645 Value::iterator 1646 Value::begin() 1647 { 1648 switch ( type_ ) 1649 { 1650 #ifdef JSON_VALUE_USE_INTERNAL_MAP 1651 case arrayValue: 1652 if ( value_.array_ ) 1653 { 1654 ValueInternalArray::IteratorState it; 1655 value_.array_->makeBeginIterator( it ); 1656 return iterator( it ); 1657 } 1658 break; 1659 case objectValue: 1660 if ( value_.map_ ) 1661 { 1662 ValueInternalMap::IteratorState it; 1663 value_.map_->makeBeginIterator( it ); 1664 return iterator( it ); 1665 } 1666 break; 1667 #else 1668 case arrayValue: 1669 case objectValue: 1670 if ( value_.map_ ) 1671 return iterator( value_.map_->begin() ); 1672 break; 1673 #endif 1674 default: 1675 break; 1676 } 1677 return iterator(); 1678 } 1679 1680 Value::iterator 1681 Value::end() 1682 { 1683 switch ( type_ ) 1684 { 1685 #ifdef JSON_VALUE_USE_INTERNAL_MAP 1686 case arrayValue: 1687 if ( value_.array_ ) 1688 { 1689 ValueInternalArray::IteratorState it; 1690 value_.array_->makeEndIterator( it ); 1691 return iterator( it ); 1692 } 1693 break; 1694 case objectValue: 1695 if ( value_.map_ ) 1696 { 1697 ValueInternalMap::IteratorState it; 1698 value_.map_->makeEndIterator( it ); 1699 return iterator( it ); 1700 } 1701 break; 1702 #else 1703 case arrayValue: 1704 case objectValue: 1705 if ( value_.map_ ) 1706 return iterator( value_.map_->end() ); 1707 break; 1708 #endif 1709 default: 1710 break; 1711 } 1712 return iterator(); 1713 } 1714 1715 1716 // class PathArgument 1717 // ////////////////////////////////////////////////////////////////// 1718 1719 PathArgument::PathArgument() 1720 : key_() 1721 , index_() 1722 , kind_( kindNone ) 1723 { 1724 } 1725 1726 1727 PathArgument::PathArgument( ArrayIndex index ) 1728 : key_() 1729 , index_( index ) 1730 , kind_( kindIndex ) 1731 { 1732 } 1733 1734 1735 PathArgument::PathArgument( const char *key ) 1736 : key_( key ) 1737 , index_() 1738 , kind_( kindKey ) 1739 { 1740 } 1741 1742 1743 PathArgument::PathArgument( const std::string &key ) 1744 : key_( key.c_str() ) 1745 , index_() 1746 , kind_( kindKey ) 1747 { 1748 } 1749 1750 // class Path 1751 // ////////////////////////////////////////////////////////////////// 1752 1753 Path::Path( const std::string &path, 1754 const PathArgument &a1, 1755 const PathArgument &a2, 1756 const PathArgument &a3, 1757 const PathArgument &a4, 1758 const PathArgument &a5 ) 1759 { 1760 InArgs in; 1761 in.push_back( &a1 ); 1762 in.push_back( &a2 ); 1763 in.push_back( &a3 ); 1764 in.push_back( &a4 ); 1765 in.push_back( &a5 ); 1766 makePath( path, in ); 1767 } 1768 1769 1770 void 1771 Path::makePath( const std::string &path, 1772 const InArgs &in ) 1773 { 1774 const char *current = path.c_str(); 1775 const char *end = current + path.length(); 1776 InArgs::const_iterator itInArg = in.begin(); 1777 while ( current != end ) 1778 { 1779 if ( *current == '[' ) 1780 { 1781 ++current; 1782 if ( *current == '%' ) 1783 addPathInArg( path, in, itInArg, PathArgument::kindIndex ); 1784 else 1785 { 1786 ArrayIndex index = 0; 1787 for ( ; current != end && *current >= '0' && *current <= '9'; ++current ) 1788 index = index * 10 + ArrayIndex(*current - '0'); 1789 args_.push_back( index ); 1790 } 1791 if ( current == end || *current++ != ']' ) 1792 invalidPath( path, int(current - path.c_str()) ); 1793 } 1794 else if ( *current == '%' ) 1795 { 1796 addPathInArg( path, in, itInArg, PathArgument::kindKey ); 1797 ++current; 1798 } 1799 else if ( *current == '.' ) 1800 { 1801 ++current; 1802 } 1803 else 1804 { 1805 const char *beginName = current; 1806 while ( current != end && !strchr( "[.", *current ) ) 1807 ++current; 1808 args_.push_back( std::string( beginName, current ) ); 1809 } 1810 } 1811 } 1812 1813 1814 void 1815 Path::addPathInArg( const std::string &path, 1816 const InArgs &in, 1817 InArgs::const_iterator &itInArg, 1818 PathArgument::Kind kind ) 1819 { 1820 if ( itInArg == in.end() ) 1821 { 1822 // Error: missing argument %d 1823 } 1824 else if ( (*itInArg)->kind_ != kind ) 1825 { 1826 // Error: bad argument type 1827 } 1828 else 1829 { 1830 args_.push_back( **itInArg ); 1831 } 1832 } 1833 1834 1835 void 1836 Path::invalidPath( const std::string &path, 1837 int location ) 1838 { 1839 // Error: invalid path. 1840 } 1841 1842 1843 const Value & 1844 Path::resolve( const Value &root ) const 1845 { 1846 const Value *node = &root; 1847 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) 1848 { 1849 const PathArgument &arg = *it; 1850 if ( arg.kind_ == PathArgument::kindIndex ) 1851 { 1852 if ( !node->isArray() || !node->isValidIndex( arg.index_ ) ) 1853 { 1854 // Error: unable to resolve path (array value expected at position... 1855 } 1856 node = &((*node)[arg.index_]); 1857 } 1858 else if ( arg.kind_ == PathArgument::kindKey ) 1859 { 1860 if ( !node->isObject() ) 1861 { 1862 // Error: unable to resolve path (object value expected at position...) 1863 } 1864 node = &((*node)[arg.key_]); 1865 if ( node == &Value::null ) 1866 { 1867 // Error: unable to resolve path (object has no member named '' at position...) 1868 } 1869 } 1870 } 1871 return *node; 1872 } 1873 1874 1875 Value 1876 Path::resolve( const Value &root, 1877 const Value &defaultValue ) const 1878 { 1879 const Value *node = &root; 1880 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) 1881 { 1882 const PathArgument &arg = *it; 1883 if ( arg.kind_ == PathArgument::kindIndex ) 1884 { 1885 if ( !node->isArray() || !node->isValidIndex( arg.index_ ) ) 1886 return defaultValue; 1887 node = &((*node)[arg.index_]); 1888 } 1889 else if ( arg.kind_ == PathArgument::kindKey ) 1890 { 1891 if ( !node->isObject() ) 1892 return defaultValue; 1893 node = &((*node)[arg.key_]); 1894 if ( node == &Value::null ) 1895 return defaultValue; 1896 } 1897 } 1898 return *node; 1899 } 1900 1901 1902 Value & 1903 Path::make( Value &root ) const 1904 { 1905 Value *node = &root; 1906 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) 1907 { 1908 const PathArgument &arg = *it; 1909 if ( arg.kind_ == PathArgument::kindIndex ) 1910 { 1911 if ( !node->isArray() ) 1912 { 1913 // Error: node is not an array at position ... 1914 } 1915 node = &((*node)[arg.index_]); 1916 } 1917 else if ( arg.kind_ == PathArgument::kindKey ) 1918 { 1919 if ( !node->isObject() ) 1920 { 1921 // Error: node is not an object at position... 1922 } 1923 node = &((*node)[arg.key_]); 1924 } 1925 } 1926 return *node; 1927 } 1928 1929 1930 } // namespace Json 1931