00001
00002
00003
00004
00005
00006 #if !defined(JSON_IS_AMALGAMATION)
00007 # include <json/value.h>
00008 # include <json/writer.h>
00009 # ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
00010 # include "json_batchallocator.h"
00011 # endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
00012 #endif // if !defined(JSON_IS_AMALGAMATION)
00013 #include <iostream>
00014 #include <utility>
00015 #include <stdexcept>
00016 #include <cstring>
00017 #include <cassert>
00018 #ifdef JSON_USE_CPPTL
00019 # include <cpptl/conststring.h>
00020 #endif
00021 #include <cstddef>
00022
00023 #define JSON_ASSERT_UNREACHABLE assert( false )
00024 #define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
00025 #define JSON_FAIL_MESSAGE( message ) throw std::runtime_error( message );
00026 #define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) JSON_FAIL_MESSAGE( message )
00027
00028 namespace Json {
00029
00030 const Value Value::null;
00031 const Int Value::minInt = Int( ~(UInt(-1)/2) );
00032 const Int Value::maxInt = Int( UInt(-1)/2 );
00033 const UInt Value::maxUInt = UInt(-1);
00034 const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) );
00035 const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 );
00036 const UInt64 Value::maxUInt64 = UInt64(-1);
00037 const LargestInt Value::minLargestInt = LargestInt( ~(LargestUInt(-1)/2) );
00038 const LargestInt Value::maxLargestInt = LargestInt( LargestUInt(-1)/2 );
00039 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
00040
00041
00043 static const unsigned int unknown = (unsigned)-1;
00044
00045
00053 static inline char *
00054 duplicateStringValue( const char *value,
00055 unsigned int length = unknown )
00056 {
00057 if ( length == unknown )
00058 length = (unsigned int)strlen(value);
00059 char *newString = static_cast<char *>( malloc( length + 1 ) );
00060 JSON_ASSERT_MESSAGE( newString != 0, "Failed to allocate string value buffer" );
00061 memcpy( newString, value, length );
00062 newString[length] = 0;
00063 return newString;
00064 }
00065
00066
00069 static inline void
00070 releaseStringValue( char *value )
00071 {
00072 if ( value )
00073 free( value );
00074 }
00075
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #if !defined(JSON_IS_AMALGAMATION)
00087 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00088 # include "json_internalarray.inl"
00089 # include "json_internalmap.inl"
00090 # endif // JSON_VALUE_USE_INTERNAL_MAP
00091
00092 # include "json_valueiterator.inl"
00093 #endif // if !defined(JSON_IS_AMALGAMATION)
00094
00095 namespace Json {
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 Value::CommentInfo::CommentInfo()
00107 : comment_( 0 )
00108 {
00109 }
00110
00111 Value::CommentInfo::~CommentInfo()
00112 {
00113 if ( comment_ )
00114 releaseStringValue( comment_ );
00115 }
00116
00117
00118 void
00119 Value::CommentInfo::setComment( const char *text )
00120 {
00121 if ( comment_ )
00122 releaseStringValue( comment_ );
00123 JSON_ASSERT( text != 0 );
00124 JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
00125
00126 comment_ = duplicateStringValue( text );
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 # ifndef JSON_VALUE_USE_INTERNAL_MAP
00138
00139
00140
00141
00142 Value::CZString::CZString( ArrayIndex index )
00143 : cstr_( 0 )
00144 , index_( index )
00145 {
00146 }
00147
00148 Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
00149 : cstr_( allocate == duplicate ? duplicateStringValue(cstr)
00150 : cstr )
00151 , index_( allocate )
00152 {
00153 }
00154
00155 Value::CZString::CZString( const CZString &other )
00156 : cstr_( other.index_ != noDuplication && other.cstr_ != 0
00157 ? duplicateStringValue( other.cstr_ )
00158 : other.cstr_ )
00159 , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
00160 : other.index_ )
00161 {
00162 }
00163
00164 Value::CZString::~CZString()
00165 {
00166 if ( cstr_ && index_ == duplicate )
00167 releaseStringValue( const_cast<char *>( cstr_ ) );
00168 }
00169
00170 void
00171 Value::CZString::swap( CZString &other )
00172 {
00173 std::swap( cstr_, other.cstr_ );
00174 std::swap( index_, other.index_ );
00175 }
00176
00177 Value::CZString &
00178 Value::CZString::operator =( const CZString &other )
00179 {
00180 CZString temp( other );
00181 swap( temp );
00182 return *this;
00183 }
00184
00185 bool
00186 Value::CZString::operator<( const CZString &other ) const
00187 {
00188 if ( cstr_ )
00189 return strcmp( cstr_, other.cstr_ ) < 0;
00190 return index_ < other.index_;
00191 }
00192
00193 bool
00194 Value::CZString::operator==( const CZString &other ) const
00195 {
00196 if ( cstr_ )
00197 return strcmp( cstr_, other.cstr_ ) == 0;
00198 return index_ == other.index_;
00199 }
00200
00201
00202 ArrayIndex
00203 Value::CZString::index() const
00204 {
00205 return index_;
00206 }
00207
00208
00209 const char *
00210 Value::CZString::c_str() const
00211 {
00212 return cstr_;
00213 }
00214
00215 bool
00216 Value::CZString::isStaticString() const
00217 {
00218 return index_ == noDuplication;
00219 }
00220
00221 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00236 Value::Value( ValueType type )
00237 : type_( type )
00238 , allocated_( 0 )
00239 , comments_( 0 )
00240 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00241 , itemIsUsed_( 0 )
00242 #endif
00243 {
00244 switch ( type )
00245 {
00246 case nullValue:
00247 break;
00248 case intValue:
00249 case uintValue:
00250 value_.int_ = 0;
00251 break;
00252 case realValue:
00253 value_.real_ = 0.0;
00254 break;
00255 case stringValue:
00256 value_.string_ = 0;
00257 break;
00258 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00259 case arrayValue:
00260 case objectValue:
00261 value_.map_ = new ObjectValues();
00262 break;
00263 #else
00264 case arrayValue:
00265 value_.array_ = arrayAllocator()->newArray();
00266 break;
00267 case objectValue:
00268 value_.map_ = mapAllocator()->newMap();
00269 break;
00270 #endif
00271 case booleanValue:
00272 value_.bool_ = false;
00273 break;
00274 default:
00275 JSON_ASSERT_UNREACHABLE;
00276 }
00277 }
00278
00279
00280 #if defined(JSON_HAS_INT64)
00281 Value::Value( UInt value )
00282 : type_( uintValue )
00283 , comments_( 0 )
00284 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00285 , itemIsUsed_( 0 )
00286 #endif
00287 {
00288 value_.uint_ = value;
00289 }
00290
00291 Value::Value( Int value )
00292 : type_( intValue )
00293 , comments_( 0 )
00294 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00295 , itemIsUsed_( 0 )
00296 #endif
00297 {
00298 value_.int_ = value;
00299 }
00300
00301 #endif // if defined(JSON_HAS_INT64)
00302
00303
00304 Value::Value( Int64 value )
00305 : type_( intValue )
00306 , comments_( 0 )
00307 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00308 , itemIsUsed_( 0 )
00309 #endif
00310 {
00311 value_.int_ = value;
00312 }
00313
00314
00315 Value::Value( UInt64 value )
00316 : type_( uintValue )
00317 , comments_( 0 )
00318 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00319 , itemIsUsed_( 0 )
00320 #endif
00321 {
00322 value_.uint_ = value;
00323 }
00324
00325 Value::Value( double value )
00326 : type_( realValue )
00327 , comments_( 0 )
00328 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00329 , itemIsUsed_( 0 )
00330 #endif
00331 {
00332 value_.real_ = value;
00333 }
00334
00335 Value::Value( const char *value )
00336 : type_( stringValue )
00337 , allocated_( true )
00338 , comments_( 0 )
00339 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00340 , itemIsUsed_( 0 )
00341 #endif
00342 {
00343 value_.string_ = duplicateStringValue( value );
00344 }
00345
00346
00347 Value::Value( const char *beginValue,
00348 const char *endValue )
00349 : type_( stringValue )
00350 , allocated_( true )
00351 , comments_( 0 )
00352 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00353 , itemIsUsed_( 0 )
00354 #endif
00355 {
00356 value_.string_ = duplicateStringValue( beginValue,
00357 (unsigned int)(endValue - beginValue) );
00358 }
00359
00360
00361 Value::Value( const std::string &value )
00362 : type_( stringValue )
00363 , allocated_( true )
00364 , comments_( 0 )
00365 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00366 , itemIsUsed_( 0 )
00367 #endif
00368 {
00369 value_.string_ = duplicateStringValue( value.c_str(),
00370 (unsigned int)value.length() );
00371
00372 }
00373
00374 Value::Value( const StaticString &value )
00375 : type_( stringValue )
00376 , allocated_( false )
00377 , comments_( 0 )
00378 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00379 , itemIsUsed_( 0 )
00380 #endif
00381 {
00382 value_.string_ = const_cast<char *>( value.c_str() );
00383 }
00384
00385
00386 # ifdef JSON_USE_CPPTL
00387 Value::Value( const CppTL::ConstString &value )
00388 : type_( stringValue )
00389 , allocated_( true )
00390 , comments_( 0 )
00391 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00392 , itemIsUsed_( 0 )
00393 #endif
00394 {
00395 value_.string_ = duplicateStringValue( value, value.length() );
00396 }
00397 # endif
00398
00399 Value::Value( bool value )
00400 : type_( booleanValue )
00401 , comments_( 0 )
00402 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00403 , itemIsUsed_( 0 )
00404 #endif
00405 {
00406 value_.bool_ = value;
00407 }
00408
00409
00410 Value::Value( const Value &other )
00411 : type_( other.type_ )
00412 , comments_( 0 )
00413 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00414 , itemIsUsed_( 0 )
00415 #endif
00416 {
00417 switch ( type_ )
00418 {
00419 case nullValue:
00420 case intValue:
00421 case uintValue:
00422 case realValue:
00423 case booleanValue:
00424 value_ = other.value_;
00425 break;
00426 case stringValue:
00427 if ( other.value_.string_ )
00428 {
00429 value_.string_ = duplicateStringValue( other.value_.string_ );
00430 allocated_ = true;
00431 }
00432 else
00433 value_.string_ = 0;
00434 break;
00435 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00436 case arrayValue:
00437 case objectValue:
00438 value_.map_ = new ObjectValues( *other.value_.map_ );
00439 break;
00440 #else
00441 case arrayValue:
00442 value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
00443 break;
00444 case objectValue:
00445 value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
00446 break;
00447 #endif
00448 default:
00449 JSON_ASSERT_UNREACHABLE;
00450 }
00451 if ( other.comments_ )
00452 {
00453 comments_ = new CommentInfo[numberOfCommentPlacement];
00454 for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
00455 {
00456 const CommentInfo &otherComment = other.comments_[comment];
00457 if ( otherComment.comment_ )
00458 comments_[comment].setComment( otherComment.comment_ );
00459 }
00460 }
00461 }
00462
00463
00464 Value::~Value()
00465 {
00466 switch ( type_ )
00467 {
00468 case nullValue:
00469 case intValue:
00470 case uintValue:
00471 case realValue:
00472 case booleanValue:
00473 break;
00474 case stringValue:
00475 if ( allocated_ )
00476 releaseStringValue( value_.string_ );
00477 break;
00478 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00479 case arrayValue:
00480 case objectValue:
00481 delete value_.map_;
00482 break;
00483 #else
00484 case arrayValue:
00485 arrayAllocator()->destructArray( value_.array_ );
00486 break;
00487 case objectValue:
00488 mapAllocator()->destructMap( value_.map_ );
00489 break;
00490 #endif
00491 default:
00492 JSON_ASSERT_UNREACHABLE;
00493 }
00494
00495 if ( comments_ )
00496 delete[] comments_;
00497 }
00498
00499 Value &
00500 Value::operator=( const Value &other )
00501 {
00502 Value temp( other );
00503 swap( temp );
00504 return *this;
00505 }
00506
00507 void
00508 Value::swap( Value &other )
00509 {
00510 ValueType temp = type_;
00511 type_ = other.type_;
00512 other.type_ = temp;
00513 std::swap( value_, other.value_ );
00514 int temp2 = allocated_;
00515 allocated_ = other.allocated_;
00516 other.allocated_ = temp2;
00517 }
00518
00519 ValueType
00520 Value::type() const
00521 {
00522 return type_;
00523 }
00524
00525
00526 int
00527 Value::compare( const Value &other ) const
00528 {
00529 if ( *this < other )
00530 return -1;
00531 if ( *this > other )
00532 return 1;
00533 return 0;
00534 }
00535
00536
00537 bool
00538 Value::operator <( const Value &other ) const
00539 {
00540 int typeDelta = type_ - other.type_;
00541 if ( typeDelta )
00542 return typeDelta < 0 ? true : false;
00543 switch ( type_ )
00544 {
00545 case nullValue:
00546 return false;
00547 case intValue:
00548 return value_.int_ < other.value_.int_;
00549 case uintValue:
00550 return value_.uint_ < other.value_.uint_;
00551 case realValue:
00552 return value_.real_ < other.value_.real_;
00553 case booleanValue:
00554 return value_.bool_ < other.value_.bool_;
00555 case stringValue:
00556 return ( value_.string_ == 0 && other.value_.string_ )
00557 || ( other.value_.string_
00558 && value_.string_
00559 && strcmp( value_.string_, other.value_.string_ ) < 0 );
00560 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00561 case arrayValue:
00562 case objectValue:
00563 {
00564 int delta = int( value_.map_->size() - other.value_.map_->size() );
00565 if ( delta )
00566 return delta < 0;
00567 return (*value_.map_) < (*other.value_.map_);
00568 }
00569 #else
00570 case arrayValue:
00571 return value_.array_->compare( *(other.value_.array_) ) < 0;
00572 case objectValue:
00573 return value_.map_->compare( *(other.value_.map_) ) < 0;
00574 #endif
00575 default:
00576 JSON_ASSERT_UNREACHABLE;
00577 }
00578 return false;
00579 }
00580
00581 bool
00582 Value::operator <=( const Value &other ) const
00583 {
00584 return !(other < *this);
00585 }
00586
00587 bool
00588 Value::operator >=( const Value &other ) const
00589 {
00590 return !(*this < other);
00591 }
00592
00593 bool
00594 Value::operator >( const Value &other ) const
00595 {
00596 return other < *this;
00597 }
00598
00599 bool
00600 Value::operator ==( const Value &other ) const
00601 {
00602
00603
00604
00605
00606 int temp = other.type_;
00607 if ( type_ != temp )
00608 return false;
00609 switch ( type_ )
00610 {
00611 case nullValue:
00612 return true;
00613 case intValue:
00614 return value_.int_ == other.value_.int_;
00615 case uintValue:
00616 return value_.uint_ == other.value_.uint_;
00617 case realValue:
00618 return value_.real_ == other.value_.real_;
00619 case booleanValue:
00620 return value_.bool_ == other.value_.bool_;
00621 case stringValue:
00622 return ( value_.string_ == other.value_.string_ )
00623 || ( other.value_.string_
00624 && value_.string_
00625 && strcmp( value_.string_, other.value_.string_ ) == 0 );
00626 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00627 case arrayValue:
00628 case objectValue:
00629 return value_.map_->size() == other.value_.map_->size()
00630 && (*value_.map_) == (*other.value_.map_);
00631 #else
00632 case arrayValue:
00633 return value_.array_->compare( *(other.value_.array_) ) == 0;
00634 case objectValue:
00635 return value_.map_->compare( *(other.value_.map_) ) == 0;
00636 #endif
00637 default:
00638 JSON_ASSERT_UNREACHABLE;
00639 }
00640 return false;
00641 }
00642
00643 bool
00644 Value::operator !=( const Value &other ) const
00645 {
00646 return !( *this == other );
00647 }
00648
00649 const char *
00650 Value::asCString() const
00651 {
00652 JSON_ASSERT( type_ == stringValue );
00653 return value_.string_;
00654 }
00655
00656
00657 std::string
00658 Value::asString() const
00659 {
00660 switch ( type_ )
00661 {
00662 case nullValue:
00663 return "";
00664 case stringValue:
00665 return value_.string_ ? value_.string_ : "";
00666 case booleanValue:
00667 return value_.bool_ ? "true" : "false";
00668 case intValue:
00669 case uintValue:
00670 case realValue:
00671 case arrayValue:
00672 case objectValue:
00673 JSON_FAIL_MESSAGE( "Type is not convertible to string" );
00674 default:
00675 JSON_ASSERT_UNREACHABLE;
00676 }
00677 return "";
00678 }
00679
00680 # ifdef JSON_USE_CPPTL
00681 CppTL::ConstString
00682 Value::asConstString() const
00683 {
00684 return CppTL::ConstString( asString().c_str() );
00685 }
00686 # endif
00687
00688
00689 Value::Int
00690 Value::asInt() const
00691 {
00692 switch ( type_ )
00693 {
00694 case nullValue:
00695 return 0;
00696 case intValue:
00697 JSON_ASSERT_MESSAGE( value_.int_ >= minInt && value_.int_ <= maxInt, "unsigned integer out of signed int range" );
00698 return Int(value_.int_);
00699 case uintValue:
00700 JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" );
00701 return Int(value_.uint_);
00702 case realValue:
00703 JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
00704 return Int( value_.real_ );
00705 case booleanValue:
00706 return value_.bool_ ? 1 : 0;
00707 case stringValue:
00708 case arrayValue:
00709 case objectValue:
00710 JSON_FAIL_MESSAGE( "Type is not convertible to int" );
00711 default:
00712 JSON_ASSERT_UNREACHABLE;
00713 }
00714 return 0;
00715 }
00716
00717
00718 Value::UInt
00719 Value::asUInt() const
00720 {
00721 switch ( type_ )
00722 {
00723 case nullValue:
00724 return 0;
00725 case intValue:
00726 JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
00727 JSON_ASSERT_MESSAGE( value_.int_ <= maxUInt, "signed integer out of UInt range" );
00728 return UInt(value_.int_);
00729 case uintValue:
00730 JSON_ASSERT_MESSAGE( value_.uint_ <= maxUInt, "unsigned integer out of UInt range" );
00731 return UInt(value_.uint_);
00732 case realValue:
00733 JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
00734 return UInt( value_.real_ );
00735 case booleanValue:
00736 return value_.bool_ ? 1 : 0;
00737 case stringValue:
00738 case arrayValue:
00739 case objectValue:
00740 JSON_FAIL_MESSAGE( "Type is not convertible to uint" );
00741 default:
00742 JSON_ASSERT_UNREACHABLE;
00743 }
00744 return 0;
00745 }
00746
00747
00748 # if defined(JSON_HAS_INT64)
00749
00750 Value::Int64
00751 Value::asInt64() const
00752 {
00753 switch ( type_ )
00754 {
00755 case nullValue:
00756 return 0;
00757 case intValue:
00758 return value_.int_;
00759 case uintValue:
00760 JSON_ASSERT_MESSAGE( value_.uint_ <= UInt64(maxInt64), "unsigned integer out of Int64 range" );
00761 return value_.uint_;
00762 case realValue:
00763 JSON_ASSERT_MESSAGE( value_.real_ >= minInt64 && value_.real_ <= maxInt64, "Real out of Int64 range" );
00764 return Int( value_.real_ );
00765 case booleanValue:
00766 return value_.bool_ ? 1 : 0;
00767 case stringValue:
00768 case arrayValue:
00769 case objectValue:
00770 JSON_FAIL_MESSAGE( "Type is not convertible to Int64" );
00771 default:
00772 JSON_ASSERT_UNREACHABLE;
00773 }
00774 return 0;
00775 }
00776
00777
00778 Value::UInt64
00779 Value::asUInt64() const
00780 {
00781 switch ( type_ )
00782 {
00783 case nullValue:
00784 return 0;
00785 case intValue:
00786 JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to UInt64" );
00787 return value_.int_;
00788 case uintValue:
00789 return value_.uint_;
00790 case realValue:
00791 JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt64, "Real out of UInt64 range" );
00792 return UInt( value_.real_ );
00793 case booleanValue:
00794 return value_.bool_ ? 1 : 0;
00795 case stringValue:
00796 case arrayValue:
00797 case objectValue:
00798 JSON_FAIL_MESSAGE( "Type is not convertible to UInt64" );
00799 default:
00800 JSON_ASSERT_UNREACHABLE;
00801 }
00802 return 0;
00803 }
00804 # endif // if defined(JSON_HAS_INT64)
00805
00806
00807 LargestInt
00808 Value::asLargestInt() const
00809 {
00810 #if defined(JSON_NO_INT64)
00811 return asInt();
00812 #else
00813 return asInt64();
00814 #endif
00815 }
00816
00817
00818 LargestUInt
00819 Value::asLargestUInt() const
00820 {
00821 #if defined(JSON_NO_INT64)
00822 return asUInt();
00823 #else
00824 return asUInt64();
00825 #endif
00826 }
00827
00828
00829 double
00830 Value::asDouble() const
00831 {
00832 switch ( type_ )
00833 {
00834 case nullValue:
00835 return 0.0;
00836 case intValue:
00837 return static_cast<double>( value_.int_ );
00838 case uintValue:
00839 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00840 return static_cast<double>( value_.uint_ );
00841 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00842 return static_cast<double>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
00843 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00844 case realValue:
00845 return value_.real_;
00846 case booleanValue:
00847 return value_.bool_ ? 1.0 : 0.0;
00848 case stringValue:
00849 case arrayValue:
00850 case objectValue:
00851 JSON_FAIL_MESSAGE( "Type is not convertible to double" );
00852 default:
00853 JSON_ASSERT_UNREACHABLE;
00854 }
00855 return 0;
00856 }
00857
00858 float
00859 Value::asFloat() const
00860 {
00861 switch ( type_ )
00862 {
00863 case nullValue:
00864 return 0.0f;
00865 case intValue:
00866 return static_cast<float>( value_.int_ );
00867 case uintValue:
00868 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00869 return static_cast<float>( value_.uint_ );
00870 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00871 return static_cast<float>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
00872 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
00873 case realValue:
00874 return static_cast<float>( value_.real_ );
00875 case booleanValue:
00876 return value_.bool_ ? 1.0f : 0.0f;
00877 case stringValue:
00878 case arrayValue:
00879 case objectValue:
00880 JSON_FAIL_MESSAGE( "Type is not convertible to float" );
00881 default:
00882 JSON_ASSERT_UNREACHABLE;
00883 }
00884 return 0.0f;
00885 }
00886
00887 bool
00888 Value::asBool() const
00889 {
00890 switch ( type_ )
00891 {
00892 case nullValue:
00893 return false;
00894 case intValue:
00895 case uintValue:
00896 return value_.int_ != 0;
00897 case realValue:
00898 return value_.real_ != 0.0;
00899 case booleanValue:
00900 return value_.bool_;
00901 case stringValue:
00902 return value_.string_ && value_.string_[0] != 0;
00903 case arrayValue:
00904 case objectValue:
00905 return value_.map_->size() != 0;
00906 default:
00907 JSON_ASSERT_UNREACHABLE;
00908 }
00909 return false;
00910 }
00911
00912
00913 bool
00914 Value::isConvertibleTo( ValueType other ) const
00915 {
00916 switch ( type_ )
00917 {
00918 case nullValue:
00919 return true;
00920 case intValue:
00921 return ( other == nullValue && value_.int_ == 0 )
00922 || other == intValue
00923 || ( other == uintValue && value_.int_ >= 0 )
00924 || other == realValue
00925 || other == stringValue
00926 || other == booleanValue;
00927 case uintValue:
00928 return ( other == nullValue && value_.uint_ == 0 )
00929 || ( other == intValue && value_.uint_ <= (unsigned)maxInt )
00930 || other == uintValue
00931 || other == realValue
00932 || other == stringValue
00933 || other == booleanValue;
00934 case realValue:
00935 return ( other == nullValue && value_.real_ == 0.0 )
00936 || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
00937 || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
00938 || other == realValue
00939 || other == stringValue
00940 || other == booleanValue;
00941 case booleanValue:
00942 return ( other == nullValue && value_.bool_ == false )
00943 || other == intValue
00944 || other == uintValue
00945 || other == realValue
00946 || other == stringValue
00947 || other == booleanValue;
00948 case stringValue:
00949 return other == stringValue
00950 || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
00951 case arrayValue:
00952 return other == arrayValue
00953 || ( other == nullValue && value_.map_->size() == 0 );
00954 case objectValue:
00955 return other == objectValue
00956 || ( other == nullValue && value_.map_->size() == 0 );
00957 default:
00958 JSON_ASSERT_UNREACHABLE;
00959 }
00960 return false;
00961 }
00962
00963
00965 ArrayIndex
00966 Value::size() const
00967 {
00968 switch ( type_ )
00969 {
00970 case nullValue:
00971 case intValue:
00972 case uintValue:
00973 case realValue:
00974 case booleanValue:
00975 case stringValue:
00976 return 0;
00977 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00978 case arrayValue:
00979 if ( !value_.map_->empty() )
00980 {
00981 ObjectValues::const_iterator itLast = value_.map_->end();
00982 --itLast;
00983 return (*itLast).first.index()+1;
00984 }
00985 return 0;
00986 case objectValue:
00987 return ArrayIndex( value_.map_->size() );
00988 #else
00989 case arrayValue:
00990 return Int( value_.array_->size() );
00991 case objectValue:
00992 return Int( value_.map_->size() );
00993 #endif
00994 default:
00995 JSON_ASSERT_UNREACHABLE;
00996 }
00997 return 0;
00998 }
00999
01000
01001 bool
01002 Value::empty() const
01003 {
01004 if ( isNull() || isArray() || isObject() )
01005 return size() == 0u;
01006 else
01007 return false;
01008 }
01009
01010
01011 bool
01012 Value::operator!() const
01013 {
01014 return isNull();
01015 }
01016
01017
01018 void
01019 Value::clear()
01020 {
01021 JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue );
01022
01023 switch ( type_ )
01024 {
01025 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01026 case arrayValue:
01027 case objectValue:
01028 value_.map_->clear();
01029 break;
01030 #else
01031 case arrayValue:
01032 value_.array_->clear();
01033 break;
01034 case objectValue:
01035 value_.map_->clear();
01036 break;
01037 #endif
01038 default:
01039 break;
01040 }
01041 }
01042
01043 void
01044 Value::resize( ArrayIndex newSize )
01045 {
01046 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
01047 if ( type_ == nullValue )
01048 *this = Value( arrayValue );
01049 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01050 ArrayIndex oldSize = size();
01051 if ( newSize == 0 )
01052 clear();
01053 else if ( newSize > oldSize )
01054 (*this)[ newSize - 1 ];
01055 else
01056 {
01057 for ( ArrayIndex index = newSize; index < oldSize; ++index )
01058 {
01059 value_.map_->erase( index );
01060 }
01061 assert( size() == newSize );
01062 }
01063 #else
01064 value_.array_->resize( newSize );
01065 #endif
01066 }
01067
01068
01069 Value &
01070 Value::operator[]( ArrayIndex index )
01071 {
01072 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
01073 if ( type_ == nullValue )
01074 *this = Value( arrayValue );
01075 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01076 CZString key( index );
01077 ObjectValues::iterator it = value_.map_->lower_bound( key );
01078 if ( it != value_.map_->end() && (*it).first == key )
01079 return (*it).second;
01080
01081 ObjectValues::value_type defaultValue( key, null );
01082 it = value_.map_->insert( it, defaultValue );
01083 return (*it).second;
01084 #else
01085 return value_.array_->resolveReference( index );
01086 #endif
01087 }
01088
01089
01090 Value &
01091 Value::operator[]( int index )
01092 {
01093 JSON_ASSERT( index >= 0 );
01094 return (*this)[ ArrayIndex(index) ];
01095 }
01096
01097
01098 const Value &
01099 Value::operator[]( ArrayIndex index ) const
01100 {
01101 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
01102 if ( type_ == nullValue )
01103 return null;
01104 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01105 CZString key( index );
01106 ObjectValues::const_iterator it = value_.map_->find( key );
01107 if ( it == value_.map_->end() )
01108 return null;
01109 return (*it).second;
01110 #else
01111 Value *value = value_.array_->find( index );
01112 return value ? *value : null;
01113 #endif
01114 }
01115
01116
01117 const Value &
01118 Value::operator[]( int index ) const
01119 {
01120 JSON_ASSERT( index >= 0 );
01121 return (*this)[ ArrayIndex(index) ];
01122 }
01123
01124
01125 Value &
01126 Value::operator[]( const char *key )
01127 {
01128 return resolveReference( key, false );
01129 }
01130
01131
01132 Value &
01133 Value::resolveReference( const char *key,
01134 bool isStatic )
01135 {
01136 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
01137 if ( type_ == nullValue )
01138 *this = Value( objectValue );
01139 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01140 CZString actualKey( key, isStatic ? CZString::noDuplication
01141 : CZString::duplicateOnCopy );
01142 ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
01143 if ( it != value_.map_->end() && (*it).first == actualKey )
01144 return (*it).second;
01145
01146 ObjectValues::value_type defaultValue( actualKey, null );
01147 it = value_.map_->insert( it, defaultValue );
01148 Value &value = (*it).second;
01149 return value;
01150 #else
01151 return value_.map_->resolveReference( key, isStatic );
01152 #endif
01153 }
01154
01155
01156 Value
01157 Value::get( ArrayIndex index,
01158 const Value &defaultValue ) const
01159 {
01160 const Value *value = &((*this)[index]);
01161 return value == &null ? defaultValue : *value;
01162 }
01163
01164
01165 bool
01166 Value::isValidIndex( ArrayIndex index ) const
01167 {
01168 return index < size();
01169 }
01170
01171
01172
01173 const Value &
01174 Value::operator[]( const char *key ) const
01175 {
01176 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
01177 if ( type_ == nullValue )
01178 return null;
01179 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01180 CZString actualKey( key, CZString::noDuplication );
01181 ObjectValues::const_iterator it = value_.map_->find( actualKey );
01182 if ( it == value_.map_->end() )
01183 return null;
01184 return (*it).second;
01185 #else
01186 const Value *value = value_.map_->find( key );
01187 return value ? *value : null;
01188 #endif
01189 }
01190
01191
01192 Value &
01193 Value::operator[]( const std::string &key )
01194 {
01195 return (*this)[ key.c_str() ];
01196 }
01197
01198
01199 const Value &
01200 Value::operator[]( const std::string &key ) const
01201 {
01202 return (*this)[ key.c_str() ];
01203 }
01204
01205 Value &
01206 Value::operator[]( const StaticString &key )
01207 {
01208 return resolveReference( key, true );
01209 }
01210
01211
01212 # ifdef JSON_USE_CPPTL
01213 Value &
01214 Value::operator[]( const CppTL::ConstString &key )
01215 {
01216 return (*this)[ key.c_str() ];
01217 }
01218
01219
01220 const Value &
01221 Value::operator[]( const CppTL::ConstString &key ) const
01222 {
01223 return (*this)[ key.c_str() ];
01224 }
01225 # endif
01226
01227
01228 Value &
01229 Value::append( const Value &value )
01230 {
01231 return (*this)[size()] = value;
01232 }
01233
01234
01235 Value
01236 Value::get( const char *key,
01237 const Value &defaultValue ) const
01238 {
01239 const Value *value = &((*this)[key]);
01240 return value == &null ? defaultValue : *value;
01241 }
01242
01243
01244 Value
01245 Value::get( const std::string &key,
01246 const Value &defaultValue ) const
01247 {
01248 return get( key.c_str(), defaultValue );
01249 }
01250
01251 Value
01252 Value::removeMember( const char* key )
01253 {
01254 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
01255 if ( type_ == nullValue )
01256 return null;
01257 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01258 CZString actualKey( key, CZString::noDuplication );
01259 ObjectValues::iterator it = value_.map_->find( actualKey );
01260 if ( it == value_.map_->end() )
01261 return null;
01262 Value old(it->second);
01263 value_.map_->erase(it);
01264 return old;
01265 #else
01266 Value *value = value_.map_->find( key );
01267 if (value){
01268 Value old(*value);
01269 value_.map_.remove( key );
01270 return old;
01271 } else {
01272 return null;
01273 }
01274 #endif
01275 }
01276
01277 Value
01278 Value::removeMember( const std::string &key )
01279 {
01280 return removeMember( key.c_str() );
01281 }
01282
01283 # ifdef JSON_USE_CPPTL
01284 Value
01285 Value::get( const CppTL::ConstString &key,
01286 const Value &defaultValue ) const
01287 {
01288 return get( key.c_str(), defaultValue );
01289 }
01290 # endif
01291
01292 bool
01293 Value::isMember( const char *key ) const
01294 {
01295 const Value *value = &((*this)[key]);
01296 return value != &null;
01297 }
01298
01299
01300 bool
01301 Value::isMember( const std::string &key ) const
01302 {
01303 return isMember( key.c_str() );
01304 }
01305
01306
01307 # ifdef JSON_USE_CPPTL
01308 bool
01309 Value::isMember( const CppTL::ConstString &key ) const
01310 {
01311 return isMember( key.c_str() );
01312 }
01313 #endif
01314
01315 Value::Members
01316 Value::getMemberNames() const
01317 {
01318 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
01319 if ( type_ == nullValue )
01320 return Value::Members();
01321 Members members;
01322 members.reserve( value_.map_->size() );
01323 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01324 ObjectValues::const_iterator it = value_.map_->begin();
01325 ObjectValues::const_iterator itEnd = value_.map_->end();
01326 for ( ; it != itEnd; ++it )
01327 members.push_back( std::string( (*it).first.c_str() ) );
01328 #else
01329 ValueInternalMap::IteratorState it;
01330 ValueInternalMap::IteratorState itEnd;
01331 value_.map_->makeBeginIterator( it );
01332 value_.map_->makeEndIterator( itEnd );
01333 for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
01334 members.push_back( std::string( ValueInternalMap::key( it ) ) );
01335 #endif
01336 return members;
01337 }
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 bool
01366 Value::isNull() const
01367 {
01368 return type_ == nullValue;
01369 }
01370
01371
01372 bool
01373 Value::isBool() const
01374 {
01375 return type_ == booleanValue;
01376 }
01377
01378
01379 bool
01380 Value::isInt() const
01381 {
01382 return type_ == intValue;
01383 }
01384
01385
01386 bool
01387 Value::isUInt() const
01388 {
01389 return type_ == uintValue;
01390 }
01391
01392
01393 bool
01394 Value::isIntegral() const
01395 {
01396 return type_ == intValue
01397 || type_ == uintValue
01398 || type_ == booleanValue;
01399 }
01400
01401
01402 bool
01403 Value::isDouble() const
01404 {
01405 return type_ == realValue;
01406 }
01407
01408
01409 bool
01410 Value::isNumeric() const
01411 {
01412 return isIntegral() || isDouble();
01413 }
01414
01415
01416 bool
01417 Value::isString() const
01418 {
01419 return type_ == stringValue;
01420 }
01421
01422
01423 bool
01424 Value::isArray() const
01425 {
01426 return type_ == nullValue || type_ == arrayValue;
01427 }
01428
01429
01430 bool
01431 Value::isObject() const
01432 {
01433 return type_ == nullValue || type_ == objectValue;
01434 }
01435
01436
01437 void
01438 Value::setComment( const char *comment,
01439 CommentPlacement placement )
01440 {
01441 if ( !comments_ )
01442 comments_ = new CommentInfo[numberOfCommentPlacement];
01443 comments_[placement].setComment( comment );
01444 }
01445
01446
01447 void
01448 Value::setComment( const std::string &comment,
01449 CommentPlacement placement )
01450 {
01451 setComment( comment.c_str(), placement );
01452 }
01453
01454
01455 bool
01456 Value::hasComment( CommentPlacement placement ) const
01457 {
01458 return comments_ != 0 && comments_[placement].comment_ != 0;
01459 }
01460
01461 std::string
01462 Value::getComment( CommentPlacement placement ) const
01463 {
01464 if ( hasComment(placement) )
01465 return comments_[placement].comment_;
01466 return "";
01467 }
01468
01469
01470 std::string
01471 Value::toStyledString() const
01472 {
01473 StyledWriter writer;
01474 return writer.write( *this );
01475 }
01476
01477
01478 Value::const_iterator
01479 Value::begin() const
01480 {
01481 switch ( type_ )
01482 {
01483 #ifdef JSON_VALUE_USE_INTERNAL_MAP
01484 case arrayValue:
01485 if ( value_.array_ )
01486 {
01487 ValueInternalArray::IteratorState it;
01488 value_.array_->makeBeginIterator( it );
01489 return const_iterator( it );
01490 }
01491 break;
01492 case objectValue:
01493 if ( value_.map_ )
01494 {
01495 ValueInternalMap::IteratorState it;
01496 value_.map_->makeBeginIterator( it );
01497 return const_iterator( it );
01498 }
01499 break;
01500 #else
01501 case arrayValue:
01502 case objectValue:
01503 if ( value_.map_ )
01504 return const_iterator( value_.map_->begin() );
01505 break;
01506 #endif
01507 default:
01508 break;
01509 }
01510 return const_iterator();
01511 }
01512
01513 Value::const_iterator
01514 Value::end() const
01515 {
01516 switch ( type_ )
01517 {
01518 #ifdef JSON_VALUE_USE_INTERNAL_MAP
01519 case arrayValue:
01520 if ( value_.array_ )
01521 {
01522 ValueInternalArray::IteratorState it;
01523 value_.array_->makeEndIterator( it );
01524 return const_iterator( it );
01525 }
01526 break;
01527 case objectValue:
01528 if ( value_.map_ )
01529 {
01530 ValueInternalMap::IteratorState it;
01531 value_.map_->makeEndIterator( it );
01532 return const_iterator( it );
01533 }
01534 break;
01535 #else
01536 case arrayValue:
01537 case objectValue:
01538 if ( value_.map_ )
01539 return const_iterator( value_.map_->end() );
01540 break;
01541 #endif
01542 default:
01543 break;
01544 }
01545 return const_iterator();
01546 }
01547
01548
01549 Value::iterator
01550 Value::begin()
01551 {
01552 switch ( type_ )
01553 {
01554 #ifdef JSON_VALUE_USE_INTERNAL_MAP
01555 case arrayValue:
01556 if ( value_.array_ )
01557 {
01558 ValueInternalArray::IteratorState it;
01559 value_.array_->makeBeginIterator( it );
01560 return iterator( it );
01561 }
01562 break;
01563 case objectValue:
01564 if ( value_.map_ )
01565 {
01566 ValueInternalMap::IteratorState it;
01567 value_.map_->makeBeginIterator( it );
01568 return iterator( it );
01569 }
01570 break;
01571 #else
01572 case arrayValue:
01573 case objectValue:
01574 if ( value_.map_ )
01575 return iterator( value_.map_->begin() );
01576 break;
01577 #endif
01578 default:
01579 break;
01580 }
01581 return iterator();
01582 }
01583
01584 Value::iterator
01585 Value::end()
01586 {
01587 switch ( type_ )
01588 {
01589 #ifdef JSON_VALUE_USE_INTERNAL_MAP
01590 case arrayValue:
01591 if ( value_.array_ )
01592 {
01593 ValueInternalArray::IteratorState it;
01594 value_.array_->makeEndIterator( it );
01595 return iterator( it );
01596 }
01597 break;
01598 case objectValue:
01599 if ( value_.map_ )
01600 {
01601 ValueInternalMap::IteratorState it;
01602 value_.map_->makeEndIterator( it );
01603 return iterator( it );
01604 }
01605 break;
01606 #else
01607 case arrayValue:
01608 case objectValue:
01609 if ( value_.map_ )
01610 return iterator( value_.map_->end() );
01611 break;
01612 #endif
01613 default:
01614 break;
01615 }
01616 return iterator();
01617 }
01618
01619
01620
01621
01622
01623 PathArgument::PathArgument()
01624 : kind_( kindNone )
01625 {
01626 }
01627
01628
01629 PathArgument::PathArgument( ArrayIndex index )
01630 : index_( index )
01631 , kind_( kindIndex )
01632 {
01633 }
01634
01635
01636 PathArgument::PathArgument( const char *key )
01637 : key_( key )
01638 , kind_( kindKey )
01639 {
01640 }
01641
01642
01643 PathArgument::PathArgument( const std::string &key )
01644 : key_( key.c_str() )
01645 , kind_( kindKey )
01646 {
01647 }
01648
01649
01650
01651
01652 Path::Path( const std::string &path,
01653 const PathArgument &a1,
01654 const PathArgument &a2,
01655 const PathArgument &a3,
01656 const PathArgument &a4,
01657 const PathArgument &a5 )
01658 {
01659 InArgs in;
01660 in.push_back( &a1 );
01661 in.push_back( &a2 );
01662 in.push_back( &a3 );
01663 in.push_back( &a4 );
01664 in.push_back( &a5 );
01665 makePath( path, in );
01666 }
01667
01668
01669 void
01670 Path::makePath( const std::string &path,
01671 const InArgs &in )
01672 {
01673 const char *current = path.c_str();
01674 const char *end = current + path.length();
01675 InArgs::const_iterator itInArg = in.begin();
01676 while ( current != end )
01677 {
01678 if ( *current == '[' )
01679 {
01680 ++current;
01681 if ( *current == '%' )
01682 addPathInArg( path, in, itInArg, PathArgument::kindIndex );
01683 else
01684 {
01685 ArrayIndex index = 0;
01686 for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
01687 index = index * 10 + ArrayIndex(*current - '0');
01688 args_.push_back( index );
01689 }
01690 if ( current == end || *current++ != ']' )
01691 invalidPath( path, int(current - path.c_str()) );
01692 }
01693 else if ( *current == '%' )
01694 {
01695 addPathInArg( path, in, itInArg, PathArgument::kindKey );
01696 ++current;
01697 }
01698 else if ( *current == '.' )
01699 {
01700 ++current;
01701 }
01702 else
01703 {
01704 const char *beginName = current;
01705 while ( current != end && !strchr( "[.", *current ) )
01706 ++current;
01707 args_.push_back( std::string( beginName, current ) );
01708 }
01709 }
01710 }
01711
01712
01713 void
01714 Path::addPathInArg( const std::string &path,
01715 const InArgs &in,
01716 InArgs::const_iterator &itInArg,
01717 PathArgument::Kind kind )
01718 {
01719 if ( itInArg == in.end() )
01720 {
01721
01722 }
01723 else if ( (*itInArg)->kind_ != kind )
01724 {
01725
01726 }
01727 else
01728 {
01729 args_.push_back( **itInArg );
01730 }
01731 }
01732
01733
01734 void
01735 Path::invalidPath( const std::string &path,
01736 int location )
01737 {
01738
01739 }
01740
01741
01742 const Value &
01743 Path::resolve( const Value &root ) const
01744 {
01745 const Value *node = &root;
01746 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
01747 {
01748 const PathArgument &arg = *it;
01749 if ( arg.kind_ == PathArgument::kindIndex )
01750 {
01751 if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
01752 {
01753
01754 }
01755 node = &((*node)[arg.index_]);
01756 }
01757 else if ( arg.kind_ == PathArgument::kindKey )
01758 {
01759 if ( !node->isObject() )
01760 {
01761
01762 }
01763 node = &((*node)[arg.key_]);
01764 if ( node == &Value::null )
01765 {
01766
01767 }
01768 }
01769 }
01770 return *node;
01771 }
01772
01773
01774 Value
01775 Path::resolve( const Value &root,
01776 const Value &defaultValue ) const
01777 {
01778 const Value *node = &root;
01779 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
01780 {
01781 const PathArgument &arg = *it;
01782 if ( arg.kind_ == PathArgument::kindIndex )
01783 {
01784 if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
01785 return defaultValue;
01786 node = &((*node)[arg.index_]);
01787 }
01788 else if ( arg.kind_ == PathArgument::kindKey )
01789 {
01790 if ( !node->isObject() )
01791 return defaultValue;
01792 node = &((*node)[arg.key_]);
01793 if ( node == &Value::null )
01794 return defaultValue;
01795 }
01796 }
01797 return *node;
01798 }
01799
01800
01801 Value &
01802 Path::make( Value &root ) const
01803 {
01804 Value *node = &root;
01805 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
01806 {
01807 const PathArgument &arg = *it;
01808 if ( arg.kind_ == PathArgument::kindIndex )
01809 {
01810 if ( !node->isArray() )
01811 {
01812
01813 }
01814 node = &((*node)[arg.index_]);
01815 }
01816 else if ( arg.kind_ == PathArgument::kindKey )
01817 {
01818 if ( !node->isObject() )
01819 {
01820
01821 }
01822 node = &((*node)[arg.key_]);
01823 }
01824 }
01825 return *node;
01826 }
01827
01828
01829 }