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