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