Compare commits

..

36 Commits

Author SHA1 Message Date
Christopher Dunn
65b47144f1 partially revert 'Added features that allow the reader to accept common non-standard JSON.'
revert '642befc836ac5093b528e7d8b4fd66b66735a98c',
but keep the *added* methods for `decodedNumber()` and `decodedDouble()`.
2015-03-31 15:07:43 -05:00
Christopher Dunn
6bc7bff8ad partially revert 'fix bug for static init'
re: 28836b8acc

A global instance of a Value (viz. 'null') was a mistake,
but dropping it breaks binary-compatibility. So we will keep it
everywhere except the one platform where it was crashing, ARM.
2015-03-31 15:07:43 -05:00
Christopher Dunn
5e5d4f79bc revert 'Made it possible to drop null placeholders from array output.'
revert ae3c7a7aab
2015-03-31 15:07:43 -05:00
Christopher Dunn
42c395a9b6 Revert "added option to FastWriter which omits the trailing new line character"
This reverts commit 5bf16105b5.
2015-03-31 15:07:43 -05:00
Christopher Dunn
7fa28fc7c8 revert 'Added structured error reporting to Reader.'
revert 68db655347
issue #147
2015-03-31 15:07:43 -05:00
Christopher Dunn
ec71240def revert 'Add public semantic error reporting'
for binary-compatibility with 0.6.0
issue #147
was #57
2015-03-31 15:07:42 -05:00
Christopher Dunn
58c2ab5527 partially revert "Switch to copy-and-swap idiom for operator=."
This partially reverts commit 45cd9490cd.

Ignored ValueInternal* changes, since those did not produce symbols for
Debian build. (They must not have used the INTERNAL stuff.)

Ignored CZString changes since those are private (and sizeof struct did
not change).

  https://github.com/open-source-parsers/jsoncpp/issues/78

Conflicts:
	include/json/value.h
	src/lib_json/json_internalarray.inl
	src/lib_json/json_internalmap.inl
	src/lib_json/json_value.cpp
2015-03-31 15:07:42 -05:00
Christopher Dunn
b3e4ed5277 NOT C++11 2015-03-31 15:07:42 -05:00
Christopher Dunn
e9543de4c3 0.10.z (based on 1.6.z, but binary-compat w/ 0.6.0-rc2) 2015-03-31 15:07:42 -05:00
Christopher Dunn
1269f26494 prefer std::string for setComment()
in case of embedded nulls
2015-03-31 15:07:42 -05:00
Christopher Dunn
9cb88d2ca6 1.6.1 <- 1.6.0 2015-03-31 15:07:14 -05:00
Christopher Dunn
363e51c0a9 Merge pull request #232 from cdunn2001/fix-snprintf
Fix snprintf

Well, it passes Travis. But when we have time, we should clean up how snprintf is used in both reader and writer.
2015-03-31 15:06:11 -05:00
Christopher Dunn
240ddb6a1b use std::snprintf for C++11 2015-03-31 15:04:24 -05:00
Baruch Siach
9dd77dc0ef Revert "Use std namespace for snprintf."
This reverts commit 1c58876185.

std::snprintf() is only available in C++11, which is not provided by
all compilers. Since the C library snprintf() can easily be used as a
replacement on Linux systems, this patch changes jsoncpp to use the C
library snprintf() instead of C++11 std::snprintf(), fixing the build error
below:

    src/lib_json/json_writer.cpp:33:18: error: 'snprintf' is not a member of 'std'

See #231, #224, and #218.
2015-03-31 15:04:24 -05:00
Christopher Dunn
244b1496e1 Merge pull request #225 from selaselah/master
fix find_program() bug: no result in not-win sys
2015-03-31 11:32:06 -05:00
selaselah
c083835261 fix find_program() bug: no result in not-win sys 2015-03-19 19:18:58 +08:00
Christopher Dunn
cbe7e7c9cb Merge pull request #221 from btolfa/forgotten-virtual-dtor
Added forgotten virtual dtor for `Json::CharReader::Factory`.

