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 27namespace Json { 28 29const Value Value::null; 30const Int Value::minInt = Int( ~(UInt(-1)/2) ); 31const Int Value::maxInt = Int( UInt(-1)/2 ); 32const UInt Value::maxUInt = UInt(-1); 33# if defined(JSON_HAS_INT64) 34const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) ); 35const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 ); 36const 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. 40static const double maxUInt64AsDouble = 18446744073709551615.0; 41#endif // defined(JSON_HAS_INT64) 42const LargestInt Value::minLargestInt = LargestInt( ~(LargestUInt(-1)/2) ); 43const LargestInt Value::maxLargestInt = LargestInt( LargestUInt(-1)/2 ); 44const LargestUInt Value::maxLargestUInt = LargestUInt(-1); 45 46 47/// Unknown size marker 48static const unsigned int unknown = (unsigned)-1; 49 50#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) 51template <typename T, typename U> 52static 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) 56static inline double integerToDouble( Json::UInt64 value ) 57{ 58 return static_cast<double>( Int64(value/2) ) * 2.0 + Int64(value & 1); 59} 60 61template<typename T> 62static inline double integerToDouble( T value ) 63{ 64 return static_cast<double>( value ); 65} 66 67template <typename T, typename U> 68static 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 */ 81static inline char * 82duplicateStringValue( 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 */ 103static inline void 104releaseStringValue( 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 129namespace Json { 130 131// ////////////////////////////////////////////////////////////////// 132// ////////////////////////////////////////////////////////////////// 133// ////////////////////////////////////////////////////////////////// 134// class Value::CommentInfo 135// ////////////////////////////////////////////////////////////////// 136// ////////////////////////////////////////////////////////////////// 137// ////////////////////////////////////////////////////////////////// 138 139 140Value::CommentInfo::CommentInfo() 141 : comment_( 0 ) 142{ 143} 144 145Value::CommentInfo::~CommentInfo() 146{ 147 if ( comment_ ) 148 releaseStringValue( comment_ ); 149} 150 151 152void 153Value::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 176Value::CZString::CZString( ArrayIndex index ) 177 : cstr_( 0 ) 178 , index_( index ) 179{ 180} 181 182Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) 183 : cstr_( allocate == duplicate ? duplicateStringValue(cstr) 184 : cstr ) 185 , index_( allocate ) 186{ 187} 188 189Value::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 198Value::CZString::~CZString() 199{ 200 if ( cstr_ && index_ == duplicate ) 201 releaseStringValue( const_cast<char *>( cstr_ ) ); 202} 203 204void 205Value::CZString::swap( CZString &other ) 206{ 207 std::swap( cstr_, other.cstr_ ); 208 std::swap( index_, other.index_ ); 209} 210 211Value::CZString & 212Value::CZString::operator =( const CZString &other ) 213{ 214 CZString temp( other ); 215 swap( temp ); 216 return *this; 217} 218 219bool 220Value::CZString::operator<( const CZString &other ) const 221{ 222 if ( cstr_ ) 223 return strcmp( cstr_, other.cstr_ ) < 0; 224 return index_ < other.index_; 225} 226 227bool 228Value::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 236ArrayIndex 237Value::CZString::index() const 238{ 239 return index_; 240} 241 242 243const char * 244Value::CZString::c_str() const 245{ 246 return cstr_; 247} 248 249bool 250Value::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 */ 270Value::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 314Value::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 325Value::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) 338Value::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 350Value::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 362Value::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 373Value::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 385Value::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 399Value::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 412Value::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 425Value::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 437Value::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 449Value::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 504Value::~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 539Value & 540Value::operator=( const Value &other ) 541{ 542 Value temp( other ); 543 swap( temp ); 544 return *this; 545} 546 547void 548Value::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 559ValueType 560Value::type() const 561{ 562 return type_; 563} 564 565 566int 567Value::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 577bool 578Value::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 621bool 622Value::operator <=( const Value &other ) const 623{ 624 return !(other < *this); 625} 626 627bool 628Value::operator >=( const Value &other ) const 629{ 630 return !(*this < other); 631} 632 633bool 634Value::operator >( const Value &other ) const 635{ 636 return other < *this; 637} 638 639bool 640Value::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 683bool 684Value::operator !=( const Value &other ) const 685{ 686 return !( *this == other ); 687} 688 689const char * 690Value::asCString() const 691{ 692 JSON_ASSERT( type_ == stringValue ); 693 return value_.string_; 694} 695 696 697std::string 698Value::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 720CppTL::ConstString 721Value::asConstString() const 722{ 723 return CppTL::ConstString( asString().c_str() ); 724} 725# endif 726 727 728Value::Int 729Value::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 753Value::UInt 754Value::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 780Value::Int64 781Value::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 804Value::UInt64 805Value::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 829LargestInt 830Value::asLargestInt() const 831{ 832#if defined(JSON_NO_INT64) 833 return asInt(); 834#else 835 return asInt64(); 836#endif 837} 838 839 840LargestUInt 841Value::asLargestUInt() const 842{ 843#if defined(JSON_NO_INT64) 844 return asUInt(); 845#else 846 return asUInt64(); 847#endif 848} 849 850 851double 852Value::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 876float 877Value::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 901bool 902Value::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 923bool 924Value::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 971ArrayIndex 972Value::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 1006bool 1007Value::empty() const 1008{ 1009 if ( isNull() || isArray() || isObject() ) 1010 return size() == 0u; 1011 else 1012 return false; 1013} 1014 1015 1016bool 1017Value::operator!() const 1018{ 1019 return isNull(); 1020} 1021 1022 1023void 1024Value::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 1048void 1049Value::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 1074Value & 1075Value::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 1095Value & 1096Value::operator[]( int index ) 1097{ 1098 JSON_ASSERT( index >= 0 ); 1099 return (*this)[ ArrayIndex(index) ]; 1100} 1101 1102 1103const Value & 1104Value::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 1122const Value & 1123Value::operator[]( int index ) const 1124{ 1125 JSON_ASSERT( index >= 0 ); 1126 return (*this)[ ArrayIndex(index) ]; 1127} 1128 1129 1130Value & 1131Value::operator[]( const char *key ) 1132{ 1133 return resolveReference( key, false ); 1134} 1135 1136 1137Value & 1138Value::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 1161Value 1162Value::get( ArrayIndex index, 1163 const Value &defaultValue ) const 1164{ 1165 const Value *value = &((*this)[index]); 1166 return value == &null ? defaultValue : *value; 1167} 1168 1169 1170bool 1171Value::isValidIndex( ArrayIndex index ) const 1172{ 1173 return index < size(); 1174} 1175 1176 1177 1178const Value & 1179Value::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 1197Value & 1198Value::operator[]( const std::string &key ) 1199{ 1200 return (*this)[ key.c_str() ]; 1201} 1202 1203 1204const Value & 1205Value::operator[]( const std::string &key ) const 1206{ 1207 return (*this)[ key.c_str() ]; 1208} 1209 1210Value & 1211Value::operator[]( const StaticString &key ) 1212{ 1213 return resolveReference( key, true ); 1214} 1215 1216 1217# ifdef JSON_USE_CPPTL 1218Value & 1219Value::operator[]( const CppTL::ConstString &key ) 1220{ 1221 return (*this)[ key.c_str() ]; 1222} 1223 1224 1225const Value & 1226Value::operator[]( const CppTL::ConstString &key ) const 1227{ 1228 return (*this)[ key.c_str() ]; 1229} 1230# endif 1231 1232 1233Value & 1234Value::append( const Value &value ) 1235{ 1236 return (*this)[size()] = value; 1237} 1238 1239 1240Value 1241Value::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 1249Value 1250Value::get( const std::string &key, 1251 const Value &defaultValue ) const 1252{ 1253 return get( key.c_str(), defaultValue ); 1254} 1255 1256Value 1257Value::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 1282Value 1283Value::removeMember( const std::string &key ) 1284{ 1285 return removeMember( key.c_str() ); 1286} 1287 1288# ifdef JSON_USE_CPPTL 1289Value 1290Value::get( const CppTL::ConstString &key, 1291 const Value &defaultValue ) const 1292{ 1293 return get( key.c_str(), defaultValue ); 1294} 1295# endif 1296 1297bool 1298Value::isMember( const char *key ) const 1299{ 1300 const Value *value = &((*this)[key]); 1301 return value != &null; 1302} 1303 1304 1305bool 1306Value::isMember( const std::string &key ) const 1307{ 1308 return isMember( key.c_str() ); 1309} 1310 1311 1312# ifdef JSON_USE_CPPTL 1313bool 1314Value::isMember( const CppTL::ConstString &key ) const 1315{ 1316 return isMember( key.c_str() ); 1317} 1318#endif 1319 1320Value::Members 1321Value::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 1369static bool IsIntegral(double d) { 1370 double integral_part; 1371 return modf(d, &integral_part) == 0.0; 1372} 1373 1374 1375bool 1376Value::isNull() const 1377{ 1378 return type_ == nullValue; 1379} 1380 1381 1382bool 1383Value::isBool() const 1384{ 1385 return type_ == booleanValue; 1386} 1387 1388 1389bool 1390Value::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 1409bool 1410Value::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 1428bool 1429Value::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 1452bool 1453Value::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 1477bool 1478Value::isIntegral() const 1479{ 1480#if defined(JSON_HAS_INT64) 1481 return isInt64() || isUInt64(); 1482#else 1483 return isInt() || isUInt(); 1484#endif 1485} 1486 1487 1488bool 1489Value::isDouble() const 1490{ 1491 return type_ == realValue || isIntegral(); 1492} 1493 1494 1495bool 1496Value::isNumeric() const 1497{ 1498 return isIntegral() || isDouble(); 1499} 1500 1501 1502bool 1503Value::isString() const 1504{ 1505 return type_ == stringValue; 1506} 1507 1508 1509bool 1510Value::isArray() const 1511{ 1512 return type_ == arrayValue; 1513} 1514 1515 1516bool 1517Value::isObject() const 1518{ 1519 return type_ == objectValue; 1520} 1521 1522 1523void 1524Value::setComment( const char *comment, 1525 CommentPlacement placement ) 1526{ 1527 if ( !comments_ ) 1528 comments_ = new CommentInfo[numberOfCommentPlacement]; 1529 comments_[placement].setComment( comment ); 1530} 1531 1532 1533void 1534Value::setComment( const std::string &comment, 1535 CommentPlacement placement ) 1536{ 1537 setComment( comment.c_str(), placement ); 1538} 1539 1540 1541bool 1542Value::hasComment( CommentPlacement placement ) const 1543{ 1544 return comments_ != 0 && comments_[placement].comment_ != 0; 1545} 1546 1547std::string 1548Value::getComment( CommentPlacement placement ) const 1549{ 1550 if ( hasComment(placement) ) 1551 return comments_[placement].comment_; 1552 return ""; 1553} 1554 1555 1556std::string 1557Value::toStyledString() const 1558{ 1559 StyledWriter writer; 1560 return writer.write( *this ); 1561} 1562 1563 1564Value::const_iterator 1565Value::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 1599Value::const_iterator 1600Value::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 1635Value::iterator 1636Value::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 1670Value::iterator 1671Value::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 1709PathArgument::PathArgument() 1710 : key_() 1711 , index_() 1712 , kind_( kindNone ) 1713{ 1714} 1715 1716 1717PathArgument::PathArgument( ArrayIndex index ) 1718 : key_() 1719 , index_( index ) 1720 , kind_( kindIndex ) 1721{ 1722} 1723 1724 1725PathArgument::PathArgument( const char *key ) 1726 : key_( key ) 1727 , index_() 1728 , kind_( kindKey ) 1729{ 1730} 1731 1732 1733PathArgument::PathArgument( const std::string &key ) 1734 : key_( key.c_str() ) 1735 , index_() 1736 , kind_( kindKey ) 1737{ 1738} 1739 1740// class Path 1741// ////////////////////////////////////////////////////////////////// 1742 1743Path::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 1760void 1761Path::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 1804void 1805Path::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 1825void 1826Path::invalidPath( const std::string &path, 1827 int location ) 1828{ 1829 // Error: invalid path. 1830} 1831 1832 1833const Value & 1834Path::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 1865Value 1866Path::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 1892Value & 1893Path::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