aboutsummaryrefslogtreecommitdiff
path: root/lib/jsoncpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jsoncpp/src')
-rw-r--r--lib/jsoncpp/src/jsontestrunner/main.cpp88
-rw-r--r--lib/jsoncpp/src/lib_json/json_batchallocator.h5
-rw-r--r--lib/jsoncpp/src/lib_json/json_internalarray.inl5
-rw-r--r--lib/jsoncpp/src/lib_json/json_internalmap.inl7
-rw-r--r--lib/jsoncpp/src/lib_json/json_reader.cpp73
-rw-r--r--lib/jsoncpp/src/lib_json/json_tool.h93
-rw-r--r--lib/jsoncpp/src/lib_json/json_value.cpp373
-rw-r--r--lib/jsoncpp/src/lib_json/json_valueiterator.inl7
-rw-r--r--lib/jsoncpp/src/lib_json/json_writer.cpp75
-rw-r--r--lib/jsoncpp/src/test_lib_json/jsontest.cpp10
-rw-r--r--lib/jsoncpp/src/test_lib_json/jsontest.h9
-rw-r--r--lib/jsoncpp/src/test_lib_json/main.cpp27
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 *&current )
+{
+ *--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 *&current )
-{
- *--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 );
}