arnaucube
arnaucube/commonroutesServerPublic Self-hosted repository
commonroutesServer/www/plugins/ionic-plugin-keyboard/src/blackberry10/native/public/json_value.cpp
www/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