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