Drizzled Public API Documentation

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