Coverage Report

Created: 2017-02-05 08:41

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