Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

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