1 // Copyright 2007-2010 Baptiste Lepilleur
2 // Distributed under MIT license, or public domain if desired and
3 // recognized in your jurisdiction.
4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
7 #include "json_value.h"
8 #include "json_writer.h"
14 # include <cpptl/conststring.h>
16 #include <cstddef> // size_t
17 #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
18 # include "json_batchallocator.h"
19 #endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
21 #define JSON_ASSERT_UNREACHABLE assert( false )
22 #define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
23 #define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message );
27 const Value Value::null;
28 const Int Value::minInt = Int( ~(UInt(-1)/2) );
29 const Int Value::maxInt = Int( UInt(-1)/2 );
30 const UInt Value::maxUInt = UInt(-1);
32 /// Unknown size marker
33 enum { unknown = (unsigned)-1 };
36 /** Duplicates the specified string value.
37 * @param value Pointer to the string to duplicate. Must be zero-terminated if
38 * length is "unknown".
39 * @param length Length of the value. if equals to unknown, then it will be
40 * computed using strlen(value).
41 * @return Pointer on the duplicate instance of string.
44 duplicateStringValue( const char *value,
45 unsigned int length = unknown )
47 if ( length == unknown )
48 length = (unsigned int)strlen(value);
49 char *newString = static_cast<char *>( malloc( length + 1 ) );
50 memcpy( newString, value, length );
51 newString[length] = 0;
56 /** Free the string duplicated by duplicateStringValue().
59 releaseStringValue( char *value )
67 // //////////////////////////////////////////////////////////////////
68 // //////////////////////////////////////////////////////////////////
69 // //////////////////////////////////////////////////////////////////
71 // //////////////////////////////////////////////////////////////////
72 // //////////////////////////////////////////////////////////////////
73 // //////////////////////////////////////////////////////////////////
74 #ifdef JSON_VALUE_USE_INTERNAL_MAP
75 # include "json_internalarray.inl"
76 # include "json_internalmap.inl"
77 #endif // JSON_VALUE_USE_INTERNAL_MAP
79 # include "json_valueiterator.inl"
82 // //////////////////////////////////////////////////////////////////
83 // //////////////////////////////////////////////////////////////////
84 // //////////////////////////////////////////////////////////////////
85 // class Value::CommentInfo
86 // //////////////////////////////////////////////////////////////////
87 // //////////////////////////////////////////////////////////////////
88 // //////////////////////////////////////////////////////////////////
91 Value::CommentInfo::CommentInfo()
96 Value::CommentInfo::~CommentInfo()
99 releaseStringValue( comment_ );
104 Value::CommentInfo::setComment( const char *text )
107 releaseStringValue( comment_ );
109 JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
110 // It seems that /**/ style comments are acceptable as well.
111 comment_ = duplicateStringValue( text );
115 // //////////////////////////////////////////////////////////////////
116 // //////////////////////////////////////////////////////////////////
117 // //////////////////////////////////////////////////////////////////
118 // class Value::CZString
119 // //////////////////////////////////////////////////////////////////
120 // //////////////////////////////////////////////////////////////////
121 // //////////////////////////////////////////////////////////////////
122 # ifndef JSON_VALUE_USE_INTERNAL_MAP
124 // Notes: index_ indicates if the string was allocated when
125 // a string is stored.
127 Value::CZString::CZString( ArrayIndex index )
133 Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
134 : cstr_( allocate == duplicate ? duplicateStringValue(cstr)
140 Value::CZString::CZString( const CZString &other )
141 : cstr_( other.index_ != noDuplication && other.cstr_ != 0
142 ? duplicateStringValue( other.cstr_ )
144 , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
149 Value::CZString::~CZString()
151 if ( cstr_ && index_ == duplicate )
152 releaseStringValue( const_cast<char *>( cstr_ ) );
156 Value::CZString::swap( CZString &other )
158 std::swap( cstr_, other.cstr_ );
159 std::swap( index_, other.index_ );
163 Value::CZString::operator =( const CZString &other )
165 CZString temp( other );
171 Value::CZString::operator<( const CZString &other ) const
174 return strcmp( cstr_, other.cstr_ ) < 0;
175 return index_ < other.index_;
179 Value::CZString::operator==( const CZString &other ) const
182 return strcmp( cstr_, other.cstr_ ) == 0;
183 return index_ == other.index_;
188 Value::CZString::index() const
195 Value::CZString::c_str() const
201 Value::CZString::isStaticString() const
203 return index_ == noDuplication;
206 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
209 // //////////////////////////////////////////////////////////////////
210 // //////////////////////////////////////////////////////////////////
211 // //////////////////////////////////////////////////////////////////
212 // class Value::Value
213 // //////////////////////////////////////////////////////////////////
214 // //////////////////////////////////////////////////////////////////
215 // //////////////////////////////////////////////////////////////////
217 /*! \internal Default constructor initialization must be equivalent to:
218 * memset( this, 0, sizeof(Value) )
219 * This optimization is used in ValueInternalMap fast allocator.
221 Value::Value( ValueType type )
225 # ifdef JSON_VALUE_USE_INTERNAL_MAP
243 #ifndef JSON_VALUE_USE_INTERNAL_MAP
246 value_.map_ = new ObjectValues();
250 value_.array_ = arrayAllocator()->newArray();
253 value_.map_ = mapAllocator()->newMap();
257 value_.bool_ = false;
260 JSON_ASSERT_UNREACHABLE;
265 #if !defined(JSON_NO_INT64)
266 Value::Value( ArrayIndex value )
269 # ifdef JSON_VALUE_USE_INTERNAL_MAP
273 value_.uint_ = value;
276 Value::Value( int value )
279 # ifdef JSON_VALUE_USE_INTERNAL_MAP
286 #endif // if !defined(JSON_NO_INT64)
289 Value::Value( Int value )
292 # ifdef JSON_VALUE_USE_INTERNAL_MAP
300 Value::Value( UInt value )
303 # ifdef JSON_VALUE_USE_INTERNAL_MAP
307 value_.uint_ = value;
310 Value::Value( double value )
313 # ifdef JSON_VALUE_USE_INTERNAL_MAP
317 value_.real_ = value;
320 Value::Value( const char *value )
321 : type_( stringValue )
324 # ifdef JSON_VALUE_USE_INTERNAL_MAP
328 value_.string_ = duplicateStringValue( value );
332 Value::Value( const char *beginValue,
333 const char *endValue )
334 : type_( stringValue )
337 # ifdef JSON_VALUE_USE_INTERNAL_MAP
341 value_.string_ = duplicateStringValue( beginValue,
342 (unsigned int)(endValue - beginValue) );
346 Value::Value( const std::string &value )
347 : type_( stringValue )
350 # ifdef JSON_VALUE_USE_INTERNAL_MAP
354 value_.string_ = duplicateStringValue( value.c_str(),
355 (unsigned int)value.length() );
359 Value::Value( const StaticString &value )
360 : type_( stringValue )
361 , allocated_( false )
363 # ifdef JSON_VALUE_USE_INTERNAL_MAP
367 value_.string_ = const_cast<char *>( value.c_str() );
371 # ifdef JSON_USE_CPPTL
372 Value::Value( const CppTL::ConstString &value )
373 : type_( stringValue )
376 # ifdef JSON_VALUE_USE_INTERNAL_MAP
380 value_.string_ = duplicateStringValue( value, value.length() );
384 Value::Value( bool value )
385 : type_( booleanValue )
387 # ifdef JSON_VALUE_USE_INTERNAL_MAP
391 value_.bool_ = value;
395 Value::Value( const Value &other )
396 : type_( other.type_ )
398 # ifdef JSON_VALUE_USE_INTERNAL_MAP
409 value_ = other.value_;
412 if ( other.value_.string_ )
414 value_.string_ = duplicateStringValue( other.value_.string_ );
420 #ifndef JSON_VALUE_USE_INTERNAL_MAP
423 value_.map_ = new ObjectValues( *other.value_.map_ );
427 value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
430 value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
434 JSON_ASSERT_UNREACHABLE;
436 if ( other.comments_ )
438 comments_ = new CommentInfo[numberOfCommentPlacement];
439 for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
441 const CommentInfo &otherComment = other.comments_[comment];
442 if ( otherComment.comment_ )
443 comments_[comment].setComment( otherComment.comment_ );
461 releaseStringValue( value_.string_ );
463 #ifndef JSON_VALUE_USE_INTERNAL_MAP
470 arrayAllocator()->destructArray( value_.array_ );
473 mapAllocator()->destructMap( value_.map_ );
477 JSON_ASSERT_UNREACHABLE;
485 Value::operator=( const Value &other )
493 Value::swap( Value &other )
495 ValueType temp = type_;
498 std::swap( value_, other.value_ );
499 int temp2 = allocated_;
500 allocated_ = other.allocated_;
501 other.allocated_ = temp2;
512 Value::compare( const Value &other )
515 int typeDelta = other.type_ - type_;
520 return other.type_ == type_;
522 if ( other.type_.isNumeric()
530 delete value_.array_;
535 JSON_ASSERT_UNREACHABLE;
538 return 0; // unreachable
542 Value::operator <( const Value &other ) const
544 int typeDelta = type_ - other.type_;
546 return typeDelta < 0 ? true : false;
552 return value_.int_ < other.value_.int_;
554 return value_.uint_ < other.value_.uint_;
556 return value_.real_ < other.value_.real_;
558 return value_.bool_ < other.value_.bool_;
560 return ( value_.string_ == 0 && other.value_.string_ )
561 || ( other.value_.string_
563 && strcmp( value_.string_, other.value_.string_ ) < 0 );
564 #ifndef JSON_VALUE_USE_INTERNAL_MAP
568 int delta = int( value_.map_->size() - other.value_.map_->size() );
571 return (*value_.map_) < (*other.value_.map_);
575 return value_.array_->compare( *(other.value_.array_) ) < 0;
577 return value_.map_->compare( *(other.value_.map_) ) < 0;
580 JSON_ASSERT_UNREACHABLE;
582 return 0; // unreachable
586 Value::operator <=( const Value &other ) const
588 return !(other > *this);
592 Value::operator >=( const Value &other ) const
594 return !(*this < other);
598 Value::operator >( const Value &other ) const
600 return other < *this;
604 Value::operator ==( const Value &other ) const
606 //if ( type_ != other.type_ )
608 // attempt to take address of bit-field structure member `Json::Value::type_'
609 // Beats me, but a temp solves the problem.
610 int temp = other.type_;
618 return value_.int_ == other.value_.int_;
620 return value_.uint_ == other.value_.uint_;
622 return value_.real_ == other.value_.real_;
624 return value_.bool_ == other.value_.bool_;
626 return ( value_.string_ == other.value_.string_ )
627 || ( other.value_.string_
629 && strcmp( value_.string_, other.value_.string_ ) == 0 );
630 #ifndef JSON_VALUE_USE_INTERNAL_MAP
633 return value_.map_->size() == other.value_.map_->size()
634 && (*value_.map_) == (*other.value_.map_);
637 return value_.array_->compare( *(other.value_.array_) ) == 0;
639 return value_.map_->compare( *(other.value_.map_) ) == 0;
642 JSON_ASSERT_UNREACHABLE;
644 return 0; // unreachable
648 Value::operator !=( const Value &other ) const
650 return !( *this == other );
654 Value::asCString() const
656 JSON_ASSERT( type_ == stringValue );
657 return value_.string_;
662 Value::asString() const
669 return value_.string_ ? value_.string_ : "";
671 return value_.bool_ ? "true" : "false";
677 JSON_ASSERT_MESSAGE( false, "Type is not convertible to string" );
679 JSON_ASSERT_UNREACHABLE;
681 return ""; // unreachable
684 # ifdef JSON_USE_CPPTL
686 Value::asConstString() const
688 return CppTL::ConstString( asString().c_str() );
702 JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" );
705 JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
706 return Int( value_.real_ );
708 return value_.bool_ ? 1 : 0;
712 JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" );
714 JSON_ASSERT_UNREACHABLE;
716 return 0; // unreachable;
720 Value::asUInt() const
727 JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
732 JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
733 return UInt( value_.real_ );
735 return value_.bool_ ? 1 : 0;
739 JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" );
741 JSON_ASSERT_UNREACHABLE;
743 return 0; // unreachable;
747 Value::asDouble() const
754 return static_cast<double>( value_.int_ );
756 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
757 return static_cast<double>( value_.uint_ );
758 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
759 return static_cast<double>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
760 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
764 return value_.bool_ ? 1.0 : 0.0;
768 JSON_ASSERT_MESSAGE( false, "Type is not convertible to double" );
770 JSON_ASSERT_UNREACHABLE;
772 return 0; // unreachable;
776 Value::asBool() const
784 return value_.int_ != 0;
786 return value_.real_ != 0.0;
790 return value_.string_ && value_.string_[0] != 0;
793 return value_.map_->size() != 0;
795 JSON_ASSERT_UNREACHABLE;
797 return false; // unreachable;
802 Value::isConvertibleTo( ValueType other ) const
809 return ( other == nullValue && value_.int_ == 0 )
811 || ( other == uintValue && value_.int_ >= 0 )
812 || other == realValue
813 || other == stringValue
814 || other == booleanValue;
816 return ( other == nullValue && value_.uint_ == 0 )
817 || ( other == intValue && value_.uint_ <= (unsigned)maxInt )
818 || other == uintValue
819 || other == realValue
820 || other == stringValue
821 || other == booleanValue;
823 return ( other == nullValue && value_.real_ == 0.0 )
824 || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
825 || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
826 || other == realValue
827 || other == stringValue
828 || other == booleanValue;
830 return ( other == nullValue && value_.bool_ == false )
832 || other == uintValue
833 || other == realValue
834 || other == stringValue
835 || other == booleanValue;
837 return other == stringValue
838 || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
840 return other == arrayValue
841 || ( other == nullValue && value_.map_->size() == 0 );
843 return other == objectValue
844 || ( other == nullValue && value_.map_->size() == 0 );
846 JSON_ASSERT_UNREACHABLE;
848 return false; // unreachable;
852 /// Number of values in array or object
865 #ifndef JSON_VALUE_USE_INTERNAL_MAP
866 case arrayValue: // size of the array is highest index + 1
867 if ( !value_.map_->empty() )
869 ObjectValues::const_iterator itLast = value_.map_->end();
871 return (*itLast).first.index()+1;
875 return ArrayIndex( value_.map_->size() );
878 return Int( value_.array_->size() );
880 return Int( value_.map_->size() );
883 JSON_ASSERT_UNREACHABLE;
885 return 0; // unreachable;
892 if ( isNull() || isArray() || isObject() )
900 Value::operator!() const
909 JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue );
913 #ifndef JSON_VALUE_USE_INTERNAL_MAP
916 value_.map_->clear();
920 value_.array_->clear();
923 value_.map_->clear();
932 Value::resize( ArrayIndex newSize )
934 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
935 if ( type_ == nullValue )
936 *this = Value( arrayValue );
937 #ifndef JSON_VALUE_USE_INTERNAL_MAP
938 ArrayIndex oldSize = size();
941 else if ( newSize > oldSize )
942 (*this)[ newSize - 1 ];
945 for ( ArrayIndex index = newSize; index < oldSize; ++index )
947 value_.map_->erase( index );
949 assert( size() == newSize );
952 value_.array_->resize( newSize );
958 Value::operator[]( ArrayIndex index )
960 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
961 if ( type_ == nullValue )
962 *this = Value( arrayValue );
963 #ifndef JSON_VALUE_USE_INTERNAL_MAP
964 CZString key( index );
965 ObjectValues::iterator it = value_.map_->lower_bound( key );
966 if ( it != value_.map_->end() && (*it).first == key )
969 ObjectValues::value_type defaultValue( key, null );
970 it = value_.map_->insert( it, defaultValue );
973 return value_.array_->resolveReference( index );
979 Value::operator[]( ArrayIndex index ) const
981 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
982 if ( type_ == nullValue )
984 #ifndef JSON_VALUE_USE_INTERNAL_MAP
985 CZString key( index );
986 ObjectValues::const_iterator it = value_.map_->find( key );
987 if ( it == value_.map_->end() )
991 Value *value = value_.array_->find( index );
992 return value ? *value : null;
998 Value::operator[]( const char *key )
1000 return resolveReference( key, false );
1005 Value::resolveReference( const char *key,
1008 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
1009 if ( type_ == nullValue )
1010 *this = Value( objectValue );
1011 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1012 CZString actualKey( key, isStatic ? CZString::noDuplication
1013 : CZString::duplicateOnCopy );
1014 ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
1015 if ( it != value_.map_->end() && (*it).first == actualKey )
1016 return (*it).second;
1018 ObjectValues::value_type defaultValue( actualKey, null );
1019 it = value_.map_->insert( it, defaultValue );
1020 Value &value = (*it).second;
1023 return value_.map_->resolveReference( key, isStatic );
1029 Value::get( ArrayIndex index,
1030 const Value &defaultValue ) const
1032 const Value *value = &((*this)[index]);
1033 return value == &null ? defaultValue : *value;
1038 Value::isValidIndex( ArrayIndex index ) const
1040 return index < size();
1046 Value::operator[]( const char *key ) const
1048 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
1049 if ( type_ == nullValue )
1051 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1052 CZString actualKey( key, CZString::noDuplication );
1053 ObjectValues::const_iterator it = value_.map_->find( actualKey );
1054 if ( it == value_.map_->end() )
1056 return (*it).second;
1058 const Value *value = value_.map_->find( key );
1059 return value ? *value : null;
1065 Value::operator[]( const std::string &key )
1067 return (*this)[ key.c_str() ];
1072 Value::operator[]( const std::string &key ) const
1074 return (*this)[ key.c_str() ];
1078 Value::operator[]( const StaticString &key )
1080 return resolveReference( key, true );
1084 # ifdef JSON_USE_CPPTL
1086 Value::operator[]( const CppTL::ConstString &key )
1088 return (*this)[ key.c_str() ];
1093 Value::operator[]( const CppTL::ConstString &key ) const
1095 return (*this)[ key.c_str() ];
1101 Value::append( const Value &value )
1103 return (*this)[size()] = value;
1108 Value::get( const char *key,
1109 const Value &defaultValue ) const
1111 const Value *value = &((*this)[key]);
1112 return value == &null ? defaultValue : *value;
1117 Value::get( const std::string &key,
1118 const Value &defaultValue ) const
1120 return get( key.c_str(), defaultValue );
1124 Value::removeMember( const char* key )
1126 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
1127 if ( type_ == nullValue )
1129 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1130 CZString actualKey( key, CZString::noDuplication );
1131 ObjectValues::iterator it = value_.map_->find( actualKey );
1132 if ( it == value_.map_->end() )
1134 Value old(it->second);
1135 value_.map_->erase(it);
1138 Value *value = value_.map_->find( key );
1141 value_.map_.remove( key );
1150 Value::removeMember( const std::string &key )
1152 return removeMember( key.c_str() );
1155 # ifdef JSON_USE_CPPTL
1157 Value::get( const CppTL::ConstString &key,
1158 const Value &defaultValue ) const
1160 return get( key.c_str(), defaultValue );
1165 Value::isMember( const char *key ) const
1167 const Value *value = &((*this)[key]);
1168 return value != &null;
1173 Value::isMember( const std::string &key ) const
1175 return isMember( key.c_str() );
1179 # ifdef JSON_USE_CPPTL
1181 Value::isMember( const CppTL::ConstString &key ) const
1183 return isMember( key.c_str() );
1188 Value::getMemberNames() const
1190 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
1191 if ( type_ == nullValue )
1192 return Value::Members();
1194 members.reserve( value_.map_->size() );
1195 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1196 ObjectValues::const_iterator it = value_.map_->begin();
1197 ObjectValues::const_iterator itEnd = value_.map_->end();
1198 for ( ; it != itEnd; ++it )
1199 members.push_back( std::string( (*it).first.c_str() ) );
1201 ValueInternalMap::IteratorState it;
1202 ValueInternalMap::IteratorState itEnd;
1203 value_.map_->makeBeginIterator( it );
1204 value_.map_->makeEndIterator( itEnd );
1205 for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
1206 members.push_back( std::string( ValueInternalMap::key( it ) ) );
1211 //# ifdef JSON_USE_CPPTL
1213 //Value::enumMemberNames() const
1215 // if ( type_ == objectValue )
1217 // return CppTL::Enum::any( CppTL::Enum::transform(
1218 // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
1219 // MemberNamesTransform() ) );
1221 // return EnumMemberNames();
1226 //Value::enumValues() const
1228 // if ( type_ == objectValue || type_ == arrayValue )
1229 // return CppTL::Enum::anyValues( *(value_.map_),
1230 // CppTL::Type<const Value &>() );
1231 // return EnumValues();
1238 Value::isNull() const
1240 return type_ == nullValue;
1245 Value::isBool() const
1247 return type_ == booleanValue;
1252 Value::isInt() const
1254 return type_ == intValue;
1259 Value::isUInt() const
1261 return type_ == uintValue;
1266 Value::isIntegral() const
1268 return type_ == intValue
1269 || type_ == uintValue
1270 || type_ == booleanValue;
1275 Value::isDouble() const
1277 return type_ == realValue;
1282 Value::isNumeric() const
1284 return isIntegral() || isDouble();
1289 Value::isString() const
1291 return type_ == stringValue;
1296 Value::isArray() const
1298 return type_ == nullValue || type_ == arrayValue;
1303 Value::isObject() const
1305 return type_ == nullValue || type_ == objectValue;
1310 Value::setComment( const char *comment,
1311 CommentPlacement placement )
1314 comments_ = new CommentInfo[numberOfCommentPlacement];
1315 comments_[placement].setComment( comment );
1320 Value::setComment( const std::string &comment,
1321 CommentPlacement placement )
1323 setComment( comment.c_str(), placement );
1328 Value::hasComment( CommentPlacement placement ) const
1330 return comments_ != 0 && comments_[placement].comment_ != 0;
1334 Value::getComment( CommentPlacement placement ) const
1336 if ( hasComment(placement) )
1337 return comments_[placement].comment_;
1343 Value::toStyledString() const
1345 StyledWriter writer;
1346 return writer.write( *this );
1350 Value::const_iterator
1351 Value::begin() const
1355 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1357 if ( value_.array_ )
1359 ValueInternalArray::IteratorState it;
1360 value_.array_->makeBeginIterator( it );
1361 return const_iterator( it );
1367 ValueInternalMap::IteratorState it;
1368 value_.map_->makeBeginIterator( it );
1369 return const_iterator( it );
1376 return const_iterator( value_.map_->begin() );
1382 return const_iterator();
1385 Value::const_iterator
1390 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1392 if ( value_.array_ )
1394 ValueInternalArray::IteratorState it;
1395 value_.array_->makeEndIterator( it );
1396 return const_iterator( it );
1402 ValueInternalMap::IteratorState it;
1403 value_.map_->makeEndIterator( it );
1404 return const_iterator( it );
1411 return const_iterator( value_.map_->end() );
1417 return const_iterator();
1426 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1428 if ( value_.array_ )
1430 ValueInternalArray::IteratorState it;
1431 value_.array_->makeBeginIterator( it );
1432 return iterator( it );
1438 ValueInternalMap::IteratorState it;
1439 value_.map_->makeBeginIterator( it );
1440 return iterator( it );
1447 return iterator( value_.map_->begin() );
1461 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1463 if ( value_.array_ )
1465 ValueInternalArray::IteratorState it;
1466 value_.array_->makeEndIterator( it );
1467 return iterator( it );
1473 ValueInternalMap::IteratorState it;
1474 value_.map_->makeEndIterator( it );
1475 return iterator( it );
1482 return iterator( value_.map_->end() );
1492 // class PathArgument
1493 // //////////////////////////////////////////////////////////////////
1495 PathArgument::PathArgument()
1501 PathArgument::PathArgument( ArrayIndex index )
1503 , kind_( kindIndex )
1508 PathArgument::PathArgument( const char *key )
1515 PathArgument::PathArgument( const std::string &key )
1516 : key_( key.c_str() )
1522 // //////////////////////////////////////////////////////////////////
1524 Path::Path( const std::string &path,
1525 const PathArgument &a1,
1526 const PathArgument &a2,
1527 const PathArgument &a3,
1528 const PathArgument &a4,
1529 const PathArgument &a5 )
1532 in.push_back( &a1 );
1533 in.push_back( &a2 );
1534 in.push_back( &a3 );
1535 in.push_back( &a4 );
1536 in.push_back( &a5 );
1537 makePath( path, in );
1542 Path::makePath( const std::string &path,
1545 const char *current = path.c_str();
1546 const char *end = current + path.length();
1547 InArgs::const_iterator itInArg = in.begin();
1548 while ( current != end )
1550 if ( *current == '[' )
1553 if ( *current == '%' )
1554 addPathInArg( path, in, itInArg, PathArgument::kindIndex );
1557 ArrayIndex index = 0;
1558 for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
1559 index = index * 10 + ArrayIndex(*current - '0');
1560 args_.push_back( index );
1562 if ( current == end || *current++ != ']' )
1563 invalidPath( path, int(current - path.c_str()) );
1565 else if ( *current == '%' )
1567 addPathInArg( path, in, itInArg, PathArgument::kindKey );
1570 else if ( *current == '.' )
1576 const char *beginName = current;
1577 while ( current != end && !strchr( "[.", *current ) )
1579 args_.push_back( std::string( beginName, current ) );
1586 Path::addPathInArg( const std::string &path,
1588 InArgs::const_iterator &itInArg,
1589 PathArgument::Kind kind )
1591 if ( itInArg == in.end() )
1593 // Error: missing argument %d
1595 else if ( (*itInArg)->kind_ != kind )
1597 // Error: bad argument type
1601 args_.push_back( **itInArg );
1607 Path::invalidPath( const std::string &path,
1610 // Error: invalid path.
1615 Path::resolve( const Value &root ) const
1617 const Value *node = &root;
1618 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
1620 const PathArgument &arg = *it;
1621 if ( arg.kind_ == PathArgument::kindIndex )
1623 if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
1625 // Error: unable to resolve path (array value expected at position...
1627 node = &((*node)[arg.index_]);
1629 else if ( arg.kind_ == PathArgument::kindKey )
1631 if ( !node->isObject() )
1633 // Error: unable to resolve path (object value expected at position...)
1635 node = &((*node)[arg.key_]);
1636 if ( node == &Value::null )
1638 // Error: unable to resolve path (object has no member named '' at position...)
1647 Path::resolve( const Value &root,
1648 const Value &defaultValue ) const
1650 const Value *node = &root;
1651 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
1653 const PathArgument &arg = *it;
1654 if ( arg.kind_ == PathArgument::kindIndex )
1656 if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
1657 return defaultValue;
1658 node = &((*node)[arg.index_]);
1660 else if ( arg.kind_ == PathArgument::kindKey )
1662 if ( !node->isObject() )
1663 return defaultValue;
1664 node = &((*node)[arg.key_]);
1665 if ( node == &Value::null )
1666 return defaultValue;
1674 Path::make( Value &root ) const
1676 Value *node = &root;
1677 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
1679 const PathArgument &arg = *it;
1680 if ( arg.kind_ == PathArgument::kindIndex )
1682 if ( !node->isArray() )
1684 // Error: node is not an array at position ...
1686 node = &((*node)[arg.index_]);
1688 else if ( arg.kind_ == PathArgument::kindKey )
1690 if ( !node->isObject() )
1692 // Error: node is not an object at position...
1694 node = &((*node)[arg.key_]);