diff options
author | montellese <montellese@xbmc.org> | 2011-01-28 14:08:12 +0100 |
---|---|---|
committer | montellese <montellese@xbmc.org> | 2011-04-01 20:35:50 +0200 |
commit | 0158bd9ab97f4a4fa8d7770f4137905a3503b224 (patch) | |
tree | c457e66ff0e2eb2a7e2121e3e2d7719dfc8c73cc /lib/jsoncpp/src | |
parent | 97b5e9f770405d37ce0f6ca95f538e80fefe18aa (diff) |
JSONRPC: update of jsoncpp library to latest revision
Diffstat (limited to 'lib/jsoncpp/src')
-rw-r--r-- | lib/jsoncpp/src/jsontestrunner/main.cpp | 88 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_batchallocator.h | 5 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_internalarray.inl | 5 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_internalmap.inl | 7 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_reader.cpp | 73 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_tool.h | 93 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_value.cpp | 373 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_valueiterator.inl | 7 | ||||
-rw-r--r-- | lib/jsoncpp/src/lib_json/json_writer.cpp | 75 | ||||
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/jsontest.cpp | 10 | ||||
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/jsontest.h | 9 | ||||
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/main.cpp | 27 |
12 files changed, 542 insertions, 230 deletions
diff --git a/lib/jsoncpp/src/jsontestrunner/main.cpp b/lib/jsoncpp/src/jsontestrunner/main.cpp index 231ee0c44d..2da3ede9ea 100644 --- a/lib/jsoncpp/src/jsontestrunner/main.cpp +++ b/lib/jsoncpp/src/jsontestrunner/main.cpp @@ -1,3 +1,12 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +/* This executable is used for testing parser/writer using real JSON files. + */ + + #include <json/json.h> #include <algorithm> // sort #include <stdio.h> @@ -35,10 +44,10 @@ printValueTree( FILE *fout, Json::Value &value, const std::string &path = "." ) fprintf( fout, "%s=null\n", path.c_str() ); break; case Json::intValue: - fprintf( fout, "%s=%d\n", path.c_str(), value.asInt() ); + fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asLargestInt() ).c_str() ); break; case Json::uintValue: - fprintf( fout, "%s=%u\n", path.c_str(), value.asUInt() ); + fprintf( fout, "%s=%s\n", path.c_str(), Json::valueToString( value.asLargestUInt() ).c_str() ); break; case Json::realValue: fprintf( fout, "%s=%.16g\n", path.c_str(), value.asDouble() ); @@ -148,6 +157,19 @@ removeSuffix( const std::string &path, return path.substr( 0, path.length() - extension.length() ); } + +static void +printConfig() +{ + // Print the configuration used to compile JsonCpp +#if defined(JSON_NO_INT64) + printf( "JSON_NO_INT64=1\n" ); +#else + printf( "JSON_NO_INT64=0\n" ); +#endif +} + + static int printUsage( const char *argv[] ) { @@ -175,6 +197,12 @@ parseCommandLine( int argc, const char *argv[], ++index; } + if ( std::string(argv[1]) == "--json-config" ) + { + printConfig(); + return 3; + } + if ( index == argc || index + 1 < argc ) { return printUsage( argv ); @@ -196,37 +224,45 @@ int main( int argc, const char *argv[] ) return exitCode; } - std::string input = readInputTestFile( path.c_str() ); - if ( input.empty() ) + try { - printf( "Failed to read input or empty input: %s\n", path.c_str() ); - return 3; - } + std::string input = readInputTestFile( path.c_str() ); + if ( input.empty() ) + { + printf( "Failed to read input or empty input: %s\n", path.c_str() ); + return 3; + } - 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 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"; + 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 root; + exitCode = parseAndSaveValueTree( input, actualPath, "input", root, features, parseOnly ); + if ( exitCode == 0 && !parseOnly ) { - Json::Value rewriteRoot; - exitCode = parseAndSaveValueTree( rewrite, rewriteActualPath, - "rewrite", rewriteRoot, features, 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; } diff --git a/lib/jsoncpp/src/lib_json/json_batchallocator.h b/lib/jsoncpp/src/lib_json/json_batchallocator.h index 87ea5ed807..173e2ed257 100644 --- a/lib/jsoncpp/src/lib_json/json_batchallocator.h +++ b/lib/jsoncpp/src/lib_json/json_batchallocator.h @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED # define JSONCPP_BATCHALLOCATOR_H_INCLUDED diff --git a/lib/jsoncpp/src/lib_json/json_internalarray.inl b/lib/jsoncpp/src/lib_json/json_internalarray.inl index 9b985d2585..66d838ec0b 100644 --- a/lib/jsoncpp/src/lib_json/json_internalarray.inl +++ b/lib/jsoncpp/src/lib_json/json_internalarray.inl @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + // included by json_value.cpp // everything is within Json namespace diff --git a/lib/jsoncpp/src/lib_json/json_internalmap.inl b/lib/jsoncpp/src/lib_json/json_internalmap.inl index 19771488d6..d0dd62adae 100644 --- a/lib/jsoncpp/src/lib_json/json_internalmap.inl +++ b/lib/jsoncpp/src/lib_json/json_internalmap.inl @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + // included by json_value.cpp // everything is within Json namespace @@ -415,7 +420,7 @@ ValueInternalMap::setNewItem( const char *key, ValueInternalLink *link, BucketIndex index ) { - char *duplicatedKey = valueAllocator()->makeMemberName( key ); + char *duplicatedKey = makeMemberName( key ); ++itemCount_; link->keys_[index] = duplicatedKey; link->items_[index].setItemUsed(); diff --git a/lib/jsoncpp/src/lib_json/json_reader.cpp b/lib/jsoncpp/src/lib_json/json_reader.cpp index 4eb2d11fd3..60dc4c9199 100644 --- a/lib/jsoncpp/src/lib_json/json_reader.cpp +++ b/lib/jsoncpp/src/lib_json/json_reader.cpp @@ -1,5 +1,11 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #include <json/reader.h> #include <json/value.h> +#include "json_tool.h" #include <utility> #include <cstdio> #include <cassert> @@ -66,42 +72,6 @@ containsNewLine( Reader::Location begin, return false; } -static std::string codePointToUTF8(unsigned int cp) -{ - std::string result; - - // based on description from http://en.wikipedia.org/wiki/UTF-8 - - if (cp <= 0x7f) - { - result.resize(1); - result[0] = static_cast<char>(cp); - } - else if (cp <= 0x7FF) - { - result.resize(2); - result[1] = static_cast<char>(0x80 | (0x3f & cp)); - result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6))); - } - else if (cp <= 0xFFFF) - { - result.resize(3); - result[2] = static_cast<char>(0x80 | (0x3f & cp)); - result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6))); - result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12))); - } - else if (cp <= 0x10FFFF) - { - result.resize(4); - result[3] = static_cast<char>(0x80 | (0x3f & cp)); - result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); - result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12))); - result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18))); - } - - return result; -} - // Class Reader // ////////////////////////////////////////////////////////////////// @@ -590,26 +560,41 @@ Reader::decodeNumber( Token &token ) } if ( isDouble ) return decodeDouble( token ); + // 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. Location current = token.start_; bool isNegative = *current == '-'; if ( isNegative ) ++current; - Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt) - : Value::maxUInt) / 10; - Value::UInt value = 0; + Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt) + : Value::maxLargestUInt; + Value::LargestUInt threshold = maxIntegerValue / 10; + Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 ); + assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 ); + Value::LargestUInt 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 ) - return decodeDouble( token ); - value = value * 10 + Value::UInt(c - '0'); + { + // If the current digit is not the last one, or if it is + // greater than the last digit of the maximum integer value, + // the parse the number as a double. + if ( current != token.end_ || digit > lastDigitThreshold ) + { + return decodeDouble( token ); + } + } + value = value * 10 + digit; } if ( isNegative ) - currentValue() = -Value::Int( value ); - else if ( value <= Value::UInt(Value::maxInt) ) - currentValue() = Value::Int( value ); + currentValue() = -Value::LargestInt( value ); + else if ( value <= Value::LargestUInt(Value::maxInt) ) + currentValue() = Value::LargestInt( value ); else currentValue() = value; return true; diff --git a/lib/jsoncpp/src/lib_json/json_tool.h b/lib/jsoncpp/src/lib_json/json_tool.h new file mode 100644 index 0000000000..658031bbba --- /dev/null +++ b/lib/jsoncpp/src/lib_json/json_tool.h @@ -0,0 +1,93 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED +# define LIB_JSONCPP_JSON_TOOL_H_INCLUDED + +/* This header provides common string manipulation support, such as UTF-8, + * portable conversion from/to string... + * + * It is an internal header that must not be exposed. + */ + +namespace Json { + +/// Converts a unicode code-point to UTF-8. +static inline std::string +codePointToUTF8(unsigned int cp) +{ + std::string result; + + // based on description from http://en.wikipedia.org/wiki/UTF-8 + + if (cp <= 0x7f) + { + result.resize(1); + result[0] = static_cast<char>(cp); + } + else if (cp <= 0x7FF) + { + result.resize(2); + result[1] = static_cast<char>(0x80 | (0x3f & cp)); + result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6))); + } + else if (cp <= 0xFFFF) + { + result.resize(3); + result[2] = static_cast<char>(0x80 | (0x3f & cp)); + result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6))); + result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12))); + } + else if (cp <= 0x10FFFF) + { + result.resize(4); + result[3] = static_cast<char>(0x80 | (0x3f & cp)); + result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); + result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12))); + result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18))); + } + + return result; +} + + +/// Returns true if ch is a control character (in range [0,32[). +static inline bool +isControlCharacter(char ch) +{ + return ch > 0 && ch <= 0x1F; +} + + +enum { + /// Constant that specify the size of the buffer that must be passed to uintToString. + uintToStringBufferSize = 3*sizeof(LargestUInt)+1 +}; + +// Defines a char buffer for use with uintToString(). +typedef char UIntToStringBuffer[uintToStringBufferSize]; + + +/** Converts an unsigned integer to string. + * @param value Unsigned interger to convert to string + * @param current Input/Output string buffer. + * Must have at least uintToStringBufferSize chars free. + */ +static inline void +uintToString( LargestUInt value, + char *¤t ) +{ + *--current = 0; + do + { + *--current = char(value % 10) + '0'; + value /= 10; + } + while ( value != 0 ); +} + +} // namespace Json { + +#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED diff --git a/lib/jsoncpp/src/lib_json/json_value.cpp b/lib/jsoncpp/src/lib_json/json_value.cpp index bee3f70f64..218c127553 100644 --- a/lib/jsoncpp/src/lib_json/json_value.cpp +++ b/lib/jsoncpp/src/lib_json/json_value.cpp @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #include <iostream> #include <json/value.h> #include <json/writer.h> @@ -20,95 +25,50 @@ namespace Json { const Value Value::null; -const Value::Int Value::minInt = Value::Int( ~(Value::UInt(-1)/2) ); -const Value::Int Value::maxInt = Value::Int( Value::UInt(-1)/2 ); -const Value::UInt Value::maxUInt = Value::UInt(-1); - -// A "safe" implementation of strdup. Allow null pointer to be passed. -// Also avoid warning on msvc80. -// -//inline char *safeStringDup( const char *czstring ) -//{ -// if ( czstring ) -// { -// const size_t length = (unsigned int)( strlen(czstring) + 1 ); -// char *newString = static_cast<char *>( malloc( length ) ); -// memcpy( newString, czstring, length ); -// return newString; -// } -// return 0; -//} -// -//inline char *safeStringDup( const std::string &str ) -//{ -// if ( !str.empty() ) -// { -// const size_t length = str.length(); -// char *newString = static_cast<char *>( malloc( length + 1 ) ); -// memcpy( newString, str.c_str(), length ); -// newString[length] = 0; -// return newString; -// } -// return 0; -//} - -ValueAllocator::~ValueAllocator() +const Int Value::minInt = Int( ~(UInt(-1)/2) ); +const Int Value::maxInt = Int( UInt(-1)/2 ); +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 +enum { unknown = (unsigned)-1 }; + + +/** Duplicates the specified string value. + * @param value Pointer to the string to duplicate. Must be zero-terminated if + * length is "unknown". + * @param length Length of the value. if equals to unknown, then it will be + * computed using strlen(value). + * @return Pointer on the duplicate instance of string. + */ +static inline char * +duplicateStringValue( const char *value, + unsigned int length = unknown ) { + if ( length == unknown ) + length = (unsigned int)strlen(value); + char *newString = static_cast<char *>( malloc( length + 1 ) ); + memcpy( newString, value, length ); + newString[length] = 0; + return newString; } -class DefaultValueAllocator : public ValueAllocator -{ -public: - virtual ~DefaultValueAllocator() - { - } - - virtual char *makeMemberName( const char *memberName ) - { - return duplicateStringValue( memberName ); - } - - virtual void releaseMemberName( char *memberName ) - { - releaseStringValue( memberName ); - } - - virtual char *duplicateStringValue( const char *value, - unsigned int length = unknown ) - { - //@todo invesgate this old optimization - //if ( !value || value[0] == 0 ) - // return 0; - - if ( length == unknown ) - length = (unsigned int)strlen(value); - char *newString = static_cast<char *>( malloc( length + 1 ) ); - memcpy( newString, value, length ); - newString[length] = 0; - return newString; - } - virtual void releaseStringValue( char *value ) - { - if ( value ) - free( value ); - } -}; - -static ValueAllocator *&valueAllocator() +/** Free the string duplicated by duplicateStringValue(). + */ +static inline void +releaseStringValue( char *value ) { - static DefaultValueAllocator defaultAllocator; - static ValueAllocator *valueAllocator = &defaultAllocator; - return valueAllocator; + if ( value ) + free( value ); } -static struct DummyValueAllocatorInitializer { - DummyValueAllocatorInitializer() - { - valueAllocator(); // ensure valueAllocator() statics are initialized before main(). - } -} dummyValueAllocatorInitializer; - // ////////////////////////////////////////////////////////////////// @@ -143,7 +103,7 @@ Value::CommentInfo::CommentInfo() Value::CommentInfo::~CommentInfo() { if ( comment_ ) - valueAllocator()->releaseStringValue( comment_ ); + releaseStringValue( comment_ ); } @@ -151,11 +111,11 @@ void Value::CommentInfo::setComment( const char *text ) { if ( comment_ ) - valueAllocator()->releaseStringValue( comment_ ); + releaseStringValue( comment_ ); JSON_ASSERT( text ); JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /"); // It seems that /**/ style comments are acceptable as well. - comment_ = valueAllocator()->duplicateStringValue( text ); + comment_ = duplicateStringValue( text ); } @@ -171,14 +131,14 @@ Value::CommentInfo::setComment( const char *text ) // Notes: index_ indicates if the string was allocated when // a string is stored. -Value::CZString::CZString( int index ) +Value::CZString::CZString( ArrayIndex index ) : cstr_( 0 ) , index_( index ) { } Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) - : cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr) + : cstr_( allocate == duplicate ? duplicateStringValue(cstr) : cstr ) , index_( allocate ) { @@ -186,7 +146,7 @@ Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) Value::CZString::CZString( const CZString &other ) : cstr_( other.index_ != noDuplication && other.cstr_ != 0 - ? valueAllocator()->makeMemberName( other.cstr_ ) + ? duplicateStringValue( other.cstr_ ) : other.cstr_ ) , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_ ) @@ -196,7 +156,7 @@ Value::CZString::CZString( const CZString &other ) Value::CZString::~CZString() { if ( cstr_ && index_ == duplicate ) - valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) ); + releaseStringValue( const_cast<char *>( cstr_ ) ); } void @@ -231,7 +191,7 @@ Value::CZString::operator==( const CZString &other ) const } -int +ArrayIndex Value::CZString::index() const { return index_; @@ -309,6 +269,17 @@ Value::Value( ValueType type ) } +#if defined(JSON_HAS_INT64) +Value::Value( UInt value ) + : type_( uintValue ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.uint_ = value; +} + Value::Value( Int value ) : type_( intValue ) , comments_( 0 ) @@ -319,8 +290,21 @@ 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 ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP @@ -348,9 +332,24 @@ Value::Value( const char *value ) , itemIsUsed_( 0 ) #endif { - value_.string_ = valueAllocator()->duplicateStringValue( value ); + value_.string_ = duplicateStringValue( value ); +} + + +Value::Value( const char *beginValue, + const char *endValue ) + : type_( stringValue ) + , allocated_( true ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.string_ = duplicateStringValue( beginValue, + (unsigned int)(endValue - beginValue) ); } + Value::Value( const std::string &value ) : type_( stringValue ) , allocated_( true ) @@ -359,8 +358,8 @@ Value::Value( const std::string &value ) , itemIsUsed_( 0 ) #endif { - value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(), - (unsigned int)value.length() ); + value_.string_ = duplicateStringValue( value.c_str(), + (unsigned int)value.length() ); } @@ -385,7 +384,7 @@ Value::Value( const CppTL::ConstString &value ) , itemIsUsed_( 0 ) #endif { - value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() ); + value_.string_ = duplicateStringValue( value, value.length() ); } # endif @@ -419,7 +418,7 @@ Value::Value( const Value &other ) case stringValue: if ( other.value_.string_ ) { - value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ ); + value_.string_ = duplicateStringValue( other.value_.string_ ); allocated_ = true; } else @@ -466,7 +465,7 @@ Value::~Value() break; case stringValue: if ( allocated_ ) - valueAllocator()->releaseStringValue( value_.string_ ); + releaseStringValue( value_.string_ ); break; #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: @@ -697,6 +696,7 @@ Value::asConstString() const } # endif + Value::Int Value::asInt() const { @@ -705,10 +705,11 @@ Value::asInt() const case nullValue: return 0; 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: - JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" ); - return value_.uint_; + JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" ); + return Int(value_.uint_); case realValue: JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" ); return Int( value_.real_ ); @@ -724,6 +725,7 @@ Value::asInt() const return 0; // unreachable; } + Value::UInt Value::asUInt() const { @@ -733,9 +735,11 @@ Value::asUInt() const return 0; case intValue: 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: - return value_.uint_; + JSON_ASSERT_MESSAGE( value_.uint_ <= maxUInt, "unsigned integer out of UInt range" ); + return UInt(value_.uint_); case realValue: JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" ); return UInt( value_.real_ ); @@ -751,6 +755,88 @@ Value::asUInt() const 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 Value::asDouble() const { @@ -759,9 +845,13 @@ Value::asDouble() const case nullValue: return 0.0; case intValue: - return value_.int_; + return static_cast<double>( value_.int_ ); case uintValue: - return value_.uint_; +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<double>( value_.uint_ ); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<double>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) case realValue: return value_.real_; case booleanValue: @@ -776,6 +866,35 @@ Value::asDouble() const return 0; // unreachable; } +float +Value::asFloat() const +{ + switch ( type_ ) + { + case nullValue: + return 0.0f; + case intValue: + return static_cast<float>( value_.int_ ); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<float>( value_.uint_ ); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<float>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return static_cast<float>( value_.real_ ); + case booleanValue: + return value_.bool_ ? 1.0f : 0.0f; + case stringValue: + case arrayValue: + case objectValue: + JSON_ASSERT_MESSAGE( false, "Type is not convertible to float" ); + default: + JSON_ASSERT_UNREACHABLE; + } + return 0.0f; // unreachable; +} + bool Value::asBool() const { @@ -854,7 +973,7 @@ Value::isConvertibleTo( ValueType other ) const /// Number of values in array or object -Value::UInt +ArrayIndex Value::size() const { switch ( type_ ) @@ -876,7 +995,7 @@ Value::size() const } return 0; case objectValue: - return Int( value_.map_->size() ); + return ArrayIndex( value_.map_->size() ); #else case arrayValue: return Int( value_.array_->size() ); @@ -933,21 +1052,23 @@ Value::clear() } void -Value::resize( UInt newSize ) +Value::resize( ArrayIndex newSize ) { JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) *this = Value( arrayValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP - UInt oldSize = size(); + ArrayIndex oldSize = size(); if ( newSize == 0 ) clear(); else if ( newSize > oldSize ) (*this)[ newSize - 1 ]; else { - for ( UInt index = newSize; index < oldSize; ++index ) + for ( ArrayIndex index = newSize; index < oldSize; ++index ) + { value_.map_->erase( index ); + } assert( size() == newSize ); } #else @@ -957,7 +1078,7 @@ Value::resize( UInt newSize ) Value & -Value::operator[]( UInt index ) +Value::operator[]( ArrayIndex index ) { JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) @@ -977,8 +1098,16 @@ Value::operator[]( UInt index ) } +Value & +Value::operator[]( int index ) +{ + JSON_ASSERT( index >= 0 ); + return (*this)[ ArrayIndex(index) ]; +} + + const Value & -Value::operator[]( UInt index ) const +Value::operator[]( ArrayIndex index ) const { JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) @@ -996,6 +1125,14 @@ Value::operator[]( UInt index ) const } +const Value & +Value::operator[]( int index ) const +{ + JSON_ASSERT( index >= 0 ); + return (*this)[ ArrayIndex(index) ]; +} + + Value & Value::operator[]( const char *key ) { @@ -1028,7 +1165,7 @@ Value::resolveReference( const char *key, Value -Value::get( UInt index, +Value::get( ArrayIndex index, const Value &defaultValue ) const { const Value *value = &((*this)[index]); @@ -1037,7 +1174,7 @@ Value::get( UInt index, bool -Value::isValidIndex( UInt index ) const +Value::isValidIndex( ArrayIndex index ) const { return index < size(); } @@ -1047,8 +1184,8 @@ Value::isValidIndex( UInt index ) const const Value & Value::operator[]( const char *key ) const { - JSON_ASSERT( type_ == nullValue || type_ == objectValue || type_ == arrayValue ); - if ( type_ == nullValue || type_ == arrayValue) + JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey( key, CZString::noDuplication ); @@ -1500,7 +1637,7 @@ PathArgument::PathArgument() } -PathArgument::PathArgument( Value::UInt index ) +PathArgument::PathArgument( ArrayIndex index ) : index_( index ) , kind_( kindIndex ) { @@ -1556,9 +1693,9 @@ Path::makePath( const std::string &path, addPathInArg( path, in, itInArg, PathArgument::kindIndex ); else { - Value::UInt index = 0; + ArrayIndex index = 0; for ( ; current != end && *current >= '0' && *current <= '9'; ++current ) - index = index * 10 + Value::UInt(*current - '0'); + index = index * 10 + ArrayIndex(*current - '0'); args_.push_back( index ); } if ( current == end || *current++ != ']' ) diff --git a/lib/jsoncpp/src/lib_json/json_valueiterator.inl b/lib/jsoncpp/src/lib_json/json_valueiterator.inl index 898c35895b..bd7c8d2079 100644 --- a/lib/jsoncpp/src/lib_json/json_valueiterator.inl +++ b/lib/jsoncpp/src/lib_json/json_valueiterator.inl @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + // included by json_value.cpp // everything is within Json namespace @@ -176,7 +181,7 @@ ValueIteratorBase::key() const } -Value::UInt +UInt ValueIteratorBase::index() const { #ifndef JSON_VALUE_USE_INTERNAL_MAP diff --git a/lib/jsoncpp/src/lib_json/json_writer.cpp b/lib/jsoncpp/src/lib_json/json_writer.cpp index 2f17428954..f101cbcfb5 100644 --- a/lib/jsoncpp/src/lib_json/json_writer.cpp +++ b/lib/jsoncpp/src/lib_json/json_writer.cpp @@ -1,4 +1,10 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #include <json/writer.h> +#include "json_tool.h" #include <utility> #include <assert.h> #include <stdio.h> @@ -13,11 +19,6 @@ namespace Json { -static bool isControlCharacter(char ch) -{ - return ch > 0 && ch <= 0x1F; -} - static bool containsControlCharacter( const char* str ) { while ( *str ) @@ -27,26 +28,16 @@ static bool containsControlCharacter( const char* str ) } return false; } -static void uintToString( unsigned int value, - char *¤t ) -{ - *--current = 0; - do - { - *--current = (value % 10) + '0'; - value /= 10; - } - while ( value != 0 ); -} -std::string valueToString( Value::Int value ) + +std::string valueToString( LargestInt value ) { - char buffer[32]; + UIntToStringBuffer buffer; char *current = buffer + sizeof(buffer); bool isNegative = value < 0; if ( isNegative ) value = -value; - uintToString( Value::UInt(value), current ); + uintToString( LargestUInt(value), current ); if ( isNegative ) *--current = '-'; assert( current >= buffer ); @@ -54,15 +45,31 @@ std::string valueToString( Value::Int value ) } -std::string valueToString( Value::UInt value ) +std::string valueToString( LargestUInt value ) { - char buffer[32]; + UIntToStringBuffer buffer; char *current = buffer + sizeof(buffer); uintToString( value, current ); assert( current >= buffer ); 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 ) { char buffer[32]; @@ -71,17 +78,7 @@ std::string valueToString( double value ) #else sprintf(buffer, "%#.16g", value); #endif - char* ch = buffer; - // Incase sprintf have written ',' as decimal point switch it to '.' - while (*ch != '\0'){ - if (*ch == ','){ - *ch = '.'; - break; - } - ch++; - } - - ch = buffer + strlen(buffer) - 1; + char* ch = buffer + strlen(buffer) - 1; if (*ch != '0') return buffer; // nothing to truncate, so save time while(ch > buffer && *ch == '0'){ --ch; @@ -126,7 +123,7 @@ std::string valueToQuotedString( const char *value ) // We have to walk value and escape any special characters. // Appending to std::string is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL + std::string::size_type maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL std::string result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; @@ -223,10 +220,10 @@ FastWriter::writeValue( const Value &value ) document_ += "null"; break; case intValue: - document_ += valueToString( value.asInt() ); + document_ += valueToString( value.asLargestInt() ); break; case uintValue: - document_ += valueToString( value.asUInt() ); + document_ += valueToString( value.asLargestUInt() ); break; case realValue: document_ += valueToString( value.asDouble() ); @@ -306,10 +303,10 @@ StyledWriter::writeValue( const Value &value ) pushValue( "null" ); break; case intValue: - pushValue( valueToString( value.asInt() ) ); + pushValue( valueToString( value.asLargestInt() ) ); break; case uintValue: - pushValue( valueToString( value.asUInt() ) ); + pushValue( valueToString( value.asLargestUInt() ) ); break; case realValue: pushValue( valueToString( value.asDouble() ) ); @@ -582,10 +579,10 @@ StyledStreamWriter::writeValue( const Value &value ) pushValue( "null" ); break; case intValue: - pushValue( valueToString( value.asInt() ) ); + pushValue( valueToString( value.asLargestInt() ) ); break; case uintValue: - pushValue( valueToString( value.asUInt() ) ); + pushValue( valueToString( value.asLargestUInt() ) ); break; case realValue: pushValue( valueToString( value.asDouble() ) ); diff --git a/lib/jsoncpp/src/test_lib_json/jsontest.cpp b/lib/jsoncpp/src/test_lib_json/jsontest.cpp index dfd2b5c77d..02e7b21699 100644 --- a/lib/jsoncpp/src/test_lib_json/jsontest.cpp +++ b/lib/jsoncpp/src/test_lib_json/jsontest.cpp @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC #include "jsontest.h" #include <stdio.h> @@ -304,6 +309,11 @@ TestCase::TestCase() } +TestCase::~TestCase() +{ +} + + void TestCase::run( TestResult &result ) { diff --git a/lib/jsoncpp/src/test_lib_json/jsontest.h b/lib/jsoncpp/src/test_lib_json/jsontest.h index b2553baea1..0d072382e1 100644 --- a/lib/jsoncpp/src/test_lib_json/jsontest.h +++ b/lib/jsoncpp/src/test_lib_json/jsontest.h @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #ifndef JSONTEST_H_INCLUDED # define JSONTEST_H_INCLUDED @@ -110,6 +115,8 @@ namespace JsonTest { public: TestCase(); + virtual ~TestCase(); + void run( TestResult &result ); virtual const char *testName() const = 0; @@ -192,7 +199,7 @@ namespace JsonTest { /// JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y; /// JSONTEST_ASSERT( x == y ); #define JSONTEST_ASSERT( expr ) \ - if ( condition ) \ + if ( expr ) \ { \ } \ else \ diff --git a/lib/jsoncpp/src/test_lib_json/main.cpp b/lib/jsoncpp/src/test_lib_json/main.cpp index b80776d630..de64200ce7 100644 --- a/lib/jsoncpp/src/test_lib_json/main.cpp +++ b/lib/jsoncpp/src/test_lib_json/main.cpp @@ -1,3 +1,8 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + #include <json/json.h> #include "jsontest.h" @@ -23,6 +28,7 @@ struct ValueTest : JsonTest::TestCase Json::Value unsignedInteger_; Json::Value smallUnsignedInteger_; Json::Value real_; + Json::Value float_; Json::Value array1_; Json::Value object1_; Json::Value emptyString_; @@ -38,6 +44,7 @@ struct ValueTest : JsonTest::TestCase , smallUnsignedInteger_( Json::Value::UInt( Json::Value::maxInt ) ) , unsignedInteger_( 34567890u ) , real_( 1234.56789 ) + , float_( 0.00390625f ) , emptyString_( "" ) , string1_( "a" ) , string_( "sometext with space" ) @@ -167,6 +174,23 @@ JSONTEST_FIXTURE( ValueTest, isUInt ) } +JSONTEST_FIXTURE( ValueTest, accessArray ) +{ + const unsigned int index0 = 0; + JSONTEST_ASSERT( Json::Value(1234) == array1_[index0] ) << "Json::Value::operator[ArrayIndex]"; + JSONTEST_ASSERT( Json::Value(1234) == array1_[0] ) << "Json::Value::operator[int]"; + + const Json::Value &constArray = array1_; + JSONTEST_ASSERT( Json::Value(1234) == constArray[index0] ) << "Json::Value::operator[ArrayIndex] const"; + JSONTEST_ASSERT( Json::Value(1234) == constArray[0] ) << "Json::Value::operator[int] const"; +} + + +JSONTEST_FIXTURE( ValueTest, asFloat ) +{ + JSONTEST_ASSERT_EQUAL( 0.00390625f, float_.asFloat() ) << "Json::Value::asFloat()"; +} + void ValueTest::checkConstMemberCount( const Json::Value &value, unsigned int expectedCount ) { @@ -240,5 +264,8 @@ int main( int argc, const char *argv[] ) JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isDouble ); JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isString ); JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isNull ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isNull ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, accessArray ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, asFloat ); return runner.runCommandLine( argc, argv ); } |