@@ -28,6 +28,8 @@ namespace Json {
2828Features::Features ()
2929 : allowComments_( true )
3030 , strictRoot_( false )
31+ , allowDroppedNullPlaceholders_ ( false )
32+ , allowNumericKeys_ ( false )
3133{
3234}
3335
@@ -45,6 +47,8 @@ Features::strictMode()
4547 Features features;
4648 features.allowComments_ = false ;
4749 features.strictRoot_ = true ;
50+ features.allowDroppedNullPlaceholders_ = false ;
51+ features.allowNumericKeys_ = false ;
4852 return features;
4953}
5054
@@ -230,6 +234,16 @@ Reader::readValue()
230234 case tokenNull:
231235 currentValue () = Value ();
232236 break ;
237+ case tokenArraySeparator:
238+ if ( features_.allowDroppedNullPlaceholders_ )
239+ {
240+ // "Un-read" the current token and mark the current value as a null
241+ // token.
242+ current_--;
243+ currentValue () = Value ();
244+ break ;
245+ }
246+ // Else, fall through...
233247 default :
234248 return addError ( " Syntax error: value, object or array expected." , token );
235249 }
@@ -493,12 +507,24 @@ Reader::readObject( Token &/*tokenStart*/ )
493507 break ;
494508 if ( tokenName.type_ == tokenObjectEnd && name.empty () ) // empty object
495509 return true ;
496- if ( tokenName.type_ != tokenString )
497- break ;
498-
499510 name = " " ;
500- if ( !decodeString ( tokenName, name ) )
501- return recoverFromError ( tokenObjectEnd );
511+ if ( tokenName.type_ == tokenString )
512+ {
513+ if ( !decodeString ( tokenName, name ) )
514+ return recoverFromError ( tokenObjectEnd );
515+ }
516+ else if ( tokenName.type_ == tokenNumber &&
517+ features_.allowNumericKeys_ )
518+ {
519+ Value numberName;
520+ if ( !decodeNumber ( tokenName, numberName ) )
521+ return recoverFromError ( tokenObjectEnd );
522+ name = numberName.asString ();
523+ }
524+ else
525+ {
526+ break ;
527+ }
502528
503529 Token colon;
504530 if ( !readToken ( colon ) || colon.type_ != tokenMemberSeparator )
@@ -582,6 +608,17 @@ Reader::readArray( Token &/*tokenStart*/ )
582608
583609bool
584610Reader::decodeNumber ( Token &token )
611+ {
612+ Value decoded;
613+ if ( !decodeNumber ( token, decoded ) )
614+ return false ;
615+ currentValue () = decoded;
616+ return true ;
617+ }
618+
619+
620+ bool
621+ Reader::decodeNumber ( Token &token, Value &decoded )
585622{
586623 bool isDouble = false ;
587624 for ( Location inspect = token.start_ ; inspect != token.end_ ; ++inspect )
@@ -591,7 +628,7 @@ Reader::decodeNumber( Token &token )
591628 || ( *inspect == ' -' && inspect != token.start_ );
592629 }
593630 if ( isDouble )
594- return decodeDouble ( token );
631+ return decodeDouble ( token, decoded );
595632 // Attempts to parse the number as an integer. If the number is
596633 // larger than the maximum supported value of an integer then
597634 // we decode the number as a double.
@@ -619,23 +656,34 @@ Reader::decodeNumber( Token &token )
619656 current != token.end_ ||
620657 digit > maxIntegerValue % 10 )
621658 {
622- return decodeDouble ( token );
659+ return decodeDouble ( token, decoded );
623660 }
624661 }
625662 value = value * 10 + digit;
626663 }
627664 if ( isNegative )
628- currentValue () = -Value::LargestInt ( value );
665+ decoded = -Value::LargestInt ( value );
629666 else if ( value <= Value::LargestUInt (Value::maxInt) )
630- currentValue () = Value::LargestInt ( value );
667+ decoded = Value::LargestInt ( value );
631668 else
632- currentValue () = value;
669+ decoded = value;
633670 return true ;
634671}
635672
636673
637674bool
638675Reader::decodeDouble ( Token &token )
676+ {
677+ Value decoded;
678+ if ( !decodeDouble ( token, decoded ) )
679+ return false ;
680+ currentValue () = decoded;
681+ return true ;
682+ }
683+
684+
685+ bool
686+ Reader::decodeDouble ( Token &token, Value &decoded )
639687{
640688 double value = 0 ;
641689 const int bufferSize = 32 ;
@@ -669,7 +717,7 @@ Reader::decodeDouble( Token &token )
669717
670718 if ( count != 1 )
671719 return addError ( " '" + std::string ( token.start_ , token.end_ ) + " ' is not a number." , token );
672- currentValue () = value;
720+ decoded = value;
673721 return true ;
674722}
675723
0 commit comments