diff -ru jsoncpp-0.5.0.orig/include/json/config.h jsoncpp-0.5.0/include/json/config.h --- jsoncpp-0.5.0.orig/include/json/config.h 2014-10-09 16:44:24.119176867 +0300 +++ jsoncpp-0.5.0/include/json/config.h 2014-10-09 16:58:42.000000000 +0300 @@ -40,4 +40,15 @@ # define JSON_API # endif +#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6 +// Microsoft Visual Studio 6 only support conversion from __int64 to double +// (no conversion from unsigned __int64). +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' +// characters in the debug information) +// All projects I've ever seen with VS6 were using this globally (not bothering +// with pragma push/pop). +#pragma warning(disable : 4786) +#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 + #endif // JSON_CONFIG_H_INCLUDED diff -ru jsoncpp-0.5.0.orig/include/json/forwards.h jsoncpp-0.5.0/include/json/forwards.h --- jsoncpp-0.5.0.orig/include/json/forwards.h 2010-03-12 09:31:35.000000000 +0200 +++ jsoncpp-0.5.0/include/json/forwards.h 2014-10-09 16:57:28.000000000 +0300 @@ -18,6 +18,17 @@ // value.h typedef int Int; typedef unsigned int UInt; + +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio + typedef __int64 Int64; + typedef unsigned __int64 UInt64; +#else // if defined(_MSC_VER) // Other platforms, use long long + typedef long long int Int64; + typedef unsigned long long int UInt64; +#endif // if defined(_MSC_VER) +#define JSON_HAS_INT64 + class StaticString; class Path; class PathArgument; diff -ru jsoncpp-0.5.0.orig/include/json/value.h jsoncpp-0.5.0/include/json/value.h --- jsoncpp-0.5.0.orig/include/json/value.h 2014-08-28 18:30:06.428576854 +0300 +++ jsoncpp-0.5.0/include/json/value.h 2014-10-09 17:10:08.000000000 +0300 @@ -121,12 +121,21 @@ typedef ValueConstIterator const_iterator; typedef Json::UInt UInt; typedef Json::Int Int; +#if defined(JSON_HAS_INT64) + typedef Json::UInt64 UInt64; + typedef Json::Int64 Int64; +#endif // defined(JSON_HAS_INT64) typedef UInt ArrayIndex; static const Value null; static const Int minInt; static const Int maxInt; static const UInt maxUInt; +#if defined(JSON_HAS_INT64) + static const Int64 minInt64; + static const Int64 maxInt64; + static const UInt64 maxUInt64; +#endif private: #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION @@ -184,6 +193,10 @@ Value( ValueType type = nullValue ); Value( Int 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( const char *value ); Value( const char *beginValue, const char *endValue ); @@ -231,6 +244,10 @@ # endif Int asInt() const; UInt asUInt() const; +#if defined(JSON_HAS_INT64) + Int64 asInt64() const; + UInt64 asUInt64() const; +#endif // if defined(JSON_HAS_INT64) double asDouble() const; bool asBool() const; @@ -238,6 +255,10 @@ bool isBool() const; bool isInt() const; bool isUInt() const; +#if defined(JSON_HAS_INT64) + bool isInt64() const; + bool isUInt64() const; +#endif // if defined(JSON_HAS_INT64) bool isIntegral() const; bool isDouble() const; bool isNumeric() const; @@ -424,8 +445,13 @@ union ValueHolder { +#if defined(JSON_HAS_INT64) + Int64 int_; + UInt64 uint_; +#else Int int_; UInt uint_; +#endif double real_; bool bool_; char *string_; diff -ru jsoncpp-0.5.0.orig/include/json/writer.h jsoncpp-0.5.0/include/json/writer.h --- jsoncpp-0.5.0.orig/include/json/writer.h 2010-03-12 09:31:35.000000000 +0200 +++ jsoncpp-0.5.0/include/json/writer.h 2014-10-09 17:04:10.000000000 +0300 @@ -159,6 +159,10 @@ std::string JSON_API valueToString( Int value ); std::string JSON_API valueToString( UInt value ); +#if defined(JSON_HAS_INT64) + std::string JSON_API valueToString(Int64 value); + std::string JSON_API valueToString(UInt64 value); +#endif // if defined(JSON_HAS_INT64) std::string JSON_API valueToString( double value ); std::string JSON_API valueToString( bool value ); std::string JSON_API valueToQuotedString( const char *value ); diff -ru jsoncpp-0.5.0.orig/src/lib_json/json_reader.cpp jsoncpp-0.5.0/src/lib_json/json_reader.cpp --- jsoncpp-0.5.0.orig/src/lib_json/json_reader.cpp 2010-03-12 09:31:35.000000000 +0200 +++ jsoncpp-0.5.0/src/lib_json/json_reader.cpp 2014-10-17 15:07:49.000000000 +0300 @@ -594,24 +594,67 @@ bool isNegative = *current == '-'; if ( isNegative ) ++current; - Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt) - : Value::maxUInt) / 10; +#if defined(JSON_HAS_INT64) + Value::UInt64 maxValue = + isNegative ? Value::UInt64(-Value::minInt64) + : Value::maxUInt64; + Value::UInt64 threshold = maxValue / 10; + Value::UInt64 value = 0; + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return addError("'" + std::string(token.start_, token.end_) + + "' is not a number.", + token); + Value::UInt digit(c - '0'); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > maxValue % 10) { + return decodeDouble(token); + } + } + value = value * 10 + digit; + } + if (isNegative) + currentValue() = -Value::Int64(value); + else if (value <= Value::UInt64(Value::maxInt)) + currentValue() = Value::Int64(value); + else + currentValue() = value; +#else + Value::UInt maxValue = + isNegative ? Value::UInt(-Value::minInt) + : Value::maxUInt; + Value::UInt threshold = maxValue / 10; Value::UInt value = 0; - while ( current < token.end_ ) - { - Char c = *current++; - if ( c < '0' || c > '9' ) - return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token ); - if ( value >= threshold ) - return decodeDouble( token ); - value = value * 10 + Value::UInt(c - '0'); + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return addError("'" + std::string(token.start_, token.end_) + + "' is not a number.", + token); + Value::UInt digit(c - '0'); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > maxValue % 10) { + return decodeDouble(token); + } + } + value = value * 10 + digit; } - if ( isNegative ) - currentValue() = -Value::Int( value ); - else if ( value <= Value::UInt(Value::maxInt) ) - currentValue() = Value::Int( value ); + if (isNegative) + currentValue() = -Value::Int(value); else - currentValue() = value; + currentValue() = value; +#endif return true; } diff -ru jsoncpp-0.5.0.orig/src/lib_json/json_value.cpp jsoncpp-0.5.0/src/lib_json/json_value.cpp --- jsoncpp-0.5.0.orig/src/lib_json/json_value.cpp 2010-03-12 09:31:35.000000000 +0200 +++ jsoncpp-0.5.0/src/lib_json/json_value.cpp 2014-10-09 17:32:59.000000000 +0300 @@ -23,6 +23,15 @@ const Int Value::minInt = Int( ~(UInt(-1)/2) ); const Int Value::maxInt = Int( UInt(-1)/2 ); const UInt Value::maxUInt = UInt(-1); +#if defined(JSON_HAS_INT64) +const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); +const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); +const UInt64 Value::maxUInt64 = UInt64(-1); +// The constant is hard-coded because some compiler have trouble +// converting Value::maxUInt64 to a double correctly (AIX/xlC). +// Assumes that UInt64 is a 64 bits integer. +static const double maxUInt64AsDouble = 18446744073709551615.0; +#endif // defined(JSON_HAS_INT64) // A "safe" implementation of strdup. Allow null pointer to be passed. // Also avoid warning on msvc80. @@ -330,6 +339,29 @@ value_.uint_ = value; } +#if defined(JSON_HAS_INT64) +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 ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.uint_ = value; +} +#endif // defined(JSON_HAS_INT64) + Value::Value( double value ) : type_( realValue ) , comments_( 0 ) @@ -766,6 +798,62 @@ 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_ < (unsigned)maxInt64, "integer out of signed integer range" ); + return value_.uint_; + case realValue: + JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer 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 int" ); + 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 unsigned integer" ); + return value_.int_; + case uintValue: + return value_.uint_; + case realValue: + JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt64, "Real out of unsigned integer 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 uint" ); + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable; +} +#endif // if defined(JSON_HAS_INT64) + double Value::asDouble() const { @@ -1268,17 +1356,31 @@ bool Value::isInt() const { - return type_ == intValue; + return type_ == intValue && value_.int_ >= minInt && value_.int_ <= maxInt; } bool Value::isUInt() const { - return type_ == uintValue; + return type_ == uintValue && value_.uint_ <= maxUInt; +} + +#if defined(JSON_HAS_INT64) +bool +Value::isInt64() const +{ + return type_ == intValue; } +bool +Value::isUInt64() const +{ + return type_ == uintValue; +} +#endif + bool Value::isIntegral() const { diff -ru jsoncpp-0.5.0.orig/src/lib_json/json_writer.cpp jsoncpp-0.5.0/src/lib_json/json_writer.cpp --- jsoncpp-0.5.0.orig/src/lib_json/json_writer.cpp 2010-03-12 09:31:35.000000000 +0200 +++ jsoncpp-0.5.0/src/lib_json/json_writer.cpp 2014-10-17 14:50:03.000000000 +0300 @@ -38,6 +38,19 @@ } while ( value != 0 ); } +#if defined(JSON_HAS_INT64) +static void uintToString( UInt64 value, + char *¤t ) +{ + *--current = 0; + do + { + *--current = (value % 10) + '0'; + value /= 10; + } + while ( value != 0 ); +} +#endif std::string valueToString( Int value ) { @@ -63,6 +76,32 @@ return current; } +#if defined(JSON_HAS_INT64) +std::string valueToString( Int64 value ) +{ + char buffer[32]; + char *current = buffer + sizeof(buffer); + bool isNegative = value < 0; + if ( isNegative ) + value = -value; + uintToString( UInt64(value), current ); + if ( isNegative ) + *--current = '-'; + assert( current >= buffer ); + return current; +} + + +std::string valueToString( UInt64 value ) +{ + char buffer[32]; + char *current = buffer + sizeof(buffer); + uintToString( value, current ); + assert( current >= buffer ); + return current; +} +#endif + std::string valueToString( double value ) { char buffer[32]; @@ -213,10 +252,18 @@ document_ += "null"; break; case intValue: +#if defined(JSON_HAS_INT64) + document_ += valueToString( value.asInt64() ); +#else document_ += valueToString( value.asInt() ); +#endif break; case uintValue: +#if defined(JSON_HAS_INT64) + document_ += valueToString( value.asUInt64() ) ; +#else document_ += valueToString( value.asUInt() ); +#endif break; case realValue: document_ += valueToString( value.asDouble() ); @@ -296,10 +343,18 @@ pushValue( "null" ); break; case intValue: +#if defined(JSON_HAS_INT64) + pushValue( valueToString( value.asInt64() ) ); +#else pushValue( valueToString( value.asInt() ) ); +#endif break; case uintValue: +#if defined(JSON_HAS_INT64) + pushValue( valueToString( value.asUInt64() ) ); +#else pushValue( valueToString( value.asUInt() ) ); +#endif break; case realValue: pushValue( valueToString( value.asDouble() ) ); @@ -572,10 +627,18 @@ pushValue( "null" ); break; case intValue: +#if defined(JSON_HAS_INT64) + pushValue( valueToString( value.asInt64() ) ); +#else pushValue( valueToString( value.asInt() ) ); +#endif break; case uintValue: +#if defined(JSON_HAS_INT64) + pushValue( valueToString( value.asUInt64() ) ); +#else pushValue( valueToString( value.asUInt() ) ); +#endif break; case realValue: pushValue( valueToString( value.asDouble() ) );