Drizzled Public API Documentation

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