Added features that allow the reader to accept common non-standard JSON.
This is a version of patch #17, from Clay Wood:
http://sourceforge.net/p/jsoncpp/patches/17/
diff --git a/include/json/features.h b/include/json/features.h
index 4353278..221d8ff 100644
--- a/include/json/features.h
+++ b/include/json/features.h
@@ -42,6 +42,12 @@
/// \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
diff --git a/include/json/reader.h b/include/json/reader.h
index 3d8f628..0771342 100644
--- a/include/json/reader.h
+++ b/include/json/reader.h
@@ -146,9 +146,11 @@
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 ¤t,
Location end,
diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp
index ed4f7a3..9ba4024 100644
--- a/src/lib_json/json_reader.cpp
+++ b/src/lib_json/json_reader.cpp
@@ -28,6 +28,8 @@
Features::Features()
: allowComments_( true )
, strictRoot_( false )
+ , allowDroppedNullPlaceholders_ ( false )
+ , allowNumericKeys_ ( false )
{
}
@@ -45,6 +47,8 @@
Features features;
features.allowComments_ = false;
features.strictRoot_ = true;
+ features.allowDroppedNullPlaceholders_ = false;
+ features.allowNumericKeys_ = false;
return features;
}
@@ -230,6 +234,16 @@
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 );
}
@@ -493,12 +507,24 @@
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 )
@@ -583,6 +609,17 @@
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 )
{
@@ -591,7 +628,7 @@
|| ( *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.
@@ -619,17 +656,17 @@
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;
}
@@ -637,6 +674,17 @@
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;
int count;
@@ -669,7 +717,7 @@
if ( count != 1 )
return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
- currentValue() = value;
+ decoded = value;
return true;
}