Skip to content

Commit 642befc

Browse files
committed
Added features that allow the reader to accept common non-standard JSON.
This is a version of patch open-source-parsers#17, from Clay Wood: http://sourceforge.net/p/jsoncpp/patches/17/
1 parent 77cd838 commit 642befc

3 files changed

Lines changed: 67 additions & 11 deletions

File tree

include/json/features.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ namespace Json {
4242

4343
/// \c true if root must be either an array or an object value. Default: \c false.
4444
bool strictRoot_;
45+
46+
/// \c true if dropped null placeholders are allowed. Default: \c false.
47+
bool allowDroppedNullPlaceholders_;
48+
49+
/// \c true if numeric object key are allowed. Default: \c false.
50+
bool allowNumericKeys_;
4551
};
4652

4753
} // namespace Json

include/json/reader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,11 @@ namespace Json {
146146
bool readObject( Token &token );
147147
bool readArray( Token &token );
148148
bool decodeNumber( Token &token );
149+
bool decodeNumber( Token &token, Value &decoded );
149150
bool decodeString( Token &token );
150151
bool decodeString( Token &token, std::string &decoded );
151152
bool decodeDouble( Token &token );
153+
bool decodeDouble( Token &token, Value &decoded );
152154
bool decodeUnicodeCodePoint( Token &token,
153155
Location &current,
154156
Location end,

src/lib_json/json_reader.cpp

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace Json {
2828
Features::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

583609
bool
584610
Reader::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

637674
bool
638675
Reader::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

Comments
 (0)