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