Home | History | Annotate | Download | only in lib_json
      1 // Copyright 2011 Baptiste Lepilleur
      2 // Distributed under MIT license, or public domain if desired and
      3 // recognized in your jurisdiction.
      4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
      5 
      6 #if !defined(JSON_IS_AMALGAMATION)
      7 # include <json/assertions.h>
      8 # include <json/value.h>
      9 # include <json/writer.h>
     10 # ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
     11 #  include "json_batchallocator.h"
     12 # endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
     13 #endif // if !defined(JSON_IS_AMALGAMATION)
     14 #include <math.h>
     15 #include <sstream>
     16 #include <utility>
     17 #include <stdexcept>
     18 #include <cstring>
     19 #include <cassert>
     20 #ifdef JSON_USE_CPPTL
     21 # include <cpptl/conststring.h>
     22 #endif
     23 #include <cstddef>    // size_t
     24 
     25 #define JSON_ASSERT_UNREACHABLE assert( false )
     26 
     27 namespace Json {
     28 
     29 const Value Value::null;
     30 const Int Value::minInt = Int( ~(UInt(-1)/2) );
     31 const Int Value::maxInt = Int( UInt(-1)/2 );
     32 const UInt Value::maxUInt = UInt(-1);
     33 # if defined(JSON_HAS_INT64)
     34 const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) );
     35 const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 );
     36 const UInt64 Value::maxUInt64 = UInt64(-1);
     37 // The constant is hard-coded because some compiler have trouble
     38 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
     39 // Assumes that UInt64 is a 64 bits integer.
     40 static const double maxUInt64AsDouble = 18446744073709551615.0;
     41 #endif // defined(JSON_HAS_INT64)
     42 const LargestInt Value::minLargestInt = LargestInt( ~(LargestUInt(-1)/2) );
     43 const LargestInt Value::maxLargestInt = LargestInt( LargestUInt(-1)/2 );
     44 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
     45 
     46 
     47 /// Unknown size marker
     48 static const unsigned int unknown = (unsigned)-1;
     49 
     50 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
     51 template <typename T, typename U>
     52 static inline bool InRange(double d, T min, U max) {
     53    return d >= min && d <= max;
     54 }
     55 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
     56 static inline double integerToDouble( Json::UInt64 value )
     57 {
     58     return static_cast<double>( Int64(value/2) ) * 2.0 + Int64(value & 1);
     59 }
     60 
     61 template<typename T>
     62 static inline double integerToDouble( T value )
     63 {
     64     return static_cast<double>( value );
     65 }
     66 
     67 template <typename T, typename U>
     68 static inline bool InRange(double d, T min, U max) {
     69    return d >= integerToDouble(min) && d <= integerToDouble(max);
     70 }
     71 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
     72 
     73 
     74 /** Duplicates the specified string value.
     75  * @param value Pointer to the string to duplicate. Must be zero-terminated if
     76  *              length is "unknown".
     77  * @param length Length of the value. if equals to unknown, then it will be
     78  *               computed using strlen(value).
     79  * @return Pointer on the duplicate instance of string.
     80  */
     81 static inline char *
     82 duplicateStringValue( const char *value,
     83                       unsigned int length = unknown )
     84 {
     85    if ( length == unknown )
     86       length = (unsigned int)strlen(value);
     87 
     88    // Avoid an integer overflow in the call to malloc below by limiting length
     89    // to a sane value.
     90    if (length >= (unsigned)Value::maxInt)
     91       length = Value::maxInt - 1;
     92 
     93    char *newString = static_cast<char *>( malloc( length + 1 ) );
     94    JSON_ASSERT_MESSAGE( newString != 0, "Failed to allocate string value buffer" );
     95    memcpy( newString, value, length );
     96    newString[length] = 0;
     97    return newString;
     98 }
     99 
    100 
    101 /** Free the string duplicated by duplicateStringValue().
    102  */
    103 static inline void
    104 releaseStringValue( char *value )
    105 {
    106    if ( value )
    107       free( value );
    108 }
    109 
    110 } // namespace Json
    111 
    112 
    113 // //////////////////////////////////////////////////////////////////
    114 // //////////////////////////////////////////////////////////////////
    115 // //////////////////////////////////////////////////////////////////
    116 // ValueInternals...
    117 // //////////////////////////////////////////////////////////////////
    118 // //////////////////////////////////////////////////////////////////
    119 // //////////////////////////////////////////////////////////////////
    120 #if !defined(JSON_IS_AMALGAMATION)
    121 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    122 #  include "json_internalarray.inl"
    123 #  include "json_internalmap.inl"
    124 # endif // JSON_VALUE_USE_INTERNAL_MAP
    125 
    126 # include "json_valueiterator.inl"
    127 #endif // if !defined(JSON_IS_AMALGAMATION)
    128 
    129 namespace Json {
    130 
    131 // //////////////////////////////////////////////////////////////////
    132 // //////////////////////////////////////////////////////////////////
    133 // //////////////////////////////////////////////////////////////////
    134 // class Value::CommentInfo
    135 // //////////////////////////////////////////////////////////////////
    136 // //////////////////////////////////////////////////////////////////
    137 // //////////////////////////////////////////////////////////////////
    138 
    139 
    140 Value::CommentInfo::CommentInfo()
    141    : comment_( 0 )
    142 {
    143 }
    144 
    145 Value::CommentInfo::~CommentInfo()
    146 {
    147    if ( comment_ )
    148       releaseStringValue( comment_ );
    149 }
    150 
    151 
    152 void
    153 Value::CommentInfo::setComment( const char *text )
    154 {
    155    if ( comment_ )
    156       releaseStringValue( comment_ );
    157    JSON_ASSERT( text != 0 );
    158    JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
    159    // It seems that /**/ style comments are acceptable as well.
    160    comment_ = duplicateStringValue( text );
    161 }
    162 
    163 
    164 // //////////////////////////////////////////////////////////////////
    165 // //////////////////////////////////////////////////////////////////
    166 // //////////////////////////////////////////////////////////////////
    167 // class Value::CZString
    168 // //////////////////////////////////////////////////////////////////
    169 // //////////////////////////////////////////////////////////////////
    170 // //////////////////////////////////////////////////////////////////
    171 # ifndef JSON_VALUE_USE_INTERNAL_MAP
    172 
    173 // Notes: index_ indicates if the string was allocated when
    174 // a string is stored.
    175 
    176 Value::CZString::CZString( ArrayIndex index )
    177    : cstr_( 0 )
    178    , index_( index )
    179 {
    180 }
    181 
    182 Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
    183    : cstr_( allocate == duplicate ? duplicateStringValue(cstr)
    184                                   : cstr )
    185    , index_( allocate )
    186 {
    187 }
    188 
    189 Value::CZString::CZString( const CZString &other )
    190 : cstr_( other.index_ != noDuplication &&  other.cstr_ != 0
    191                 ?  duplicateStringValue( other.cstr_ )
    192                 : other.cstr_ )
    193    , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
    194                          : other.index_ )
    195 {
    196 }
    197 
    198 Value::CZString::~CZString()
    199 {
    200    if ( cstr_  &&  index_ == duplicate )
    201       releaseStringValue( const_cast<char *>( cstr_ ) );
    202 }
    203 
    204 void
    205 Value::CZString::swap( CZString &other )
    206 {
    207    std::swap( cstr_, other.cstr_ );
    208    std::swap( index_, other.index_ );
    209 }
    210 
    211 Value::CZString &
    212 Value::CZString::operator =( const CZString &other )
    213 {
    214    CZString temp( other );
    215    swap( temp );
    216    return *this;
    217 }
    218 
    219 bool
    220 Value::CZString::operator<( const CZString &other ) const
    221 {
    222    if ( cstr_ )
    223       return strcmp( cstr_, other.cstr_ ) < 0;
    224    return index_ < other.index_;
    225 }
    226 
    227 bool
    228 Value::CZString::operator==( const CZString &other ) const
    229 {
    230    if ( cstr_ )
    231       return strcmp( cstr_, other.cstr_ ) == 0;
    232    return index_ == other.index_;
    233 }
    234 
    235 
    236 ArrayIndex
    237 Value::CZString::index() const
    238 {
    239    return index_;
    240 }
    241 
    242 
    243 const char *
    244 Value::CZString::c_str() const
    245 {
    246    return cstr_;
    247 }
    248 
    249 bool
    250 Value::CZString::isStaticString() const
    251 {
    252    return index_ == noDuplication;
    253 }
    254 
    255 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
    256 
    257 
    258 // //////////////////////////////////////////////////////////////////
    259 // //////////////////////////////////////////////////////////////////
    260 // //////////////////////////////////////////////////////////////////
    261 // class Value::Value
    262 // //////////////////////////////////////////////////////////////////
    263 // //////////////////////////////////////////////////////////////////
    264 // //////////////////////////////////////////////////////////////////
    265 
    266 /*! \internal Default constructor initialization must be equivalent to:
    267  * memset( this, 0, sizeof(Value) )
    268  * This optimization is used in ValueInternalMap fast allocator.
    269  */
    270 Value::Value( ValueType type )
    271    : type_( type )
    272    , allocated_( false )
    273 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    274    , itemIsUsed_( 0 )
    275 #endif
    276    , comments_( 0 )
    277 {
    278    switch ( type )
    279    {
    280    case nullValue:
    281       break;
    282    case intValue:
    283    case uintValue:
    284       value_.int_ = 0;
    285       break;
    286    case realValue:
    287       value_.real_ = 0.0;
    288       break;
    289    case stringValue:
    290       value_.string_ = 0;
    291       break;
    292 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    293    case arrayValue:
    294    case objectValue:
    295       value_.map_ = new ObjectValues();
    296       break;
    297 #else
    298    case arrayValue:
    299       value_.array_ = arrayAllocator()->newArray();
    300       break;
    301    case objectValue:
    302       value_.map_ = mapAllocator()->newMap();
    303       break;
    304 #endif
    305    case booleanValue:
    306       value_.bool_ = false;
    307       break;
    308    default:
    309       JSON_ASSERT_UNREACHABLE;
    310    }
    311 }
    312 
    313 
    314 Value::Value( UInt value )
    315    : type_( uintValue )
    316    , allocated_( false )
    317 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    318    , itemIsUsed_( 0 )
    319 #endif
    320    , comments_( 0 )
    321 {
    322    value_.uint_ = value;
    323 }
    324 
    325 Value::Value( Int value )
    326    : type_( intValue )
    327    , allocated_( false )
    328 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    329    , itemIsUsed_( 0 )
    330 #endif
    331    , comments_( 0 )
    332 {
    333    value_.int_ = value;
    334 }
    335 
    336 
    337 # if defined(JSON_HAS_INT64)
    338 Value::Value( Int64 value )
    339    : type_( intValue )
    340    , allocated_( false )
    341 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    342    , itemIsUsed_( 0 )
    343 #endif
    344    , comments_( 0 )
    345 {
    346    value_.int_ = value;
    347 }
    348 
    349 
    350 Value::Value( UInt64 value )
    351    : type_( uintValue )
    352    , allocated_( false )
    353 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    354    , itemIsUsed_( 0 )
    355 #endif
    356    , comments_( 0 )
    357 {
    358    value_.uint_ = value;
    359 }
    360 #endif // defined(JSON_HAS_INT64)
    361 
    362 Value::Value( double value )
    363    : type_( realValue )
    364    , allocated_( false )
    365 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    366    , itemIsUsed_( 0 )
    367 #endif
    368    , comments_( 0 )
    369 {
    370    value_.real_ = value;
    371 }
    372 
    373 Value::Value( const char *value )
    374    : type_( stringValue )
    375    , allocated_( true )
    376 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    377    , itemIsUsed_( 0 )
    378 #endif
    379    , comments_( 0 )
    380 {
    381    value_.string_ = duplicateStringValue( value );
    382 }
    383 
    384 
    385 Value::Value( const char *beginValue,
    386               const char *endValue )
    387    : type_( stringValue )
    388    , allocated_( true )
    389 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    390    , itemIsUsed_( 0 )
    391 #endif
    392    , comments_( 0 )
    393 {
    394    value_.string_ = duplicateStringValue( beginValue,
    395                                           (unsigned int)(endValue - beginValue) );
    396 }
    397 
    398 
    399 Value::Value( const std::string &value )
    400    : type_( stringValue )
    401    , allocated_( true )
    402 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    403    , itemIsUsed_( 0 )
    404 #endif
    405    , comments_( 0 )
    406 {
    407    value_.string_ = duplicateStringValue( value.c_str(),
    408                                           (unsigned int)value.length() );
    409 
    410 }
    411 
    412 Value::Value( const StaticString &value )
    413    : type_( stringValue )
    414    , allocated_( false )
    415 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    416    , itemIsUsed_( 0 )
    417 #endif
    418    , comments_( 0 )
    419 {
    420    value_.string_ = const_cast<char *>( value.c_str() );
    421 }
    422 
    423 
    424 # ifdef JSON_USE_CPPTL
    425 Value::Value( const CppTL::ConstString &value )
    426    : type_( stringValue )
    427    , allocated_( true )
    428 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    429    , itemIsUsed_( 0 )
    430 #endif
    431    , comments_( 0 )
    432 {
    433    value_.string_ = duplicateStringValue( value, value.length() );
    434 }
    435 # endif
    436 
    437 Value::Value( bool value )
    438    : type_( booleanValue )
    439    , allocated_( false )
    440 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    441    , itemIsUsed_( 0 )
    442 #endif
    443    , comments_( 0 )
    444 {
    445    value_.bool_ = value;
    446 }
    447 
    448 
    449 Value::Value( const Value &other )
    450    : type_( other.type_ )
    451    , allocated_( false )
    452 # ifdef JSON_VALUE_USE_INTERNAL_MAP
    453    , itemIsUsed_( 0 )
    454 #endif
    455    , comments_( 0 )
    456 {
    457    switch ( type_ )
    458    {
    459    case nullValue:
    460    case intValue:
    461    case uintValue:
    462    case realValue:
    463    case booleanValue:
    464       value_ = other.value_;
    465       break;
    466    case stringValue:
    467       if ( other.value_.string_ )
    468       {
    469          value_.string_ = duplicateStringValue( other.value_.string_ );
    470          allocated_ = true;
    471       }
    472       else
    473          value_.string_ = 0;
    474       break;
    475 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    476    case arrayValue:
    477    case objectValue:
    478       value_.map_ = new ObjectValues( *other.value_.map_ );
    479       break;
    480 #else
    481    case arrayValue:
    482       value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
    483       break;
    484    case objectValue:
    485       value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
    486       break;
    487 #endif
    488    default:
    489       JSON_ASSERT_UNREACHABLE;
    490    }
    491    if ( other.comments_ )
    492    {
    493       comments_ = new CommentInfo[numberOfCommentPlacement];
    494       for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
    495       {
    496          const CommentInfo &otherComment = other.comments_[comment];
    497          if ( otherComment.comment_ )
    498             comments_[comment].setComment( otherComment.comment_ );
    499       }
    500    }
    501 }
    502 
    503 
    504 Value::~Value()
    505 {
    506    switch ( type_ )
    507    {
    508    case nullValue:
    509    case intValue:
    510    case uintValue:
    511    case realValue:
    512    case booleanValue:
    513       break;
    514    case stringValue:
    515       if ( allocated_ )
    516          releaseStringValue( value_.string_ );
    517       break;
    518 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    519    case arrayValue:
    520    case objectValue:
    521       delete value_.map_;
    522       break;
    523 #else
    524    case arrayValue:
    525       arrayAllocator()->destructArray( value_.array_ );
    526       break;
    527    case objectValue:
    528       mapAllocator()->destructMap( value_.map_ );
    529       break;
    530 #endif
    531    default:
    532       JSON_ASSERT_UNREACHABLE;
    533    }
    534 
    535    if ( comments_ )
    536       delete[] comments_;
    537 }
    538 
    539 Value &
    540 Value::operator=( const Value &other )
    541 {
    542    Value temp( other );
    543    swap( temp );
    544    return *this;
    545 }
    546 
    547 void
    548 Value::swap( Value &other )
    549 {
    550    ValueType temp = type_;
    551    type_ = other.type_;
    552    other.type_ = temp;
    553    std::swap( value_, other.value_ );
    554    int temp2 = allocated_;
    555    allocated_ = other.allocated_;
    556    other.allocated_ = temp2;
    557 }
    558 
    559 ValueType
    560 Value::type() const
    561 {
    562    return type_;
    563 }
    564 
    565 
    566 int
    567 Value::compare( const Value &other ) const
    568 {
    569    if ( *this < other )
    570       return -1;
    571    if ( *this > other )
    572       return 1;
    573    return 0;
    574 }
    575 
    576 
    577 bool
    578 Value::operator <( const Value &other ) const
    579 {
    580    int typeDelta = type_ - other.type_;
    581    if ( typeDelta )
    582       return typeDelta < 0 ? true : false;
    583    switch ( type_ )
    584    {
    585    case nullValue:
    586       return false;
    587    case intValue:
    588       return value_.int_ < other.value_.int_;
    589    case uintValue:
    590       return value_.uint_ < other.value_.uint_;
    591    case realValue:
    592       return value_.real_ < other.value_.real_;
    593    case booleanValue:
    594       return value_.bool_ < other.value_.bool_;
    595    case stringValue:
    596       return ( value_.string_ == 0  &&  other.value_.string_ )
    597              || ( other.value_.string_
    598                   &&  value_.string_
    599                   && strcmp( value_.string_, other.value_.string_ ) < 0 );
    600 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    601    case arrayValue:
    602    case objectValue:
    603       {
    604          int delta = int( value_.map_->size() - other.value_.map_->size() );
    605          if ( delta )
    606             return delta < 0;
    607          return (*value_.map_) < (*other.value_.map_);
    608       }
    609 #else
    610    case arrayValue:
    611       return value_.array_->compare( *(other.value_.array_) ) < 0;
    612    case objectValue:
    613       return value_.map_->compare( *(other.value_.map_) ) < 0;
    614 #endif
    615    default:
    616       JSON_ASSERT_UNREACHABLE;
    617    }
    618    return false;  // unreachable
    619 }
    620 
    621 bool
    622 Value::operator <=( const Value &other ) const
    623 {
    624    return !(other < *this);
    625 }
    626 
    627 bool
    628 Value::operator >=( const Value &other ) const
    629 {
    630    return !(*this < other);
    631 }
    632 
    633 bool
    634 Value::operator >( const Value &other ) const
    635 {
    636    return other < *this;
    637 }
    638 
    639 bool
    640 Value::operator ==( const Value &other ) const
    641 {
    642    //if ( type_ != other.type_ )
    643    // GCC 2.95.3 says:
    644    // attempt to take address of bit-field structure member `Json::Value::type_'
    645    // Beats me, but a temp solves the problem.
    646    int temp = other.type_;
    647    if ( type_ != temp )
    648       return false;
    649    switch ( type_ )
    650    {
    651    case nullValue:
    652       return true;
    653    case intValue:
    654       return value_.int_ == other.value_.int_;
    655    case uintValue:
    656       return value_.uint_ == other.value_.uint_;
    657    case realValue:
    658       return value_.real_ == other.value_.real_;
    659    case booleanValue:
    660       return value_.bool_ == other.value_.bool_;
    661    case stringValue:
    662       return ( value_.string_ == other.value_.string_ )
    663              || ( other.value_.string_
    664                   &&  value_.string_
    665                   && strcmp( value_.string_, other.value_.string_ ) == 0 );
    666 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    667    case arrayValue:
    668    case objectValue:
    669       return value_.map_->size() == other.value_.map_->size()
    670              && (*value_.map_) == (*other.value_.map_);
    671 #else
    672    case arrayValue:
    673       return value_.array_->compare( *(other.value_.array_) ) == 0;
    674    case objectValue:
    675       return value_.map_->compare( *(other.value_.map_) ) == 0;
    676 #endif
    677    default:
    678       JSON_ASSERT_UNREACHABLE;
    679    }
    680    return false;  // unreachable
    681 }
    682 
    683 bool
    684 Value::operator !=( const Value &other ) const
    685 {
    686    return !( *this == other );
    687 }
    688 
    689 const char *
    690 Value::asCString() const
    691 {
    692    JSON_ASSERT( type_ == stringValue );
    693    return value_.string_;
    694 }
    695 
    696 
    697 std::string
    698 Value::asString() const
    699 {
    700    switch ( type_ )
    701    {
    702    case nullValue:
    703       return "";
    704    case stringValue:
    705       return value_.string_ ? value_.string_ : "";
    706    case booleanValue:
    707       return value_.bool_ ? "true" : "false";
    708    case intValue:
    709       return valueToString( value_.int_ );
    710    case uintValue:
    711       return valueToString( value_.uint_ );
    712    case realValue:
    713       return valueToString( value_.real_ );
    714    default:
    715       JSON_FAIL_MESSAGE( "Type is not convertible to string" );
    716    }
    717 }
    718 
    719 # ifdef JSON_USE_CPPTL
    720 CppTL::ConstString
    721 Value::asConstString() const
    722 {
    723    return CppTL::ConstString( asString().c_str() );
    724 }
    725 # endif
    726 
    727 
    728 Value::Int
    729 Value::asInt() const
    730 {
    731    switch ( type_ )
    732    {
    733    case intValue:
    734       JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
    735       return Int(value_.int_);
    736    case uintValue:
    737       JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
    738       return Int(value_.uint_);
    739    case realValue:
    740       JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), "double out of Int range");
    741       return Int(value_.real_);
    742    case nullValue:
    743       return 0;
    744    case booleanValue:
    745       return value_.bool_ ? 1 : 0;
    746    default:
    747       break;
    748    }
    749    JSON_FAIL_MESSAGE("Value is not convertible to Int.");
    750 }
    751 
    752 
    753 Value::UInt
    754 Value::asUInt() const
    755 {
    756    switch ( type_ )
    757    {
    758    case intValue:
    759       JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
    760       return UInt(value_.int_);
    761    case uintValue:
    762       JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
    763       return UInt(value_.uint_);
    764    case realValue:
    765       JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), "double out of UInt range");
    766       return UInt( value_.real_ );
    767    case nullValue:
    768       return 0;
    769    case booleanValue:
    770       return value_.bool_ ? 1 : 0;
    771    default:
    772       break;
    773    }
    774    JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
    775 }
    776 
    777 
    778 # if defined(JSON_HAS_INT64)
    779 
    780 Value::Int64
    781 Value::asInt64() const
    782 {
    783    switch ( type_ )
    784    {
    785    case intValue:
    786       return Int64(value_.int_);
    787    case uintValue:
    788       JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
    789       return Int64(value_.uint_);
    790    case realValue:
    791       JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), "double out of Int64 range");
    792       return Int64(value_.real_);
    793    case nullValue:
    794       return 0;
    795    case booleanValue:
    796       return value_.bool_ ? 1 : 0;
    797    default:
    798       break;
    799    }
    800    JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
    801 }
    802 
    803 
    804 Value::UInt64
    805 Value::asUInt64() const
    806 {
    807    switch ( type_ )
    808    {
    809    case intValue:
    810       JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
    811       return UInt64(value_.int_);
    812    case uintValue:
    813       return UInt64(value_.uint_);
    814    case realValue:
    815       JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), "double out of UInt64 range");
    816       return UInt64( value_.real_ );
    817    case nullValue:
    818       return 0;
    819    case booleanValue:
    820       return value_.bool_ ? 1 : 0;
    821    default:
    822       break;
    823    }
    824    JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
    825 }
    826 # endif // if defined(JSON_HAS_INT64)
    827 
    828 
    829 LargestInt
    830 Value::asLargestInt() const
    831 {
    832 #if defined(JSON_NO_INT64)
    833     return asInt();
    834 #else
    835     return asInt64();
    836 #endif
    837 }
    838 
    839 
    840 LargestUInt
    841 Value::asLargestUInt() const
    842 {
    843 #if defined(JSON_NO_INT64)
    844     return asUInt();
    845 #else
    846     return asUInt64();
    847 #endif
    848 }
    849 
    850 
    851 double
    852 Value::asDouble() const
    853 {
    854    switch ( type_ )
    855    {
    856    case intValue:
    857       return static_cast<double>( value_.int_ );
    858    case uintValue:
    859 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    860       return static_cast<double>( value_.uint_ );
    861 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    862       return integerToDouble( value_.uint_ );
    863 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    864    case realValue:
    865       return value_.real_;
    866    case nullValue:
    867       return 0.0;
    868    case booleanValue:
    869       return value_.bool_ ? 1.0 : 0.0;
    870    default:
    871       break;
    872    }
    873    JSON_FAIL_MESSAGE("Value is not convertible to double.");
    874 }
    875 
    876 float
    877 Value::asFloat() const
    878 {
    879    switch ( type_ )
    880    {
    881    case intValue:
    882       return static_cast<float>( value_.int_ );
    883    case uintValue:
    884 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    885       return static_cast<float>( value_.uint_ );
    886 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    887       return integerToDouble( value_.uint_ );
    888 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    889    case realValue:
    890       return static_cast<float>( value_.real_ );
    891    case nullValue:
    892       return 0.0;
    893    case booleanValue:
    894       return value_.bool_ ? 1.0f : 0.0f;
    895    default:
    896       break;
    897    }
    898    JSON_FAIL_MESSAGE("Value is not convertible to float.");
    899 }
    900 
    901 bool
    902 Value::asBool() const
    903 {
    904    switch ( type_ )
    905    {
    906    case booleanValue:
    907       return value_.bool_;
    908    case nullValue:
    909       return false;
    910    case intValue:
    911       return value_.int_ ? true : false;
    912    case uintValue:
    913       return value_.uint_ ? true : false;
    914    case realValue:
    915       return value_.real_ ? true : false;
    916    default:
    917       break;
    918    }
    919    JSON_FAIL_MESSAGE("Value is not convertible to bool.");
    920 }
    921 
    922 
    923 bool
    924 Value::isConvertibleTo( ValueType other ) const
    925 {
    926    switch ( other )
    927    {
    928    case nullValue:
    929       return ( isNumeric() && asDouble() == 0.0 )
    930              || ( type_ == booleanValue && value_.bool_ == false )
    931              || ( type_ == stringValue && asString() == "" )
    932              || ( type_ == arrayValue && value_.map_->size() == 0 )
    933              || ( type_ == objectValue && value_.map_->size() == 0 )
    934              || type_ == nullValue;
    935    case intValue:
    936       return isInt()
    937              || (type_ == realValue && InRange(value_.real_, minInt, maxInt))
    938              || type_ == booleanValue
    939              || type_ == nullValue;
    940    case uintValue:
    941       return isUInt()
    942              || (type_ == realValue && InRange(value_.real_, 0, maxUInt))
    943              || type_ == booleanValue
    944              || type_ == nullValue;
    945    case realValue:
    946       return isNumeric()
    947              || type_ == booleanValue
    948              || type_ == nullValue;
    949    case booleanValue:
    950       return isNumeric()
    951              || type_ == booleanValue
    952              || type_ == nullValue;
    953    case stringValue:
    954       return isNumeric()
    955              || type_ == booleanValue
    956              || type_ == stringValue
    957              || type_ == nullValue;
    958    case arrayValue:
    959       return type_ == arrayValue
    960              || type_ == nullValue;
    961    case objectValue:
    962       return type_ == objectValue
    963              || type_ == nullValue;
    964    }
    965    JSON_ASSERT_UNREACHABLE;
    966    return false;
    967 }
    968 
    969 
    970 /// Number of values in array or object
    971 ArrayIndex
    972 Value::size() const
    973 {
    974    switch ( type_ )
    975    {
    976    case nullValue:
    977    case intValue:
    978    case uintValue:
    979    case realValue:
    980    case booleanValue:
    981    case stringValue:
    982       return 0;
    983 #ifndef JSON_VALUE_USE_INTERNAL_MAP
    984    case arrayValue:  // size of the array is highest index + 1
    985       if ( !value_.map_->empty() )
    986       {
    987          ObjectValues::const_iterator itLast = value_.map_->end();
    988          --itLast;
    989          return (*itLast).first.index()+1;
    990       }
    991       return 0;
    992    case objectValue:
    993       return ArrayIndex( value_.map_->size() );
    994 #else
    995    case arrayValue:
    996       return Int( value_.array_->size() );
    997    case objectValue:
    998       return Int( value_.map_->size() );
    999 #endif
   1000    }
   1001    JSON_ASSERT_UNREACHABLE;
   1002    return 0; // unreachable;
   1003 }
   1004 
   1005 
   1006 bool
   1007 Value::empty() const
   1008 {
   1009    if ( isNull() || isArray() || isObject() )
   1010       return size() == 0u;
   1011    else
   1012       return false;
   1013 }
   1014 
   1015 
   1016 bool
   1017 Value::operator!() const
   1018 {
   1019    return isNull();
   1020 }
   1021 
   1022 
   1023 void
   1024 Value::clear()
   1025 {
   1026    JSON_ASSERT( type_ == nullValue  ||  type_ == arrayValue  || type_ == objectValue );
   1027 
   1028    switch ( type_ )
   1029    {
   1030 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1031    case arrayValue:
   1032    case objectValue:
   1033       value_.map_->clear();
   1034       break;
   1035 #else
   1036    case arrayValue:
   1037       value_.array_->clear();
   1038       break;
   1039    case objectValue:
   1040       value_.map_->clear();
   1041       break;
   1042 #endif
   1043    default:
   1044       break;
   1045    }
   1046 }
   1047 
   1048 void
   1049 Value::resize( ArrayIndex newSize )
   1050 {
   1051    JSON_ASSERT( type_ == nullValue  ||  type_ == arrayValue );
   1052    if ( type_ == nullValue )
   1053       *this = Value( arrayValue );
   1054 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1055    ArrayIndex oldSize = size();
   1056    if ( newSize == 0 )
   1057       clear();
   1058    else if ( newSize > oldSize )
   1059       (*this)[ newSize - 1 ];
   1060    else
   1061    {
   1062       for ( ArrayIndex index = newSize; index < oldSize; ++index )
   1063       {
   1064          value_.map_->erase( index );
   1065       }
   1066       assert( size() == newSize );
   1067    }
   1068 #else
   1069    value_.array_->resize( newSize );
   1070 #endif
   1071 }
   1072 
   1073 
   1074 Value &
   1075 Value::operator[]( ArrayIndex index )
   1076 {
   1077    JSON_ASSERT( type_ == nullValue  ||  type_ == arrayValue );
   1078    if ( type_ == nullValue )
   1079       *this = Value( arrayValue );
   1080 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1081    CZString key( index );
   1082    ObjectValues::iterator it = value_.map_->lower_bound( key );
   1083    if ( it != value_.map_->end()  &&  (*it).first == key )
   1084       return (*it).second;
   1085 
   1086    ObjectValues::value_type defaultValue( key, null );
   1087    it = value_.map_->insert( it, defaultValue );
   1088    return (*it).second;
   1089 #else
   1090    return value_.array_->resolveReference( index );
   1091 #endif
   1092 }
   1093 
   1094 
   1095 Value &
   1096 Value::operator[]( int index )
   1097 {
   1098    JSON_ASSERT( index >= 0 );
   1099    return (*this)[ ArrayIndex(index) ];
   1100 }
   1101 
   1102 
   1103 const Value &
   1104 Value::operator[]( ArrayIndex index ) const
   1105 {
   1106    JSON_ASSERT( type_ == nullValue  ||  type_ == arrayValue );
   1107    if ( type_ == nullValue )
   1108       return null;
   1109 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1110    CZString key( index );
   1111    ObjectValues::const_iterator it = value_.map_->find( key );
   1112    if ( it == value_.map_->end() )
   1113       return null;
   1114    return (*it).second;
   1115 #else
   1116    Value *value = value_.array_->find( index );
   1117    return value ? *value : null;
   1118 #endif
   1119 }
   1120 
   1121 
   1122 const Value &
   1123 Value::operator[]( int index ) const
   1124 {
   1125    JSON_ASSERT( index >= 0 );
   1126    return (*this)[ ArrayIndex(index) ];
   1127 }
   1128 
   1129 
   1130 Value &
   1131 Value::operator[]( const char *key )
   1132 {
   1133    return resolveReference( key, false );
   1134 }
   1135 
   1136 
   1137 Value &
   1138 Value::resolveReference( const char *key,
   1139                          bool isStatic )
   1140 {
   1141    JSON_ASSERT( type_ == nullValue  ||  type_ == objectValue );
   1142    if ( type_ == nullValue )
   1143       *this = Value( objectValue );
   1144 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1145    CZString actualKey( key, isStatic ? CZString::noDuplication
   1146                                      : CZString::duplicateOnCopy );
   1147    ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
   1148    if ( it != value_.map_->end()  &&  (*it).first == actualKey )
   1149       return (*it).second;
   1150 
   1151    ObjectValues::value_type defaultValue( actualKey, null );
   1152    it = value_.map_->insert( it, defaultValue );
   1153    Value &value = (*it).second;
   1154    return value;
   1155 #else
   1156    return value_.map_->resolveReference( key, isStatic );
   1157 #endif
   1158 }
   1159 
   1160 
   1161 Value
   1162 Value::get( ArrayIndex index,
   1163             const Value &defaultValue ) const
   1164 {
   1165    const Value *value = &((*this)[index]);
   1166    return value == &null ? defaultValue : *value;
   1167 }
   1168 
   1169 
   1170 bool
   1171 Value::isValidIndex( ArrayIndex index ) const
   1172 {
   1173    return index < size();
   1174 }
   1175 
   1176 
   1177 
   1178 const Value &
   1179 Value::operator[]( const char *key ) const
   1180 {
   1181    JSON_ASSERT( type_ == nullValue  ||  type_ == objectValue );
   1182    if ( type_ == nullValue )
   1183       return null;
   1184 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1185    CZString actualKey( key, CZString::noDuplication );
   1186    ObjectValues::const_iterator it = value_.map_->find( actualKey );
   1187    if ( it == value_.map_->end() )
   1188       return null;
   1189    return (*it).second;
   1190 #else
   1191    const Value *value = value_.map_->find( key );
   1192    return value ? *value : null;
   1193 #endif
   1194 }
   1195 
   1196 
   1197 Value &
   1198 Value::operator[]( const std::string &key )
   1199 {
   1200    return (*this)[ key.c_str() ];
   1201 }
   1202 
   1203 
   1204 const Value &
   1205 Value::operator[]( const std::string &key ) const
   1206 {
   1207    return (*this)[ key.c_str() ];
   1208 }
   1209 
   1210 Value &
   1211 Value::operator[]( const StaticString &key )
   1212 {
   1213    return resolveReference( key, true );
   1214 }
   1215 
   1216 
   1217 # ifdef JSON_USE_CPPTL
   1218 Value &
   1219 Value::operator[]( const CppTL::ConstString &key )
   1220 {
   1221    return (*this)[ key.c_str() ];
   1222 }
   1223 
   1224 
   1225 const Value &
   1226 Value::operator[]( const CppTL::ConstString &key ) const
   1227 {
   1228    return (*this)[ key.c_str() ];
   1229 }
   1230 # endif
   1231 
   1232 
   1233 Value &
   1234 Value::append( const Value &value )
   1235 {
   1236    return (*this)[size()] = value;
   1237 }
   1238 
   1239 
   1240 Value
   1241 Value::get( const char *key,
   1242             const Value &defaultValue ) const
   1243 {
   1244    const Value *value = &((*this)[key]);
   1245    return value == &null ? defaultValue : *value;
   1246 }
   1247 
   1248 
   1249 Value
   1250 Value::get( const std::string &key,
   1251             const Value &defaultValue ) const
   1252 {
   1253    return get( key.c_str(), defaultValue );
   1254 }
   1255 
   1256 Value
   1257 Value::removeMember( const char* key )
   1258 {
   1259    JSON_ASSERT( type_ == nullValue  ||  type_ == objectValue );
   1260    if ( type_ == nullValue )
   1261       return null;
   1262 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1263    CZString actualKey( key, CZString::noDuplication );
   1264    ObjectValues::iterator it = value_.map_->find( actualKey );
   1265    if ( it == value_.map_->end() )
   1266       return null;
   1267    Value old(it->second);
   1268    value_.map_->erase(it);
   1269    return old;
   1270 #else
   1271    Value *value = value_.map_->find( key );
   1272    if (value){
   1273       Value old(*value);
   1274       value_.map_.remove( key );
   1275       return old;
   1276    } else {
   1277       return null;
   1278    }
   1279 #endif
   1280 }
   1281 
   1282 Value
   1283 Value::removeMember( const std::string &key )
   1284 {
   1285    return removeMember( key.c_str() );
   1286 }
   1287 
   1288 # ifdef JSON_USE_CPPTL
   1289 Value
   1290 Value::get( const CppTL::ConstString &key,
   1291             const Value &defaultValue ) const
   1292 {
   1293    return get( key.c_str(), defaultValue );
   1294 }
   1295 # endif
   1296 
   1297 bool
   1298 Value::isMember( const char *key ) const
   1299 {
   1300    const Value *value = &((*this)[key]);
   1301    return value != &null;
   1302 }
   1303 
   1304 
   1305 bool
   1306 Value::isMember( const std::string &key ) const
   1307 {
   1308    return isMember( key.c_str() );
   1309 }
   1310 
   1311 
   1312 # ifdef JSON_USE_CPPTL
   1313 bool
   1314 Value::isMember( const CppTL::ConstString &key ) const
   1315 {
   1316    return isMember( key.c_str() );
   1317 }
   1318 #endif
   1319 
   1320 Value::Members
   1321 Value::getMemberNames() const
   1322 {
   1323    JSON_ASSERT( type_ == nullValue  ||  type_ == objectValue );
   1324    if ( type_ == nullValue )
   1325        return Value::Members();
   1326    Members members;
   1327    members.reserve( value_.map_->size() );
   1328 #ifndef JSON_VALUE_USE_INTERNAL_MAP
   1329    ObjectValues::const_iterator it = value_.map_->begin();
   1330    ObjectValues::const_iterator itEnd = value_.map_->end();
   1331    for ( ; it != itEnd; ++it )
   1332       members.push_back( std::string( (*it).first.c_str() ) );
   1333 #else
   1334    ValueInternalMap::IteratorState it;
   1335    ValueInternalMap::IteratorState itEnd;
   1336    value_.map_->makeBeginIterator( it );
   1337    value_.map_->makeEndIterator( itEnd );
   1338    for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
   1339       members.push_back( std::string( ValueInternalMap::key( it ) ) );
   1340 #endif
   1341    return members;
   1342 }
   1343 //
   1344 //# ifdef JSON_USE_CPPTL
   1345 //EnumMemberNames
   1346 //Value::enumMemberNames() const
   1347 //{
   1348 //   if ( type_ == objectValue )
   1349 //   {
   1350 //      return CppTL::Enum::any(  CppTL::Enum::transform(
   1351 //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
   1352 //         MemberNamesTransform() ) );
   1353 //   }
   1354 //   return EnumMemberNames();
   1355 //}
   1356 //
   1357 //
   1358 //EnumValues
   1359 //Value::enumValues() const
   1360 //{
   1361 //   if ( type_ == objectValue  ||  type_ == arrayValue )
   1362 //      return CppTL::Enum::anyValues( *(value_.map_),
   1363 //                                     CppTL::Type<const Value &>() );
   1364 //   return EnumValues();
   1365 //}
   1366 //
   1367 //# endif
   1368 
   1369 static bool IsIntegral(double d) {
   1370   double integral_part;
   1371   return modf(d, &integral_part) == 0.0;
   1372 }
   1373 
   1374 
   1375 bool
   1376 Value::isNull() const
   1377 {
   1378    return type_ == nullValue;
   1379 }
   1380 
   1381 
   1382 bool
   1383 Value::isBool() const
   1384 {
   1385    return type_ == booleanValue;
   1386 }
   1387 
   1388 
   1389 bool
   1390 Value::isInt() const
   1391 {
   1392    switch ( type_ )
   1393    {
   1394    case intValue:
   1395       return value_.int_ >= minInt  &&  value_.int_ <= maxInt;
   1396    case uintValue:
   1397       return value_.uint_ <= UInt(maxInt);
   1398    case realValue:
   1399       return value_.real_ >= minInt &&
   1400              value_.real_ <= maxInt &&
   1401              IsIntegral(value_.real_);
   1402    default:
   1403       break;
   1404    }
   1405    return false;
   1406 }
   1407 
   1408 
   1409 bool
   1410 Value::isUInt() const
   1411 {
   1412    switch ( type_ )
   1413    {
   1414    case intValue:
   1415       return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
   1416    case uintValue:
   1417       return value_.uint_ <= maxUInt;
   1418    case realValue:
   1419       return value_.real_ >= 0 &&
   1420              value_.real_ <= maxUInt &&
   1421              IsIntegral(value_.real_);
   1422    default:
   1423       break;
   1424    }
   1425    return false;
   1426 }
   1427 
   1428 bool
   1429 Value::isInt64() const
   1430 {
   1431 # if defined(JSON_HAS_INT64)
   1432    switch ( type_ )
   1433    {
   1434    case intValue:
   1435      return true;
   1436    case uintValue:
   1437       return value_.uint_ <= UInt64(maxInt64);
   1438    case realValue:
   1439       // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
   1440       // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
   1441       // require the value to be strictly less than the limit.
   1442       return value_.real_ >= double(minInt64) &&
   1443              value_.real_ < double(maxInt64) &&
   1444              IsIntegral(value_.real_);
   1445    default:
   1446       break;
   1447    }
   1448 # endif  // JSON_HAS_INT64
   1449    return false;
   1450 }
   1451 
   1452 bool
   1453 Value::isUInt64() const
   1454 {
   1455 # if defined(JSON_HAS_INT64)
   1456    switch ( type_ )
   1457    {
   1458    case intValue:
   1459      return value_.int_ >= 0;
   1460    case uintValue:
   1461       return true;
   1462    case realValue:
   1463       // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
   1464       // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
   1465       // require the value to be strictly less than the limit.
   1466       return value_.real_ >= 0 &&
   1467              value_.real_ < maxUInt64AsDouble &&
   1468              IsIntegral(value_.real_);
   1469    default:
   1470       break;
   1471    }
   1472 # endif  // JSON_HAS_INT64
   1473    return false;
   1474 }
   1475 
   1476 
   1477 bool
   1478 Value::isIntegral() const
   1479 {
   1480 #if defined(JSON_HAS_INT64)
   1481   return isInt64() || isUInt64();
   1482 #else
   1483   return isInt() || isUInt();
   1484 #endif
   1485 }
   1486 
   1487 
   1488 bool
   1489 Value::isDouble() const
   1490 {
   1491    return type_ == realValue || isIntegral();
   1492 }
   1493 
   1494 
   1495 bool
   1496 Value::isNumeric() const
   1497 {
   1498    return isIntegral() || isDouble();
   1499 }
   1500 
   1501 
   1502 bool
   1503 Value::isString() const
   1504 {
   1505    return type_ == stringValue;
   1506 }
   1507 
   1508 
   1509 bool
   1510 Value::isArray() const
   1511 {
   1512    return type_ == arrayValue;
   1513 }
   1514 
   1515 
   1516 bool
   1517 Value::isObject() const
   1518 {
   1519    return type_ == objectValue;
   1520 }
   1521 
   1522 
   1523 void
   1524 Value::setComment( const char *comment,
   1525                    CommentPlacement placement )
   1526 {
   1527    if ( !comments_ )
   1528       comments_ = new CommentInfo[numberOfCommentPlacement];
   1529    comments_[placement].setComment( comment );
   1530 }
   1531 
   1532 
   1533 void
   1534 Value::setComment( const std::string &comment,
   1535                    CommentPlacement placement )
   1536 {
   1537    setComment( comment.c_str(), placement );
   1538 }
   1539 
   1540 
   1541 bool
   1542 Value::hasComment( CommentPlacement placement ) const
   1543 {
   1544    return comments_ != 0  &&  comments_[placement].comment_ != 0;
   1545 }
   1546 
   1547 std::string
   1548 Value::getComment( CommentPlacement placement ) const
   1549 {
   1550    if ( hasComment(placement) )
   1551       return comments_[placement].comment_;
   1552    return "";
   1553 }
   1554 
   1555 
   1556 std::string
   1557 Value::toStyledString() const
   1558 {
   1559    StyledWriter writer;
   1560    return writer.write( *this );
   1561 }
   1562 
   1563 
   1564 Value::const_iterator
   1565 Value::begin() const
   1566 {
   1567    switch ( type_ )
   1568    {
   1569 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1570    case arrayValue:
   1571       if ( value_.array_ )
   1572       {
   1573          ValueInternalArray::IteratorState it;
   1574          value_.array_->makeBeginIterator( it );
   1575          return const_iterator( it );
   1576       }
   1577       break;
   1578    case objectValue:
   1579       if ( value_.map_ )
   1580       {
   1581          ValueInternalMap::IteratorState it;
   1582          value_.map_->makeBeginIterator( it );
   1583          return const_iterator( it );
   1584       }
   1585       break;
   1586 #else
   1587    case arrayValue:
   1588    case objectValue:
   1589       if ( value_.map_ )
   1590          return const_iterator( value_.map_->begin() );
   1591       break;
   1592 #endif
   1593    default:
   1594       break;
   1595    }
   1596    return const_iterator();
   1597 }
   1598 
   1599 Value::const_iterator
   1600 Value::end() const
   1601 {
   1602    switch ( type_ )
   1603    {
   1604 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1605    case arrayValue:
   1606       if ( value_.array_ )
   1607       {
   1608          ValueInternalArray::IteratorState it;
   1609          value_.array_->makeEndIterator( it );
   1610          return const_iterator( it );
   1611       }
   1612       break;
   1613    case objectValue:
   1614       if ( value_.map_ )
   1615       {
   1616          ValueInternalMap::IteratorState it;
   1617          value_.map_->makeEndIterator( it );
   1618          return const_iterator( it );
   1619       }
   1620       break;
   1621 #else
   1622    case arrayValue:
   1623    case objectValue:
   1624       if ( value_.map_ )
   1625          return const_iterator( value_.map_->end() );
   1626       break;
   1627 #endif
   1628    default:
   1629       break;
   1630    }
   1631    return const_iterator();
   1632 }
   1633 
   1634 
   1635 Value::iterator
   1636 Value::begin()
   1637 {
   1638    switch ( type_ )
   1639    {
   1640 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1641    case arrayValue:
   1642       if ( value_.array_ )
   1643       {
   1644          ValueInternalArray::IteratorState it;
   1645          value_.array_->makeBeginIterator( it );
   1646          return iterator( it );
   1647       }
   1648       break;
   1649    case objectValue:
   1650       if ( value_.map_ )
   1651       {
   1652          ValueInternalMap::IteratorState it;
   1653          value_.map_->makeBeginIterator( it );
   1654          return iterator( it );
   1655       }
   1656       break;
   1657 #else
   1658    case arrayValue:
   1659    case objectValue:
   1660       if ( value_.map_ )
   1661          return iterator( value_.map_->begin() );
   1662       break;
   1663 #endif
   1664    default:
   1665       break;
   1666    }
   1667    return iterator();
   1668 }
   1669 
   1670 Value::iterator
   1671 Value::end()
   1672 {
   1673    switch ( type_ )
   1674    {
   1675 #ifdef JSON_VALUE_USE_INTERNAL_MAP
   1676    case arrayValue:
   1677       if ( value_.array_ )
   1678       {
   1679          ValueInternalArray::IteratorState it;
   1680          value_.array_->makeEndIterator( it );
   1681          return iterator( it );
   1682       }
   1683       break;
   1684    case objectValue:
   1685       if ( value_.map_ )
   1686       {
   1687          ValueInternalMap::IteratorState it;
   1688          value_.map_->makeEndIterator( it );
   1689          return iterator( it );
   1690       }
   1691       break;
   1692 #else
   1693    case arrayValue:
   1694    case objectValue:
   1695       if ( value_.map_ )
   1696          return iterator( value_.map_->end() );
   1697       break;
   1698 #endif
   1699    default:
   1700       break;
   1701    }
   1702    return iterator();
   1703 }
   1704 
   1705 
   1706 // class PathArgument
   1707 // //////////////////////////////////////////////////////////////////
   1708 
   1709 PathArgument::PathArgument()
   1710    : key_()
   1711    , index_()
   1712    , kind_( kindNone )
   1713 {
   1714 }
   1715 
   1716 
   1717 PathArgument::PathArgument( ArrayIndex index )
   1718    : key_()
   1719    , index_( index )
   1720    , kind_( kindIndex )
   1721 {
   1722 }
   1723 
   1724 
   1725 PathArgument::PathArgument( const char *key )
   1726    : key_( key )
   1727    , index_()
   1728    , kind_( kindKey )
   1729 {
   1730 }
   1731 
   1732 
   1733 PathArgument::PathArgument( const std::string &key )
   1734    : key_( key.c_str() )
   1735    , index_()
   1736    , kind_( kindKey )
   1737 {
   1738 }
   1739 
   1740 // class Path
   1741 // //////////////////////////////////////////////////////////////////
   1742 
   1743 Path::Path( const std::string &path,
   1744             const PathArgument &a1,
   1745             const PathArgument &a2,
   1746             const PathArgument &a3,
   1747             const PathArgument &a4,
   1748             const PathArgument &a5 )
   1749 {
   1750    InArgs in;
   1751    in.push_back( &a1 );
   1752    in.push_back( &a2 );
   1753    in.push_back( &a3 );
   1754    in.push_back( &a4 );
   1755    in.push_back( &a5 );
   1756    makePath( path, in );
   1757 }
   1758 
   1759 
   1760 void
   1761 Path::makePath( const std::string &path,
   1762                 const InArgs &in )
   1763 {
   1764    const char *current = path.c_str();
   1765    const char *end = current + path.length();
   1766    InArgs::const_iterator itInArg = in.begin();
   1767    while ( current != end )
   1768    {
   1769       if ( *current == '[' )
   1770       {
   1771          ++current;
   1772          if ( *current == '%' )
   1773             addPathInArg( path, in, itInArg, PathArgument::kindIndex );
   1774          else
   1775          {
   1776             ArrayIndex index = 0;
   1777             for ( ; current != end && *current >= '0'  &&  *current <= '9'; ++current )
   1778                index = index * 10 + ArrayIndex(*current - '0');
   1779             args_.push_back( index );
   1780          }
   1781          if ( current == end  ||  *current++ != ']' )
   1782             invalidPath( path, int(current - path.c_str()) );
   1783       }
   1784       else if ( *current == '%' )
   1785       {
   1786          addPathInArg( path, in, itInArg, PathArgument::kindKey );
   1787          ++current;
   1788       }
   1789       else if ( *current == '.' )
   1790       {
   1791          ++current;
   1792       }
   1793       else
   1794       {
   1795          const char *beginName = current;
   1796          while ( current != end  &&  !strchr( "[.", *current ) )
   1797             ++current;
   1798          args_.push_back( std::string( beginName, current ) );
   1799       }
   1800    }
   1801 }
   1802 
   1803 
   1804 void
   1805 Path::addPathInArg( const std::string &path,
   1806                     const InArgs &in,
   1807                     InArgs::const_iterator &itInArg,
   1808                     PathArgument::Kind kind )
   1809 {
   1810    if ( itInArg == in.end() )
   1811    {
   1812       // Error: missing argument %d
   1813    }
   1814    else if ( (*itInArg)->kind_ != kind )
   1815    {
   1816       // Error: bad argument type
   1817    }
   1818    else
   1819    {
   1820       args_.push_back( **itInArg );
   1821    }
   1822 }
   1823 
   1824 
   1825 void
   1826 Path::invalidPath( const std::string &path,
   1827                    int location )
   1828 {
   1829    // Error: invalid path.
   1830 }
   1831 
   1832 
   1833 const Value &
   1834 Path::resolve( const Value &root ) const
   1835 {
   1836    const Value *node = &root;
   1837    for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
   1838    {
   1839       const PathArgument &arg = *it;
   1840       if ( arg.kind_ == PathArgument::kindIndex )
   1841       {
   1842          if ( !node->isArray()  ||  !node->isValidIndex( arg.index_ ) )
   1843          {
   1844             // Error: unable to resolve path (array value expected at position...
   1845          }
   1846          node = &((*node)[arg.index_]);
   1847       }
   1848       else if ( arg.kind_ == PathArgument::kindKey )
   1849       {
   1850          if ( !node->isObject() )
   1851          {
   1852             // Error: unable to resolve path (object value expected at position...)
   1853          }
   1854          node = &((*node)[arg.key_]);
   1855          if ( node == &Value::null )
   1856          {
   1857             // Error: unable to resolve path (object has no member named '' at position...)
   1858          }
   1859       }
   1860    }
   1861    return *node;
   1862 }
   1863 
   1864 
   1865 Value
   1866 Path::resolve( const Value &root,
   1867                const Value &defaultValue ) const
   1868 {
   1869    const Value *node = &root;
   1870    for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
   1871    {
   1872       const PathArgument &arg = *it;
   1873       if ( arg.kind_ == PathArgument::kindIndex )
   1874       {
   1875          if ( !node->isArray()  ||  !node->isValidIndex( arg.index_ ) )
   1876             return defaultValue;
   1877          node = &((*node)[arg.index_]);
   1878       }
   1879       else if ( arg.kind_ == PathArgument::kindKey )
   1880       {
   1881          if ( !node->isObject() )
   1882             return defaultValue;
   1883          node = &((*node)[arg.key_]);
   1884          if ( node == &Value::null )
   1885             return defaultValue;
   1886       }
   1887    }
   1888    return *node;
   1889 }
   1890 
   1891 
   1892 Value &
   1893 Path::make( Value &root ) const
   1894 {
   1895    Value *node = &root;
   1896    for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
   1897    {
   1898       const PathArgument &arg = *it;
   1899       if ( arg.kind_ == PathArgument::kindIndex )
   1900       {
   1901          if ( !node->isArray() )
   1902          {
   1903             // Error: node is not an array at position ...
   1904          }
   1905          node = &((*node)[arg.index_]);
   1906       }
   1907       else if ( arg.kind_ == PathArgument::kindKey )
   1908       {
   1909          if ( !node->isObject() )
   1910          {
   1911             // Error: node is not an object at position...
   1912          }
   1913          node = &((*node)[arg.key_]);
   1914       }
   1915    }
   1916    return *node;
   1917 }
   1918 
   1919 
   1920 } // namespace Json
   1921