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