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