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