JsonCpp project page JsonCpp home page

json_value.cpp

Go to the documentation of this file.
00001 // Copyright 2007-2010 Baptiste Lepilleur
00002 // Distributed under MIT license, or public domain if desired and
00003 // recognized in your jurisdiction.
00004 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
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>    // size_t
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 } // namespace Json
00077 
00078 
00079 // //////////////////////////////////////////////////////////////////
00080 // //////////////////////////////////////////////////////////////////
00081 // //////////////////////////////////////////////////////////////////
00082 // ValueInternals...
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 // class Value::CommentInfo
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    // It seems that /**/ style comments are acceptable as well.
00126    comment_ = duplicateStringValue( text );
00127 }
00128 
00129 
00130 // //////////////////////////////////////////////////////////////////
00131 // //////////////////////////////////////////////////////////////////
00132 // //////////////////////////////////////////////////////////////////
00133 // class Value::CZString
00134 // //////////////////////////////////////////////////////////////////
00135 // //////////////////////////////////////////////////////////////////
00136 // //////////////////////////////////////////////////////////////////
00137 # ifndef JSON_VALUE_USE_INTERNAL_MAP
00138 
00139 // Notes: index_ indicates if the string was allocated when
00140 // a string is stored.
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 // class Value::Value
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;  // unreachable
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    //if ( type_ != other.type_ )
00603    // GCC 2.95.3 says:
00604    // attempt to take address of bit-field structure member `Json::Value::type_'
00605    // Beats me, but a temp solves the problem.
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;  // unreachable
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 ""; // unreachable
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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:  // size of the array is highest index + 1
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; // unreachable;
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 //# ifdef JSON_USE_CPPTL
01340 //EnumMemberNames
01341 //Value::enumMemberNames() const
01342 //{
01343 //   if ( type_ == objectValue )
01344 //   {
01345 //      return CppTL::Enum::any(  CppTL::Enum::transform(
01346 //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
01347 //         MemberNamesTransform() ) );
01348 //   }
01349 //   return EnumMemberNames();
01350 //}
01351 //
01352 //
01353 //EnumValues 
01354 //Value::enumValues() const
01355 //{
01356 //   if ( type_ == objectValue  ||  type_ == arrayValue )
01357 //      return CppTL::Enum::anyValues( *(value_.map_), 
01358 //                                     CppTL::Type<const Value &>() );
01359 //   return EnumValues();
01360 //}
01361 //
01362 //# endif
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 // class PathArgument
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 // class Path
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       // Error: missing argument %d
01722    }
01723    else if ( (*itInArg)->kind_ != kind )
01724    {
01725       // Error: bad argument type
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    // Error: invalid path.
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             // Error: unable to resolve path (array value expected at position...
01754          }
01755          node = &((*node)[arg.index_]);
01756       }
01757       else if ( arg.kind_ == PathArgument::kindKey )
01758       {
01759          if ( !node->isObject() )
01760          {
01761             // Error: unable to resolve path (object value expected at position...)
01762          }
01763          node = &((*node)[arg.key_]);
01764          if ( node == &Value::null )
01765          {
01766             // Error: unable to resolve path (object has no member named '' at position...)
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             // Error: node is not an array at position ...
01813          }
01814          node = &((*node)[arg.index_]);
01815       }
01816       else if ( arg.kind_ == PathArgument::kindKey )
01817       {
01818          if ( !node->isObject() )
01819          {
01820             // Error: node is not an object at position...
01821          }
01822          node = &((*node)[arg.key_]);
01823       }
01824    }
01825    return *node;
01826 }
01827 
01828 
01829 } // namespace Json

SourceForge Logo hosts this site. Send comments to:
Json-cpp Developers