(Without this, the destructor of the derived `CharReaderBuilder` would not be called, which is a small memory leak.)
2015-03-15 13:49:24 -05:00
Tengiz Sharafiev
be183def8f Update reader.h 2015-03-14 21:30:00 +03:00
Christopher Dunn
951bd3d05d Merge pull request #219 from cdunn2001/c-std-headers
Close #218. Fix #214.
2015-03-11 21:36:51 -05:00
Connor Manning
1c58876185 Use std namespace for snprintf. 2015-03-11 21:33:08 -05:00
Connor Manning
2f2034629e Constrain MSVC _isfinite to before 2013, remove duplicate includes. 2015-03-11 21:33:08 -05:00
Dani-Hub
7020451b44 Fix isfinite for MSVC. 2015-03-11 21:32:59 -05:00
Connor Manning
80497f102e Use C++ standard headers. 2015-03-10 18:48:45 -05:00
Dani-Hub
f9feb66be2 Change exception data member
from "reference to string" to "string" (Resolves the most serious part of issue #216)
2015-03-09 18:42:16 -05:00
Christopher Dunn
ed495edcc1 prefer ValueIterator::name() to ::memberName()
in case of embedded nulls
2015-03-08 14:35:00 -05:00
Christopher Dunn
3c0a383877 Merge pull request #212 from cdunn2001/macro-deprec
close #210
2015-03-08 13:10:37 -05:00
Dani-Hub
5003983029 Make preprocessor query robust against older gcc versions 2015-03-08 13:07:27 -05:00
Dani-Hub
871b311e7e Provide JSONCPP_DEPRECATED definitions for clang and gcc 2015-03-08 13:07:27 -05:00
Christopher Dunn
cdbc35f6ac 1.6.0 2015-03-08 12:57:13 -05:00
Christopher Dunn
4e30c4fcdb comments 2015-03-08 12:56:32 -05:00
Christopher Dunn
0d33cb3639 Merge pull request #211 from cdunn2001/except
* Add Json::Exception and derivatives.
* Clarify when exceptions are thrown, to avoid crashes caused by malicious input.
* Use our own type (derived fro std::exception) so they are trappable.
2015-03-08 12:50:34 -05:00
Christopher Dunn
2250b3c29d use Json::RuntimeError 2015-03-08 12:44:55 -05:00
Christopher Dunn
9376368d86 use Json::LogicError in macros 2015-03-08 12:42:53 -05:00
Christopher Dunn
5383794cc9 Runtime/LogicError and throwers 2015-03-08 12:31:57 -05:00
Christopher Dunn
75279ccec2 base Json::Exception 2015-03-08 12:20:06 -05:00
Christopher Dunn
717b08695e clarify errors
* use macros for logic errors, not input errors
* throw on parsing failure in `operator>>()`, not assert
* throw on malloc, not assert
2015-03-08 12:06:22 -05:00
14 changed files with 189 additions and 47 deletions

View File

@@ -60,7 +60,7 @@ ENDMACRO(jsoncpp_parse_version)
#SET( JSONCPP_VERSION_MAJOR X ) #SET( JSONCPP_VERSION_MAJOR X )
#SET( JSONCPP_VERSION_MINOR Y ) #SET( JSONCPP_VERSION_MINOR Y )
#SET( JSONCPP_VERSION_PATCH Z ) #SET( JSONCPP_VERSION_PATCH Z )
SET( JSONCPP_VERSION 0.9.4 ) SET( JSONCPP_VERSION 0.10.1 )
jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION ) jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION )
#IF(NOT JSONCPP_VERSION_FOUND) #IF(NOT JSONCPP_VERSION_FOUND)
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z") # MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")

View File

@@ -31,7 +31,7 @@ def find_program(*filenames):
paths = os.environ.get('PATH', '').split(os.pathsep) paths = os.environ.get('PATH', '').split(os.pathsep)
suffixes = ('win32' in sys.platform) and '.exe .com .bat .cmd' or '' suffixes = ('win32' in sys.platform) and '.exe .com .bat .cmd' or ''
for filename in filenames: for filename in filenames:
for name in [filename+ext for ext in suffixes.split()]: for name in [filename+ext for ext in suffixes.split(' ')]:
for directory in paths: for directory in paths:
full_path = os.path.join(directory, name) full_path = os.path.join(directory, name)
if os.path.isfile(full_path): if os.path.isfile(full_path):

View File

