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