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 }