mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-10-15 15:16:47 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1e5ebffce6 | ||
![]() |
e753cc5693 | ||
![]() |
7b304c22f0 | ||
![]() |
dbee5f968c | ||
![]() |
c27b2794fd | ||
![]() |
335aed7208 | ||
![]() |
c74784621e | ||
![]() |
44fb853041 | ||
![]() |
b0403282a7 |
@@ -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 1.6.0 )
|
SET( JSONCPP_VERSION 0.9.4 )
|
||||||
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")
|
||||||
@@ -94,10 +94,10 @@ endif( MSVC )
|
|||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
# using regular Clang or AppleClang
|
# using regular Clang or AppleClang
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
# using GCC
|
# using GCC
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wextra -pedantic")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
IF(JSONCPP_WITH_WARNING_AS_ERROR)
|
IF(JSONCPP_WITH_WARNING_AS_ERROR)
|
||||||
|
@@ -13,30 +13,22 @@
|
|||||||
#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>
|
||||||
// @todo <= add detail about condition in exception
|
#define JSON_ASSERT(condition) \
|
||||||
# define JSON_ASSERT(condition) \
|
{if (!(condition)) {throw std::logic_error( "assert json failed" );}} // @todo <= add detail about condition in exception
|
||||||
{if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
|
#define JSON_FAIL_MESSAGE(message) \
|
||||||
|
|
||||||
# define JSON_FAIL_MESSAGE(message) \
|
|
||||||
{ \
|
{ \
|
||||||
std::ostringstream oss; oss << message; \
|
std::ostringstream oss; oss << message; \
|
||||||
Json::throwLogicError(oss.str()); \
|
throw std::logic_error(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 builds we abort, for a core-dump or debugger.
|
// release bugs 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()); \
|
||||||
|
@@ -70,14 +70,6 @@
|
|||||||
#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)
|
||||||
|
@@ -44,12 +44,6 @@ public:
|
|||||||
/// \c true if root must be either an array or an object value. Default: \c
|
/// \c true if root must be either an array or an object value. Default: \c
|
||||||
/// false.
|
/// false.
|
||||||
bool strictRoot_;
|
bool strictRoot_;
|
||||||
|
|
||||||
/// \c true if dropped null placeholders are allowed. Default: \c false.
|
|
||||||
bool allowDroppedNullPlaceholders_;
|
|
||||||
|
|
||||||
/// \c true if numeric object key are allowed. Default: \c false.
|
|
||||||
bool allowNumericKeys_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Json
|
} // namespace Json
|
||||||
|
@@ -35,18 +35,6 @@ public:
|
|||||||
typedef char Char;
|
typedef char Char;
|
||||||
typedef const Char* Location;
|
typedef const Char* Location;
|
||||||
|
|
||||||
/** \brief An error tagged with where in the JSON text it was encountered.
|
|
||||||
*
|
|
||||||
* The offsets give the [start, limit) range of bytes within the text. Note
|
|
||||||
* that this is bytes, not codepoints.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct StructuredError {
|
|
||||||
size_t offset_start;
|
|
||||||
size_t offset_limit;
|
|
||||||
std::string message;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \brief Constructs a Reader allowing all features
|
/** \brief Constructs a Reader allowing all features
|
||||||
* for parsing.
|
* for parsing.
|
||||||
*/
|
*/
|
||||||
@@ -110,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
|
||||||
@@ -123,38 +111,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::string getFormattedErrorMessages() const;
|
std::string getFormattedErrorMessages() const;
|
||||||
|
|
||||||
/** \brief Returns a vector of structured erros encounted while parsing.
|
|
||||||
* \return A (possibly empty) vector of StructuredError objects. Currently
|
|
||||||
* only one error can be returned, but the caller should tolerate
|
|
||||||
* multiple
|
|
||||||
* errors. This can occur if the parser recovers from a non-fatal
|
|
||||||
* parse error and then encounters additional errors.
|
|
||||||
*/
|
|
||||||
std::vector<StructuredError> getStructuredErrors() const;
|
|
||||||
|
|
||||||
/** \brief Add a semantic error message.
|
|
||||||
* \param value JSON Value location associated with the error
|
|
||||||
* \param message The error message.
|
|
||||||
* \return \c true if the error was successfully added, \c false if the
|
|
||||||
* Value offset exceeds the document size.
|
|
||||||
*/
|
|
||||||
bool pushError(const Value& value, const std::string& message);
|
|
||||||
|
|
||||||
/** \brief Add a semantic error message with extra context.
|
|
||||||
* \param value JSON Value location associated with the error
|
|
||||||
* \param message The error message.
|
|
||||||
* \param extra Additional JSON Value location to contextualize the error
|
|
||||||
* \return \c true if the error was successfully added, \c false if either
|
|
||||||
* Value offset exceeds the document size.
|
|
||||||
*/
|
|
||||||
bool pushError(const Value& value, const std::string& message, const Value& extra);
|
|
||||||
|
|
||||||
/** \brief Return whether there are any errors.
|
|
||||||
* \return \c true if there are no errors to report \c false if
|
|
||||||
* errors have occurred.
|
|
||||||
*/
|
|
||||||
bool good() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TokenType {
|
enum TokenType {
|
||||||
tokenEndOfStream = 0,
|
tokenEndOfStream = 0,
|
||||||
@@ -270,7 +226,6 @@ 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)
|
||||||
*/
|
*/
|
||||||
@@ -280,6 +235,8 @@ 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;
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#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>
|
||||||
@@ -33,31 +32,6 @@
|
|||||||
*/
|
*/
|
||||||
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 {
|
||||||
@@ -160,8 +134,11 @@ public:
|
|||||||
typedef Json::LargestUInt LargestUInt;
|
typedef Json::LargestUInt LargestUInt;
|
||||||
typedef Json::ArrayIndex ArrayIndex;
|
typedef Json::ArrayIndex ArrayIndex;
|
||||||
|
|
||||||
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
|
static const Value& nullRef;
|
||||||
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
|
#if !defined(__ARMEL__)
|
||||||
|
/// \deprecated This exists for binary compatibility only. Use nullRef.
|
||||||
|
static const Value null;
|
||||||
|
#endif
|
||||||
/// Minimum signed integer value that can be stored in a Json::Value.
|
/// Minimum signed integer value that can be stored in a Json::Value.
|
||||||
static const LargestInt minLargestInt;
|
static const LargestInt minLargestInt;
|
||||||
/// Maximum signed integer value that can be stored in a Json::Value.
|
/// Maximum signed integer value that can be stored in a Json::Value.
|
||||||
@@ -283,7 +260,7 @@ Json::Value obj_value(Json::objectValue); // {}
|
|||||||
|
|
||||||
/// Deep copy, then swap(other).
|
/// Deep copy, then swap(other).
|
||||||
/// \note Over-write existing comments. To preserve comments, use #swapPayload().
|
/// \note Over-write existing comments. To preserve comments, use #swapPayload().
|
||||||
Value& operator=(Value other);
|
Value &operator=(const Value &other);
|
||||||
/// Swap everything.
|
/// Swap everything.
|
||||||
void swap(Value& other);
|
void swap(Value& other);
|
||||||
/// Swap values but leave comments and source offsets in place.
|
/// Swap values but leave comments and source offsets in place.
|
||||||
@@ -529,13 +506,6 @@ Json::Value obj_value(Json::objectValue); // {}
|
|||||||
iterator begin();
|
iterator begin();
|
||||||
iterator end();
|
iterator end();
|
||||||
|
|
||||||
// Accessors for the [start, limit) range of bytes within the JSON text from
|
|
||||||
// which this value was parsed, if any.
|
|
||||||
void setOffsetStart(size_t start);
|
|
||||||
void setOffsetLimit(size_t limit);
|
|
||||||
size_t getOffsetStart() const;
|
|
||||||
size_t getOffsetLimit() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initBasic(ValueType type, bool allocated = false);
|
void initBasic(ValueType type, bool allocated = false);
|
||||||
|
|
||||||
@@ -572,11 +542,6 @@ private:
|
|||||||
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
|
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
|
||||||
// If not allocated_, string_ must be null-terminated.
|
// If not allocated_, string_ must be null-terminated.
|
||||||
CommentInfo* comments_;
|
CommentInfo* comments_;
|
||||||
|
|
||||||
// [start, limit) byte offsets in the source JSON text from which this Value
|
|
||||||
// was extracted.
|
|
||||||
size_t start_;
|
|
||||||
size_t limit_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Experimental and untested: represents an element of the "path" to
|
/** \brief Experimental and untested: represents an element of the "path" to
|
||||||
@@ -667,22 +632,16 @@ public:
|
|||||||
/// Value.
|
/// Value.
|
||||||
Value key() const;
|
Value key() const;
|
||||||
|
|
||||||
/// Return the index of the referenced Value, or -1 if it is not an arrayValue.
|
/// Return the index of the referenced Value. -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.
|
||||||
/// \note Better version than memberName(). Allows embedded nulls.
|
/// Better version than memberName(). Allows embedded nulls.
|
||||||
char const* memberName(char const** end) const;
|
char const* memberName(char const** end) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -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 "1.6.0"
|
# define JSONCPP_VERSION_STRING "0.9.4"
|
||||||
# define JSONCPP_VERSION_MAJOR 1
|
# define JSONCPP_VERSION_MAJOR 0
|
||||||
# define JSONCPP_VERSION_MINOR 6
|
# define JSONCPP_VERSION_MINOR 9
|
||||||
# define JSONCPP_VERSION_PATCH 0
|
# define JSONCPP_VERSION_PATCH 4
|
||||||
# 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))
|
||||||
|
|
||||||
|
@@ -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 (For now, we always return zero, so check the stream instead.)
|
\return zero on success
|
||||||
\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. (And really, this is an implementation detail.)
|
* \deprecated Use StreamWriter.
|
||||||
*/
|
*/
|
||||||
class JSON_API Writer {
|
class JSON_API Writer {
|
||||||
public:
|
public:
|
||||||
@@ -151,22 +151,12 @@ 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() {}
|
||||||
|
|
||||||
void enableYAMLCompatibility();
|
void enableYAMLCompatibility();
|
||||||
|
|
||||||
/** \brief Drop the "null" string from the writer's output for nullValues.
|
|
||||||
* Strictly speaking, this is not valid JSON. But when the output is being
|
|
||||||
* fed to a browser's Javascript, it makes for smaller output and the
|
|
||||||
* browser can handle the output just fine.
|
|
||||||
*/
|
|
||||||
void dropNullPlaceholders();
|
|
||||||
|
|
||||||
void omitEndingLineFeed();
|
|
||||||
|
|
||||||
public: // overridden from Writer
|
public: // overridden from Writer
|
||||||
virtual std::string write(const Value& root);
|
virtual std::string write(const Value& root);
|
||||||
|
|
||||||
@@ -175,8 +165,6 @@ private:
|
|||||||
|
|
||||||
std::string document_;
|
std::string document_;
|
||||||
bool yamlCompatiblityEnabled_;
|
bool yamlCompatiblityEnabled_;
|
||||||
bool dropNullPlaceholders_;
|
|
||||||
bool omitEndingLineFeed_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
|
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#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
|
||||||
@@ -42,17 +43,14 @@ typedef std::auto_ptr<CharReader> CharReaderPtr;
|
|||||||
// ////////////////////////////////
|
// ////////////////////////////////
|
||||||
|
|
||||||
Features::Features()
|
Features::Features()
|
||||||
: allowComments_(true), strictRoot_(false),
|
: allowComments_(true), strictRoot_(false)
|
||||||
allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
|
{}
|
||||||
|
|
||||||
Features Features::all() { return Features(); }
|
Features Features::all() { return Features(); }
|
||||||
|
|
||||||
Features Features::strictMode() {
|
Features Features::strictMode() {
|
||||||
Features features;
|
Features features;
|
||||||
features.allowComments_ = false;
|
features.allowComments_ = false;
|
||||||
features.strictRoot_ = true;
|
features.strictRoot_ = true;
|
||||||
features.allowDroppedNullPlaceholders_ = false;
|
|
||||||
features.allowNumericKeys_ = false;
|
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +145,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) throwRuntimeError("Exceeded stackLimit in readValue().");
|
if (stackDepth_g >= stackLimit_g) throw std::runtime_error("Exceeded stackLimit in readValue().");
|
||||||
++stackDepth_g;
|
++stackDepth_g;
|
||||||
|
|
||||||
Token token;
|
Token token;
|
||||||
@@ -162,11 +160,9 @@ bool Reader::readValue() {
|
|||||||
switch (token.type_) {
|
switch (token.type_) {
|
||||||
case tokenObjectBegin:
|
case tokenObjectBegin:
|
||||||
successful = readObject(token);
|
successful = readObject(token);
|
||||||
currentValue().setOffsetLimit(current_ - begin_);
|
|
||||||
break;
|
break;
|
||||||
case tokenArrayBegin:
|
case tokenArrayBegin:
|
||||||
successful = readArray(token);
|
successful = readArray(token);
|
||||||
currentValue().setOffsetLimit(current_ - begin_);
|
|
||||||
break;
|
break;
|
||||||
case tokenNumber:
|
case tokenNumber:
|
||||||
successful = decodeNumber(token);
|
successful = decodeNumber(token);
|
||||||
@@ -178,42 +174,22 @@ bool Reader::readValue() {
|
|||||||
{
|
{
|
||||||
Value v(true);
|
Value v(true);
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tokenFalse:
|
case tokenFalse:
|
||||||
{
|
{
|
||||||
Value v(false);
|
Value v(false);
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tokenNull:
|
case tokenNull:
|
||||||
{
|
{
|
||||||
Value v;
|
Value v;
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tokenArraySeparator:
|
// Else, fall through...
|
||||||
case tokenObjectEnd:
|
|
||||||
case tokenArrayEnd:
|
|
||||||
if (features_.allowDroppedNullPlaceholders_) {
|
|
||||||
// "Un-read" the current token and mark the current value as a null
|
|
||||||
// token.
|
|
||||||
current_--;
|
|
||||||
Value v;
|
|
||||||
currentValue().swapPayload(v);
|
|
||||||
currentValue().setOffsetStart(current_ - begin_ - 1);
|
|
||||||
currentValue().setOffsetLimit(current_ - begin_);
|
|
||||||
break;
|
|
||||||
} // Else, fall through...
|
|
||||||
default:
|
default:
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return addError("Syntax error: value, object or array expected.", token);
|
return addError("Syntax error: value, object or array expected.", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,12 +417,11 @@ bool Reader::readString() {
|
|||||||
return c == '"';
|
return c == '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Reader::readObject(Token& tokenStart) {
|
bool Reader::readObject(Token& /*tokenStart*/) {
|
||||||
Token tokenName;
|
Token tokenName;
|
||||||
std::string name;
|
std::string name;
|
||||||
Value init(objectValue);
|
Value init(objectValue);
|
||||||
currentValue().swapPayload(init);
|
currentValue().swapPayload(init);
|
||||||
currentValue().setOffsetStart(tokenStart.start_ - begin_);
|
|
||||||
while (readToken(tokenName)) {
|
while (readToken(tokenName)) {
|
||||||
bool initialTokenOk = true;
|
bool initialTokenOk = true;
|
||||||
while (tokenName.type_ == tokenComment && initialTokenOk)
|
while (tokenName.type_ == tokenComment && initialTokenOk)
|
||||||
@@ -459,11 +434,6 @@ bool Reader::readObject(Token& tokenStart) {
|
|||||||
if (tokenName.type_ == tokenString) {
|
if (tokenName.type_ == tokenString) {
|
||||||
if (!decodeString(tokenName, name))
|
if (!decodeString(tokenName, name))
|
||||||
return recoverFromError(tokenObjectEnd);
|
return recoverFromError(tokenObjectEnd);
|
||||||
} else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
|
|
||||||
Value numberName;
|
|
||||||
if (!decodeNumber(tokenName, numberName))
|
|
||||||
return recoverFromError(tokenObjectEnd);
|
|
||||||
name = numberName.asString();
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -497,10 +467,9 @@ bool Reader::readObject(Token& tokenStart) {
|
|||||||
"Missing '}' or object member name", tokenName, tokenObjectEnd);
|
"Missing '}' or object member name", tokenName, tokenObjectEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Reader::readArray(Token& tokenStart) {
|
bool Reader::readArray(Token& /*tokenStart*/) {
|
||||||
Value init(arrayValue);
|
Value init(arrayValue);
|
||||||
currentValue().swapPayload(init);
|
currentValue().swapPayload(init);
|
||||||
currentValue().setOffsetStart(tokenStart.start_ - begin_);
|
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
if (*current_ == ']') // empty array
|
if (*current_ == ']') // empty array
|
||||||
{
|
{
|
||||||
@@ -540,8 +509,6 @@ bool Reader::decodeNumber(Token& token) {
|
|||||||
if (!decodeNumber(token, decoded))
|
if (!decodeNumber(token, decoded))
|
||||||
return false;
|
return false;
|
||||||
currentValue().swapPayload(decoded);
|
currentValue().swapPayload(decoded);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,8 +557,6 @@ bool Reader::decodeDouble(Token& token) {
|
|||||||
if (!decodeDouble(token, decoded))
|
if (!decodeDouble(token, decoded))
|
||||||
return false;
|
return false;
|
||||||
currentValue().swapPayload(decoded);
|
currentValue().swapPayload(decoded);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,8 +602,6 @@ bool Reader::decodeString(Token& token) {
|
|||||||
return false;
|
return false;
|
||||||
Value decoded(decoded_string);
|
Value decoded(decoded_string);
|
||||||
currentValue().swapPayload(decoded);
|
currentValue().swapPayload(decoded);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,59 +813,8 @@ std::string Reader::getFormattedErrorMessages() const {
|
|||||||
return formattedMessage;
|
return formattedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
|
// Reader
|
||||||
std::vector<Reader::StructuredError> allErrors;
|
/////////////////////////
|
||||||
for (Errors::const_iterator itError = errors_.begin();
|
|
||||||
itError != errors_.end();
|
|
||||||
++itError) {
|
|
||||||
const ErrorInfo& error = *itError;
|
|
||||||
Reader::StructuredError structured;
|
|
||||||
structured.offset_start = error.token_.start_ - begin_;
|
|
||||||
structured.offset_limit = error.token_.end_ - begin_;
|
|
||||||
structured.message = error.message_;
|
|
||||||
allErrors.push_back(structured);
|
|
||||||
}
|
|
||||||
return allErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Reader::pushError(const Value& value, const std::string& message) {
|
|
||||||
size_t length = end_ - begin_;
|
|
||||||
if(value.getOffsetStart() > length
|
|
||||||
|| value.getOffsetLimit() > length)
|
|
||||||
return false;
|
|
||||||
Token token;
|
|
||||||
token.type_ = tokenError;
|
|
||||||
token.start_ = begin_ + value.getOffsetStart();
|
|
||||||
token.end_ = end_ + value.getOffsetLimit();
|
|
||||||
ErrorInfo info;
|
|
||||||
info.token_ = token;
|
|
||||||
info.message_ = message;
|
|
||||||
info.extra_ = 0;
|
|
||||||
errors_.push_back(info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
|
|
||||||
size_t length = end_ - begin_;
|
|
||||||
if(value.getOffsetStart() > length
|
|
||||||
|| value.getOffsetLimit() > length
|
|
||||||
|| extra.getOffsetLimit() > length)
|
|
||||||
return false;
|
|
||||||
Token token;
|
|
||||||
token.type_ = tokenError;
|
|
||||||
token.start_ = begin_ + value.getOffsetStart();
|
|
||||||
token.end_ = begin_ + value.getOffsetLimit();
|
|
||||||
ErrorInfo info;
|
|
||||||
info.token_ = token;
|
|
||||||
info.message_ = message;
|
|
||||||
info.extra_ = begin_ + extra.getOffsetStart();
|
|
||||||
errors_.push_back(info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Reader::good() const {
|
|
||||||
return !errors_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// exact copy of Features
|
// exact copy of Features
|
||||||
class OurFeatures {
|
class OurFeatures {
|
||||||
@@ -952,10 +864,6 @@ public:
|
|||||||
Value& root,
|
Value& root,
|
||||||
bool collectComments = true);
|
bool collectComments = true);
|
||||||
std::string getFormattedErrorMessages() const;
|
std::string getFormattedErrorMessages() const;
|
||||||
std::vector<StructuredError> getStructuredErrors() const;
|
|
||||||
bool pushError(const Value& value, const std::string& message);
|
|
||||||
bool pushError(const Value& value, const std::string& message, const Value& extra);
|
|
||||||
bool good() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OurReader(OurReader const&); // no impl
|
OurReader(OurReader const&); // no impl
|
||||||
@@ -1106,7 +1014,7 @@ bool OurReader::parse(const char* beginDoc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OurReader::readValue() {
|
bool OurReader::readValue() {
|
||||||
if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
|
if (stackDepth_ >= features_.stackLimit_) throw std::runtime_error("Exceeded stackLimit in readValue().");
|
||||||
++stackDepth_;
|
++stackDepth_;
|
||||||
Token token;
|
Token token;
|
||||||
skipCommentTokens(token);
|
skipCommentTokens(token);
|
||||||
@@ -1120,11 +1028,9 @@ bool OurReader::readValue() {
|
|||||||
switch (token.type_) {
|
switch (token.type_) {
|
||||||
case tokenObjectBegin:
|
case tokenObjectBegin:
|
||||||
successful = readObject(token);
|
successful = readObject(token);
|
||||||
currentValue().setOffsetLimit(current_ - begin_);
|
|
||||||
break;
|
break;
|
||||||
case tokenArrayBegin:
|
case tokenArrayBegin:
|
||||||
successful = readArray(token);
|
successful = readArray(token);
|
||||||
currentValue().setOffsetLimit(current_ - begin_);
|
|
||||||
break;
|
break;
|
||||||
case tokenNumber:
|
case tokenNumber:
|
||||||
successful = decodeNumber(token);
|
successful = decodeNumber(token);
|
||||||
@@ -1136,24 +1042,18 @@ bool OurReader::readValue() {
|
|||||||
{
|
{
|
||||||
Value v(true);
|
Value v(true);
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tokenFalse:
|
case tokenFalse:
|
||||||
{
|
{
|
||||||
Value v(false);
|
Value v(false);
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tokenNull:
|
case tokenNull:
|
||||||
{
|
{
|
||||||
Value v;
|
Value v;
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tokenArraySeparator:
|
case tokenArraySeparator:
|
||||||
@@ -1165,13 +1065,9 @@ bool OurReader::readValue() {
|
|||||||
current_--;
|
current_--;
|
||||||
Value v;
|
Value v;
|
||||||
currentValue().swapPayload(v);
|
currentValue().swapPayload(v);
|
||||||
currentValue().setOffsetStart(current_ - begin_ - 1);
|
|
||||||
currentValue().setOffsetLimit(current_ - begin_);
|
|
||||||
break;
|
break;
|
||||||
} // else, fall through ...
|
} // else, fall through ...
|
||||||
default:
|
default:
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return addError("Syntax error: value, object or array expected.", token);
|
return addError("Syntax error: value, object or array expected.", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1403,7 +1299,6 @@ bool OurReader::readObject(Token& tokenStart) {
|
|||||||
std::string name;
|
std::string name;
|
||||||
Value init(objectValue);
|
Value init(objectValue);
|
||||||
currentValue().swapPayload(init);
|
currentValue().swapPayload(init);
|
||||||
currentValue().setOffsetStart(tokenStart.start_ - begin_);
|
|
||||||
while (readToken(tokenName)) {
|
while (readToken(tokenName)) {
|
||||||
bool initialTokenOk = true;
|
bool initialTokenOk = true;
|
||||||
while (tokenName.type_ == tokenComment && initialTokenOk)
|
while (tokenName.type_ == tokenComment && initialTokenOk)
|
||||||
@@ -1430,7 +1325,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)) throwRuntimeError("keylength >= 2^30");
|
if (name.length() >= (1U<<30)) throw std::runtime_error("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(
|
||||||
@@ -1463,7 +1358,6 @@ bool OurReader::readObject(Token& tokenStart) {
|
|||||||
bool OurReader::readArray(Token& tokenStart) {
|
bool OurReader::readArray(Token& tokenStart) {
|
||||||
Value init(arrayValue);
|
Value init(arrayValue);
|
||||||
currentValue().swapPayload(init);
|
currentValue().swapPayload(init);
|
||||||
currentValue().setOffsetStart(tokenStart.start_ - begin_);
|
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
if (*current_ == ']') // empty array
|
if (*current_ == ']') // empty array
|
||||||
{
|
{
|
||||||
@@ -1503,8 +1397,6 @@ bool OurReader::decodeNumber(Token& token) {
|
|||||||
if (!decodeNumber(token, decoded))
|
if (!decodeNumber(token, decoded))
|
||||||
return false;
|
return false;
|
||||||
currentValue().swapPayload(decoded);
|
currentValue().swapPayload(decoded);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1553,8 +1445,6 @@ bool OurReader::decodeDouble(Token& token) {
|
|||||||
if (!decodeDouble(token, decoded))
|
if (!decodeDouble(token, decoded))
|
||||||
return false;
|
return false;
|
||||||
currentValue().swapPayload(decoded);
|
currentValue().swapPayload(decoded);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1600,8 +1490,6 @@ bool OurReader::decodeString(Token& token) {
|
|||||||
return false;
|
return false;
|
||||||
Value decoded(decoded_string);
|
Value decoded(decoded_string);
|
||||||
currentValue().swapPayload(decoded);
|
currentValue().swapPayload(decoded);
|
||||||
currentValue().setOffsetStart(token.start_ - begin_);
|
|
||||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1808,60 +1696,6 @@ std::string OurReader::getFormattedErrorMessages() const {
|
|||||||
return formattedMessage;
|
return formattedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
|
|
||||||
std::vector<OurReader::StructuredError> allErrors;
|
|
||||||
for (Errors::const_iterator itError = errors_.begin();
|
|
||||||
itError != errors_.end();
|
|
||||||
++itError) {
|
|
||||||
const ErrorInfo& error = *itError;
|
|
||||||
OurReader::StructuredError structured;
|
|
||||||
structured.offset_start = error.token_.start_ - begin_;
|
|
||||||
structured.offset_limit = error.token_.end_ - begin_;
|
|
||||||
structured.message = error.message_;
|
|
||||||
allErrors.push_back(structured);
|
|
||||||
}
|
|
||||||
return allErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OurReader::pushError(const Value& value, const std::string& message) {
|
|
||||||
size_t length = end_ - begin_;
|
|
||||||
if(value.getOffsetStart() > length
|
|
||||||
|| value.getOffsetLimit() > length)
|
|
||||||
return false;
|
|
||||||
Token token;
|
|
||||||
token.type_ = tokenError;
|
|
||||||
token.start_ = begin_ + value.getOffsetStart();
|
|
||||||
token.end_ = end_ + value.getOffsetLimit();
|
|
||||||
ErrorInfo info;
|
|
||||||
info.token_ = token;
|
|
||||||
info.message_ = message;
|
|
||||||
info.extra_ = 0;
|
|
||||||
errors_.push_back(info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) {
|
|
||||||
size_t length = end_ - begin_;
|
|
||||||
if(value.getOffsetStart() > length
|
|
||||||
|| value.getOffsetLimit() > length
|
|
||||||
|| extra.getOffsetLimit() > length)
|
|
||||||
return false;
|
|
||||||
Token token;
|
|
||||||
token.type_ = tokenError;
|
|
||||||
token.start_ = begin_ + value.getOffsetStart();
|
|
||||||
token.end_ = begin_ + value.getOffsetLimit();
|
|
||||||
ErrorInfo info;
|
|
||||||
info.token_ = token;
|
|
||||||
info.message_ = message;
|
|
||||||
info.extra_ = begin_ + extra.getOffsetStart();
|
|
||||||
errors_.push_back(info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OurReader::good() const {
|
|
||||||
return !errors_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class OurCharReader : public CharReader {
|
class OurCharReader : public CharReader {
|
||||||
bool const collectComments_;
|
bool const collectComments_;
|
||||||
@@ -1993,7 +1827,7 @@ std::istream& operator>>(std::istream& sin, Value& root) {
|
|||||||
"Error from reader: %s",
|
"Error from reader: %s",
|
||||||
errs.c_str());
|
errs.c_str());
|
||||||
|
|
||||||
throwRuntimeError("reader error");
|
JSON_FAIL_MESSAGE("reader error");
|
||||||
}
|
}
|
||||||
return sin;
|
return sin;
|
||||||
}
|
}
|
||||||
|
@@ -29,12 +29,13 @@ namespace Json {
|
|||||||
#if defined(__ARMEL__)
|
#if defined(__ARMEL__)
|
||||||
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
|
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
|
||||||
#else
|
#else
|
||||||
|
// This exists for binary compatibility only. Use nullRef.
|
||||||
|
const Value Value::null;
|
||||||
#define ALIGNAS(byte_alignment)
|
#define ALIGNAS(byte_alignment)
|
||||||
#endif
|
#endif
|
||||||
static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
|
static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
|
||||||
const unsigned char& kNullRef = kNull[0];
|
const unsigned char& kNullRef = kNull[0];
|
||||||
const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
|
const Value& Value::nullRef = reinterpret_cast<const Value&>(kNullRef);
|
||||||
const Value& Value::nullRef = null;
|
|
||||||
|
|
||||||
const Int Value::minInt = Int(~(UInt(-1) / 2));
|
const Int Value::minInt = Int(~(UInt(-1) / 2));
|
||||||
const Int Value::maxInt = Int(UInt(-1) / 2);
|
const Int Value::maxInt = Int(UInt(-1) / 2);
|
||||||
@@ -87,11 +88,9 @@ 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));
|
||||||
if (newString == NULL) {
|
JSON_ASSERT_MESSAGE(newString != 0,
|
||||||
throwRuntimeError(
|
"in Json::Value::duplicateStringValue(): "
|
||||||
"in Json::Value::duplicateStringValue(): "
|
"Failed to allocate string value buffer");
|
||||||
"Failed to allocate string value buffer");
|
|
||||||
}
|
|
||||||
memcpy(newString, value, length);
|
memcpy(newString, value, length);
|
||||||
newString[length] = 0;
|
newString[length] = 0;
|
||||||
return newString;
|
return newString;
|
||||||
@@ -110,11 +109,9 @@ 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));
|
||||||
if (newString == 0) {
|
JSON_ASSERT_MESSAGE(newString != 0,
|
||||||
throwRuntimeError(
|
"in Json::Value::duplicateAndPrefixStringValue(): "
|
||||||
"in Json::Value::duplicateAndPrefixStringValue(): "
|
"Failed to allocate string value buffer");
|
||||||
"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
|
||||||
@@ -152,47 +149,6 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////
|
||||||
// //////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////
|
||||||
// //////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////
|
||||||
@@ -401,7 +357,7 @@ Value::Value(bool value) {
|
|||||||
Value::Value(Value const& other)
|
Value::Value(Value const& other)
|
||||||
: type_(other.type_), allocated_(false)
|
: type_(other.type_), allocated_(false)
|
||||||
,
|
,
|
||||||
comments_(0), start_(other.start_), limit_(other.limit_)
|
comments_(0)
|
||||||
{
|
{
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case nullValue:
|
case nullValue:
|
||||||
@@ -466,8 +422,9 @@ Value::~Value() {
|
|||||||
delete[] comments_;
|
delete[] comments_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value& Value::operator=(Value other) {
|
Value &Value::operator=(const Value &other) {
|
||||||
swap(other);
|
Value temp(other);
|
||||||
|
swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,8 +441,6 @@ void Value::swapPayload(Value& other) {
|
|||||||
void Value::swap(Value& other) {
|
void Value::swap(Value& other) {
|
||||||
swapPayload(other);
|
swapPayload(other);
|
||||||
std::swap(comments_, other.comments_);
|
std::swap(comments_, other.comments_);
|
||||||
std::swap(start_, other.start_);
|
|
||||||
std::swap(limit_, other.limit_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType Value::type() const { return type_; }
|
ValueType Value::type() const { return type_; }
|
||||||
@@ -887,8 +842,6 @@ void Value::clear() {
|
|||||||
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
|
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
|
||||||
type_ == objectValue,
|
type_ == objectValue,
|
||||||
"in Json::Value::clear(): requires complex value");
|
"in Json::Value::clear(): requires complex value");
|
||||||
start_ = 0;
|
|
||||||
limit_ = 0;
|
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case arrayValue:
|
case arrayValue:
|
||||||
case objectValue:
|
case objectValue:
|
||||||
@@ -964,8 +917,6 @@ void Value::initBasic(ValueType type, bool allocated) {
|
|||||||
type_ = type;
|
type_ = type;
|
||||||
allocated_ = allocated;
|
allocated_ = allocated;
|
||||||
comments_ = 0;
|
comments_ = 0;
|
||||||
start_ = 0;
|
|
||||||
limit_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access an object value by name, create a null member if it does not exist.
|
// Access an object value by name, create a null member if it does not exist.
|
||||||
@@ -1335,14 +1286,6 @@ std::string Value::getComment(CommentPlacement placement) const {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::setOffsetStart(size_t start) { start_ = start; }
|
|
||||||
|
|
||||||
void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
|
|
||||||
|
|
||||||
size_t Value::getOffsetStart() const { return start_; }
|
|
||||||
|
|
||||||
size_t Value::getOffsetLimit() const { return limit_; }
|
|
||||||
|
|
||||||
std::string Value::toStyledString() const {
|
std::string Value::toStyledString() const {
|
||||||
StyledWriter writer;
|
StyledWriter writer;
|
||||||
return writer.write(*this);
|
return writer.write(*this);
|
||||||
|
@@ -92,14 +92,6 @@ 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 : "";
|
||||||
|
@@ -12,25 +12,16 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <cassert>
|
#include <stdexcept>
|
||||||
#include <cstring>
|
#include <assert.h>
|
||||||
#include <cstdio>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
|
#include <string.h>
|
||||||
#include <float.h>
|
|
||||||
#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
|
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
|
||||||
|
#include <float.h>
|
||||||
|
#define isfinite _finite
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#else
|
|
||||||
#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
|
||||||
@@ -38,6 +29,11 @@
|
|||||||
#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
|
||||||
@@ -284,28 +280,21 @@ Writer::~Writer() {}
|
|||||||
// //////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FastWriter::FastWriter()
|
FastWriter::FastWriter()
|
||||||
: yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
|
: yamlCompatiblityEnabled_(false) {}
|
||||||
omitEndingLineFeed_(false) {}
|
|
||||||
|
|
||||||
void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
|
void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
|
||||||
|
|
||||||
void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
|
|
||||||
|
|
||||||
void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
|
|
||||||
|
|
||||||
std::string FastWriter::write(const Value& root) {
|
std::string FastWriter::write(const Value& root) {
|
||||||
document_ = "";
|
document_ = "";
|
||||||
writeValue(root);
|
writeValue(root);
|
||||||
if (!omitEndingLineFeed_)
|
document_ += "\n";
|
||||||
document_ += "\n";
|
|
||||||
return document_;
|
return document_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FastWriter::writeValue(const Value& value) {
|
void FastWriter::writeValue(const Value& value) {
|
||||||
switch (value.type()) {
|
switch (value.type()) {
|
||||||
case nullValue:
|
case nullValue:
|
||||||
if (!dropNullPlaceholders_)
|
document_ += "null";
|
||||||
document_ += "null";
|
|
||||||
break;
|
break;
|
||||||
case intValue:
|
case intValue:
|
||||||
document_ += valueToString(value.asLargestInt());
|
document_ += valueToString(value.asLargestInt());
|
||||||
@@ -1084,7 +1073,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
|
|||||||
} else if (cs_str == "None") {
|
} else if (cs_str == "None") {
|
||||||
cs = CommentStyle::None;
|
cs = CommentStyle::None;
|
||||||
} else {
|
} else {
|
||||||
throwRuntimeError("commentStyle must be 'All' or 'None'");
|
throw std::runtime_error("commentStyle must be 'All' or 'None'");
|
||||||
}
|
}
|
||||||
std::string colonSymbol = " : ";
|
std::string colonSymbol = " : ";
|
||||||
if (eyc) {
|
if (eyc) {
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#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.
|
||||||
@@ -1498,25 +1499,6 @@ JSONTEST_FIXTURE(ValueTest, typeChecksThrowExceptions) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONTEST_FIXTURE(ValueTest, offsetAccessors) {
|
|
||||||
Json::Value x;
|
|
||||||
JSONTEST_ASSERT(x.getOffsetStart() == 0);
|
|
||||||
JSONTEST_ASSERT(x.getOffsetLimit() == 0);
|
|
||||||
x.setOffsetStart(10);
|
|
||||||
x.setOffsetLimit(20);
|
|
||||||
JSONTEST_ASSERT(x.getOffsetStart() == 10);
|
|
||||||
JSONTEST_ASSERT(x.getOffsetLimit() == 20);
|
|
||||||
Json::Value y(x);
|
|
||||||
JSONTEST_ASSERT(y.getOffsetStart() == 10);
|
|
||||||
JSONTEST_ASSERT(y.getOffsetLimit() == 20);
|
|
||||||
Json::Value z;
|
|
||||||
z.swap(y);
|
|
||||||
JSONTEST_ASSERT(z.getOffsetStart() == 10);
|
|
||||||
JSONTEST_ASSERT(z.getOffsetLimit() == 20);
|
|
||||||
JSONTEST_ASSERT(y.getOffsetStart() == 0);
|
|
||||||
JSONTEST_ASSERT(y.getOffsetLimit() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSONTEST_FIXTURE(ValueTest, StaticString) {
|
JSONTEST_FIXTURE(ValueTest, StaticString) {
|
||||||
char mutant[] = "hello";
|
char mutant[] = "hello";
|
||||||
Json::StaticString ss(mutant);
|
Json::StaticString ss(mutant);
|
||||||
@@ -1637,17 +1619,6 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WriterTest : JsonTest::TestCase {};
|
|
||||||
|
|
||||||
JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) {
|
|
||||||
Json::FastWriter writer;
|
|
||||||
Json::Value nullValue;
|
|
||||||
JSONTEST_ASSERT(writer.write(nullValue) == "null\n");
|
|
||||||
|
|
||||||
writer.dropNullPlaceholders();
|
|
||||||
JSONTEST_ASSERT(writer.write(nullValue) == "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StreamWriterTest : JsonTest::TestCase {};
|
struct StreamWriterTest : JsonTest::TestCase {};
|
||||||
|
|
||||||
JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) {
|
JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) {
|
||||||
@@ -1689,7 +1660,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) {
|
|||||||
bool ok = reader.parse("{ \"property\" : \"value\" }", root);
|
bool ok = reader.parse("{ \"property\" : \"value\" }", root);
|
||||||
JSONTEST_ASSERT(ok);
|
JSONTEST_ASSERT(ok);
|
||||||
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
|
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
|
||||||
JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
|
JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
|
||||||
@@ -1701,25 +1671,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
|
|||||||
root);
|
root);
|
||||||
JSONTEST_ASSERT(ok);
|
JSONTEST_ASSERT(ok);
|
||||||
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
|
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
|
||||||
JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0);
|
|
||||||
JSONTEST_ASSERT(root["property"].getOffsetStart() == 15);
|
|
||||||
JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34);
|
|
||||||
JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16);
|
|
||||||
JSONTEST_ASSERT(root["property"][0].getOffsetLimit() == 23);
|
|
||||||
JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25);
|
|
||||||
JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33);
|
|
||||||
JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44);
|
|
||||||
JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 76);
|
|
||||||
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57);
|
|
||||||
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 60);
|
|
||||||
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 71);
|
|
||||||
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 75);
|
|
||||||
JSONTEST_ASSERT(root["null"].getOffsetStart() == 87);
|
|
||||||
JSONTEST_ASSERT(root["null"].getOffsetLimit() == 91);
|
|
||||||
JSONTEST_ASSERT(root["false"].getOffsetStart() == 103);
|
|
||||||
JSONTEST_ASSERT(root["false"].getOffsetLimit() == 108);
|
|
||||||
JSONTEST_ASSERT(root.getOffsetStart() == 0);
|
|
||||||
JSONTEST_ASSERT(root.getOffsetLimit() == 110);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
|
JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
|
||||||
@@ -1730,13 +1681,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
|
|||||||
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
|
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
|
||||||
"* Line 1, Column 15\n Syntax error: value, object or array "
|
"* Line 1, Column 15\n Syntax error: value, object or array "
|
||||||
"expected.\n");
|
"expected.\n");
|
||||||
std::vector<Json::Reader::StructuredError> errors =
|
|
||||||
reader.getStructuredErrors();
|
|
||||||
JSONTEST_ASSERT(errors.size() == 1);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).offset_start == 14);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).offset_limit == 15);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).message ==
|
|
||||||
"Syntax error: value, object or array expected.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
|
JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
|
||||||
@@ -1747,13 +1691,6 @@ JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
|
|||||||
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
|
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
|
||||||
"* Line 1, Column 19\n Syntax error: value, object or array "
|
"* Line 1, Column 19\n Syntax error: value, object or array "
|
||||||
"expected.\n");
|
"expected.\n");
|
||||||
std::vector<Json::Reader::StructuredError> errors =
|
|
||||||
reader.getStructuredErrors();
|
|
||||||
JSONTEST_ASSERT(errors.size() == 1);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).offset_start == 18);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).offset_limit == 19);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).message ==
|
|
||||||
"Syntax error: value, object or array expected.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
|
JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
|
||||||
@@ -1764,12 +1701,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
|
|||||||
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
|
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
|
||||||
"* Line 1, Column 16\n Bad escape sequence in string\nSee "
|
"* Line 1, Column 16\n Bad escape sequence in string\nSee "
|
||||||
"Line 1, Column 20 for detail.\n");
|
"Line 1, Column 20 for detail.\n");
|
||||||
std::vector<Json::Reader::StructuredError> errors =
|
|
||||||
reader.getStructuredErrors();
|
|
||||||
JSONTEST_ASSERT(errors.size() == 1);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).offset_start == 15);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).offset_limit == 23);
|
|
||||||
JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CharReaderTest : JsonTest::TestCase {};
|
struct CharReaderTest : JsonTest::TestCase {};
|
||||||
@@ -2282,42 +2213,6 @@ 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);
|
||||||
@@ -2338,7 +2233,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors);
|
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore);
|
||||||
@@ -2346,7 +2240,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys);
|
||||||
|
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders);
|
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders);
|
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes);
|
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes);
|
||||||
|
|
||||||
@@ -2382,8 +2275,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user