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