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