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