comparison third_party/json/json_value.cpp @ 0:add35537fdbb tip

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