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