OLD | NEW |
(Empty) | |
| 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 by 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 : dupl
icate) |
| 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 UI
nt64 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_ == objectV
alue ); |
| 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(i
t) ) |
| 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'; ++cu
rrent ) |
| 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 p
osition...) |
| 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 |
OLD | NEW |