mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-01-06 08:41:10 +01:00
Major rework of 64 integer support: 64 bits integer are only returned when explicitly request via Json::Value::asInt64(), unlike previous implementation where Json::Value::asInt() returned a 64 bits integer.
This eases porting portable code and does not break compatibility with the previous release. Json::Value::asLargestInt() has also be added to ease writing portable code independent of 64 bits integer support. It is typically used to implement writers.
This commit is contained in:
parent
5c5628aec2
commit
842e9ac54b
35
NEWS.txt
35
NEWS.txt
@ -18,17 +18,38 @@
|
|||||||
initialization/destruction order issues (bug #2934500).
|
initialization/destruction order issues (bug #2934500).
|
||||||
The DefaultValueAllocator has been inlined in code.
|
The DefaultValueAllocator has been inlined in code.
|
||||||
|
|
||||||
- Added support for 64 bits integer. Json::Int and Json::UInt are
|
- Added support for 64 bits integer:
|
||||||
now 64 bits integers on system that support them (more precisely
|
|
||||||
they are of the size of long long, so if it is 128 bits it will
|
Types Json::Int64 and Json::UInt64 have been added. They are aliased
|
||||||
also work).
|
to 64 bits integers on system that support them (based on __int64 on
|
||||||
|
Microsoft Visual Studio platform, and long long on other platforms).
|
||||||
|
|
||||||
|
Types Json::LargestInt and Json::LargestUInt have been added. They are
|
||||||
|
aliased to the largest integer type supported:
|
||||||
|
either Json::Int/Json::UInt or Json::Int64/Json::UInt64 respectively.
|
||||||
|
|
||||||
|
Json::Value::asInt() and Json::Value::asUInt() still returns plain
|
||||||
|
"int" based types, but asserts if an attempt is made to retrieve
|
||||||
|
a 64 bits value that can not represented as the return type.
|
||||||
|
|
||||||
|
Json::Value::asInt64() and Json::Value::asUInt64() have been added
|
||||||
|
to obtain the 64 bits integer value.
|
||||||
|
|
||||||
|
Json::Value::asLargestInt() and Json::Value::asLargestUInt() returns
|
||||||
|
the integer as a LargestInt/LargestUInt respectively. Those functions
|
||||||
|
functions are typically used when implementing writer.
|
||||||
|
|
||||||
|
The reader attempts to read number as 64 bits integer, and fall back
|
||||||
|
to reading a double if the number is not in the range of 64 bits
|
||||||
|
integer.
|
||||||
|
|
||||||
Warning: Json::Value::asInt() and Json::Value::asUInt() now returns
|
Warning: Json::Value::asInt() and Json::Value::asUInt() now returns
|
||||||
long long. This changes break code that was passing the return value
|
long long. This changes break code that was passing the return value
|
||||||
to *printf() function.
|
to *printf() function.
|
||||||
|
|
||||||
Notes: you can switch back to the 32 bits only behavior by defining the
|
Support for 64 bits integer can be disabled by defining the macro
|
||||||
macro JSON_NO_INT64 (se include/json/config.h).
|
JSON_NO_INT64 (uncomment it in json/config.h for example), though
|
||||||
|
it should have no impact on existing usage.
|
||||||
|
|
||||||
- The type Json::ArrayIndex is used for indexes of a JSON value array. It
|
- The type Json::ArrayIndex is used for indexes of a JSON value array. It
|
||||||
is an unsigned int (typically 32 bits).
|
is an unsigned int (typically 32 bits).
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for integer
|
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for integer
|
||||||
// Storages.
|
// Storages, and 64 bits integer support is disabled.
|
||||||
// #define JSON_NO_INT64 1
|
// #define JSON_NO_INT64 1
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6
|
#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6
|
||||||
@ -57,18 +57,24 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace Json {
|
namespace Json {
|
||||||
# if defined(JSON_NO_INT64)
|
|
||||||
typedef int Int;
|
typedef int Int;
|
||||||
typedef unsigned int UInt;
|
typedef unsigned int UInt;
|
||||||
|
# if defined(JSON_NO_INT64)
|
||||||
|
typedef int LargestInt;
|
||||||
|
typedef unsigned int LargestUInt;
|
||||||
|
# undef JSON_HAS_INT64
|
||||||
# else // if defined(JSON_NO_INT64)
|
# else // if defined(JSON_NO_INT64)
|
||||||
// For Microsoft Visual use specific types as long long is not supported
|
// For Microsoft Visual use specific types as long long is not supported
|
||||||
# if defined(_MSC_VER) // Microsoft Visual Studio
|
# if defined(_MSC_VER) // Microsoft Visual Studio
|
||||||
typedef __int64 Int;
|
typedef __int64 Int64;
|
||||||
typedef unsigned __int64 UInt;
|
typedef unsigned __int64 UInt64;
|
||||||
# else // if defined(_MSC_VER) // Other platforms, use long long
|
# else // if defined(_MSC_VER) // Other platforms, use long long
|
||||||
typedef long long int Int;
|
typedef long long int Int64;
|
||||||
typedef unsigned long long int UInt;
|
typedef unsigned long long int UInt64;
|
||||||
# endif // if defined(_MSC_VER)
|
# endif // if defined(_MSC_VER)
|
||||||
|
typedef Int64 LargestInt;
|
||||||
|
typedef UInt64 LargestUInt;
|
||||||
|
# define JSON_HAS_INT64
|
||||||
# endif // if defined(JSON_NO_INT64)
|
# endif // if defined(JSON_NO_INT64)
|
||||||
} // end namespace Json
|
} // end namespace Json
|
||||||
|
|
||||||
|
@ -126,13 +126,36 @@ namespace Json {
|
|||||||
typedef ValueConstIterator const_iterator;
|
typedef ValueConstIterator const_iterator;
|
||||||
typedef Json::UInt UInt;
|
typedef Json::UInt UInt;
|
||||||
typedef Json::Int Int;
|
typedef Json::Int Int;
|
||||||
|
# if defined(JSON_HAS_INT64)
|
||||||
|
typedef Json::UInt64 UInt64;
|
||||||
|
typedef Json::Int64 Int64;
|
||||||
|
#endif // defined(JSON_HAS_INT64)
|
||||||
|
typedef Json::LargestInt LargestInt;
|
||||||
|
typedef Json::LargestUInt LargestUInt;
|
||||||
typedef Json::ArrayIndex ArrayIndex;
|
typedef Json::ArrayIndex ArrayIndex;
|
||||||
|
|
||||||
static const Value null;
|
static const Value null;
|
||||||
static const Int minInt;
|
/// Minimum signed integer value that can be stored in a Json::Value.
|
||||||
|
static const LargestInt minLargestInt;
|
||||||
|
/// Maximum signed integer value that can be stored in a Json::Value.
|
||||||
|
static const LargestInt maxLargestInt;
|
||||||
|
/// Maximum unsigned integer value that can be stored in a Json::Value.
|
||||||
|
static const LargestUInt maxLargestUInt;
|
||||||
|
|
||||||
|
/// Minimum signed int value that can be stored in a Json::Value.
|
||||||
|
static const Int minInt;
|
||||||
|
/// Maximum signed int value that can be stored in a Json::Value.
|
||||||
static const Int maxInt;
|
static const Int maxInt;
|
||||||
|
/// Maximum unsigned int value that can be stored in a Json::Value.
|
||||||
static const UInt maxUInt;
|
static const UInt maxUInt;
|
||||||
|
|
||||||
|
/// Minimum signed 64 bits int value that can be stored in a Json::Value.
|
||||||
|
static const Int64 minInt64;
|
||||||
|
/// Maximum signed 64 bits int value that can be stored in a Json::Value.
|
||||||
|
static const Int64 maxInt64;
|
||||||
|
/// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
|
||||||
|
static const UInt64 maxUInt64;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
|
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
|
||||||
# ifndef JSON_VALUE_USE_INTERNAL_MAP
|
# ifndef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
@ -187,12 +210,12 @@ namespace Json {
|
|||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
Value( ValueType type = nullValue );
|
Value( ValueType type = nullValue );
|
||||||
#if !defined(JSON_NO_INT64)
|
|
||||||
Value( int value );
|
|
||||||
Value( ArrayIndex value );
|
|
||||||
#endif // if !defined(JSON_NO_INT64)
|
|
||||||
Value( Int value );
|
Value( Int value );
|
||||||
Value( UInt value );
|
Value( UInt value );
|
||||||
|
#if defined(JSON_HAS_INT64)
|
||||||
|
Value( Int64 value );
|
||||||
|
Value( UInt64 value );
|
||||||
|
#endif // if defined(JSON_HAS_INT64)
|
||||||
Value( double value );
|
Value( double value );
|
||||||
Value( const char *value );
|
Value( const char *value );
|
||||||
Value( const char *beginValue, const char *endValue );
|
Value( const char *beginValue, const char *endValue );
|
||||||
@ -240,6 +263,10 @@ namespace Json {
|
|||||||
# endif
|
# endif
|
||||||
Int asInt() const;
|
Int asInt() const;
|
||||||
UInt asUInt() const;
|
UInt asUInt() const;
|
||||||
|
Int64 asInt64() const;
|
||||||
|
UInt64 asUInt64() const;
|
||||||
|
LargestInt asLargestInt() const;
|
||||||
|
LargestUInt asLargestUInt() const;
|
||||||
float asFloat() const;
|
float asFloat() const;
|
||||||
double asDouble() const;
|
double asDouble() const;
|
||||||
bool asBool() const;
|
bool asBool() const;
|
||||||
@ -448,8 +475,8 @@ namespace Json {
|
|||||||
|
|
||||||
union ValueHolder
|
union ValueHolder
|
||||||
{
|
{
|
||||||
Int int_;
|
LargestInt int_;
|
||||||
UInt uint_;
|
LargestUInt uint_;
|
||||||
double real_;
|
double real_;
|
||||||
bool bool_;
|
bool bool_;
|
||||||
char *string_;
|
char *string_;
|
||||||
|
@ -162,8 +162,12 @@ namespace Json {
|
|||||||
bool addChildValues_;
|
bool addChildValues_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# if defined(JSON_HAS_INT64)
|
||||||
std::string JSON_API valueToString( Int value );
|
std::string JSON_API valueToString( Int value );
|
||||||
std::string JSON_API valueToString( UInt value );
|
std::string JSON_API valueToString( UInt value );
|
||||||
|
# endif // if defined(JSON_HAS_INT64)
|
||||||
|
std::string JSON_API valueToString( LargestInt value );
|
||||||
|
std::string JSON_API valueToString( LargestUInt value );
|
||||||
std::string JSON_API valueToString( double value );
|
std::string JSON_API valueToString( double value );
|
||||||
std::string JSON_API valueToString( bool value );
|
std::string JSON_API valueToString( bool value );
|
||||||
std::string JSON_API valueToQuotedString( const char *value );
|
std::string JSON_API valueToQuotedString( const char *value );
|
||||||
|
@ -44,10 +44,10 @@ printValueTree( FILE *fout, Json::Value &value, const std::string &path = "." )
|
|||||||
fprintf( fout, "%s=null\n", path.c_str() );
|
fprintf( fout, "%s=null\n", path.c_str() );
|
||||||
break;
|
break;
|
||||||
case Json::intValue:
|
case Json::intValue:
|
||||||
fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asInt() ).c_str() );
|
fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asLargestInt() ).c_str() );
|
||||||
break;
|
break;
|
||||||
case Json::uintValue:
|
case Json::uintValue:
|
||||||
fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asUInt() ).c_str() );
|
fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asLargestUInt() ).c_str() );
|
||||||
break;
|
break;
|
||||||
case Json::realValue:
|
case Json::realValue:
|
||||||
fprintf( fout, "%s=%.16g\n", path.c_str(), value.asDouble() );
|
fprintf( fout, "%s=%.16g\n", path.c_str(), value.asDouble() );
|
||||||
@ -224,36 +224,44 @@ int main( int argc, const char *argv[] )
|
|||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string input = readInputTestFile( path.c_str() );
|
try
|
||||||
if ( input.empty() )
|
|
||||||
{
|
{
|
||||||
printf( "Failed to read input or empty input: %s\n", path.c_str() );
|
std::string input = readInputTestFile( path.c_str() );
|
||||||
return 3;
|
if ( input.empty() )
|
||||||
}
|
|
||||||
|
|
||||||
std::string basePath = removeSuffix( argv[1], ".json" );
|
|
||||||
if ( !parseOnly && basePath.empty() )
|
|
||||||
{
|
|
||||||
printf( "Bad input path. Path does not end with '.expected':\n%s\n", path.c_str() );
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string actualPath = basePath + ".actual";
|
|
||||||
std::string rewritePath = basePath + ".rewrite";
|
|
||||||
std::string rewriteActualPath = basePath + ".actual-rewrite";
|
|
||||||
|
|
||||||
Json::Value root;
|
|
||||||
exitCode = parseAndSaveValueTree( input, actualPath, "input", root, features, parseOnly );
|
|
||||||
if ( exitCode == 0 && !parseOnly )
|
|
||||||
{
|
|
||||||
std::string rewrite;
|
|
||||||
exitCode = rewriteValueTree( rewritePath, root, rewrite );
|
|
||||||
if ( exitCode == 0 )
|
|
||||||
{
|
{
|
||||||
Json::Value rewriteRoot;
|
printf( "Failed to read input or empty input: %s\n", path.c_str() );
|
||||||
exitCode = parseAndSaveValueTree( rewrite, rewriteActualPath,
|
return 3;
|
||||||
"rewrite", rewriteRoot, features, parseOnly );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string basePath = removeSuffix( argv[1], ".json" );
|
||||||
|
if ( !parseOnly && basePath.empty() )
|
||||||
|
{
|
||||||
|
printf( "Bad input path. Path does not end with '.expected':\n%s\n", path.c_str() );
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string actualPath = basePath + ".actual";
|
||||||
|
std::string rewritePath = basePath + ".rewrite";
|
||||||
|
std::string rewriteActualPath = basePath + ".actual-rewrite";
|
||||||
|
|
||||||
|
Json::Value root;
|
||||||
|
exitCode = parseAndSaveValueTree( input, actualPath, "input", root, features, parseOnly );
|
||||||
|
if ( exitCode == 0 && !parseOnly )
|
||||||
|
{
|
||||||
|
std::string rewrite;
|
||||||
|
exitCode = rewriteValueTree( rewritePath, root, rewrite );
|
||||||
|
if ( exitCode == 0 )
|
||||||
|
{
|
||||||
|
Json::Value rewriteRoot;
|
||||||
|
exitCode = parseAndSaveValueTree( rewrite, rewriteActualPath,
|
||||||
|
"rewrite", rewriteRoot, features, parseOnly );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( const std::exception &e )
|
||||||
|
{
|
||||||
|
printf( "Unhandled exception:\n%s\n", e.what() );
|
||||||
|
exitCode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return exitCode;
|
return exitCode;
|
||||||
|
@ -567,12 +567,12 @@ Reader::decodeNumber( Token &token )
|
|||||||
bool isNegative = *current == '-';
|
bool isNegative = *current == '-';
|
||||||
if ( isNegative )
|
if ( isNegative )
|
||||||
++current;
|
++current;
|
||||||
Value::UInt maxIntegerValue = isNegative ? Value::UInt(-Value::minInt)
|
Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt)
|
||||||
: Value::maxUInt;
|
: Value::maxLargestUInt;
|
||||||
Value::UInt threshold = maxIntegerValue / 10;
|
Value::LargestUInt threshold = maxIntegerValue / 10;
|
||||||
Value::UInt lastDigitThreshold = maxIntegerValue % 10;
|
Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 );
|
||||||
assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 );
|
assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 );
|
||||||
Value::UInt value = 0;
|
Value::LargestUInt value = 0;
|
||||||
while ( current < token.end_ )
|
while ( current < token.end_ )
|
||||||
{
|
{
|
||||||
Char c = *current++;
|
Char c = *current++;
|
||||||
@ -592,9 +592,9 @@ Reader::decodeNumber( Token &token )
|
|||||||
value = value * 10 + digit;
|
value = value * 10 + digit;
|
||||||
}
|
}
|
||||||
if ( isNegative )
|
if ( isNegative )
|
||||||
currentValue() = -Value::Int( value );
|
currentValue() = -Value::LargestInt( value );
|
||||||
else if ( value <= Value::UInt(Value::maxInt) )
|
else if ( value <= Value::LargestUInt(Value::maxInt) )
|
||||||
currentValue() = Value::Int( value );
|
currentValue() = Value::LargestInt( value );
|
||||||
else
|
else
|
||||||
currentValue() = value;
|
currentValue() = value;
|
||||||
return true;
|
return true;
|
||||||
|
@ -63,7 +63,7 @@ isControlCharacter(char ch)
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
/// Constant that specify the size of the buffer that must be passed to uintToString.
|
/// Constant that specify the size of the buffer that must be passed to uintToString.
|
||||||
uintToStringBufferSize = 3*sizeof(UInt)+1
|
uintToStringBufferSize = 3*sizeof(LargestUInt)+1
|
||||||
};
|
};
|
||||||
|
|
||||||
// Defines a char buffer for use with uintToString().
|
// Defines a char buffer for use with uintToString().
|
||||||
@ -76,7 +76,7 @@ typedef char UIntToStringBuffer[uintToStringBufferSize];
|
|||||||
* Must have at least uintToStringBufferSize chars free.
|
* Must have at least uintToStringBufferSize chars free.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
uintToString( UInt value,
|
uintToString( LargestUInt value,
|
||||||
char *¤t )
|
char *¤t )
|
||||||
{
|
{
|
||||||
*--current = 0;
|
*--current = 0;
|
||||||
|
@ -28,6 +28,13 @@ const Value Value::null;
|
|||||||
const Int Value::minInt = Int( ~(UInt(-1)/2) );
|
const Int Value::minInt = Int( ~(UInt(-1)/2) );
|
||||||
const Int Value::maxInt = Int( UInt(-1)/2 );
|
const Int Value::maxInt = Int( UInt(-1)/2 );
|
||||||
const UInt Value::maxUInt = UInt(-1);
|
const UInt Value::maxUInt = UInt(-1);
|
||||||
|
const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) );
|
||||||
|
const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 );
|
||||||
|
const UInt64 Value::maxUInt64 = UInt64(-1);
|
||||||
|
const LargestInt Value::minLargestInt = LargestInt( ~(LargestUInt(-1)/2) );
|
||||||
|
const LargestInt Value::maxLargestInt = LargestInt( LargestUInt(-1)/2 );
|
||||||
|
const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
|
||||||
|
|
||||||
|
|
||||||
/// Unknown size marker
|
/// Unknown size marker
|
||||||
enum { unknown = (unsigned)-1 };
|
enum { unknown = (unsigned)-1 };
|
||||||
@ -262,8 +269,8 @@ Value::Value( ValueType type )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !defined(JSON_NO_INT64)
|
#if defined(JSON_HAS_INT64)
|
||||||
Value::Value( ArrayIndex value )
|
Value::Value( UInt value )
|
||||||
: type_( uintValue )
|
: type_( uintValue )
|
||||||
, comments_( 0 )
|
, comments_( 0 )
|
||||||
# ifdef JSON_VALUE_USE_INTERNAL_MAP
|
# ifdef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
@ -273,19 +280,6 @@ Value::Value( ArrayIndex value )
|
|||||||
value_.uint_ = value;
|
value_.uint_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Value( int value )
|
|
||||||
: type_( intValue )
|
|
||||||
, comments_( 0 )
|
|
||||||
# ifdef JSON_VALUE_USE_INTERNAL_MAP
|
|
||||||
, itemIsUsed_( 0 )
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
value_.int_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // if !defined(JSON_NO_INT64)
|
|
||||||
|
|
||||||
|
|
||||||
Value::Value( Int value )
|
Value::Value( Int value )
|
||||||
: type_( intValue )
|
: type_( intValue )
|
||||||
, comments_( 0 )
|
, comments_( 0 )
|
||||||
@ -296,8 +290,21 @@ Value::Value( Int value )
|
|||||||
value_.int_ = value;
|
value_.int_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // if defined(JSON_HAS_INT64)
|
||||||
|
|
||||||
Value::Value( UInt value )
|
|
||||||
|
Value::Value( Int64 value )
|
||||||
|
: type_( intValue )
|
||||||
|
, comments_( 0 )
|
||||||
|
# ifdef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
|
, itemIsUsed_( 0 )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
value_.int_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value::Value( UInt64 value )
|
||||||
: type_( uintValue )
|
: type_( uintValue )
|
||||||
, comments_( 0 )
|
, comments_( 0 )
|
||||||
# ifdef JSON_VALUE_USE_INTERNAL_MAP
|
# ifdef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
@ -689,6 +696,7 @@ Value::asConstString() const
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
||||||
Value::Int
|
Value::Int
|
||||||
Value::asInt() const
|
Value::asInt() const
|
||||||
{
|
{
|
||||||
@ -697,10 +705,11 @@ Value::asInt() const
|
|||||||
case nullValue:
|
case nullValue:
|
||||||
return 0;
|
return 0;
|
||||||
case intValue:
|
case intValue:
|
||||||
return value_.int_;
|
JSON_ASSERT_MESSAGE( value_.int_ >= minInt && value_.int_ <= maxInt, "unsigned integer out of signed int range" );
|
||||||
|
return Int(value_.int_);
|
||||||
case uintValue:
|
case uintValue:
|
||||||
JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" );
|
JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" );
|
||||||
return value_.uint_;
|
return Int(value_.uint_);
|
||||||
case realValue:
|
case realValue:
|
||||||
JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
|
JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
|
||||||
return Int( value_.real_ );
|
return Int( value_.real_ );
|
||||||
@ -716,6 +725,7 @@ Value::asInt() const
|
|||||||
return 0; // unreachable;
|
return 0; // unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Value::UInt
|
Value::UInt
|
||||||
Value::asUInt() const
|
Value::asUInt() const
|
||||||
{
|
{
|
||||||
@ -725,9 +735,11 @@ Value::asUInt() const
|
|||||||
return 0;
|
return 0;
|
||||||
case intValue:
|
case intValue:
|
||||||
JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
|
JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
|
||||||
return value_.int_;
|
JSON_ASSERT_MESSAGE( value_.int_ <= maxUInt, "signed integer out of UInt range" );
|
||||||
|
return UInt(value_.int_);
|
||||||
case uintValue:
|
case uintValue:
|
||||||
return value_.uint_;
|
JSON_ASSERT_MESSAGE( value_.uint_ <= maxUInt, "unsigned integer out of UInt range" );
|
||||||
|
return UInt(value_.uint_);
|
||||||
case realValue:
|
case realValue:
|
||||||
JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
|
JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
|
||||||
return UInt( value_.real_ );
|
return UInt( value_.real_ );
|
||||||
@ -743,6 +755,88 @@ Value::asUInt() const
|
|||||||
return 0; // unreachable;
|
return 0; // unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# if defined(JSON_HAS_INT64)
|
||||||
|
|
||||||
|
Value::Int64
|
||||||
|
Value::asInt64() const
|
||||||
|
{
|
||||||
|
switch ( type_ )
|
||||||
|
{
|
||||||
|
case nullValue:
|
||||||
|
return 0;
|
||||||
|
case intValue:
|
||||||
|
return value_.int_;
|
||||||
|
case uintValue:
|
||||||
|
JSON_ASSERT_MESSAGE( value_.uint_ <= UInt64(maxInt64), "unsigned integer out of Int64 range" );
|
||||||
|
return value_.uint_;
|
||||||
|
case realValue:
|
||||||
|
JSON_ASSERT_MESSAGE( value_.real_ >= minInt64 && value_.real_ <= maxInt64, "Real out of Int64 range" );
|
||||||
|
return Int( value_.real_ );
|
||||||
|
case booleanValue:
|
||||||
|
return value_.bool_ ? 1 : 0;
|
||||||
|
case stringValue:
|
||||||
|
case arrayValue:
|
||||||
|
case objectValue:
|
||||||
|
JSON_ASSERT_MESSAGE( false, "Type is not convertible to Int64" );
|
||||||
|
default:
|
||||||
|
JSON_ASSERT_UNREACHABLE;
|
||||||
|
}
|
||||||
|
return 0; // unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value::UInt64
|
||||||
|
Value::asUInt64() const
|
||||||
|
{
|
||||||
|
switch ( type_ )
|
||||||
|
{
|
||||||
|
case nullValue:
|
||||||
|
return 0;
|
||||||
|
case intValue:
|
||||||
|
JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to UInt64" );
|
||||||
|
return value_.int_;
|
||||||
|
case uintValue:
|
||||||
|
return value_.uint_;
|
||||||
|
case realValue:
|
||||||
|
JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt64, "Real out of UInt64 range" );
|
||||||
|
return UInt( value_.real_ );
|
||||||
|
case booleanValue:
|
||||||
|
return value_.bool_ ? 1 : 0;
|
||||||
|
case stringValue:
|
||||||
|
case arrayValue:
|
||||||
|
case objectValue:
|
||||||
|
JSON_ASSERT_MESSAGE( false, "Type is not convertible to UInt64" );
|
||||||
|
default:
|
||||||
|
JSON_ASSERT_UNREACHABLE;
|
||||||
|
}
|
||||||
|
return 0; // unreachable;
|
||||||
|
}
|
||||||
|
# endif // if defined(JSON_HAS_INT64)
|
||||||
|
|
||||||
|
|
||||||
|
LargestInt
|
||||||
|
Value::asLargestInt() const
|
||||||
|
{
|
||||||
|
#if defined(JSON_NO_INT64)
|
||||||
|
return asInt();
|
||||||
|
#else
|
||||||
|
return asInt64();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LargestUInt
|
||||||
|
Value::asLargestUInt() const
|
||||||
|
{
|
||||||
|
#if defined(JSON_NO_INT64)
|
||||||
|
return asUInt();
|
||||||
|
#else
|
||||||
|
return asUInt64();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
Value::asDouble() const
|
Value::asDouble() const
|
||||||
{
|
{
|
||||||
|
@ -29,14 +29,15 @@ static bool containsControlCharacter( const char* str )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string valueToString( Int value )
|
|
||||||
|
std::string valueToString( LargestInt value )
|
||||||
{
|
{
|
||||||
UIntToStringBuffer buffer;
|
UIntToStringBuffer buffer;
|
||||||
char *current = buffer + sizeof(buffer);
|
char *current = buffer + sizeof(buffer);
|
||||||
bool isNegative = value < 0;
|
bool isNegative = value < 0;
|
||||||
if ( isNegative )
|
if ( isNegative )
|
||||||
value = -value;
|
value = -value;
|
||||||
uintToString( UInt(value), current );
|
uintToString( LargestUInt(value), current );
|
||||||
if ( isNegative )
|
if ( isNegative )
|
||||||
*--current = '-';
|
*--current = '-';
|
||||||
assert( current >= buffer );
|
assert( current >= buffer );
|
||||||
@ -44,7 +45,7 @@ std::string valueToString( Int value )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string valueToString( UInt value )
|
std::string valueToString( LargestUInt value )
|
||||||
{
|
{
|
||||||
UIntToStringBuffer buffer;
|
UIntToStringBuffer buffer;
|
||||||
char *current = buffer + sizeof(buffer);
|
char *current = buffer + sizeof(buffer);
|
||||||
@ -53,6 +54,22 @@ std::string valueToString( UInt value )
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(JSON_HAS_INT64)
|
||||||
|
|
||||||
|
std::string valueToString( Int value )
|
||||||
|
{
|
||||||
|
return valueToString( LargestInt(value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string valueToString( UInt value )
|
||||||
|
{
|
||||||
|
return valueToString( LargestUInt(value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // # if defined(JSON_HAS_INT64)
|
||||||
|
|
||||||
|
|
||||||
std::string valueToString( double value )
|
std::string valueToString( double value )
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
@ -203,10 +220,10 @@ FastWriter::writeValue( const Value &value )
|
|||||||
document_ += "null";
|
document_ += "null";
|
||||||
break;
|
break;
|
||||||
case intValue:
|
case intValue:
|
||||||
document_ += valueToString( value.asInt() );
|
document_ += valueToString( value.asLargestInt() );
|
||||||
break;
|
break;
|
||||||
case uintValue:
|
case uintValue:
|
||||||
document_ += valueToString( value.asUInt() );
|
document_ += valueToString( value.asLargestUInt() );
|
||||||
break;
|
break;
|
||||||
case realValue:
|
case realValue:
|
||||||
document_ += valueToString( value.asDouble() );
|
document_ += valueToString( value.asDouble() );
|
||||||
@ -286,10 +303,10 @@ StyledWriter::writeValue( const Value &value )
|
|||||||
pushValue( "null" );
|
pushValue( "null" );
|
||||||
break;
|
break;
|
||||||
case intValue:
|
case intValue:
|
||||||
pushValue( valueToString( value.asInt() ) );
|
pushValue( valueToString( value.asLargestInt() ) );
|
||||||
break;
|
break;
|
||||||
case uintValue:
|
case uintValue:
|
||||||
pushValue( valueToString( value.asUInt() ) );
|
pushValue( valueToString( value.asLargestUInt() ) );
|
||||||
break;
|
break;
|
||||||
case realValue:
|
case realValue:
|
||||||
pushValue( valueToString( value.asDouble() ) );
|
pushValue( valueToString( value.asDouble() ) );
|
||||||
@ -562,10 +579,10 @@ StyledStreamWriter::writeValue( const Value &value )
|
|||||||
pushValue( "null" );
|
pushValue( "null" );
|
||||||
break;
|
break;
|
||||||
case intValue:
|
case intValue:
|
||||||
pushValue( valueToString( value.asInt() ) );
|
pushValue( valueToString( value.asLargestInt() ) );
|
||||||
break;
|
break;
|
||||||
case uintValue:
|
case uintValue:
|
||||||
pushValue( valueToString( value.asUInt() ) );
|
pushValue( valueToString( value.asLargestUInt() ) );
|
||||||
break;
|
break;
|
||||||
case realValue:
|
case realValue:
|
||||||
pushValue( valueToString( value.asDouble() ) );
|
pushValue( valueToString( value.asDouble() ) );
|
||||||
|
Loading…
Reference in New Issue
Block a user