Skip to content

Commit

Permalink
Added features that allow the reader to accept common non-standard JSON.
Browse files Browse the repository at this point in the history
This is a version of patch open-source-parsers#17, from Clay Wood:

    http://sourceforge.net/p/jsoncpp/patches/17/
  • Loading branch information
jacobsa committed Apr 23, 2014
1 parent 77cd838 commit 642befc
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
6 changes: 6 additions & 0 deletions include/json/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ namespace Json {

/// \c true if root must be either an array or an object value. Default: \c false.
bool strictRoot_;

/// \c true if dropped null placeholders are allowed. Default: \c false.
bool allowDroppedNullPlaceholders_;

/// \c true if numeric object key are allowed. Default: \c false.
bool allowNumericKeys_;
};

} // namespace Json
Expand Down
2 changes: 2 additions & 0 deletions include/json/reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,11 @@ namespace Json {
bool readObject( Token &token );
bool readArray( Token &token );
bool decodeNumber( Token &token );
bool decodeNumber( Token &token, Value &decoded );
bool decodeString( Token &token );
bool decodeString( Token &token, std::string &decoded );
bool decodeDouble( Token &token );
bool decodeDouble( Token &token, Value &decoded );
bool decodeUnicodeCodePoint( Token &token,
Location &current,
Location end,
Expand Down
70 changes: 59 additions & 11 deletions src/lib_json/json_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ namespace Json {
Features::Features()
: allowComments_( true )
, strictRoot_( false )
, allowDroppedNullPlaceholders_ ( false )
, allowNumericKeys_ ( false )
{
}

Expand All @@ -45,6 +47,8 @@ Features::strictMode()
Features features;
features.allowComments_ = false;
features.strictRoot_ = true;
features.allowDroppedNullPlaceholders_ = false;
features.allowNumericKeys_ = false;
return features;
}

Expand Down Expand Up @@ -230,6 +234,16 @@ Reader::readValue()
case tokenNull:
currentValue() = Value();
break;
case tokenArraySeparator:
if ( features_.allowDroppedNullPlaceholders_ )
{
// "Un-read" the current token and mark the current value as a null
// token.
current_--;
currentValue() = Value();
break;
}
// Else, fall through...
default:
return addError( "Syntax error: value, object or array expected.", token );
}
Expand Down Expand Up @@ -493,12 +507,24 @@ Reader::readObject( Token &/*tokenStart*/ )
break;
if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object
return true;
if ( tokenName.type_ != tokenString )
break;

name = "";
if ( !decodeString( tokenName, name ) )
return recoverFromError( tokenObjectEnd );
if ( tokenName.type_ == tokenString )
{
if ( !decodeString( tokenName, name ) )
return recoverFromError( tokenObjectEnd );
}
else if ( tokenName.type_ == tokenNumber &&
features_.allowNumericKeys_ )
{
Value numberName;
if ( !decodeNumber( tokenName, numberName ) )
return recoverFromError( tokenObjectEnd );
name = numberName.asString();
}
else
{
break;
}

Token colon;
if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
Expand Down Expand Up @@ -582,6 +608,17 @@ Reader::readArray( Token &/*tokenStart*/ )

bool
Reader::decodeNumber( Token &token )
{
Value decoded;
if ( !decodeNumber( token, decoded ) )
return false;
currentValue() = decoded;
return true;
}


bool
Reader::decodeNumber( Token &token, Value &decoded )
{
bool isDouble = false;
for ( Location inspect = token.start_; inspect != token.end_; ++inspect )
Expand All @@ -591,7 +628,7 @@ Reader::decodeNumber( Token &token )
|| ( *inspect == '-' && inspect != token.start_ );
}
if ( isDouble )
return decodeDouble( token );
return decodeDouble( token, decoded );
// Attempts to parse the number as an integer. If the number is
// larger than the maximum supported value of an integer then
// we decode the number as a double.
Expand Down Expand Up @@ -619,23 +656,34 @@ Reader::decodeNumber( Token &token )
current != token.end_ ||
digit > maxIntegerValue % 10)
{
return decodeDouble( token );
return decodeDouble( token, decoded );
}
}
value = value * 10 + digit;
}
if ( isNegative )
currentValue() = -Value::LargestInt( value );
decoded = -Value::LargestInt( value );
else if ( value <= Value::LargestUInt(Value::maxInt) )
currentValue() = Value::LargestInt( value );
decoded = Value::LargestInt( value );
else
currentValue() = value;
decoded = value;
return true;
}


bool
Reader::decodeDouble( Token &token )
{
Value decoded;
if ( !decodeDouble( token, decoded ) )
return false;
currentValue() = decoded;
return true;
}


bool
Reader::decodeDouble( Token &token, Value &decoded )
{
double value = 0;
const int bufferSize = 32;
Expand Down Expand Up @@ -669,7 +717,7 @@ Reader::decodeDouble( Token &token )

if ( count != 1 )
return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
currentValue() = value;
decoded = value;
return true;
}

Expand Down

0 comments on commit 642befc

Please sign in to comment.