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