@@ -13,22 +13,30 @@
#include "config.h" #include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
/** It should not be possible for a maliciously designed file to
* cause an abort() or seg-fault, so these macros are used only
* for pre-condition violations and internal logic errors.
*/
#if JSON_USE_EXCEPTION #if JSON_USE_EXCEPTION
#include <stdexcept>
#define JSON_ASSERT(condition) \ // @todo <= add detail about condition in exception
{if (!(condition)) {throw std::logic_error( "assert json failed" );}} // @todo <= add detail about condition in exception # define JSON_ASSERT(condition) \
#define JSON_FAIL_MESSAGE(message) \ {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
# define JSON_FAIL_MESSAGE(message) \
{ \ { \
std::ostringstream oss; oss << message; \ std::ostringstream oss; oss << message; \
throw std::logic_error(oss.str()); \ Json::throwLogicError(oss.str()); \
abort(); \
} }
//#define JSON_FAIL_MESSAGE(message) throw std::logic_error(message)
#else // JSON_USE_EXCEPTION #else // JSON_USE_EXCEPTION
#define JSON_ASSERT(condition) assert(condition)
# define JSON_ASSERT(condition) assert(condition)
// The call to assert() will show the failure message in debug builds. In // The call to assert() will show the failure message in debug builds. In
// release bugs we abort, for a core-dump or debugger. // release builds we abort, for a core-dump or debugger.
#define JSON_FAIL_MESSAGE(message) \ # define JSON_FAIL_MESSAGE(message) \
{ \ { \
std::ostringstream oss; oss << message; \ std::ostringstream oss; oss << message; \
assert(false && oss.str().c_str()); \ assert(false && oss.str().c_str()); \

View File

@@ -70,6 +70,14 @@
#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 #if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated. /// Indicates that the following function is deprecated.
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__clang__) && defined(__has_feature)
#if __has_feature(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif #endif
#if !defined(JSONCPP_DEPRECATED) #if !defined(JSONCPP_DEPRECATED)

View File

@@ -98,7 +98,7 @@ public:
* during parsing. * during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix). * \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/ */
JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead") JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
std::string getFormatedErrorMessages() const; std::string getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed /** \brief Returns a user friendly string that list errors in the parsed
@@ -226,6 +226,7 @@ public:
class Factory { class Factory {
public: public:
virtual ~Factory() {}
/** \brief Allocate a CharReader via operator new(). /** \brief Allocate a CharReader via operator new().
* \throw std::exception if something goes wrong (e.g. invalid settings) * \throw std::exception if something goes wrong (e.g. invalid settings)
*/ */
@@ -235,8 +236,6 @@ public:
/** \brief Build a CharReader implementation. /** \brief Build a CharReader implementation.
\deprecated This is experimental and will be altered before the next release.
Usage: Usage:
\code \code
using namespace Json; using namespace Json;

View File

@@ -11,6 +11,7 @@
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <string> #include <string>
#include <vector> #include <vector>
#include <exception>
#ifndef JSON_USE_CPPTL_SMALLMAP #ifndef JSON_USE_CPPTL_SMALLMAP
#include <map> #include <map>
@@ -32,6 +33,31 @@
*/ */
namespace Json { namespace Json {
/** Base class for all exceptions we throw.
*
* We use nothing but these internally. Of course, STL can throw others.
*/
class JSON_API Exception;
/** Exceptions which the user cannot easily avoid.
*
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
*
* \remark derived from Json::Exception
*/
class JSON_API RuntimeError;
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
*
* These are precondition-violations (user bugs) and internal errors (our bugs).
*
* \remark derived from Json::Exception
*/
class JSON_API LogicError;
/// used internally
void throwRuntimeError(std::string const& msg);
/// used internally
void throwLogicError(std::string const& msg);
/** \brief Type of the value held by a Value object. /** \brief Type of the value held by a Value object.
*/ */
enum ValueType { enum ValueType {
@@ -489,6 +515,7 @@ Json::Value obj_value(Json::objectValue); // {}
//# endif //# endif
/// \deprecated Always pass len. /// \deprecated Always pass len.
JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
void setComment(const char* comment, CommentPlacement placement); void setComment(const char* comment, CommentPlacement placement);
/// Comments must be //... or /* ... */ /// Comments must be //... or /* ... */
void setComment(const char* comment, size_t len, CommentPlacement placement); void setComment(const char* comment, size_t len, CommentPlacement placement);
@@ -632,16 +659,22 @@ public:
/// Value. /// Value.
Value key() const; Value key() const;
/// Return the index of the referenced Value. -1 if it is not an arrayValue. /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
UInt index() const; UInt index() const;
/// Return the member name of the referenced Value, or "" if it is not an
/// objectValue.
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
std::string name() const;
/// Return the member name of the referenced Value. "" if it is not an /// Return the member name of the referenced Value. "" if it is not an
/// objectValue. /// objectValue.
/// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
JSONCPP_DEPRECATED("Use `key = name();` instead.")
char const* memberName() const; char const* memberName() const;
/// Return the member name of the referenced Value, or NULL if it is not an /// Return the member name of the referenced Value, or NULL if it is not an
/// objectValue. /// objectValue.
/// Better version than memberName(). Allows embedded nulls. /// \note Better version than memberName(). Allows embedded nulls.
char const* memberName(char const** end) const; char const* memberName(char const** end) const;
protected: protected:

View File

@@ -4,10 +4,10 @@
#ifndef JSON_VERSION_H_INCLUDED #ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED # define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "0.9.4" # define JSONCPP_VERSION_STRING "0.10.1"
# define JSONCPP_VERSION_MAJOR 0 # define JSONCPP_VERSION_MAJOR 0
# define JSONCPP_VERSION_MINOR 9 # define JSONCPP_VERSION_MINOR 10
# define JSONCPP_VERSION_PATCH 4 # define JSONCPP_VERSION_PATCH 1
# define JSONCPP_VERSION_QUALIFIER # define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))

View File

@@ -46,7 +46,7 @@ public:
/** Write Value into document as configured in sub-class. /** Write Value into document as configured in sub-class.
Do not take ownership of sout, but maintain a reference during function. Do not take ownership of sout, but maintain a reference during function.
\pre sout != NULL \pre sout != NULL
\return zero on success \return zero on success (For now, we always return zero, so check the stream instead.)
\throw std::exception possibly, depending on configuration \throw std::exception possibly, depending on configuration
*/ */
virtual int write(Value const& root, std::ostream* sout) = 0; virtual int write(Value const& root, std::ostream* sout) = 0;
@@ -132,7 +132,7 @@ public:
}; };
/** \brief Abstract class for writers. /** \brief Abstract class for writers.
* \deprecated Use StreamWriter. * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
*/ */
class JSON_API Writer { class JSON_API Writer {
public: public:
@@ -151,6 +151,7 @@ public:
* \deprecated Use StreamWriterBuilder. * \deprecated Use StreamWriterBuilder.
*/ */
class JSON_API FastWriter : public Writer { class JSON_API FastWriter : public Writer {
public: public:
FastWriter(); FastWriter();
virtual ~FastWriter() {} virtual ~FastWriter() {}

View File

@@ -17,7 +17,6 @@
#include <sstream> #include <sstream>
#include <memory> #include <memory>
#include <set> #include <set>
#include <stdexcept>
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below #if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#define snprintf _snprintf #define snprintf _snprintf
@@ -145,7 +144,7 @@ bool Reader::readValue() {
// But this deprecated class has a security problem: Bad input can // But this deprecated class has a security problem: Bad input can
// cause a seg-fault. This seems like a fair, binary-compatible way // cause a seg-fault. This seems like a fair, binary-compatible way
// to prevent the problem. // to prevent the problem.
if (stackDepth_g >= stackLimit_g) throw std::runtime_error("Exceeded stackLimit in readValue()."); if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
++stackDepth_g; ++stackDepth_g;
Token token; Token token;
@@ -1014,7 +1013,7 @@ bool OurReader::parse(const char* beginDoc,
} }
bool OurReader::readValue() { bool OurReader::readValue() {
if (stackDepth_ >= features_.stackLimit_) throw std::runtime_error("Exceeded stackLimit in readValue()."); if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
++stackDepth_; ++stackDepth_;
Token token; Token token;
skipCommentTokens(token); skipCommentTokens(token);
@@ -1325,7 +1324,7 @@ bool OurReader::readObject(Token& tokenStart) {
return addErrorAndRecover( return addErrorAndRecover(
"Missing ':' after object member name", colon, tokenObjectEnd); "Missing ':' after object member name", colon, tokenObjectEnd);
} }
if (name.length() >= (1U<<30)) throw std::runtime_error("keylength >= 2^30"); if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
if (features_.rejectDupKeys_ && currentValue().isMember(name)) { if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
std::string msg = "Duplicate key: '" + name + "'"; std::string msg = "Duplicate key: '" + name + "'";
return addErrorAndRecover( return addErrorAndRecover(
@@ -1827,7 +1826,7 @@ std::istream& operator>>(std::istream& sin, Value& root) {
"Error from reader: %s", "Error from reader: %s",
errs.c_str()); errs.c_str());
JSON_FAIL_MESSAGE("reader error"); throwRuntimeError("reader error");
} }
return sin; return sin;
} }

View File

@@ -88,9 +88,11 @@ static inline char* duplicateStringValue(const char* value,
length = Value::maxInt - 1; length = Value::maxInt - 1;
char* newString = static_cast<char*>(malloc(length + 1)); char* newString = static_cast<char*>(malloc(length + 1));
JSON_ASSERT_MESSAGE(newString != 0, if (newString == NULL) {
"in Json::Value::duplicateStringValue(): " throwRuntimeError(
"Failed to allocate string value buffer"); "in Json::Value::duplicateStringValue(): "
"Failed to allocate string value buffer");
}
memcpy(newString, value, length); memcpy(newString, value, length);
newString[length] = 0; newString[length] = 0;
return newString; return newString;
@@ -109,9 +111,11 @@ static inline char* duplicateAndPrefixStringValue(
"length too big for prefixing"); "length too big for prefixing");
unsigned actualLength = length + sizeof(unsigned) + 1U; unsigned actualLength = length + sizeof(unsigned) + 1U;
char* newString = static_cast<char*>(malloc(actualLength)); char* newString = static_cast<char*>(malloc(actualLength));
JSON_ASSERT_MESSAGE(newString != 0, if (newString == 0) {
"in Json::Value::duplicateAndPrefixStringValue(): " throwRuntimeError(
"Failed to allocate string value buffer"); "in Json::Value::duplicateAndPrefixStringValue(): "
"Failed to allocate string value buffer");
}
*reinterpret_cast<unsigned*>(newString) = length; *reinterpret_cast<unsigned*>(newString) = length;
memcpy(newString + sizeof(unsigned), value, length); memcpy(newString + sizeof(unsigned), value, length);
newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
@@ -149,6 +153,47 @@ static inline void releaseStringValue(char* value) { free(value); }
namespace Json { namespace Json {
class JSON_API Exception : public std::exception {
public:
Exception(std::string const& msg);
virtual ~Exception() throw();
virtual char const* what() const throw();
protected:
std::string const msg_;
};
class JSON_API RuntimeError : public Exception {
public:
RuntimeError(std::string const& msg);
};
class JSON_API LogicError : public Exception {
public:
LogicError(std::string const& msg);
};
Exception::Exception(std::string const& msg)
: msg_(msg)
{}
Exception::~Exception() throw()
{}
char const* Exception::what() const throw()
{
return msg_.c_str();
}
RuntimeError::RuntimeError(std::string const& msg)
: Exception(msg)
{}
LogicError::LogicError(std::string const& msg)
: Exception(msg)
{}
void throwRuntimeError(std::string const& msg)
{
throw RuntimeError(msg);
}
void throwLogicError(std::string const& msg)
{
throw LogicError(msg);
}
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////

View File

@@ -92,6 +92,14 @@ UInt ValueIteratorBase::index() const {
return Value::UInt(-1); return Value::UInt(-1);
} }
std::string ValueIteratorBase::name() const {
char const* key;
char const* end;
key = memberName(&end);
if (!key) return std::string();
return std::string(key, end);
}
char const* ValueIteratorBase::memberName() const { char const* ValueIteratorBase::memberName() const {
const char* name = (*current_).first.data(); const char* name = (*current_).first.data();
return name ? name : ""; return name ? name : "";

View File

@@ -12,16 +12,25 @@
#include <sstream> #include <sstream>
#include <utility> #include <utility>
#include <set> #include <set>
#include <stdexcept> #include <cassert>
#include <assert.h> #include <cstring>
#include <math.h> #include <cstdio>
#include <stdio.h>
#include <string.h>
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below #if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
#include <float.h> #include <float.h>
#define isfinite _finite #define isfinite _finite
#elif defined(__sun) && defined(__SVR4) //Solaris
#include <ieeefp.h>
#define isfinite finite
#else
#include <cmath>
#define isfinite std::isfinite
#endif
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#define snprintf _snprintf #define snprintf _snprintf
#elif __cplusplus >= 201103L
#define snprintf std::snprintf
#endif #endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
@@ -29,11 +38,6 @@
#pragma warning(disable : 4996) #pragma warning(disable : 4996)
#endif #endif
#if defined(__sun) && defined(__SVR4) //Solaris
#include <ieeefp.h>
#define isfinite finite
#endif
namespace Json { namespace Json {
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
@@ -1073,7 +1077,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
} else if (cs_str == "None") { } else if (cs_str == "None") {
cs = CommentStyle::None; cs = CommentStyle::None;
} else { } else {
throw std::runtime_error("commentStyle must be 'All' or 'None'"); throwRuntimeError("commentStyle must be 'All' or 'None'");
} }
std::string colonSymbol = " : "; std::string colonSymbol = " : ";
if (eyc) { if (eyc) {

View File

@@ -6,7 +6,6 @@
#include "jsontest.h" #include "jsontest.h"
#include <json/config.h> #include <json/config.h>
#include <json/json.h> #include <json/json.h>
#include <stdexcept>
#include <cstring> #include <cstring>
// Make numeric limits more convenient to talk about. // Make numeric limits more convenient to talk about.
@@ -1524,7 +1523,7 @@ JSONTEST_FIXTURE(ValueTest, StaticString) {
JSONTEST_FIXTURE(ValueTest, CommentBefore) { JSONTEST_FIXTURE(ValueTest, CommentBefore) {
Json::Value val; // fill val Json::Value val; // fill val
val.setComment("// this comment should appear before", Json::commentBefore); val.setComment(std::string("// this comment should appear before"), Json::commentBefore);
Json::StreamWriterBuilder wbuilder; Json::StreamWriterBuilder wbuilder;
wbuilder.settings_["commentStyle"] = "All"; wbuilder.settings_["commentStyle"] = "All";
{ {
@@ -2213,6 +2212,42 @@ JSONTEST_FIXTURE(IteratorTest, distance) {
JSONTEST_ASSERT_STRING_EQUAL("b", str); JSONTEST_ASSERT_STRING_EQUAL("b", str);
} }
JSONTEST_FIXTURE(IteratorTest, names) {
Json::Value json;
json["k1"] = "a";
json["k2"] = "b";
Json::ValueIterator it = json.begin();
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value("k1"), it.key());
JSONTEST_ASSERT_STRING_EQUAL("k1", it.name());
JSONTEST_ASSERT_EQUAL(-1, it.index());
++it;
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value("k2"), it.key());
JSONTEST_ASSERT_STRING_EQUAL("k2", it.name());
JSONTEST_ASSERT_EQUAL(-1, it.index());
++it;
JSONTEST_ASSERT(it == json.end());
}
JSONTEST_FIXTURE(IteratorTest, indexes) {
Json::Value json;
json[0] = "a";
json[1] = "b";
Json::ValueIterator it = json.begin();
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(0)), it.key());
JSONTEST_ASSERT_STRING_EQUAL("", it.name());
JSONTEST_ASSERT_EQUAL(0, it.index());
++it;
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(1)), it.key());
JSONTEST_ASSERT_STRING_EQUAL("", it.name());
JSONTEST_ASSERT_EQUAL(1, it.index());
++it;
JSONTEST_ASSERT(it == json.end());
}
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
JsonTest::Runner runner; JsonTest::Runner runner;
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
@@ -2275,6 +2310,8 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, BuilderTest, settings); JSONTEST_REGISTER_FIXTURE(runner, BuilderTest, settings);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance); JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, names);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
return runner.runCommandLine(argc, argv); return runner.runCommandLine(argc, argv);
} }

View File

@@ -1 +1 @@
0.9.4 0.10.1