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