Apply the formatting specified in .clang-format file.

$ clang-format --version
  clang-format version 7.0.0 (tags/google/stable/2018-01-11)
  $ clang-format -i --style=file $(find . -name '*.cpp' -o -name '*.h')
This commit is contained in:
Billy Donahue 2018-05-20 16:55:27 -04:00
parent abd39e791b
commit b5e1fe89aa
16 changed files with 1176 additions and 1285 deletions

View File

@ -12,9 +12,8 @@
#pragma pack(push, 8) #pragma pack(push, 8)
namespace Json { namespace Json {
template<typename T> template <typename T> class SecureAllocator {
class SecureAllocator { public:
public:
// Type definitions // Type definitions
using value_type = T; using value_type = T;
using pointer = T*; using pointer = T*;
@ -48,23 +47,16 @@ class SecureAllocator {
/** /**
* Construct an item in-place at pointer P. * Construct an item in-place at pointer P.
*/ */
template<typename... Args> template <typename... Args> void construct(pointer p, Args&&... args) {
void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding" // construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...); ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
} }
size_type max_size() const { size_type max_size() const { return size_t(-1) / sizeof(T); }
return size_t(-1) / sizeof(T);
}
pointer address( reference x ) const { pointer address(reference x) const { return std::addressof(x); }
return std::addressof(x);
}
const_pointer address( const_reference x ) const { const_pointer address(const_reference x) const { return std::addressof(x); }
return std::addressof(x);
}
/** /**
* Destroy an item in-place at pointer P. * Destroy an item in-place at pointer P.
@ -76,22 +68,21 @@ class SecureAllocator {
// Boilerplate // Boilerplate
SecureAllocator() {} SecureAllocator() {}
template<typename U> SecureAllocator(const SecureAllocator<U>&) {} template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
template<typename U> struct rebind { using other = SecureAllocator<U>; }; template <typename U> struct rebind { using other = SecureAllocator<U>; };
}; };
template <typename T, typename U>
template<typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) { bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true; return true;
} }
template<typename T, typename U> template <typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) { bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false; return false;
} }
} //namespace Json } // namespace Json
#pragma pack(pop) #pragma pack(pop)

View File

@ -6,8 +6,8 @@
#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
#define CPPTL_JSON_ASSERTIONS_H_INCLUDED #define CPPTL_JSON_ASSERTIONS_H_INCLUDED
#include <stdlib.h>
#include <sstream> #include <sstream>
#include <stdlib.h>
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "config.h" #include "config.h"
@ -20,30 +20,35 @@
#if JSON_USE_EXCEPTION #if JSON_USE_EXCEPTION
// @todo <= add detail about condition in exception // @todo <= add detail about condition in exception
# define JSON_ASSERT(condition) \ #define JSON_ASSERT(condition) \
{if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
# define JSON_FAIL_MESSAGE(message) \
{ \ { \
JSONCPP_OSTRINGSTREAM oss; oss << message; \ if (!(condition)) { \
Json::throwLogicError("assert json failed"); \
} \
}
#define JSON_FAIL_MESSAGE(message) \
{ \
JSONCPP_OSTRINGSTREAM oss; \
oss << message; \
Json::throwLogicError(oss.str()); \ Json::throwLogicError(oss.str()); \
abort(); \ abort(); \
} }
#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 builds we abort, for a core-dump or debugger.
# define JSON_FAIL_MESSAGE(message) \ #define JSON_FAIL_MESSAGE(message) \
{ \ { \
JSONCPP_OSTRINGSTREAM oss; oss << message; \ JSONCPP_OSTRINGSTREAM oss; \
oss << message; \
assert(false && oss.str().c_str()); \ assert(false && oss.str().c_str()); \
abort(); \ abort(); \
} }
#endif #endif
#define JSON_ASSERT_MESSAGE(condition, message) \ #define JSON_ASSERT_MESSAGE(condition, message) \

View File

@ -6,8 +6,8 @@
#ifndef JSON_CONFIG_H_INCLUDED #ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED
#include <stddef.h> #include <stddef.h>
#include <string> //typedef String
#include <stdint.h> //typedef int64_t, uint64_t #include <stdint.h> //typedef int64_t, uint64_t
#include <string> //typedef String
/// If defined, indicates that json library is embedded in CppTL library. /// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1 //# define JSON_IN_CPPTL 1
@ -60,21 +60,21 @@
// #define JSON_NO_INT64 1 // #define JSON_NO_INT64 1
#if defined(_MSC_VER) // MSVC #if defined(_MSC_VER) // MSVC
# if _MSC_VER <= 1200 // MSVC 6 #if _MSC_VER <= 1200 // MSVC 6
// Microsoft Visual Studio 6 only support conversion from __int64 to double // Microsoft Visual Studio 6 only support conversion from __int64 to double
// (no conversion from unsigned __int64). // (no conversion from unsigned __int64).
# define JSON_USE_INT64_DOUBLE_CONVERSION 1 #define JSON_USE_INT64_DOUBLE_CONVERSION 1
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
// characters in the debug information) // characters in the debug information)
// All projects I've ever seen with VS6 were using this globally (not bothering // All projects I've ever seen with VS6 were using this globally (not bothering
// with pragma push/pop). // with pragma push/pop).
# pragma warning(disable : 4786) #pragma warning(disable : 4786)
# endif // MSVC 6 #endif // MSVC 6
# if _MSC_VER >= 1500 // MSVC 2008 #if _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))
# endif #endif
#endif // defined(_MSC_VER) #endif // defined(_MSC_VER)
@ -82,25 +82,25 @@
// is intended to override the base-class version. This makes the code more // is intended to override the base-class version. This makes the code more
// manageable and fixes a set of common hard-to-find bugs. // manageable and fixes a set of common hard-to-find bugs.
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
# define JSONCPP_OVERRIDE override #define JSONCPP_OVERRIDE override
# define JSONCPP_NOEXCEPT noexcept #define JSONCPP_NOEXCEPT noexcept
# define JSONCPP_OP_EXPLICIT explicit #define JSONCPP_OP_EXPLICIT explicit
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
# define JSONCPP_OVERRIDE override #define JSONCPP_OVERRIDE override
# define JSONCPP_NOEXCEPT throw() #define JSONCPP_NOEXCEPT throw()
# if _MSC_VER >= 1800 // MSVC 2013 #if _MSC_VER >= 1800 // MSVC 2013
# define JSONCPP_OP_EXPLICIT explicit #define JSONCPP_OP_EXPLICIT explicit
# else
# define JSONCPP_OP_EXPLICIT
# endif
#elif defined(_MSC_VER) && _MSC_VER >= 1900
# define JSONCPP_OVERRIDE override
# define JSONCPP_NOEXCEPT noexcept
# define JSONCPP_OP_EXPLICIT explicit
#else #else
# define JSONCPP_OVERRIDE #define JSONCPP_OP_EXPLICIT
# define JSONCPP_NOEXCEPT throw() #endif
# define JSONCPP_OP_EXPLICIT #elif defined(_MSC_VER) && _MSC_VER >= 1900
#define JSONCPP_OVERRIDE override
#define JSONCPP_NOEXCEPT noexcept
#define JSONCPP_OP_EXPLICIT explicit
#else
#define JSONCPP_OVERRIDE
#define JSONCPP_NOEXCEPT throw()
#define JSONCPP_OP_EXPLICIT
#endif #endif
#ifndef JSON_HAS_RVALUE_REFERENCES #ifndef JSON_HAS_RVALUE_REFERENCES
@ -128,15 +128,15 @@
#endif #endif
#ifdef __clang__ #ifdef __clang__
# if __has_extension(attribute_deprecated_with_message) #if __has_extension(attribute_deprecated_with_message)
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
# endif #endif
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
# endif // GNUC version #endif // GNUC version
#endif // __clang__ || __GNUC__ #endif // __clang__ || __GNUC__
#if !defined(JSONCPP_DEPRECATED) #if !defined(JSONCPP_DEPRECATED)
@ -144,16 +144,16 @@
#endif // if !defined(JSONCPP_DEPRECATED) #endif // if !defined(JSONCPP_DEPRECATED)
#if __GNUC__ >= 6 #if __GNUC__ >= 6
# define JSON_USE_INT64_DOUBLE_CONVERSION 1 #define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif #endif
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
# include "version.h" #include "version.h"
# if JSONCPP_USING_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
# include "allocator.h" //typedef Allocator #include "allocator.h" //typedef Allocator
# endif #endif
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
@ -178,10 +178,15 @@ typedef UInt64 LargestUInt;
#define JSON_HAS_INT64 #define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64) #endif // if defined(JSON_NO_INT64)
#if JSONCPP_USING_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> > #define JSONCPP_STRING \
#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> > std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>> #define JSONCPP_OSTRINGSTREAM \
#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> > std::basic_ostringstream<char, std::char_traits<char>, \
Json::SecureAllocator<char> >
#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char> >
#define JSONCPP_ISTRINGSTREAM \
std::basic_istringstream<char, std::char_traits<char>, \
Json::SecureAllocator<char> >
#define JSONCPP_ISTREAM std::istream #define JSONCPP_ISTREAM std::istream
#else #else
#define JSONCPP_STRING std::string #define JSONCPP_STRING std::string

View File

@ -7,9 +7,9 @@
#define JSON_JSON_H_INCLUDED #define JSON_JSON_H_INCLUDED
#include "autolink.h" #include "autolink.h"
#include "value.h"
#include "reader.h"
#include "writer.h"
#include "features.h" #include "features.h"
#include "reader.h"
#include "value.h"
#include "writer.h"
#endif // JSON_JSON_H_INCLUDED #endif // JSON_JSON_H_INCLUDED

View File

@ -12,9 +12,9 @@
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <deque> #include <deque>
#include <iosfwd> #include <iosfwd>
#include <istream>
#include <stack> #include <stack>
#include <string> #include <string>
#include <istream>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to // Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by... // be used by...
@ -151,7 +151,9 @@ public:
* \return \c true if the error was successfully added, \c false if either * \return \c true if the error was successfully added, \c false if either
* Value offset exceeds the document size. * Value offset exceeds the document size.
*/ */
bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); bool pushError(const Value& value,
const JSONCPP_STRING& message,
const Value& extra);
/** \brief Return whether there are any errors. /** \brief Return whether there are any errors.
* \return \c true if there are no errors to report \c false if * \return \c true if there are no errors to report \c false if
@ -218,7 +220,8 @@ private:
Location& current, Location& current,
Location end, Location end,
unsigned int& unicode); unsigned int& unicode);
bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool
addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken); bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const JSONCPP_STRING& message, bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token, Token& token,
@ -256,7 +259,8 @@ public:
virtual ~CharReader() {} virtual ~CharReader() {}
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
document. document.
* The document must be a UTF-8 encoded string containing the document to read. * The document must be a UTF-8 encoded string containing the document to
read.
* *
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
document to read. document to read.
@ -271,9 +275,10 @@ public:
* \return \c true if the document was successfully parsed, \c false if an * \return \c true if the document was successfully parsed, \c false if an
error occurred. error occurred.
*/ */
virtual bool parse( virtual bool parse(char const* beginDoc,
char const* beginDoc, char const* endDoc, char const* endDoc,
Value* root, JSONCPP_STRING* errs) = 0; Value* root,
JSONCPP_STRING* errs) = 0;
class JSON_API Factory { class JSON_API Factory {
public: public:
@ -313,7 +318,8 @@ public:
- `"strictRoot": false or true` - `"strictRoot": false or true`
- true if root must be either an array or an object value - true if root must be either an array or an object value
- `"allowDroppedNullPlaceholders": false or true` - `"allowDroppedNullPlaceholders": false or true`
- true if dropped null placeholders are allowed. (See StreamWriterBuilder.) - true if dropped null placeholders are allowed. (See
StreamWriterBuilder.)
- `"allowNumericKeys": false or true` - `"allowNumericKeys": false or true`
- true if numeric object keys are allowed. - true if numeric object keys are allowed.
- `"allowSingleQuotes": false or true` - `"allowSingleQuotes": false or true`
@ -327,7 +333,8 @@ public:
- If true, `parse()` returns false when extra non-whitespace trails - If true, `parse()` returns false when extra non-whitespace trails
the JSON value in the input string. the JSON value in the input string.
- `"rejectDupKeys": false or true` - `"rejectDupKeys": false or true`
- If true, `parse()` returns false when a key is duplicated within an object. - If true, `parse()` returns false when a key is duplicated within an
object.
- `"allowSpecialFloats": false or true` - `"allowSpecialFloats": false or true`
- If true, special float values (NaNs and infinities) are allowed - If true, special float values (NaNs and infinities) are allowed
and their values are lossfree restorable. and their values are lossfree restorable.
@ -371,10 +378,10 @@ public:
* Someday we might have a real StreamReader, but for now this * Someday we might have a real StreamReader, but for now this
* is convenient. * is convenient.
*/ */
bool JSON_API parseFromStream( bool JSON_API parseFromStream(CharReader::Factory const&,
CharReader::Factory const&,
JSONCPP_ISTREAM&, JSONCPP_ISTREAM&,
Value* root, std::string* errs); Value* root,
std::string* errs);
/** \brief Read from 'sin' into 'root'. /** \brief Read from 'sin' into 'root'.

View File

@ -9,9 +9,9 @@
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h" #include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <exception>
#include <string> #include <string>
#include <vector> #include <vector>
#include <exception>
#ifndef JSON_USE_CPPTL_SMALLMAP #ifndef JSON_USE_CPPTL_SMALLMAP
#include <map> #include <map>
@ -22,17 +22,17 @@
#include <cpptl/forwards.h> #include <cpptl/forwards.h>
#endif #endif
//Conditional NORETURN attribute on the throw functions would: // Conditional NORETURN attribute on the throw functions would:
// a) suppress false positives from static code analysis // a) suppress false positives from static code analysis
// b) possibly improve optimization opportunities. // b) possibly improve optimization opportunities.
#if !defined(JSONCPP_NORETURN) #if !defined(JSONCPP_NORETURN)
# if defined(_MSC_VER) #if defined(_MSC_VER)
# define JSONCPP_NORETURN __declspec(noreturn) #define JSONCPP_NORETURN __declspec(noreturn)
# elif defined(__GNUC__) #elif defined(__GNUC__)
# define JSONCPP_NORETURN __attribute__ ((__noreturn__)) #define JSONCPP_NORETURN __attribute__((__noreturn__))
# else #else
# define JSONCPP_NORETURN #define JSONCPP_NORETURN
# endif #endif
#endif #endif
// Disable warning C4251: <data member>: <type> needs to have dll-interface to // Disable warning C4251: <data member>: <type> needs to have dll-interface to
@ -57,6 +57,7 @@ public:
Exception(JSONCPP_STRING const& msg); Exception(JSONCPP_STRING const& msg);
~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
protected: protected:
JSONCPP_STRING msg_; JSONCPP_STRING msg_;
}; };
@ -183,6 +184,7 @@ private:
*/ */
class JSON_API Value { class JSON_API Value {
friend class ValueIteratorBase; friend class ValueIteratorBase;
public: public:
typedef std::vector<JSONCPP_STRING> Members; typedef std::vector<JSONCPP_STRING> Members;
typedef ValueIterator iterator; typedef ValueIterator iterator;
@ -200,8 +202,10 @@ public:
// Required for boost integration, e. g. BOOST_TEST // Required for boost integration, e. g. BOOST_TEST
typedef std::string value_type; typedef std::string value_type;
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). static const Value& null; ///< We regret this reference to a global instance;
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null ///< prefer the simpler Value().
static const Value& nullRef; ///< just a kludge for binary-compatibility; same
///< as null
static Value const& nullSingleton(); ///< Prefer this to null or nullRef. static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
/// Minimum signed integer value that can be stored in a Json::Value. /// Minimum signed integer value that can be stored in a Json::Value.
@ -241,11 +245,7 @@ private:
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
class CZString { class CZString {
public: public:
enum DuplicationPolicy { enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
noDuplication = 0,
duplicate,
duplicateOnCopy
};
CZString(ArrayIndex index); CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other); CZString(CZString const& other);
@ -262,7 +262,7 @@ private:
bool operator<(CZString const& other) const; bool operator<(CZString const& other) const;
bool operator==(CZString const& other) const; bool operator==(CZString const& other) const;
ArrayIndex index() const; ArrayIndex index() const;
//const char* c_str() const; ///< \deprecated // const char* c_str() const; ///< \deprecated
char const* data() const; char const* data() const;
unsigned length() const; unsigned length() const;
bool isStaticString() const; bool isStaticString() const;
@ -271,8 +271,8 @@ private:
void swap(CZString& other); void swap(CZString& other);
struct StringStorage { struct StringStorage {
unsigned policy_: 2; unsigned policy_ : 2;
unsigned length_: 30; // 1GB max unsigned length_ : 30; // 1GB max
}; };
char const* cstr_; // actually, a prefixed string, unless policy is noDup char const* cstr_; // actually, a prefixed string, unless policy is noDup
@ -332,7 +332,8 @@ Json::Value obj_value(Json::objectValue); // {}
* \endcode * \endcode
*/ */
Value(const StaticString& value); Value(const StaticString& value);
Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too. Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded
///< zeroes too.
#ifdef JSON_USE_CPPTL #ifdef JSON_USE_CPPTL
Value(const CppTL::ConstString& value); Value(const CppTL::ConstString& value);
#endif #endif
@ -346,7 +347,8 @@ Json::Value obj_value(Json::objectValue); // {}
~Value(); ~Value();
/// 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=(Value other);
/// Swap everything. /// Swap everything.
@ -372,14 +374,14 @@ Json::Value obj_value(Json::objectValue); // {}
const char* asCString() const; ///< Embedded zeroes could cause you trouble! const char* asCString() const; ///< Embedded zeroes could cause you trouble!
#if JSONCPP_USING_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
unsigned getCStringLength() const; //Allows you to understand the length of the CString unsigned getCStringLength() const; // Allows you to understand the length of
// the CString
#endif #endif
JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
/** Get raw char* of string-value. /** Get raw char* of string-value.
* \return false if !string. (Seg-fault if str or end are NULL.) * \return false if !string. (Seg-fault if str or end are NULL.)
*/ */
bool getString( bool getString(char const** begin, char const** end) const;
char const** begin, char const** end) const;
#ifdef JSON_USE_CPPTL #ifdef JSON_USE_CPPTL
CppTL::ConstString asConstString() const; CppTL::ConstString asConstString() const;
#endif #endif
@ -490,7 +492,8 @@ Json::Value obj_value(Json::objectValue); // {}
/** \brief Access an object value by name, create a null member if it does not /** \brief Access an object value by name, create a null member if it does not
exist. exist.
* If the object has no entry for that name, then the member name used to store * If the object has no entry for that name, then the member name used to
store
* the new entry is not duplicated. * the new entry is not duplicated.
* Example of use: * Example of use:
* \code * \code
@ -513,7 +516,8 @@ Json::Value obj_value(Json::objectValue); // {}
/// Return the member named key if it exist, defaultValue otherwise. /// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy /// \note deep copy
/// \note key may contain embedded nulls. /// \note key may contain embedded nulls.
Value get(const char* begin, const char* end, const Value& defaultValue) const; Value
get(const char* begin, const char* end, const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise. /// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy /// \note deep copy
/// \param key may contain embedded nulls. /// \param key may contain embedded nulls.
@ -646,12 +650,14 @@ private:
LargestUInt uint_; LargestUInt uint_;
double real_; double real_;
bool bool_; bool bool_;
char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ char* string_; // actually ptr to unsigned, followed by str, unless
// !allocated_
ObjectValues* map_; ObjectValues* map_;
} value_; } value_;
ValueType type_ : 8; ValueType type_ : 8;
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is
// If not allocated_, string_ must be null-terminated. // useless. 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 // [start, limit) byte offsets in the source JSON text from which this Value
@ -673,11 +679,7 @@ public:
PathArgument(const JSONCPP_STRING& key); PathArgument(const JSONCPP_STRING& key);
private: private:
enum Kind { enum Kind { kindNone = 0, kindIndex, kindKey };
kindNone = 0,
kindIndex,
kindKey
};
JSONCPP_STRING key_; JSONCPP_STRING key_;
ArrayIndex index_; ArrayIndex index_;
Kind kind_; Kind kind_;
@ -745,7 +747,8 @@ 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, 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 /// Return the member name of the referenced Value, or "" if it is not an
@ -755,7 +758,8 @@ public:
/// 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.") 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
@ -796,8 +800,8 @@ class JSON_API ValueConstIterator : public ValueIteratorBase {
public: public:
typedef const Value value_type; typedef const Value value_type;
//typedef unsigned int size_t; // typedef unsigned int size_t;
//typedef int difference_type; // typedef int difference_type;
typedef const Value& reference; typedef const Value& reference;
typedef const Value* pointer; typedef const Value* pointer;
typedef ValueConstIterator SelfType; typedef ValueConstIterator SelfType;
@ -806,9 +810,10 @@ public:
ValueConstIterator(ValueIterator const& other); ValueConstIterator(ValueIterator const& other);
private: private:
/*! \internal Use by Value to create an iterator. /*! \internal Use by Value to create an iterator.
*/ */
explicit ValueConstIterator(const Value::ObjectValues::iterator& current); explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
public: public:
SelfType& operator=(const ValueIteratorBase& other); SelfType& operator=(const ValueIteratorBase& other);
@ -857,9 +862,10 @@ public:
ValueIterator(const ValueIterator& other); ValueIterator(const ValueIterator& other);
private: private:
/*! \internal Use by Value to create an iterator. /*! \internal Use by Value to create an iterator.
*/ */
explicit ValueIterator(const Value::ObjectValues::iterator& current); explicit ValueIterator(const Value::ObjectValues::iterator& current);
public: public:
SelfType& operator=(const SelfType& other); SelfType& operator=(const SelfType& other);

View File

@ -1,14 +1,16 @@
// DO NOT EDIT. This file (and "version") is generated by CMake. // DO NOT EDIT. This file (and "version") is generated by CMake.
// Run CMake configure step to update it. // Run CMake configure step to update it.
#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.8.4" #define JSONCPP_VERSION_STRING "1.8.4"
# define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MAJOR 1
# define JSONCPP_VERSION_MINOR 8 #define JSONCPP_VERSION_MINOR 8
# define JSONCPP_VERSION_PATCH 4 #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))
#ifdef JSONCPP_USING_SECURE_MEMORY #ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY #undef JSONCPP_USING_SECURE_MEMORY

View File

@ -9,9 +9,9 @@
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "value.h" #include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <vector>
#include <string>
#include <ostream> #include <ostream>
#include <string>
#include <vector>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to // Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by... // be used by...
@ -48,8 +48,8 @@ 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 (For now, we always return zero, so check the
\throw std::exception possibly, depending on configuration stream instead.) \throw std::exception possibly, depending on configuration
*/ */
virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
@ -68,8 +68,8 @@ public:
/** \brief Write into stringstream, then return string, for convenience. /** \brief Write into stringstream, then return string, for convenience.
* A StreamWriter will be created from the factory, used, and then deleted. * A StreamWriter will be created from the factory, used, and then deleted.
*/ */
JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory,
Value const& root);
/** \brief Build a StreamWriter implementation. /** \brief Build a StreamWriter implementation.
@ -104,8 +104,8 @@ public:
browser can handle the output just fine. browser can handle the output just fine.
- "useSpecialFloats": false or true - "useSpecialFloats": false or true
- If true, outputs non-finite floating point values in the following way: - If true, outputs non-finite floating point values in the following way:
NaN values as "NaN", positive infinity as "Infinity", and negative infinity NaN values as "NaN", positive infinity as "Infinity", and negative
as "-Infinity". infinity as "-Infinity".
- "precision": int - "precision": int
- Number of precision digits for formatting of real values. - Number of precision digits for formatting of real values.
- "precisionType": "significant"(default) or "decimal" - "precisionType": "significant"(default) or "decimal"
@ -163,9 +163,10 @@ public:
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4996) // Deriving from deprecated class #pragma warning(disable : 4996) // Deriving from deprecated class
#endif #endif
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter
: public Writer {
public: public:
FastWriter(); FastWriter();
~FastWriter() JSONCPP_OVERRIDE {} ~FastWriter() JSONCPP_OVERRIDE {}
@ -222,9 +223,10 @@ private:
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4996) // Deriving from deprecated class #pragma warning(disable : 4996) // Deriving from deprecated class
#endif #endif
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
StyledWriter : public Writer {
public: public:
StyledWriter(); StyledWriter();
~StyledWriter() JSONCPP_OVERRIDE {} ~StyledWriter() JSONCPP_OVERRIDE {}
@ -290,11 +292,12 @@ private:
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4996) // Deriving from deprecated class #pragma warning(disable : 4996) // Deriving from deprecated class
#endif #endif
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter { class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
StyledStreamWriter {
public: public:
/** /**
* \param indentation Each level will be indented by this amount extra. * \param indentation Each level will be indented by this amount extra.
*/ */
StyledStreamWriter(JSONCPP_STRING indentation = "\t"); StyledStreamWriter(JSONCPP_STRING indentation = "\t");
@ -343,7 +346,9 @@ JSONCPP_STRING JSON_API valueToString(UInt value);
#endif // if defined(JSON_HAS_INT64) #endif // if defined(JSON_HAS_INT64)
JSONCPP_STRING JSON_API valueToString(LargestInt value); JSONCPP_STRING JSON_API valueToString(LargestInt value);
JSONCPP_STRING JSON_API valueToString(LargestUInt value); JSONCPP_STRING JSON_API valueToString(LargestUInt value);
JSONCPP_STRING JSON_API valueToString(double value, unsigned int precision = Value::defaultRealPrecision, JSONCPP_STRING JSON_API
valueToString(double value,
unsigned int precision = Value::defaultRealPrecision,
PrecisionType precisionType = PrecisionType::significantDigits); PrecisionType precisionType = PrecisionType::significantDigits);
JSONCPP_STRING JSON_API valueToString(bool value); JSONCPP_STRING JSON_API valueToString(bool value);
JSONCPP_STRING JSON_API valueToQuotedString(const char* value); JSONCPP_STRING JSON_API valueToQuotedString(const char* value);

View File

@ -13,13 +13,12 @@
/* This executable is used for testing parser/writer using real JSON files. /* This executable is used for testing parser/writer using real JSON files.
*/ */
#include <json/json.h>
#include <algorithm> // sort #include <algorithm> // sort
#include <json/json.h>
#include <sstream> #include <sstream>
#include <stdio.h> #include <stdio.h>
struct Options struct Options {
{
JSONCPP_STRING path; JSONCPP_STRING path;
Json::Features features; Json::Features features;
bool parseOnly; bool parseOnly;
@ -45,8 +44,8 @@ static JSONCPP_STRING normalizeFloatingPointStr(double value) {
JSONCPP_STRING::size_type indexDigit = JSONCPP_STRING::size_type indexDigit =
s.find_first_not_of('0', exponentStartIndex); s.find_first_not_of('0', exponentStartIndex);
JSONCPP_STRING exponent = "0"; JSONCPP_STRING exponent = "0";
if (indexDigit != if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different
JSONCPP_STRING::npos) // There is an exponent different from 0 // from 0
{ {
exponent = s.substr(indexDigit); exponent = s.substr(indexDigit);
} }
@ -73,8 +72,9 @@ static JSONCPP_STRING readInputTestFile(const char* path) {
return text; return text;
} }
static void static void printValueTree(FILE* fout,
printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") { Json::Value& value,
const JSONCPP_STRING& path = ".") {
if (value.hasComment(Json::commentBefore)) { if (value.hasComment(Json::commentBefore)) {
fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str());
} }
@ -83,21 +83,15 @@ printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".")
fprintf(fout, "%s=null\n", path.c_str()); fprintf(fout, "%s=null\n", path.c_str());
break; break;
case Json::intValue: case Json::intValue:
fprintf(fout, fprintf(fout, "%s=%s\n", path.c_str(),
"%s=%s\n",
path.c_str(),
Json::valueToString(value.asLargestInt()).c_str()); Json::valueToString(value.asLargestInt()).c_str());
break; break;
case Json::uintValue: case Json::uintValue:
fprintf(fout, fprintf(fout, "%s=%s\n", path.c_str(),
"%s=%s\n",
path.c_str(),
Json::valueToString(value.asLargestUInt()).c_str()); Json::valueToString(value.asLargestUInt()).c_str());
break; break;
case Json::realValue: case Json::realValue:
fprintf(fout, fprintf(fout, "%s=%s\n", path.c_str(),
"%s=%s\n",
path.c_str(),
normalizeFloatingPointStr(value.asDouble()).c_str()); normalizeFloatingPointStr(value.asDouble()).c_str());
break; break;
case Json::stringValue: case Json::stringValue:
@ -125,8 +119,7 @@ printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".")
std::sort(members.begin(), members.end()); std::sort(members.begin(), members.end());
JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : "."; JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : ".";
for (Json::Value::Members::iterator it = members.begin(); for (Json::Value::Members::iterator it = members.begin();
it != members.end(); it != members.end(); ++it) {
++it) {
const JSONCPP_STRING name = *it; const JSONCPP_STRING name = *it;
printValueTree(fout, value[name], path + suffix + name); printValueTree(fout, value[name], path + suffix + name);
} }
@ -145,13 +138,12 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input,
const JSONCPP_STRING& kind, const JSONCPP_STRING& kind,
const Json::Features& features, const Json::Features& features,
bool parseOnly, bool parseOnly,
Json::Value* root) Json::Value* root) {
{
Json::Reader reader(features); Json::Reader reader(features);
bool parsingSuccessful = reader.parse(input.data(), input.data() + input.size(), *root); bool parsingSuccessful =
reader.parse(input.data(), input.data() + input.size(), *root);
if (!parsingSuccessful) { if (!parsingSuccessful) {
printf("Failed to parse %s file: \n%s\n", printf("Failed to parse %s file: \n%s\n", kind.c_str(),
kind.c_str(),
reader.getFormattedErrorMessages().c_str()); reader.getFormattedErrorMessages().c_str());
return 1; return 1;
} }
@ -171,32 +163,24 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input,
// writer.enableYAMLCompatibility(); // writer.enableYAMLCompatibility();
// return writer.write(root); // return writer.write(root);
// } // }
static JSONCPP_STRING useStyledWriter( static JSONCPP_STRING useStyledWriter(Json::Value const& root) {
Json::Value const& root)
{
Json::StyledWriter writer; Json::StyledWriter writer;
return writer.write(root); return writer.write(root);
} }
static JSONCPP_STRING useStyledStreamWriter( static JSONCPP_STRING useStyledStreamWriter(Json::Value const& root) {
Json::Value const& root)
{
Json::StyledStreamWriter writer; Json::StyledStreamWriter writer;
JSONCPP_OSTRINGSTREAM sout; JSONCPP_OSTRINGSTREAM sout;
writer.write(sout, root); writer.write(sout, root);
return sout.str(); return sout.str();
} }
static JSONCPP_STRING useBuiltStyledStreamWriter( static JSONCPP_STRING useBuiltStyledStreamWriter(Json::Value const& root) {
Json::Value const& root)
{
Json::StreamWriterBuilder builder; Json::StreamWriterBuilder builder;
return Json::writeString(builder, root); return Json::writeString(builder, root);
} }
static int rewriteValueTree( static int rewriteValueTree(const JSONCPP_STRING& rewritePath,
const JSONCPP_STRING& rewritePath,
const Json::Value& root, const Json::Value& root,
Options::writeFuncType write, Options::writeFuncType write,
JSONCPP_STRING* rewrite) JSONCPP_STRING* rewrite) {
{
*rewrite = write(root); *rewrite = write(root);
FILE* fout = fopen(rewritePath.c_str(), "wt"); FILE* fout = fopen(rewritePath.c_str(), "wt");
if (!fout) { if (!fout) {
@ -232,9 +216,7 @@ static int printUsage(const char* argv[]) {
return 3; return 3;
} }
static int parseCommandLine( static int parseCommandLine(int argc, const char* argv[], Options* opts) {
int argc, const char* argv[], Options* opts)
{
opts->parseOnly = false; opts->parseOnly = false;
opts->write = &useStyledWriter; opts->write = &useStyledWriter;
if (argc < 2) { if (argc < 2) {
@ -270,8 +252,7 @@ static int parseCommandLine(
opts->path = argv[index]; opts->path = argv[index];
return 0; return 0;
} }
static int runTest(Options const& opts) static int runTest(Options const& opts) {
{
int exitCode = 0; int exitCode = 0;
JSONCPP_STRING input = readInputTestFile(opts.path.c_str()); JSONCPP_STRING input = readInputTestFile(opts.path.c_str());
@ -292,9 +273,8 @@ static int runTest(Options const& opts)
JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite"; JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite";
Json::Value root; Json::Value root;
exitCode = parseAndSaveValueTree( exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features,
input, actualPath, "input", opts.parseOnly, &root);
opts.features, opts.parseOnly, &root);
if (exitCode || opts.parseOnly) { if (exitCode || opts.parseOnly) {
return exitCode; return exitCode;
} }
@ -304,8 +284,7 @@ static int runTest(Options const& opts)
return exitCode; return exitCode;
} }
Json::Value rewriteRoot; Json::Value rewriteRoot;
exitCode = parseAndSaveValueTree( exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite",
rewrite, rewriteActualPath, "rewrite",
opts.features, opts.parseOnly, &rewriteRoot); opts.features, opts.parseOnly, &rewriteRoot);
if (exitCode) { if (exitCode) {
return exitCode; return exitCode;
@ -321,8 +300,7 @@ int main(int argc, const char* argv[]) {
return exitCode; return exitCode;
} }
return runTest(opts); return runTest(opts);
} } catch (const std::exception& e) {
catch (const std::exception& e) {
printf("Unhandled exception:\n%s\n", e.what()); printf("Unhandled exception:\n%s\n", e.what());
return 1; return 1;
} }

View File

@ -5,39 +5,39 @@
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "json_tool.h"
#include <json/assertions.h> #include <json/assertions.h>
#include <json/reader.h> #include <json/reader.h>
#include <json/value.h> #include <json/value.h>
#include "json_tool.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <utility>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <istream> #include <istream>
#include <sstream> #include <limits>
#include <memory> #include <memory>
#include <set> #include <set>
#include <limits> #include <sstream>
#include <utility>
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
#include <cstdio> #include <cstdio>
#if !defined(snprintf) #if !defined(snprintf)
#define snprintf std::snprintf #define snprintf std::snprintf
#endif #endif
#if !defined(sscanf) #if !defined(sscanf)
#define sscanf std::sscanf #define sscanf std::sscanf
#endif #endif
#else #else
#include <stdio.h> #include <stdio.h>
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#if !defined(snprintf) #if !defined(snprintf)
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
#endif #endif
#endif #endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
@ -45,12 +45,14 @@
#pragma warning(disable : 4996) #pragma warning(disable : 4996)
#endif #endif
// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit // Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile
// time to change the stack limit
#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT) #if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)
#define JSONCPP_DEPRECATED_STACK_LIMIT 1000 #define JSONCPP_DEPRECATED_STACK_LIMIT 1000
#endif #endif
static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() static size_t const stackLimit_g =
JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()
namespace Json { namespace Json {
@ -101,8 +103,9 @@ Reader::Reader(const Features& features)
lastValue_(), commentsBefore_(), features_(features), collectComments_() { lastValue_(), commentsBefore_(), features_(features), collectComments_() {
} }
bool bool Reader::parse(const std::string& document,
Reader::parse(const std::string& document, Value& root, bool collectComments) { Value& root,
bool collectComments) {
document_.assign(document.begin(), document.end()); document_.assign(document.begin(), document.end());
const char* begin = document_.c_str(); const char* begin = document_.c_str();
const char* end = begin + document_.length(); const char* end = begin + document_.length();
@ -165,9 +168,11 @@ bool Reader::parse(const char* beginDoc,
bool Reader::readValue() { bool Reader::readValue() {
// readValue() may call itself only if it calls readObject() or ReadArray(). // readValue() may call itself only if it calls readObject() or ReadArray().
// These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). // These methods execute nodes_.push() just before and nodes_.pop)() just
// parse() executes one nodes_.push(), so > instead of >=. // after calling readValue(). parse() executes one nodes_.push(), so > instead
if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); // of >=.
if (nodes_.size() > stackLimit_g)
throwRuntimeError("Exceeded stackLimit in readValue().");
Token token; Token token;
skipCommentTokens(token); skipCommentTokens(token);
@ -193,30 +198,24 @@ bool Reader::readValue() {
case tokenString: case tokenString:
successful = decodeString(token); successful = decodeString(token);
break; break;
case tokenTrue: case tokenTrue: {
{
Value v(true); Value v(true);
currentValue().swapPayload(v); currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - 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().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - 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().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_);
} } break;
break;
case tokenArraySeparator: case tokenArraySeparator:
case tokenObjectEnd: case tokenObjectEnd:
case tokenArrayEnd: case tokenArrayEnd:
@ -369,7 +368,8 @@ bool Reader::readComment() {
return true; return true;
} }
JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin,
Reader::Location end) {
JSONCPP_STRING normalized; JSONCPP_STRING normalized;
normalized.reserve(static_cast<size_t>(end - begin)); normalized.reserve(static_cast<size_t>(end - begin));
Reader::Location current = begin; Reader::Location current = begin;
@ -388,8 +388,9 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end
return normalized; return normalized;
} }
void void Reader::addComment(Location begin,
Reader::addComment(Location begin, Location end, CommentPlacement placement) { Location end,
CommentPlacement placement) {
assert(collectComments_); assert(collectComments_);
const JSONCPP_STRING& normalized = normalizeEOL(begin, end); const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
if (placement == commentAfterOnSameLine) { if (placement == commentAfterOnSameLine) {
@ -426,7 +427,7 @@ bool Reader::readCppStyleComment() {
} }
void Reader::readNumber() { void Reader::readNumber() {
const char *p = current_; const char* p = current_;
char c = '0'; // stopgap for already consumed character char c = '0'; // stopgap for already consumed character
// integral part // integral part
while (c >= '0' && c <= '9') while (c >= '0' && c <= '9')
@ -488,8 +489,8 @@ bool Reader::readObject(Token& tokenStart) {
Token colon; Token colon;
if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
return addErrorAndRecover( return addErrorAndRecover("Missing ':' after object member name", colon,
"Missing ':' after object member name", colon, tokenObjectEnd); tokenObjectEnd);
} }
Value& value = currentValue()[name]; Value& value = currentValue()[name];
nodes_.push(&value); nodes_.push(&value);
@ -502,8 +503,8 @@ bool Reader::readObject(Token& tokenStart) {
if (!readToken(comma) || if (!readToken(comma) ||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
comma.type_ != tokenComment)) { comma.type_ != tokenComment)) {
return addErrorAndRecover( return addErrorAndRecover("Missing ',' or '}' in object declaration",
"Missing ',' or '}' in object declaration", comma, tokenObjectEnd); comma, tokenObjectEnd);
} }
bool finalizeTokenOk = true; bool finalizeTokenOk = true;
while (comma.type_ == tokenComment && finalizeTokenOk) while (comma.type_ == tokenComment && finalizeTokenOk)
@ -511,8 +512,8 @@ bool Reader::readObject(Token& tokenStart) {
if (comma.type_ == tokenObjectEnd) if (comma.type_ == tokenObjectEnd)
return true; return true;
} }
return addErrorAndRecover( return addErrorAndRecover("Missing '}' or object member name", tokenName,
"Missing '}' or object member name", tokenName, tokenObjectEnd); tokenObjectEnd);
} }
bool Reader::readArray(Token& tokenStart) { bool Reader::readArray(Token& tokenStart) {
@ -544,8 +545,8 @@ bool Reader::readArray(Token& tokenStart) {
bool badTokenType = bool badTokenType =
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
if (!ok || badTokenType) { if (!ok || badTokenType) {
return addErrorAndRecover( return addErrorAndRecover("Missing ',' or ']' in array declaration",
"Missing ',' or ']' in array declaration", token, tokenArrayEnd); token, tokenArrayEnd);
} }
if (token.type_ == tokenArrayEnd) if (token.type_ == tokenArrayEnd)
break; break;
@ -571,7 +572,8 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
bool isNegative = *current == '-'; bool isNegative = *current == '-';
if (isNegative) if (isNegative)
++current; ++current;
// TODO: Help the compiler do the div and mod at compile time or get rid of them. // TODO: Help the compiler do the div and mod at compile time or get rid of
// them.
Value::LargestUInt maxIntegerValue = Value::LargestUInt maxIntegerValue =
isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
: Value::maxLargestUInt; : Value::maxLargestUInt;
@ -703,8 +705,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
if (end - current < 6) if (end - current < 6)
return addError( return addError(
"additional six characters expected to parse unicode surrogate pair.", "additional six characters expected to parse unicode surrogate pair.",
token, token, current);
current);
unsigned int surrogatePair; unsigned int surrogatePair;
if (*(current++) == '\\' && *(current++) == 'u') { if (*(current++) == '\\' && *(current++) == 'u') {
if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
@ -714,8 +715,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
} else } else
return addError("expecting another \\u token to begin the second half of " return addError("expecting another \\u token to begin the second half of "
"a unicode surrogate pair", "a unicode surrogate pair",
token, token, current);
current);
} }
return true; return true;
} }
@ -726,8 +726,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
unsigned int& ret_unicode) { unsigned int& ret_unicode) {
if (end - current < 4) if (end - current < 4)
return addError( return addError(
"Bad unicode escape sequence in string: four digits expected.", "Bad unicode escape sequence in string: four digits expected.", token,
token,
current); current);
int unicode = 0; int unicode = 0;
for (int index = 0; index < 4; ++index) { for (int index = 0; index < 4; ++index) {
@ -742,15 +741,15 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
else else
return addError( return addError(
"Bad unicode escape sequence in string: hexadecimal digit expected.", "Bad unicode escape sequence in string: hexadecimal digit expected.",
token, token, current);
current);
} }
ret_unicode = static_cast<unsigned int>(unicode); ret_unicode = static_cast<unsigned int>(unicode);
return true; return true;
} }
bool bool Reader::addError(const JSONCPP_STRING& message,
Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { Token& token,
Location extra) {
ErrorInfo info; ErrorInfo info;
info.token_ = token; info.token_ = token;
info.message_ = message; info.message_ = message;
@ -826,8 +825,7 @@ JSONCPP_STRING Reader::getFormatedErrorMessages() const {
JSONCPP_STRING Reader::getFormattedErrorMessages() const { JSONCPP_STRING Reader::getFormattedErrorMessages() const {
JSONCPP_STRING formattedMessage; JSONCPP_STRING formattedMessage;
for (Errors::const_iterator itError = errors_.begin(); for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end(); itError != errors_.end(); ++itError) {
++itError) {
const ErrorInfo& error = *itError; const ErrorInfo& error = *itError;
formattedMessage += formattedMessage +=
"* " + getLocationLineAndColumn(error.token_.start_) + "\n"; "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
@ -842,8 +840,7 @@ JSONCPP_STRING Reader::getFormattedErrorMessages() const {
std::vector<Reader::StructuredError> Reader::getStructuredErrors() const { std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
std::vector<Reader::StructuredError> allErrors; std::vector<Reader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin(); for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end(); itError != errors_.end(); ++itError) {
++itError) {
const ErrorInfo& error = *itError; const ErrorInfo& error = *itError;
Reader::StructuredError structured; Reader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_; structured.offset_start = error.token_.start_ - begin_;
@ -856,8 +853,7 @@ std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
ptrdiff_t const length = end_ - begin_; ptrdiff_t const length = end_ - begin_;
if(value.getOffsetStart() > length if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
|| value.getOffsetLimit() > length)
return false; return false;
Token token; Token token;
token.type_ = tokenError; token.type_ = tokenError;
@ -871,11 +867,12 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
return true; return true;
} }
bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { bool Reader::pushError(const Value& value,
const JSONCPP_STRING& message,
const Value& extra) {
ptrdiff_t const length = end_ - begin_; ptrdiff_t const length = end_ - begin_;
if(value.getOffsetStart() > length if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
|| value.getOffsetLimit() > length extra.getOffsetLimit() > length)
|| extra.getOffsetLimit() > length)
return false; return false;
Token token; Token token;
token.type_ = tokenError; token.type_ = tokenError;
@ -889,9 +886,7 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const
return true; return true;
} }
bool Reader::good() const { bool Reader::good() const { return !errors_.size(); }
return !errors_.size();
}
// exact copy of Features // exact copy of Features
class OurFeatures { class OurFeatures {
@ -935,7 +930,9 @@ public:
JSONCPP_STRING getFormattedErrorMessages() const; JSONCPP_STRING getFormattedErrorMessages() const;
std::vector<StructuredError> getStructuredErrors() const; std::vector<StructuredError> getStructuredErrors() const;
bool pushError(const Value& value, const JSONCPP_STRING& message); bool pushError(const Value& value, const JSONCPP_STRING& message);
bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); bool pushError(const Value& value,
const JSONCPP_STRING& message,
const Value& extra);
bool good() const; bool good() const;
private: private:
@ -1004,7 +1001,8 @@ private:
Location& current, Location& current,
Location end, Location end,
unsigned int& unicode); unsigned int& unicode);
bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool
addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken); bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const JSONCPP_STRING& message, bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token, Token& token,
@ -1038,7 +1036,8 @@ private:
// complete copy of Read impl, for OurReader // complete copy of Read impl, for OurReader
bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location end) { bool OurReader::containsNewLine(OurReader::Location begin,
OurReader::Location end) {
for (; begin < end; ++begin) for (; begin < end; ++begin)
if (*begin == '\n' || *begin == '\r') if (*begin == '\n' || *begin == '\r')
return true; return true;
@ -1047,8 +1046,7 @@ bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location e
OurReader::OurReader(OurFeatures const& features) OurReader::OurReader(OurFeatures const& features)
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
lastValue_(), commentsBefore_(), lastValue_(), commentsBefore_(), features_(features), collectComments_() {
features_(features), collectComments_() {
} }
bool OurReader::parse(const char* beginDoc, bool OurReader::parse(const char* beginDoc,
@ -1075,7 +1073,8 @@ bool OurReader::parse(const char* beginDoc,
Token token; Token token;
skipCommentTokens(token); skipCommentTokens(token);
if (features_.failIfExtra_) { if (features_.failIfExtra_) {
if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream) { if ((features_.strictRoot_ || token.type_ != tokenError) &&
token.type_ != tokenEndOfStream) {
addError("Extra non-whitespace after JSON value.", token); addError("Extra non-whitespace after JSON value.", token);
return false; return false;
} }
@ -1100,7 +1099,8 @@ bool OurReader::parse(const char* beginDoc,
bool OurReader::readValue() { bool OurReader::readValue() {
// To preserve the old behaviour we cast size_t to int. // To preserve the old behaviour we cast size_t to int.
if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); if (static_cast<int>(nodes_.size()) > features_.stackLimit_)
throwRuntimeError("Exceeded stackLimit in readValue().");
Token token; Token token;
skipCommentTokens(token); skipCommentTokens(token);
bool successful = true; bool successful = true;
@ -1125,54 +1125,42 @@ bool OurReader::readValue() {
case tokenString: case tokenString:
successful = decodeString(token); successful = decodeString(token);
break; break;
case tokenTrue: case tokenTrue: {
{
Value v(true); Value v(true);
currentValue().swapPayload(v); currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - 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().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - 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().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_);
} } break;
break; case tokenNaN: {
case tokenNaN:
{
Value v(std::numeric_limits<double>::quiet_NaN()); Value v(std::numeric_limits<double>::quiet_NaN());
currentValue().swapPayload(v); currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_);
} } break;
break; case tokenPosInf: {
case tokenPosInf:
{
Value v(std::numeric_limits<double>::infinity()); Value v(std::numeric_limits<double>::infinity());
currentValue().swapPayload(v); currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_);
} } break;
break; case tokenNegInf: {
case tokenNegInf:
{
Value v(-std::numeric_limits<double>::infinity()); Value v(-std::numeric_limits<double>::infinity());
currentValue().swapPayload(v); currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_);
} } break;
break;
case tokenArraySeparator: case tokenArraySeparator:
case tokenObjectEnd: case tokenObjectEnd:
case tokenArrayEnd: case tokenArrayEnd:
@ -1354,7 +1342,8 @@ bool OurReader::readComment() {
return true; return true;
} }
JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Location end) { JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin,
OurReader::Location end) {
JSONCPP_STRING normalized; JSONCPP_STRING normalized;
normalized.reserve(static_cast<size_t>(end - begin)); normalized.reserve(static_cast<size_t>(end - begin));
OurReader::Location current = begin; OurReader::Location current = begin;
@ -1373,8 +1362,9 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc
return normalized; return normalized;
} }
void void OurReader::addComment(Location begin,
OurReader::addComment(Location begin, Location end, CommentPlacement placement) { Location end,
CommentPlacement placement) {
assert(collectComments_); assert(collectComments_);
const JSONCPP_STRING& normalized = normalizeEOL(begin, end); const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
if (placement == commentAfterOnSameLine) { if (placement == commentAfterOnSameLine) {
@ -1411,7 +1401,7 @@ bool OurReader::readCppStyleComment() {
} }
bool OurReader::readNumber(bool checkInf) { bool OurReader::readNumber(bool checkInf) {
const char *p = current_; const char* p = current_;
if (checkInf && p != end_ && *p == 'I') { if (checkInf && p != end_ && *p == 'I') {
current_ = ++p; current_ = ++p;
return false; return false;
@ -1448,7 +1438,6 @@ bool OurReader::readString() {
return c == '"'; return c == '"';
} }
bool OurReader::readStringSingleQuote() { bool OurReader::readStringSingleQuote() {
Char c = 0; Char c = 0;
while (current_ != end_) { while (current_ != end_) {
@ -1490,14 +1479,14 @@ bool OurReader::readObject(Token& tokenStart) {
Token colon; Token colon;
if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
return addErrorAndRecover( return addErrorAndRecover("Missing ':' after object member name", colon,
"Missing ':' after object member name", colon, tokenObjectEnd); tokenObjectEnd);
} }
if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); if (name.length() >= (1U << 30))
throwRuntimeError("keylength >= 2^30");
if (features_.rejectDupKeys_ && currentValue().isMember(name)) { if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
JSONCPP_STRING msg = "Duplicate key: '" + name + "'"; JSONCPP_STRING msg = "Duplicate key: '" + name + "'";
return addErrorAndRecover( return addErrorAndRecover(msg, tokenName, tokenObjectEnd);
msg, tokenName, tokenObjectEnd);
} }
Value& value = currentValue()[name]; Value& value = currentValue()[name];
nodes_.push(&value); nodes_.push(&value);
@ -1510,8 +1499,8 @@ bool OurReader::readObject(Token& tokenStart) {
if (!readToken(comma) || if (!readToken(comma) ||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
comma.type_ != tokenComment)) { comma.type_ != tokenComment)) {
return addErrorAndRecover( return addErrorAndRecover("Missing ',' or '}' in object declaration",
"Missing ',' or '}' in object declaration", comma, tokenObjectEnd); comma, tokenObjectEnd);
} }
bool finalizeTokenOk = true; bool finalizeTokenOk = true;
while (comma.type_ == tokenComment && finalizeTokenOk) while (comma.type_ == tokenComment && finalizeTokenOk)
@ -1519,8 +1508,8 @@ bool OurReader::readObject(Token& tokenStart) {
if (comma.type_ == tokenObjectEnd) if (comma.type_ == tokenObjectEnd)
return true; return true;
} }
return addErrorAndRecover( return addErrorAndRecover("Missing '}' or object member name", tokenName,
"Missing '}' or object member name", tokenName, tokenObjectEnd); tokenObjectEnd);
} }
bool OurReader::readArray(Token& tokenStart) { bool OurReader::readArray(Token& tokenStart) {
@ -1552,8 +1541,8 @@ bool OurReader::readArray(Token& tokenStart) {
bool badTokenType = bool badTokenType =
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
if (!ok || badTokenType) { if (!ok || badTokenType) {
return addErrorAndRecover( return addErrorAndRecover("Missing ',' or ']' in array declaration",
"Missing ',' or ']' in array declaration", token, tokenArrayEnd); token, tokenArrayEnd);
} }
if (token.type_ == tokenArrayEnd) if (token.type_ == tokenArrayEnd)
break; break;
@ -1579,7 +1568,8 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
bool isNegative = *current == '-'; bool isNegative = *current == '-';
if (isNegative) if (isNegative)
++current; ++current;
// TODO: Help the compiler do the div and mod at compile time or get rid of them. // TODO: Help the compiler do the div and mod at compile time or get rid of
// them.
Value::LargestUInt maxIntegerValue = Value::LargestUInt maxIntegerValue =
isNegative ? Value::LargestUInt(-Value::minLargestInt) isNegative ? Value::LargestUInt(-Value::minLargestInt)
: Value::maxLargestUInt; : Value::maxLargestUInt;
@ -1735,8 +1725,7 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
if (end - current < 6) if (end - current < 6)
return addError( return addError(
"additional six characters expected to parse unicode surrogate pair.", "additional six characters expected to parse unicode surrogate pair.",
token, token, current);
current);
unsigned int surrogatePair; unsigned int surrogatePair;
if (*(current++) == '\\' && *(current++) == 'u') { if (*(current++) == '\\' && *(current++) == 'u') {
if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
@ -1746,8 +1735,7 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
} else } else
return addError("expecting another \\u token to begin the second half of " return addError("expecting another \\u token to begin the second half of "
"a unicode surrogate pair", "a unicode surrogate pair",
token, token, current);
current);
} }
return true; return true;
} }
@ -1758,8 +1746,7 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token,
unsigned int& ret_unicode) { unsigned int& ret_unicode) {
if (end - current < 4) if (end - current < 4)
return addError( return addError(
"Bad unicode escape sequence in string: four digits expected.", "Bad unicode escape sequence in string: four digits expected.", token,
token,
current); current);
int unicode = 0; int unicode = 0;
for (int index = 0; index < 4; ++index) { for (int index = 0; index < 4; ++index) {
@ -1774,15 +1761,15 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token,
else else
return addError( return addError(
"Bad unicode escape sequence in string: hexadecimal digit expected.", "Bad unicode escape sequence in string: hexadecimal digit expected.",
token, token, current);
current);
} }
ret_unicode = static_cast<unsigned int>(unicode); ret_unicode = static_cast<unsigned int>(unicode);
return true; return true;
} }
bool bool OurReader::addError(const JSONCPP_STRING& message,
OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { Token& token,
Location extra) {
ErrorInfo info; ErrorInfo info;
info.token_ = token; info.token_ = token;
info.message_ = message; info.message_ = message;
@ -1853,8 +1840,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const {
JSONCPP_STRING OurReader::getFormattedErrorMessages() const { JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
JSONCPP_STRING formattedMessage; JSONCPP_STRING formattedMessage;
for (Errors::const_iterator itError = errors_.begin(); for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end(); itError != errors_.end(); ++itError) {
++itError) {
const ErrorInfo& error = *itError; const ErrorInfo& error = *itError;
formattedMessage += formattedMessage +=
"* " + getLocationLineAndColumn(error.token_.start_) + "\n"; "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
@ -1869,8 +1855,7 @@ JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const { std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
std::vector<OurReader::StructuredError> allErrors; std::vector<OurReader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin(); for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end(); itError != errors_.end(); ++itError) {
++itError) {
const ErrorInfo& error = *itError; const ErrorInfo& error = *itError;
OurReader::StructuredError structured; OurReader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_; structured.offset_start = error.token_.start_ - begin_;
@ -1883,8 +1868,7 @@ std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
ptrdiff_t length = end_ - begin_; ptrdiff_t length = end_ - begin_;
if(value.getOffsetStart() > length if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
|| value.getOffsetLimit() > length)
return false; return false;
Token token; Token token;
token.type_ = tokenError; token.type_ = tokenError;
@ -1898,11 +1882,12 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
return true; return true;
} }
bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { bool OurReader::pushError(const Value& value,
const JSONCPP_STRING& message,
const Value& extra) {
ptrdiff_t length = end_ - begin_; ptrdiff_t length = end_ - begin_;
if(value.getOffsetStart() > length if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
|| value.getOffsetLimit() > length extra.getOffsetLimit() > length)
|| extra.getOffsetLimit() > length)
return false; return false;
Token token; Token token;
token.type_ = tokenError; token.type_ = tokenError;
@ -1916,24 +1901,19 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, con
return true; return true;
} }
bool OurReader::good() const { bool OurReader::good() const { return !errors_.size(); }
return !errors_.size();
}
class OurCharReader : public CharReader { class OurCharReader : public CharReader {
bool const collectComments_; bool const collectComments_;
OurReader reader_; OurReader reader_;
public: public:
OurCharReader( OurCharReader(bool collectComments, OurFeatures const& features)
bool collectComments, : collectComments_(collectComments), reader_(features) {}
OurFeatures const& features) bool parse(char const* beginDoc,
: collectComments_(collectComments) char const* endDoc,
, reader_(features) Value* root,
{} JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
bool parse(
char const* beginDoc, char const* endDoc,
Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
if (errs) { if (errs) {
*errs = reader_.getFormattedErrorMessages(); *errs = reader_.getFormattedErrorMessages();
@ -1942,19 +1922,15 @@ public:
} }
}; };
CharReaderBuilder::CharReaderBuilder() CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }
{ CharReaderBuilder::~CharReaderBuilder() {}
setDefaults(&settings_); CharReader* CharReaderBuilder::newCharReader() const {
}
CharReaderBuilder::~CharReaderBuilder()
{}
CharReader* CharReaderBuilder::newCharReader() const
{
bool collectComments = settings_["collectComments"].asBool(); bool collectComments = settings_["collectComments"].asBool();
OurFeatures features = OurFeatures::all(); OurFeatures features = OurFeatures::all();
features.allowComments_ = settings_["allowComments"].asBool(); features.allowComments_ = settings_["allowComments"].asBool();
features.strictRoot_ = settings_["strictRoot"].asBool(); features.strictRoot_ = settings_["strictRoot"].asBool();
features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); features.allowDroppedNullPlaceholders_ =
settings_["allowDroppedNullPlaceholders"].asBool();
features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
features.stackLimit_ = settings_["stackLimit"].asInt(); features.stackLimit_ = settings_["stackLimit"].asInt();
@ -1963,8 +1939,7 @@ CharReader* CharReaderBuilder::newCharReader() const
features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
return new OurCharReader(collectComments, features); return new OurCharReader(collectComments, features);
} }
static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) {
{
valid_keys->clear(); valid_keys->clear();
valid_keys->insert("collectComments"); valid_keys->insert("collectComments");
valid_keys->insert("allowComments"); valid_keys->insert("allowComments");
@ -1977,10 +1952,10 @@ static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
valid_keys->insert("rejectDupKeys"); valid_keys->insert("rejectDupKeys");
valid_keys->insert("allowSpecialFloats"); valid_keys->insert("allowSpecialFloats");
} }
bool CharReaderBuilder::validate(Json::Value* invalid) const bool CharReaderBuilder::validate(Json::Value* invalid) const {
{
Json::Value my_invalid; Json::Value my_invalid;
if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL if (!invalid)
invalid = &my_invalid; // so we do not need to test for NULL
Json::Value& inv = *invalid; Json::Value& inv = *invalid;
std::set<JSONCPP_STRING> valid_keys; std::set<JSONCPP_STRING> valid_keys;
getValidReaderKeys(&valid_keys); getValidReaderKeys(&valid_keys);
@ -1994,14 +1969,12 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const
} }
return 0u == inv.size(); return 0u == inv.size();
} }
Value& CharReaderBuilder::operator[](JSONCPP_STRING key) Value& CharReaderBuilder::operator[](JSONCPP_STRING key) {
{
return settings_[key]; return settings_[key];
} }
// static // static
void CharReaderBuilder::strictMode(Json::Value* settings) void CharReaderBuilder::strictMode(Json::Value* settings) {
{ //! [CharReaderBuilderStrictMode]
//! [CharReaderBuilderStrictMode]
(*settings)["allowComments"] = false; (*settings)["allowComments"] = false;
(*settings)["strictRoot"] = true; (*settings)["strictRoot"] = true;
(*settings)["allowDroppedNullPlaceholders"] = false; (*settings)["allowDroppedNullPlaceholders"] = false;
@ -2011,12 +1984,11 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
(*settings)["failIfExtra"] = true; (*settings)["failIfExtra"] = true;
(*settings)["rejectDupKeys"] = true; (*settings)["rejectDupKeys"] = true;
(*settings)["allowSpecialFloats"] = false; (*settings)["allowSpecialFloats"] = false;
//! [CharReaderBuilderStrictMode] //! [CharReaderBuilderStrictMode]
} }
// static // static
void CharReaderBuilder::setDefaults(Json::Value* settings) void CharReaderBuilder::setDefaults(Json::Value* settings) {
{ //! [CharReaderBuilderDefaults]
//! [CharReaderBuilderDefaults]
(*settings)["collectComments"] = true; (*settings)["collectComments"] = true;
(*settings)["allowComments"] = true; (*settings)["allowComments"] = true;
(*settings)["strictRoot"] = false; (*settings)["strictRoot"] = false;
@ -2027,16 +1999,16 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
(*settings)["failIfExtra"] = false; (*settings)["failIfExtra"] = false;
(*settings)["rejectDupKeys"] = false; (*settings)["rejectDupKeys"] = false;
(*settings)["allowSpecialFloats"] = false; (*settings)["allowSpecialFloats"] = false;
//! [CharReaderBuilderDefaults] //! [CharReaderBuilderDefaults]
} }
////////////////////////////////// //////////////////////////////////
// global functions // global functions
bool parseFromStream( bool parseFromStream(CharReader::Factory const& fact,
CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, JSONCPP_ISTREAM& sin,
Value* root, JSONCPP_STRING* errs) Value* root,
{ JSONCPP_STRING* errs) {
JSONCPP_OSTRINGSTREAM ssin; JSONCPP_OSTRINGSTREAM ssin;
ssin << sin.rdbuf(); ssin << sin.rdbuf();
JSONCPP_STRING doc = ssin.str(); JSONCPP_STRING doc = ssin.str();

View File

@ -89,8 +89,7 @@ static inline void uintToString(LargestUInt value, char*& current) {
* We had a sophisticated way, but it did not work in WinCE. * We had a sophisticated way, but it did not work in WinCE.
* @see https://github.com/open-source-parsers/jsoncpp/pull/9 * @see https://github.com/open-source-parsers/jsoncpp/pull/9
*/ */
template <typename Iter> template <typename Iter> Iter fixNumericLocale(Iter begin, Iter end) {
Iter fixNumericLocale(Iter begin, Iter end) {
for (; begin != end; ++begin) { for (; begin != end; ++begin) {
if (*begin == ',') { if (*begin == ',') {
*begin = '.'; *begin = '.';
@ -99,8 +98,7 @@ Iter fixNumericLocale(Iter begin, Iter end) {
return begin; return begin;
} }
template <typename Iter> template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
void fixNumericLocaleInput(Iter begin, Iter end) {
char decimalPoint = getDecimalPoint(); char decimalPoint = getDecimalPoint();
if (decimalPoint == '\0' || decimalPoint == '.') { if (decimalPoint == '\0' || decimalPoint == '.') {
return; return;
@ -116,14 +114,13 @@ void fixNumericLocaleInput(Iter begin, Iter end) {
* Return iterator that would be the new end of the range [begin,end), if we * Return iterator that would be the new end of the range [begin,end), if we
* were to delete zeros in the end of string, but not the last zero before '.'. * were to delete zeros in the end of string, but not the last zero before '.'.
*/ */
template <typename Iter> template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
Iter fixZerosInTheEnd(Iter begin, Iter end) {
for (; begin != end; --end) { for (; begin != end; --end) {
if (*(end-1) != '0') { if (*(end - 1) != '0') {
return end; return end;
} }
// Don't delete the last zero before the decimal point. // Don't delete the last zero before the decimal point.
if (begin != (end-1) && *(end-2) == '.') { if (begin != (end - 1) && *(end - 2) == '.') {
return end; return end;
} }
} }

View File

@ -8,20 +8,20 @@
#include <json/value.h> #include <json/value.h>
#include <json/writer.h> #include <json/writer.h>
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <cassert>
#include <cstring>
#include <math.h> #include <math.h>
#include <sstream> #include <sstream>
#include <utility> #include <utility>
#include <cstring>
#include <cassert>
#ifdef JSON_USE_CPPTL #ifdef JSON_USE_CPPTL
#include <cpptl/conststring.h> #include <cpptl/conststring.h>
#endif #endif
#include <cstddef> // size_t
#include <algorithm> // min() #include <algorithm> // min()
#include <cstddef> // size_t
// Disable warning C4702 : unreachable code // Disable warning C4702 : unreachable code
#if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above #if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above
#pragma warning(disable:4702) #pragma warning(disable : 4702)
#endif #endif
#define JSON_ASSERT_UNREACHABLE assert(false) #define JSON_ASSERT_UNREACHABLE assert(false)
@ -36,20 +36,19 @@ namespace Json {
#else #else
#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::null = reinterpret_cast<const Value&>(kNullRef);
//const Value& Value::nullRef = null; // const Value& Value::nullRef = null;
// static // static
Value const& Value::nullSingleton() Value const& Value::nullSingleton() {
{
static Value const nullStatic; static Value const nullStatic;
return nullStatic; return nullStatic;
} }
// for backwards compatibility, we'll leave these global references around, but DO NOT // for backwards compatibility, we'll leave these global references around, but
// use them in JSONCPP library code any more! // DO NOT use them in JSONCPP library code any more!
Value const& Value::null = Value::nullSingleton(); Value const& Value::null = Value::nullSingleton();
Value const& Value::nullRef = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton();
@ -76,12 +75,13 @@ template <typename T, typename U>
static inline bool InRange(double d, T min, U max) { static inline bool InRange(double d, T min, U max) {
// The casts can lose precision, but we are looking only for // The casts can lose precision, but we are looking only for
// an approximate range. Might fail on edge cases though. ~cdunn // an approximate range. Might fail on edge cases though. ~cdunn
//return d >= static_cast<double>(min) && d <= static_cast<double>(max); // return d >= static_cast<double>(min) && d <= static_cast<double>(max);
return d >= min && d <= max; return d >= min && d <= max;
} }
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
static inline double integerToDouble(Json::UInt64 value) { static inline double integerToDouble(Json::UInt64 value) {
return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1)); return static_cast<double>(Int64(value / 2)) * 2.0 +
static_cast<double>(Int64(value & 1));
} }
template <typename T> static inline double integerToDouble(T value) { template <typename T> static inline double integerToDouble(T value) {
@ -101,9 +101,7 @@ static inline bool InRange(double d, T min, U max) {
* computed using strlen(value). * computed using strlen(value).
* @return Pointer on the duplicate instance of string. * @return Pointer on the duplicate instance of string.
*/ */
static inline char* duplicateStringValue(const char* value, static inline char* duplicateStringValue(const char* value, size_t length) {
size_t length)
{
// Avoid an integer overflow in the call to malloc below by limiting length // Avoid an integer overflow in the call to malloc below by limiting length
// to a sane value. // to a sane value.
if (length >= static_cast<size_t>(Value::maxInt)) if (length >= static_cast<size_t>(Value::maxInt))
@ -111,8 +109,7 @@ static inline char* duplicateStringValue(const char* value,
char* newString = static_cast<char*>(malloc(length + 1)); char* newString = static_cast<char*>(malloc(length + 1));
if (newString == NULL) { if (newString == NULL) {
throwRuntimeError( 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);
@ -122,31 +119,30 @@ static inline char* duplicateStringValue(const char* value,
/* Record the length as a prefix. /* Record the length as a prefix.
*/ */
static inline char* duplicateAndPrefixStringValue( static inline char* duplicateAndPrefixStringValue(const char* value,
const char* value, unsigned int length) {
unsigned int length)
{
// Avoid an integer overflow in the call to malloc below by limiting length // Avoid an integer overflow in the call to malloc below by limiting length
// to a sane value. // to a sane value.
JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U, JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) -
sizeof(unsigned) - 1U,
"in Json::Value::duplicateAndPrefixStringValue(): " "in Json::Value::duplicateAndPrefixStringValue(): "
"length too big for prefixing"); "length too big for prefixing");
unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U; unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
char* newString = static_cast<char*>(malloc(actualLength)); char* newString = static_cast<char*>(malloc(actualLength));
if (newString == 0) { if (newString == 0) {
throwRuntimeError( 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
return newString; return newString;
} }
inline static void decodePrefixedString( inline static void decodePrefixedString(bool isPrefixed,
bool isPrefixed, char const* prefixed, char const* prefixed,
unsigned* length, char const** value) unsigned* length,
{ char const** value) {
if (!isPrefixed) { if (!isPrefixed) {
*length = static_cast<unsigned>(strlen(prefixed)); *length = static_cast<unsigned>(strlen(prefixed));
*value = prefixed; *value = prefixed;
@ -155,7 +151,8 @@ inline static void decodePrefixedString(
*value = prefixed + sizeof(unsigned); *value = prefixed + sizeof(unsigned);
} }
} }
/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). /** Free the string duplicated by
* duplicateStringValue()/duplicateAndPrefixStringValue().
*/ */
#if JSONCPP_USING_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
static inline void releasePrefixedStringValue(char* value) { static inline void releasePrefixedStringValue(char* value) {
@ -168,17 +165,13 @@ static inline void releasePrefixedStringValue(char* value) {
} }
static inline void releaseStringValue(char* value, unsigned length) { static inline void releaseStringValue(char* value, unsigned length) {
// length==0 => we allocated the strings memory // length==0 => we allocated the strings memory
size_t size = (length==0) ? strlen(value) : length; size_t size = (length == 0) ? strlen(value) : length;
memset(value, 0, size); memset(value, 0, size);
free(value); free(value);
} }
#else // !JSONCPP_USING_SECURE_MEMORY #else // !JSONCPP_USING_SECURE_MEMORY
static inline void releasePrefixedStringValue(char* value) { static inline void releasePrefixedStringValue(char* value) { free(value); }
free(value); static inline void releaseStringValue(char* value, unsigned) { free(value); }
}
static inline void releaseStringValue(char* value, unsigned) {
free(value);
}
#endif // JSONCPP_USING_SECURE_MEMORY #endif // JSONCPP_USING_SECURE_MEMORY
} // namespace Json } // namespace Json
@ -197,27 +190,15 @@ static inline void releaseStringValue(char* value, unsigned) {
namespace Json { namespace Json {
Exception::Exception(JSONCPP_STRING const& msg) Exception::Exception(JSONCPP_STRING const& msg) : msg_(msg) {}
: msg_(msg) Exception::~Exception() JSONCPP_NOEXCEPT {}
{} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); }
Exception::~Exception() JSONCPP_NOEXCEPT RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) {}
{} LogicError::LogicError(JSONCPP_STRING const& msg) : Exception(msg) {}
char const* Exception::what() const JSONCPP_NOEXCEPT JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) {
{
return msg_.c_str();
}
RuntimeError::RuntimeError(JSONCPP_STRING const& msg)
: Exception(msg)
{}
LogicError::LogicError(JSONCPP_STRING const& msg)
: Exception(msg)
{}
JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
{
throw RuntimeError(msg); throw RuntimeError(msg);
} }
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) {
{
throw LogicError(msg); throw LogicError(msg);
} }
@ -229,8 +210,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
Value::CommentInfo::CommentInfo() : comment_(0) Value::CommentInfo::CommentInfo() : comment_(0) {}
{}
Value::CommentInfo::~CommentInfo() { Value::CommentInfo::~CommentInfo() {
if (comment_) if (comment_)
@ -263,7 +243,9 @@ void Value::CommentInfo::setComment(const char* text, size_t len) {
Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {} Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate) Value::CZString::CZString(char const* str,
unsigned ulength,
DuplicationPolicy allocate)
: cstr_(str) { : cstr_(str) {
// allocate != duplicate // allocate != duplicate
storage_.policy_ = allocate & 0x3; storage_.policy_ = allocate & 0x3;
@ -274,10 +256,15 @@ Value::CZString::CZString(const CZString& other) {
cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
? duplicateStringValue(other.cstr_, other.storage_.length_) ? duplicateStringValue(other.cstr_, other.storage_.length_)
: other.cstr_); : other.cstr_);
storage_.policy_ = static_cast<unsigned>(other.cstr_ storage_.policy_ =
? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication static_cast<unsigned>(
? noDuplication : duplicate) other.cstr_
: static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U; ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
noDuplication
? noDuplication
: duplicate)
: static_cast<DuplicationPolicy>(other.storage_.policy_)) &
3U;
storage_.length_ = other.storage_.length_; storage_.length_ = other.storage_.length_;
} }
@ -290,7 +277,11 @@ Value::CZString::CZString(CZString&& other)
Value::CZString::~CZString() { Value::CZString::~CZString() {
if (cstr_ && storage_.policy_ == duplicate) { if (cstr_ && storage_.policy_ == duplicate) {
releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary releaseStringValue(const_cast<char*>(cstr_),
storage_.length_ + 1u); // +1 for null terminating
// character for sake of
// completeness but not actually
// necessary
} }
} }
@ -315,26 +306,31 @@ Value::CZString& Value::CZString::operator=(CZString&& other) {
#endif #endif
bool Value::CZString::operator<(const CZString& other) const { bool Value::CZString::operator<(const CZString& other) const {
if (!cstr_) return index_ < other.index_; if (!cstr_)
//return strcmp(cstr_, other.cstr_) < 0; return index_ < other.index_;
// return strcmp(cstr_, other.cstr_) < 0;
// Assume both are strings. // Assume both are strings.
unsigned this_len = this->storage_.length_; unsigned this_len = this->storage_.length_;
unsigned other_len = other.storage_.length_; unsigned other_len = other.storage_.length_;
unsigned min_len = std::min<unsigned>(this_len, other_len); unsigned min_len = std::min<unsigned>(this_len, other_len);
JSON_ASSERT(this->cstr_ && other.cstr_); JSON_ASSERT(this->cstr_ && other.cstr_);
int comp = memcmp(this->cstr_, other.cstr_, min_len); int comp = memcmp(this->cstr_, other.cstr_, min_len);
if (comp < 0) return true; if (comp < 0)
if (comp > 0) return false; return true;
if (comp > 0)
return false;
return (this_len < other_len); return (this_len < other_len);
} }
bool Value::CZString::operator==(const CZString& other) const { bool Value::CZString::operator==(const CZString& other) const {
if (!cstr_) return index_ == other.index_; if (!cstr_)
//return strcmp(cstr_, other.cstr_) == 0; return index_ == other.index_;
// return strcmp(cstr_, other.cstr_) == 0;
// Assume both are strings. // Assume both are strings.
unsigned this_len = this->storage_.length_; unsigned this_len = this->storage_.length_;
unsigned other_len = other.storage_.length_; unsigned other_len = other.storage_.length_;
if (this_len != other_len) return false; if (this_len != other_len)
return false;
JSON_ASSERT(this->cstr_ && other.cstr_); JSON_ASSERT(this->cstr_ && other.cstr_);
int comp = memcmp(this->cstr_, other.cstr_, this_len); int comp = memcmp(this->cstr_, other.cstr_, this_len);
return comp == 0; return comp == 0;
@ -342,10 +338,12 @@ bool Value::CZString::operator==(const CZString& other) const {
ArrayIndex Value::CZString::index() const { return index_; } ArrayIndex Value::CZString::index() const { return index_; }
//const char* Value::CZString::c_str() const { return cstr_; } // const char* Value::CZString::c_str() const { return cstr_; }
const char* Value::CZString::data() const { return cstr_; } const char* Value::CZString::data() const { return cstr_; }
unsigned Value::CZString::length() const { return storage_.length_; } unsigned Value::CZString::length() const { return storage_.length_; }
bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; } bool Value::CZString::isStaticString() const {
return storage_.policy_ == noDuplication;
}
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
@ -416,19 +414,20 @@ Value::Value(double value) {
Value::Value(const char* value) { Value::Value(const char* value) {
initBasic(stringValue, true); initBasic(stringValue, true);
JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value))); value_.string_ = duplicateAndPrefixStringValue(
value, static_cast<unsigned>(strlen(value)));
} }
Value::Value(const char* beginValue, const char* endValue) { Value::Value(const char* beginValue, const char* endValue) {
initBasic(stringValue, true); initBasic(stringValue, true);
value_.string_ = value_.string_ = duplicateAndPrefixStringValue(
duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue)); beginValue, static_cast<unsigned>(endValue - beginValue));
} }
Value::Value(const JSONCPP_STRING& value) { Value::Value(const JSONCPP_STRING& value) {
initBasic(stringValue, true); initBasic(stringValue, true);
value_.string_ = value_.string_ = duplicateAndPrefixStringValue(
duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length())); value.data(), static_cast<unsigned>(value.length()));
} }
Value::Value(const StaticString& value) { Value::Value(const StaticString& value) {
@ -439,7 +438,8 @@ Value::Value(const StaticString& value) {
#ifdef JSON_USE_CPPTL #ifdef JSON_USE_CPPTL
Value::Value(const CppTL::ConstString& value) { Value::Value(const CppTL::ConstString& value) {
initBasic(stringValue, true); initBasic(stringValue, true);
value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length())); value_.string_ = duplicateAndPrefixStringValue(
value, static_cast<unsigned>(value.length()));
} }
#endif #endif
@ -527,23 +527,28 @@ bool Value::operator<(const Value& other) const {
return value_.real_ < other.value_.real_; return value_.real_ < other.value_.real_;
case booleanValue: case booleanValue:
return value_.bool_ < other.value_.bool_; return value_.bool_ < other.value_.bool_;
case stringValue: case stringValue: {
{
if ((value_.string_ == 0) || (other.value_.string_ == 0)) { if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
if (other.value_.string_) return true; if (other.value_.string_)
else return false; return true;
else
return false;
} }
unsigned this_len; unsigned this_len;
unsigned other_len; unsigned other_len;
char const* this_str; char const* this_str;
char const* other_str; char const* other_str;
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); &this_str);
decodePrefixedString(other.allocated_, other.value_.string_, &other_len,
&other_str);
unsigned min_len = std::min<unsigned>(this_len, other_len); unsigned min_len = std::min<unsigned>(this_len, other_len);
JSON_ASSERT(this_str && other_str); JSON_ASSERT(this_str && other_str);
int comp = memcmp(this_str, other_str, min_len); int comp = memcmp(this_str, other_str, min_len);
if (comp < 0) return true; if (comp < 0)
if (comp > 0) return false; return true;
if (comp > 0)
return false;
return (this_len < other_len); return (this_len < other_len);
} }
case arrayValue: case arrayValue:
@ -584,8 +589,7 @@ bool Value::operator==(const Value& other) const {
return value_.real_ == other.value_.real_; return value_.real_ == other.value_.real_;
case booleanValue: case booleanValue:
return value_.bool_ == other.value_.bool_; return value_.bool_ == other.value_.bool_;
case stringValue: case stringValue: {
{
if ((value_.string_ == 0) || (other.value_.string_ == 0)) { if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
return (value_.string_ == other.value_.string_); return (value_.string_ == other.value_.string_);
} }
@ -593,9 +597,12 @@ bool Value::operator==(const Value& other) const {
unsigned other_len; unsigned other_len;
char const* this_str; char const* this_str;
char const* other_str; char const* other_str;
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); &this_str);
if (this_len != other_len) return false; decodePrefixedString(other.allocated_, other.value_.string_, &other_len,
&other_str);
if (this_len != other_len)
return false;
JSON_ASSERT(this_str && other_str); JSON_ASSERT(this_str && other_str);
int comp = memcmp(this_str, other_str, this_len); int comp = memcmp(this_str, other_str, this_len);
return comp == 0; return comp == 0;
@ -615,10 +622,12 @@ bool Value::operator!=(const Value& other) const { return !(*this == other); }
const char* Value::asCString() const { const char* Value::asCString() const {
JSON_ASSERT_MESSAGE(type_ == stringValue, JSON_ASSERT_MESSAGE(type_ == stringValue,
"in Json::Value::asCString(): requires stringValue"); "in Json::Value::asCString(): requires stringValue");
if (value_.string_ == 0) return 0; if (value_.string_ == 0)
return 0;
unsigned this_len; unsigned this_len;
char const* this_str; char const* this_str;
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
&this_str);
return this_str; return this_str;
} }
@ -626,17 +635,21 @@ const char* Value::asCString() const {
unsigned Value::getCStringLength() const { unsigned Value::getCStringLength() const {
JSON_ASSERT_MESSAGE(type_ == stringValue, JSON_ASSERT_MESSAGE(type_ == stringValue,
"in Json::Value::asCString(): requires stringValue"); "in Json::Value::asCString(): requires stringValue");
if (value_.string_ == 0) return 0; if (value_.string_ == 0)
return 0;
unsigned this_len; unsigned this_len;
char const* this_str; char const* this_str;
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
&this_str);
return this_len; return this_len;
} }
#endif #endif
bool Value::getString(char const** str, char const** cend) const { bool Value::getString(char const** str, char const** cend) const {
if (type_ != stringValue) return false; if (type_ != stringValue)
if (value_.string_ == 0) return false; return false;
if (value_.string_ == 0)
return false;
unsigned length; unsigned length;
decodePrefixedString(this->allocated_, this->value_.string_, &length, str); decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
*cend = *str + length; *cend = *str + length;
@ -647,12 +660,13 @@ JSONCPP_STRING Value::asString() const {
switch (type_) { switch (type_) {
case nullValue: case nullValue:
return ""; return "";
case stringValue: case stringValue: {
{ if (value_.string_ == 0)
if (value_.string_ == 0) return ""; return "";
unsigned this_len; unsigned this_len;
char const* this_str; char const* this_str;
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
&this_str);
return JSONCPP_STRING(this_str, this_len); return JSONCPP_STRING(this_str, this_len);
} }
case booleanValue: case booleanValue:
@ -672,8 +686,7 @@ JSONCPP_STRING Value::asString() const {
CppTL::ConstString Value::asConstString() const { CppTL::ConstString Value::asConstString() const {
unsigned len; unsigned len;
char const* str; char const* str;
decodePrefixedString(allocated_, value_.string_, decodePrefixedString(allocated_, value_.string_, &len, &str);
&len, &str);
return CppTL::ConstString(str, len); return CppTL::ConstString(str, len);
} }
#endif #endif
@ -911,7 +924,7 @@ bool Value::empty() const {
return false; return false;
} }
Value::operator bool() const { return ! isNull(); } Value::operator bool() const { return !isNull(); }
void Value::clear() { void Value::clear() {
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
@ -1013,8 +1026,7 @@ void Value::dupPayload(const Value& other) {
if (other.value_.string_ && other.allocated_) { if (other.value_.string_ && other.allocated_) {
unsigned len; unsigned len;
char const* str; char const* str;
decodePrefixedString(other.allocated_, other.value_.string_, decodePrefixedString(other.allocated_, other.value_.string_, &len, &str);
&len, &str);
value_.string_ = duplicateAndPrefixStringValue(str, len); value_.string_ = duplicateAndPrefixStringValue(str, len);
allocated_ = true; allocated_ = true;
} else { } else {
@ -1057,8 +1069,8 @@ void Value::dupMeta(const Value& other) {
for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
const CommentInfo& otherComment = other.comments_[comment]; const CommentInfo& otherComment = other.comments_[comment];
if (otherComment.comment_) if (otherComment.comment_)
comments_[comment].setComment( comments_[comment].setComment(otherComment.comment_,
otherComment.comment_, strlen(otherComment.comment_)); strlen(otherComment.comment_));
} }
} else { } else {
comments_ = 0; comments_ = 0;
@ -1076,8 +1088,8 @@ Value& Value::resolveReference(const char* key) {
"in Json::Value::resolveReference(): requires objectValue"); "in Json::Value::resolveReference(): requires objectValue");
if (type_ == nullValue) if (type_ == nullValue)
*this = Value(objectValue); *this = Value(objectValue);
CZString actualKey( CZString actualKey(key, static_cast<unsigned>(strlen(key)),
key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE! CZString::noDuplication); // NOTE!
ObjectValues::iterator it = value_.map_->lower_bound(actualKey); ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
if (it != value_.map_->end() && (*it).first == actualKey) if (it != value_.map_->end() && (*it).first == actualKey)
return (*it).second; return (*it).second;
@ -1089,15 +1101,14 @@ Value& Value::resolveReference(const char* key) {
} }
// @param key is not null-terminated. // @param key is not null-terminated.
Value& Value::resolveReference(char const* key, char const* cend) Value& Value::resolveReference(char const* key, char const* cend) {
{
JSON_ASSERT_MESSAGE( JSON_ASSERT_MESSAGE(
type_ == nullValue || type_ == objectValue, type_ == nullValue || type_ == objectValue,
"in Json::Value::resolveReference(key, end): requires objectValue"); "in Json::Value::resolveReference(key, end): requires objectValue");
if (type_ == nullValue) if (type_ == nullValue)
*this = Value(objectValue); *this = Value(objectValue);
CZString actualKey( CZString actualKey(key, static_cast<unsigned>(cend - key),
key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy); CZString::duplicateOnCopy);
ObjectValues::iterator it = value_.map_->lower_bound(actualKey); ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
if (it != value_.map_->end() && (*it).first == actualKey) if (it != value_.map_->end() && (*it).first == actualKey)
return (*it).second; return (*it).second;
@ -1115,27 +1126,29 @@ Value Value::get(ArrayIndex index, const Value& defaultValue) const {
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
Value const* Value::find(char const* key, char const* cend) const Value const* Value::find(char const* key, char const* cend) const {
{ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
JSON_ASSERT_MESSAGE( "in Json::Value::find(key, end, found): requires "
type_ == nullValue || type_ == objectValue, "objectValue or nullValue");
"in Json::Value::find(key, end, found): requires objectValue or nullValue"); if (type_ == nullValue)
if (type_ == nullValue) return NULL; return NULL;
CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication); CZString actualKey(key, static_cast<unsigned>(cend - key),
CZString::noDuplication);
ObjectValues::const_iterator it = value_.map_->find(actualKey); ObjectValues::const_iterator it = value_.map_->find(actualKey);
if (it == value_.map_->end()) return NULL; if (it == value_.map_->end())
return NULL;
return &(*it).second; return &(*it).second;
} }
const Value& Value::operator[](const char* key) const const Value& Value::operator[](const char* key) const {
{
Value const* found = find(key, key + strlen(key)); Value const* found = find(key, key + strlen(key));
if (!found) return nullSingleton(); if (!found)
return nullSingleton();
return *found; return *found;
} }
Value const& Value::operator[](JSONCPP_STRING const& key) const Value const& Value::operator[](JSONCPP_STRING const& key) const {
{
Value const* found = find(key.data(), key.data() + key.length()); Value const* found = find(key.data(), key.data() + key.length());
if (!found) return nullSingleton(); if (!found)
return nullSingleton();
return *found; return *found;
} }
@ -1155,10 +1168,10 @@ Value& Value::operator[](const StaticString& key) {
Value& Value::operator[](const CppTL::ConstString& key) { Value& Value::operator[](const CppTL::ConstString& key) {
return resolveReference(key.c_str(), key.end_c_str()); return resolveReference(key.c_str(), key.end_c_str());
} }
Value const& Value::operator[](CppTL::ConstString const& key) const Value const& Value::operator[](CppTL::ConstString const& key) const {
{
Value const* found = find(key.c_str(), key.end_c_str()); Value const* found = find(key.c_str(), key.end_c_str());
if (!found) return nullSingleton(); if (!found)
return nullSingleton();
return *found; return *found;
} }
#endif #endif
@ -1166,30 +1179,30 @@ Value const& Value::operator[](CppTL::ConstString const& key) const
Value& Value::append(const Value& value) { return (*this)[size()] = value; } Value& Value::append(const Value& value) { return (*this)[size()] = value; }
#if JSON_HAS_RVALUE_REFERENCES #if JSON_HAS_RVALUE_REFERENCES
Value& Value::append(Value&& value) { return (*this)[size()] = std::move(value); } Value& Value::append(Value&& value) {
return (*this)[size()] = std::move(value);
}
#endif #endif
Value Value::get(char const* key, char const* cend, Value const& defaultValue) const Value Value::get(char const* key,
{ char const* cend,
Value const& defaultValue) const {
Value const* found = find(key, cend); Value const* found = find(key, cend);
return !found ? defaultValue : *found; return !found ? defaultValue : *found;
} }
Value Value::get(char const* key, Value const& defaultValue) const Value Value::get(char const* key, Value const& defaultValue) const {
{
return get(key, key + strlen(key), defaultValue); return get(key, key + strlen(key), defaultValue);
} }
Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const {
{
return get(key.data(), key.data() + key.length(), defaultValue); return get(key.data(), key.data() + key.length(), defaultValue);
} }
bool Value::removeMember(const char* key, const char* cend, Value* removed) {
bool Value::removeMember(const char* key, const char* cend, Value* removed)
{
if (type_ != objectValue) { if (type_ != objectValue) {
return false; return false;
} }
CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication); CZString actualKey(key, static_cast<unsigned>(cend - key),
CZString::noDuplication);
ObjectValues::iterator it = value_.map_->find(actualKey); ObjectValues::iterator it = value_.map_->find(actualKey);
if (it == value_.map_->end()) if (it == value_.map_->end())
return false; return false;
@ -1202,16 +1215,13 @@ bool Value::removeMember(const char* key, const char* cend, Value* removed)
value_.map_->erase(it); value_.map_->erase(it);
return true; return true;
} }
bool Value::removeMember(const char* key, Value* removed) bool Value::removeMember(const char* key, Value* removed) {
{
return removeMember(key, key + strlen(key), removed); return removeMember(key, key + strlen(key), removed);
} }
bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) {
{
return removeMember(key.data(), key.data() + key.length(), removed); return removeMember(key.data(), key.data() + key.length(), removed);
} }
void Value::removeMember(const char* key) void Value::removeMember(const char* key) {
{
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
"in Json::Value::removeMember(): requires objectValue"); "in Json::Value::removeMember(): requires objectValue");
if (type_ == nullValue) if (type_ == nullValue)
@ -1220,8 +1230,7 @@ void Value::removeMember(const char* key)
CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
value_.map_->erase(actualKey); value_.map_->erase(actualKey);
} }
void Value::removeMember(const JSONCPP_STRING& key) void Value::removeMember(const JSONCPP_STRING& key) {
{
removeMember(key.c_str()); removeMember(key.c_str());
} }
@ -1237,7 +1246,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) {
*removed = it->second; *removed = it->second;
ArrayIndex oldSize = size(); ArrayIndex oldSize = size();
// shift left all items left, into the place of the "removed" // shift left all items left, into the place of the "removed"
for (ArrayIndex i = index; i < (oldSize - 1); ++i){ for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
CZString keey(i); CZString keey(i);
(*value_.map_)[keey] = (*this)[i + 1]; (*value_.map_)[keey] = (*this)[i + 1];
} }
@ -1255,17 +1264,14 @@ Value Value::get(const CppTL::ConstString& key,
} }
#endif #endif
bool Value::isMember(char const* key, char const* cend) const bool Value::isMember(char const* key, char const* cend) const {
{
Value const* value = find(key, cend); Value const* value = find(key, cend);
return NULL != value; return NULL != value;
} }
bool Value::isMember(char const* key) const bool Value::isMember(char const* key) const {
{
return isMember(key, key + strlen(key)); return isMember(key, key + strlen(key));
} }
bool Value::isMember(JSONCPP_STRING const& key) const bool Value::isMember(JSONCPP_STRING const& key) const {
{
return isMember(key.data(), key.data() + key.length()); return isMember(key.data(), key.data() + key.length());
} }
@ -1286,8 +1292,7 @@ Value::Members Value::getMemberNames() const {
ObjectValues::const_iterator it = value_.map_->begin(); ObjectValues::const_iterator it = value_.map_->begin();
ObjectValues::const_iterator itEnd = value_.map_->end(); ObjectValues::const_iterator itEnd = value_.map_->end();
for (; it != itEnd; ++it) { for (; it != itEnd; ++it) {
members.push_back(JSONCPP_STRING((*it).first.data(), members.push_back(JSONCPP_STRING((*it).first.data(), (*it).first.length()));
(*it).first.length()));
} }
return members; return members;
} }
@ -1418,9 +1423,11 @@ bool Value::isIntegral() const {
// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
// require the value to be strictly less than the limit. // require the value to be strictly less than the limit.
return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); return value_.real_ >= double(minInt64) &&
value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
#else #else
return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_); return value_.real_ >= minInt && value_.real_ <= maxUInt &&
IsIntegral(value_.real_);
#endif // JSON_HAS_INT64 #endif // JSON_HAS_INT64
default: default:
break; break;
@ -1428,7 +1435,9 @@ bool Value::isIntegral() const {
return false; return false;
} }
bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; } bool Value::isDouble() const {
return type_ == intValue || type_ == uintValue || type_ == realValue;
}
bool Value::isNumeric() const { return isDouble(); } bool Value::isNumeric() const { return isDouble(); }
@ -1438,10 +1447,12 @@ bool Value::isArray() const { return type_ == arrayValue; }
bool Value::isObject() const { return type_ == objectValue; } bool Value::isObject() const { return type_ == objectValue; }
void Value::setComment(const char* comment, size_t len, CommentPlacement placement) { void Value::setComment(const char* comment,
size_t len,
CommentPlacement placement) {
if (!comments_) if (!comments_)
comments_ = new CommentInfo[numberOfCommentPlacement]; comments_ = new CommentInfo[numberOfCommentPlacement];
if ((len > 0) && (comment[len-1] == '\n')) { if ((len > 0) && (comment[len - 1] == '\n')) {
// Always discard trailing newline, to aid indentation. // Always discard trailing newline, to aid indentation.
len -= 1; len -= 1;
} }
@ -1452,7 +1463,8 @@ void Value::setComment(const char* comment, CommentPlacement placement) {
setComment(comment, strlen(comment), placement); setComment(comment, strlen(comment), placement);
} }
void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) { void Value::setComment(const JSONCPP_STRING& comment,
CommentPlacement placement) {
setComment(comment.c_str(), comment.length(), placement); setComment(comment.c_str(), comment.length(), placement);
} }

View File

@ -4,76 +4,77 @@
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include <json/writer.h>
#include "json_tool.h" #include "json_tool.h"
#include <json/writer.h>
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <iomanip>
#include <memory>
#include <sstream>
#include <utility>
#include <set>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <iomanip>
#include <memory>
#include <set>
#include <sstream>
#include <utility>
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
#if !defined(isnan) #if !defined(isnan)
#define isnan std::isnan #define isnan std::isnan
#endif #endif
#if !defined(isfinite) #if !defined(isfinite)
#define isfinite std::isfinite #define isfinite std::isfinite
#endif #endif
#if !defined(snprintf) #if !defined(snprintf)
#define snprintf std::snprintf #define snprintf std::snprintf
#endif #endif
#else #else
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#if defined(_MSC_VER) #if defined(_MSC_VER)
#if !defined(isnan) #if !defined(isnan)
#include <float.h> #include <float.h>
#define isnan _isnan #define isnan _isnan
#endif #endif
#if !defined(isfinite) #if !defined(isfinite)
#include <float.h> #include <float.h>
#define isfinite _finite #define isfinite _finite
#endif #endif
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#if !defined(snprintf) #if !defined(snprintf)
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
#endif #endif
#if defined(__sun) && defined(__SVR4) //Solaris #if defined(__sun) && defined(__SVR4) // Solaris
#if !defined(isfinite) #if !defined(isfinite)
#include <ieeefp.h> #include <ieeefp.h>
#define isfinite finite #define isfinite finite
#endif #endif
#endif #endif
#if defined(__hpux) #if defined(__hpux)
#if !defined(isfinite) #if !defined(isfinite)
#if defined(__ia64) && !defined(finite) #if defined(__ia64) && !defined(finite)
#define isfinite(x) ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) #define isfinite(x) \
#endif ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x)))
#endif #endif
#endif #endif
#endif
#if !defined(isnan) #if !defined(isnan)
// IEEE standard states that NaN values will not compare to themselves // IEEE standard states that NaN values will not compare to themselves
#define isnan(x) (x!=x) #define isnan(x) (x != x)
#endif #endif
#if !defined(isfinite) #if !defined(isfinite)
#define isfinite finite #define isfinite finite
#endif #endif
#endif #endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
@ -126,20 +127,24 @@ JSONCPP_STRING valueToString(UInt value) {
#endif // # if defined(JSON_HAS_INT64) #endif // # if defined(JSON_HAS_INT64)
namespace { namespace {
JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) { JSONCPP_STRING valueToString(double value,
bool useSpecialFloats,
unsigned int precision,
PrecisionType precisionType) {
// Print into the buffer. We need not request the alternative representation // Print into the buffer. We need not request the alternative representation
// that always has a decimal point because JSON doesn't distinguish the // that always has a decimal point because JSON doesn't distinguish the
// concepts of reals and integers. // concepts of reals and integers.
if (!isfinite(value)) { if (!isfinite(value)) {
static const char* const reps[2][3] = { static const char* const reps[2][3] = { { "NaN", "-Infinity", "Infinity" },
{"NaN", "-Infinity", "Infinity"}, { "null", "-1e+9999", "1e+9999" } };
{"null", "-1e+9999", "1e+9999"}}; return reps[useSpecialFloats ? 0 : 1]
return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2]; [isnan(value) ? 0 : (value < 0) ? 1 : 2];
} }
JSONCPP_STRING buffer(size_t(36), '\0'); JSONCPP_STRING buffer(size_t(36), '\0');
while (true) { while (true) {
int len = snprintf(&*buffer.begin(), buffer.size(), int len = snprintf(
&*buffer.begin(), buffer.size(),
(precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
precision, value); precision, value);
assert(len >= 0); assert(len >= 0);
@ -159,7 +164,8 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
} }
// try to ensure we preserve the fact that this was given to us as a double on input // try to ensure we preserve the fact that this was given to us as a double on
// input
if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
buffer += ".0"; buffer += ".0";
} }
@ -167,7 +173,9 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
} }
} // namespace } // namespace
JSONCPP_STRING valueToString(double value, unsigned int precision, PrecisionType precisionType) { JSONCPP_STRING valueToString(double value,
unsigned int precision,
PrecisionType precisionType) {
return valueToString(value, false, precision, precisionType); return valueToString(value, false, precision, precisionType);
} }
@ -178,8 +186,8 @@ static bool isAnyCharRequiredQuoting(char const* s, size_t n) {
char const* const end = s + n; char const* const end = s + n;
for (char const* cur = s; cur < end; ++cur) { for (char const* cur = s; cur < end; ++cur) {
if (*cur == '\\' || *cur == '\"' || *cur < ' ' if (*cur == '\\' || *cur == '\"' || *cur < ' ' ||
|| static_cast<unsigned char>(*cur) < 0x80) static_cast<unsigned char>(*cur) < 0x80)
return true; return true;
} }
return false; return false;
@ -197,8 +205,8 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
if (e - s < 2) if (e - s < 2)
return REPLACEMENT_CHARACTER; return REPLACEMENT_CHARACTER;
unsigned int calculated = ((firstByte & 0x1F) << 6) unsigned int calculated =
| (static_cast<unsigned int>(s[1]) & 0x3F); ((firstByte & 0x1F) << 6) | (static_cast<unsigned int>(s[1]) & 0x3F);
s += 1; s += 1;
// oversized encoded characters are invalid // oversized encoded characters are invalid
return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated; return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
@ -208,9 +216,9 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
if (e - s < 3) if (e - s < 3)
return REPLACEMENT_CHARACTER; return REPLACEMENT_CHARACTER;
unsigned int calculated = ((firstByte & 0x0F) << 12) unsigned int calculated = ((firstByte & 0x0F) << 12) |
| ((static_cast<unsigned int>(s[1]) & 0x3F) << 6) ((static_cast<unsigned int>(s[1]) & 0x3F) << 6) |
| (static_cast<unsigned int>(s[2]) & 0x3F); (static_cast<unsigned int>(s[2]) & 0x3F);
s += 2; s += 2;
// surrogates aren't valid codepoints itself // surrogates aren't valid codepoints itself
// shouldn't be UTF-8 encoded // shouldn't be UTF-8 encoded
@ -224,10 +232,10 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
if (e - s < 4) if (e - s < 4)
return REPLACEMENT_CHARACTER; return REPLACEMENT_CHARACTER;
unsigned int calculated = ((firstByte & 0x07) << 18) unsigned int calculated = ((firstByte & 0x07) << 18) |
| ((static_cast<unsigned int>(s[1]) & 0x3F) << 12) ((static_cast<unsigned int>(s[1]) & 0x3F) << 12) |
| ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) |
| (static_cast<unsigned int>(s[3]) & 0x3F); (static_cast<unsigned int>(s[3]) & 0x3F);
s += 3; s += 3;
// oversized encoded characters are invalid // oversized encoded characters are invalid
return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated; return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
@ -236,8 +244,7 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
return REPLACEMENT_CHARACTER; return REPLACEMENT_CHARACTER;
} }
static const char hex2[] = static const char hex2[] = "000102030405060708090a0b0c0d0e0f"
"000102030405060708090a0b0c0d0e0f"
"101112131415161718191a1b1c1d1e1f" "101112131415161718191a1b1c1d1e1f"
"202122232425262728292a2b2c2d2e2f" "202122232425262728292a2b2c2d2e2f"
"303132333435363738393a3b3c3d3e3f" "303132333435363738393a3b3c3d3e3f"
@ -274,8 +281,7 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
// We have to walk value and escape any special characters. // We have to walk value and escape any special characters.
// Appending to JSONCPP_STRING is not efficient, but this should be rare. // Appending to JSONCPP_STRING is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.) // (Note: forward slashes are *not* rare, but I am not escaping them.)
JSONCPP_STRING::size_type maxsize = JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL
length * 2 + 3; // allescaped+quotes+NULL
JSONCPP_STRING result; JSONCPP_STRING result;
result.reserve(maxsize); // to avoid lots of mallocs result.reserve(maxsize); // to avoid lots of mallocs
result += "\""; result += "\"";
@ -320,8 +326,7 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
result += "\\u"; result += "\\u";
result += toHex16Bit(cp); result += toHex16Bit(cp);
} } else { // codepoint is not in Basic Multilingual Plane
else { // codepoint is not in Basic Multilingual Plane
// convert to surrogate pair first // convert to surrogate pair first
cp -= 0x10000; cp -= 0x10000;
result += "\\u"; result += "\\u";
@ -329,8 +334,7 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
result += "\\u"; result += "\\u";
result += toHex16Bit((cp & 0x3FF) + 0xDC00); result += toHex16Bit((cp & 0x3FF) + 0xDC00);
} }
} } break;
break;
} }
} }
result += "\""; result += "\"";
@ -381,13 +385,13 @@ void FastWriter::writeValue(const Value& value) {
case realValue: case realValue:
document_ += valueToString(value.asDouble()); document_ += valueToString(value.asDouble());
break; break;
case stringValue: case stringValue: {
{
// Is NULL possible for value.string_? No. // Is NULL possible for value.string_? No.
char const* str; char const* str;
char const* end; char const* end;
bool ok = value.getString(&str, &end); bool ok = value.getString(&str, &end);
if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str)); if (ok)
document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str));
break; break;
} }
case booleanValue: case booleanValue:
@ -411,7 +415,8 @@ void FastWriter::writeValue(const Value& value) {
const JSONCPP_STRING& name = *it; const JSONCPP_STRING& name = *it;
if (it != members.begin()) if (it != members.begin())
document_ += ','; document_ += ',';
document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())); document_ += valueToQuotedStringN(name.data(),
static_cast<unsigned>(name.length()));
document_ += yamlCompatibilityEnabled_ ? ": " : ":"; document_ += yamlCompatibilityEnabled_ ? ": " : ":";
writeValue(value[name]); writeValue(value[name]);
} }
@ -451,14 +456,15 @@ void StyledWriter::writeValue(const Value& value) {
case realValue: case realValue:
pushValue(valueToString(value.asDouble())); pushValue(valueToString(value.asDouble()));
break; break;
case stringValue: case stringValue: {
{
// Is NULL possible for value.string_? No. // Is NULL possible for value.string_? No.
char const* str; char const* str;
char const* end; char const* end;
bool ok = value.getString(&str, &end); bool ok = value.getString(&str, &end);
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); if (ok)
else pushValue(""); pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
else
pushValue("");
break; break;
} }
case booleanValue: case booleanValue:
@ -589,7 +595,9 @@ void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) {
document_ += value; document_ += value;
} }
void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); } void StyledWriter::indent() {
indentString_ += JSONCPP_STRING(indentSize_, ' ');
}
void StyledWriter::unindent() { void StyledWriter::unindent() {
assert(indentString_.size() >= indentSize_); assert(indentString_.size() >= indentSize_);
@ -606,8 +614,7 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) {
JSONCPP_STRING::const_iterator iter = comment.begin(); JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) { while (iter != comment.end()) {
document_ += *iter; document_ += *iter;
if (*iter == '\n' && if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
((iter+1) != comment.end() && *(iter + 1) == '/'))
writeIndent(); writeIndent();
++iter; ++iter;
} }
@ -638,8 +645,7 @@ bool StyledWriter::hasCommentForValue(const Value& value) {
StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
: document_(NULL), rightMargin_(74), indentation_(indentation), : document_(NULL), rightMargin_(74), indentation_(indentation),
addChildValues_(), indented_(false) addChildValues_(), indented_(false) {}
{}
void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
document_ = &out; document_ = &out;
@ -647,7 +653,8 @@ void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
indentString_.clear(); indentString_.clear();
indented_ = true; indented_ = true;
writeCommentBeforeValue(root); writeCommentBeforeValue(root);
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
indented_ = true; indented_ = true;
writeValue(root); writeValue(root);
writeCommentAfterValueOnSameLine(root); writeCommentAfterValueOnSameLine(root);
@ -669,14 +676,15 @@ void StyledStreamWriter::writeValue(const Value& value) {
case realValue: case realValue:
pushValue(valueToString(value.asDouble())); pushValue(valueToString(value.asDouble()));
break; break;
case stringValue: case stringValue: {
{
// Is NULL possible for value.string_? No. // Is NULL possible for value.string_? No.
char const* str; char const* str;
char const* end; char const* end;
bool ok = value.getString(&str, &end); bool ok = value.getString(&str, &end);
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); if (ok)
else pushValue(""); pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
else
pushValue("");
break; break;
} }
case booleanValue: case booleanValue:
@ -731,7 +739,8 @@ void StyledStreamWriter::writeArrayValue(const Value& value) {
if (hasChildValue) if (hasChildValue)
writeWithIndent(childValues_[index]); writeWithIndent(childValues_[index]);
else { else {
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
indented_ = true; indented_ = true;
writeValue(childValue); writeValue(childValue);
indented_ = false; indented_ = false;
@ -802,7 +811,8 @@ void StyledStreamWriter::writeIndent() {
} }
void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) { void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) {
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
*document_ << value; *document_ << value;
indented_ = false; indented_ = false;
} }
@ -818,13 +828,13 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
if (!root.hasComment(commentBefore)) if (!root.hasComment(commentBefore))
return; return;
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
const JSONCPP_STRING& comment = root.getComment(commentBefore); const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin(); JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) { while (iter != comment.end()) {
*document_ << *iter; *document_ << *iter;
if (*iter == '\n' && if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
((iter+1) != comment.end() && *(iter + 1) == '/'))
// writeIndent(); // would include newline // writeIndent(); // would include newline
*document_ << indentString_; *document_ << indentString_;
++iter; ++iter;
@ -862,10 +872,8 @@ struct CommentStyle {
}; };
}; };
struct BuiltStyledStreamWriter : public StreamWriter struct BuiltStyledStreamWriter : public StreamWriter {
{ BuiltStyledStreamWriter(JSONCPP_STRING const& indentation,
BuiltStyledStreamWriter(
JSONCPP_STRING const& indentation,
CommentStyle::Enum cs, CommentStyle::Enum cs,
JSONCPP_STRING const& colonSymbol, JSONCPP_STRING const& colonSymbol,
JSONCPP_STRING const& nullSymbol, JSONCPP_STRING const& nullSymbol,
@ -874,6 +882,7 @@ struct BuiltStyledStreamWriter : public StreamWriter
unsigned int precision, unsigned int precision,
PrecisionType precisionType); PrecisionType precisionType);
int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE; int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
private: private:
void writeValue(Value const& value); void writeValue(Value const& value);
void writeArrayValue(Value const& value); void writeArrayValue(Value const& value);
@ -912,27 +921,19 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
bool useSpecialFloats, bool useSpecialFloats,
unsigned int precision, unsigned int precision,
PrecisionType precisionType) PrecisionType precisionType)
: rightMargin_(74) : rightMargin_(74), indentation_(indentation), cs_(cs),
, indentation_(indentation) colonSymbol_(colonSymbol), nullSymbol_(nullSymbol),
, cs_(cs) endingLineFeedSymbol_(endingLineFeedSymbol), addChildValues_(false),
, colonSymbol_(colonSymbol) indented_(false), useSpecialFloats_(useSpecialFloats),
, nullSymbol_(nullSymbol) precision_(precision), precisionType_(precisionType) {}
, endingLineFeedSymbol_(endingLineFeedSymbol) int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) {
, addChildValues_(false)
, indented_(false)
, useSpecialFloats_(useSpecialFloats)
, precision_(precision)
, precisionType_(precisionType)
{
}
int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
{
sout_ = sout; sout_ = sout;
addChildValues_ = false; addChildValues_ = false;
indented_ = true; indented_ = true;
indentString_.clear(); indentString_.clear();
writeCommentBeforeValue(root); writeCommentBeforeValue(root);
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
indented_ = true; indented_ = true;
writeValue(root); writeValue(root);
writeCommentAfterValueOnSameLine(root); writeCommentAfterValueOnSameLine(root);
@ -952,16 +953,18 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
pushValue(valueToString(value.asLargestUInt())); pushValue(valueToString(value.asLargestUInt()));
break; break;
case realValue: case realValue:
pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_, precisionType_)); pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_,
precisionType_));
break; break;
case stringValue: case stringValue: {
{
// Is NULL is possible for value.string_? No. // Is NULL is possible for value.string_? No.
char const* str; char const* str;
char const* end; char const* end;
bool ok = value.getString(&str, &end); bool ok = value.getString(&str, &end);
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); if (ok)
else pushValue(""); pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
else
pushValue("");
break; break;
} }
case booleanValue: case booleanValue:
@ -982,7 +985,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
JSONCPP_STRING const& name = *it; JSONCPP_STRING const& name = *it;
Value const& childValue = value[name]; Value const& childValue = value[name];
writeCommentBeforeValue(childValue); writeCommentBeforeValue(childValue);
writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()))); writeWithIndent(valueToQuotedStringN(
name.data(), static_cast<unsigned>(name.length())));
*sout_ << colonSymbol_; *sout_ << colonSymbol_;
writeValue(childValue); writeValue(childValue);
if (++it == members.end()) { if (++it == members.end()) {
@ -1016,7 +1020,8 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
if (hasChildValue) if (hasChildValue)
writeWithIndent(childValues_[index]); writeWithIndent(childValues_[index]);
else { else {
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
indented_ = true; indented_ = true;
writeValue(childValue); writeValue(childValue);
indented_ = false; indented_ = false;
@ -1034,13 +1039,15 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
{ {
assert(childValues_.size() == size); assert(childValues_.size() == size);
*sout_ << "["; *sout_ << "[";
if (!indentation_.empty()) *sout_ << " "; if (!indentation_.empty())
*sout_ << " ";
for (unsigned index = 0; index < size; ++index) { for (unsigned index = 0; index < size; ++index) {
if (index > 0) if (index > 0)
*sout_ << ((!indentation_.empty()) ? ", " : ","); *sout_ << ((!indentation_.empty()) ? ", " : ",");
*sout_ << childValues_[index]; *sout_ << childValues_[index];
} }
if (!indentation_.empty()) *sout_ << " "; if (!indentation_.empty())
*sout_ << " ";
*sout_ << "]"; *sout_ << "]";
} }
} }
@ -1093,7 +1100,8 @@ void BuiltStyledStreamWriter::writeIndent() {
} }
void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) { void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) {
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
*sout_ << value; *sout_ << value;
indented_ = false; indented_ = false;
} }
@ -1106,17 +1114,18 @@ void BuiltStyledStreamWriter::unindent() {
} }
void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
if (cs_ == CommentStyle::None) return; if (cs_ == CommentStyle::None)
return;
if (!root.hasComment(commentBefore)) if (!root.hasComment(commentBefore))
return; return;
if (!indented_) writeIndent(); if (!indented_)
writeIndent();
const JSONCPP_STRING& comment = root.getComment(commentBefore); const JSONCPP_STRING& comment = root.getComment(commentBefore);
JSONCPP_STRING::const_iterator iter = comment.begin(); JSONCPP_STRING::const_iterator iter = comment.begin();
while (iter != comment.end()) { while (iter != comment.end()) {
*sout_ << *iter; *sout_ << *iter;
if (*iter == '\n' && if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
((iter+1) != comment.end() && *(iter + 1) == '/'))
// writeIndent(); // would write extra newline // writeIndent(); // would write extra newline
*sout_ << indentString_; *sout_ << indentString_;
++iter; ++iter;
@ -1124,8 +1133,10 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
indented_ = false; indented_ = false;
} }
void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) { void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
if (cs_ == CommentStyle::None) return; Value const& root) {
if (cs_ == CommentStyle::None)
return;
if (root.hasComment(commentAfterOnSameLine)) if (root.hasComment(commentAfterOnSameLine))
*sout_ << " " + root.getComment(commentAfterOnSameLine); *sout_ << " " + root.getComment(commentAfterOnSameLine);
@ -1145,23 +1156,12 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
/////////////// ///////////////
// StreamWriter // StreamWriter
StreamWriter::StreamWriter() StreamWriter::StreamWriter() : sout_(NULL) {}
: sout_(NULL) StreamWriter::~StreamWriter() {}
{ StreamWriter::Factory::~Factory() {}
} StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); }
StreamWriter::~StreamWriter() StreamWriterBuilder::~StreamWriterBuilder() {}
{ StreamWriter* StreamWriterBuilder::newStreamWriter() const {
}
StreamWriter::Factory::~Factory()
{}
StreamWriterBuilder::StreamWriterBuilder()
{
setDefaults(&settings_);
}
StreamWriterBuilder::~StreamWriterBuilder()
{}
StreamWriter* StreamWriterBuilder::newStreamWriter() const
{
JSONCPP_STRING indentation = settings_["indentation"].asString(); JSONCPP_STRING indentation = settings_["indentation"].asString();
JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); JSONCPP_STRING cs_str = settings_["commentStyle"].asString();
JSONCPP_STRING pt_str = settings_["precisionType"].asString(); JSONCPP_STRING pt_str = settings_["precisionType"].asString();
@ -1195,14 +1195,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
if (dnp) { if (dnp) {
nullSymbol.clear(); nullSymbol.clear();
} }
if (pre > 17) pre = 17; if (pre > 17)
pre = 17;
JSONCPP_STRING endingLineFeedSymbol; JSONCPP_STRING endingLineFeedSymbol;
return new BuiltStyledStreamWriter( return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol,
indentation, cs, endingLineFeedSymbol, usf, pre,
colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre, precisionType); precisionType);
} }
static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys) static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys) {
{
valid_keys->clear(); valid_keys->clear();
valid_keys->insert("indentation"); valid_keys->insert("indentation");
valid_keys->insert("commentStyle"); valid_keys->insert("commentStyle");
@ -1212,10 +1212,10 @@ static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
valid_keys->insert("precision"); valid_keys->insert("precision");
valid_keys->insert("precisionType"); valid_keys->insert("precisionType");
} }
bool StreamWriterBuilder::validate(Json::Value* invalid) const bool StreamWriterBuilder::validate(Json::Value* invalid) const {
{
Json::Value my_invalid; Json::Value my_invalid;
if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL if (!invalid)
invalid = &my_invalid; // so we do not need to test for NULL
Json::Value& inv = *invalid; Json::Value& inv = *invalid;
std::set<JSONCPP_STRING> valid_keys; std::set<JSONCPP_STRING> valid_keys;
getValidWriterKeys(&valid_keys); getValidWriterKeys(&valid_keys);
@ -1229,13 +1229,11 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const
} }
return 0u == inv.size(); return 0u == inv.size();
} }
Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) {
{
return settings_[key]; return settings_[key];
} }
// static // static
void StreamWriterBuilder::setDefaults(Json::Value* settings) void StreamWriterBuilder::setDefaults(Json::Value* settings) {
{
//! [StreamWriterBuilderDefaults] //! [StreamWriterBuilderDefaults]
(*settings)["commentStyle"] = "All"; (*settings)["commentStyle"] = "All";
(*settings)["indentation"] = "\t"; (*settings)["indentation"] = "\t";
@ -1247,7 +1245,8 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
//! [StreamWriterBuilderDefaults] //! [StreamWriterBuilderDefaults]
} }
JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) { JSONCPP_STRING writeString(StreamWriter::Factory const& builder,
Value const& root) {
JSONCPP_OSTRINGSTREAM sout; JSONCPP_OSTRINGSTREAM sout;
StreamWriterPtr const writer(builder.newStreamWriter()); StreamWriterPtr const writer(builder.newStreamWriter());
writer->write(root, &sout); writer->write(root, &sout);

View File

@ -93,8 +93,8 @@ TestResult::addFailure(const char* file, unsigned int line, const char* expr) {
if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext
{ {
lastUsedPredicateId_ = lastNode->id_; lastUsedPredicateId_ = lastNode->id_;
addFailureInfo( addFailureInfo(lastNode->file_, lastNode->line_, lastNode->expr_,
lastNode->file_, lastNode->line_, lastNode->expr_, nestingLevel); nestingLevel);
// Link the PredicateContext to the failure for message target when // Link the PredicateContext to the failure for message target when
// popping the PredicateContext. // popping the PredicateContext.
lastNode->failure_ = &(failures_.back()); lastNode->failure_ = &(failures_.back());
@ -257,8 +257,7 @@ void Runner::runTestAt(unsigned int index, TestResult& result) const {
#endif // if JSON_USE_EXCEPTION #endif // if JSON_USE_EXCEPTION
test->run(result); test->run(result);
#if JSON_USE_EXCEPTION #if JSON_USE_EXCEPTION
} } catch (const std::exception& e) {
catch (const std::exception& e) {
result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:") result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:")
<< e.what(); << e.what();
} }
@ -294,9 +293,7 @@ bool Runner::runAllTest(bool printSummary) const {
if (printSummary) { if (printSummary) {
unsigned int failedCount = static_cast<unsigned int>(failures.size()); unsigned int failedCount = static_cast<unsigned int>(failures.size());
unsigned int passedCount = count - failedCount; unsigned int passedCount = count - failedCount;
printf("%d/%d tests passed (%d failure(s))\n", printf("%d/%d tests passed (%d failure(s))\n", passedCount, count,
passedCount,
count,
failedCount); failedCount);
} }
return false; return false;
@ -398,8 +395,8 @@ void Runner::preventDialogOnCrash() {
_CrtSetReportHook(&msvcrtSilentReportHook); _CrtSetReportHook(&msvcrtSilentReportHook);
#endif // if defined(_MSC_VER) #endif // if defined(_MSC_VER)
// @todo investigate this handler (for buffer overflow) // @todo investigate this handler (for buffer overflow)
// _set_security_error_handler // _set_security_error_handler
#if defined(_WIN32) #if defined(_WIN32)
// Prevents the system from popping a dialog for debugging if the // Prevents the system from popping a dialog for debugging if the
@ -430,9 +427,7 @@ JSONCPP_STRING ToJsonString(const char* toConvert) {
return JSONCPP_STRING(toConvert); return JSONCPP_STRING(toConvert);
} }
JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { return in; }
return in;
}
#if JSONCPP_USING_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
JSONCPP_STRING ToJsonString(std::string in) { JSONCPP_STRING ToJsonString(std::string in) {

View File

@ -6,12 +6,12 @@
#ifndef JSONTEST_H_INCLUDED #ifndef JSONTEST_H_INCLUDED
#define JSONTEST_H_INCLUDED #define JSONTEST_H_INCLUDED
#include <deque>
#include <json/config.h> #include <json/config.h>
#include <json/value.h> #include <json/value.h>
#include <json/writer.h> #include <json/writer.h>
#include <stdio.h>
#include <deque>
#include <sstream> #include <sstream>
#include <stdio.h>
#include <string> #include <string>
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
@ -231,21 +231,14 @@ TestResult& checkStringEqual(TestResult& result,
/// \brief Asserts that two values are equals. /// \brief Asserts that two values are equals.
#define JSONTEST_ASSERT_EQUAL(expected, actual) \ #define JSONTEST_ASSERT_EQUAL(expected, actual) \
JsonTest::checkEqual(*result_, \ JsonTest::checkEqual(*result_, expected, actual, __FILE__, __LINE__, \
expected, \
actual, \
__FILE__, \
__LINE__, \
#expected " == " #actual) #expected " == " #actual)
/// \brief Asserts that two values are equals. /// \brief Asserts that two values are equals.
#define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \ #define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \
JsonTest::checkStringEqual(*result_, \ JsonTest::checkStringEqual(*result_, JsonTest::ToJsonString(expected), \
JsonTest::ToJsonString(expected), \ JsonTest::ToJsonString(actual), __FILE__, \
JsonTest::ToJsonString(actual), \ __LINE__, #expected " == " #actual)
__FILE__, \
__LINE__, \
#expected " == " #actual)
/// \brief Asserts that a given expression throws an exception /// \brief Asserts that a given expression throws an exception
#define JSONTEST_ASSERT_THROWS(expr) \ #define JSONTEST_ASSERT_THROWS(expr) \
@ -253,13 +246,12 @@ TestResult& checkStringEqual(TestResult& result,
bool _threw = false; \ bool _threw = false; \
try { \ try { \
expr; \ expr; \
} \ } catch (...) { \
catch (...) { \
_threw = true; \ _threw = true; \
} \ } \
if (!_threw) \ if (!_threw) \
result_->addFailure( \ result_->addFailure(__FILE__, __LINE__, \
__FILE__, __LINE__, "expected exception thrown: " #expr); \ "expected exception thrown: " #expr); \
} }
/// \brief Begin a fixture test case. /// \brief Begin a fixture test case.
@ -271,7 +263,9 @@ TestResult& checkStringEqual(TestResult& result,
} \ } \
\ \
public: /* overridden from TestCase */ \ public: /* overridden from TestCase */ \
const char* testName() const JSONCPP_OVERRIDE { return #FixtureType "/" #name; } \ const char* testName() const JSONCPP_OVERRIDE { \
return #FixtureType "/" #name; \
} \
void runTestCase() JSONCPP_OVERRIDE; \ void runTestCase() JSONCPP_OVERRIDE; \
}; \ }; \
\ \

View File

@ -11,14 +11,14 @@
#endif #endif
#include "jsontest.h" #include "jsontest.h"
#include <cmath>
#include <cstring>
#include <iomanip>
#include <json/config.h> #include <json/config.h>
#include <json/json.h> #include <json/json.h>
#include <cstring>
#include <limits> #include <limits>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <iomanip>
#include <cmath>
// Make numeric limits more convenient to talk about. // Make numeric limits more convenient to talk about.
// Assumes int type in 32 bits. // Assumes int type in 32 bits.
@ -29,8 +29,8 @@
#define kint64min Json::Value::minInt64 #define kint64min Json::Value::minInt64
#define kuint64max Json::Value::maxUInt64 #define kuint64max Json::Value::maxUInt64
//static const double kdint64max = double(kint64max); // static const double kdint64max = double(kint64max);
//static const float kfint64max = float(kint64max); // static const float kfint64max = float(kint64max);
static const float kfint32max = float(kint32max); static const float kfint32max = float(kint32max);
static const float kfuint32max = float(kuint32max); static const float kfuint32max = float(kuint32max);
@ -123,8 +123,8 @@ JSONCPP_STRING ValueTest::normalizeFloatingPointStr(const JSONCPP_STRING& s) {
JSONCPP_STRING::size_type indexDigit = JSONCPP_STRING::size_type indexDigit =
s.find_first_not_of('0', exponentStartIndex); s.find_first_not_of('0', exponentStartIndex);
JSONCPP_STRING exponent = "0"; JSONCPP_STRING exponent = "0";
if (indexDigit != if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different
JSONCPP_STRING::npos) // There is an exponent different from 0 // from 0
{ {
exponent = s.substr(indexDigit); exponent = s.substr(indexDigit);
} }
@ -269,19 +269,17 @@ JSONTEST_FIXTURE(ValueTest, arrays) {
JSONTEST_ASSERT_EQUAL(Json::Value(17), got); JSONTEST_ASSERT_EQUAL(Json::Value(17), got);
JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now
} }
JSONTEST_FIXTURE(ValueTest, arrayIssue252) JSONTEST_FIXTURE(ValueTest, arrayIssue252) {
{
int count = 5; int count = 5;
Json::Value root; Json::Value root;
Json::Value item; Json::Value item;
root["array"] = Json::Value::nullRef; root["array"] = Json::Value::nullRef;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++) {
{
item["a"] = i; item["a"] = i;
item["b"] = i; item["b"] = i;
root["array"][i] = item; root["array"][i] = item;
} }
//JSONTEST_ASSERT_EQUAL(5, root["array"].size()); // JSONTEST_ASSERT_EQUAL(5, root["array"].size());
} }
JSONTEST_FIXTURE(ValueTest, null) { JSONTEST_FIXTURE(ValueTest, null) {
@ -311,10 +309,10 @@ JSONTEST_FIXTURE(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(Json::Value::null, null_); JSONTEST_ASSERT_EQUAL(Json::Value::null, null_);
// Test using a Value in a boolean context (false iff null) // Test using a Value in a boolean context (false iff null)
JSONTEST_ASSERT_EQUAL(null_,false); JSONTEST_ASSERT_EQUAL(null_, false);
JSONTEST_ASSERT_EQUAL(object1_,true); JSONTEST_ASSERT_EQUAL(object1_, true);
JSONTEST_ASSERT_EQUAL(!null_,true); JSONTEST_ASSERT_EQUAL(!null_, true);
JSONTEST_ASSERT_EQUAL(!object1_,false); JSONTEST_ASSERT_EQUAL(!object1_, false);
} }
JSONTEST_FIXTURE(ValueTest, strings) { JSONTEST_FIXTURE(ValueTest, strings) {
@ -660,7 +658,8 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble()); JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat()); JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1048576.0", JSONTEST_ASSERT_STRING_EQUAL(
"1048576.0",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// -2^20 // -2^20
@ -901,7 +900,8 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asDouble()); JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asDouble());
JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat()); JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1099511627776.0", JSONTEST_ASSERT_STRING_EQUAL(
"1099511627776.0",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// -2^40 // -2^40
@ -976,7 +976,8 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(float(Json::UInt64(1) << 63), val.asFloat()); JSONTEST_ASSERT_EQUAL(float(Json::UInt64(1) << 63), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("9.2233720368547758e+18", JSONTEST_ASSERT_STRING_EQUAL(
"9.2233720368547758e+18",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// int64 min // int64 min
@ -1024,7 +1025,8 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asDouble()); JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-9.2233720368547758e+18", JSONTEST_ASSERT_STRING_EQUAL(
"-9.2233720368547758e+18",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// 10^19 // 10^19
@ -1071,7 +1073,8 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(1e19, val.asDouble()); JSONTEST_ASSERT_EQUAL(1e19, val.asDouble());
JSONTEST_ASSERT_EQUAL(1e19, val.asFloat()); JSONTEST_ASSERT_EQUAL(1e19, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1e+19", JSONTEST_ASSERT_STRING_EQUAL(
"1e+19",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// uint64 max // uint64 max
@ -1115,7 +1118,8 @@ JSONTEST_FIXTURE(ValueTest, integers) {
JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asDouble()); JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1.8446744073709552e+19", JSONTEST_ASSERT_STRING_EQUAL(
"1.8446744073709552e+19",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
#endif #endif
} }
@ -1205,7 +1209,8 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) {
JSONTEST_ASSERT_EQUAL(2147483647U, val.asLargestUInt()); JSONTEST_ASSERT_EQUAL(2147483647U, val.asLargestUInt());
#endif #endif
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("2147483647.5", JSONTEST_ASSERT_EQUAL(
"2147483647.5",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A bit under int32 min // A bit under int32 min
@ -1233,7 +1238,8 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) {
JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 31), val.asLargestInt()); JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 31), val.asLargestInt());
#endif #endif
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("-2147483648.5", JSONTEST_ASSERT_EQUAL(
"-2147483648.5",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A bit over uint32 max // A bit over uint32 max
@ -1263,29 +1269,34 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) {
val.asLargestUInt()); val.asLargestUInt());
#endif #endif
JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("4294967295.5", JSONTEST_ASSERT_EQUAL(
"4294967295.5",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
val = Json::Value(1.2345678901234); val = Json::Value(1.2345678901234);
JSONTEST_ASSERT_STRING_EQUAL("1.2345678901234001", JSONTEST_ASSERT_STRING_EQUAL(
"1.2345678901234001",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A 16-digit floating point number. // A 16-digit floating point number.
val = Json::Value(2199023255552000.0f); val = Json::Value(2199023255552000.0f);
JSONTEST_ASSERT_EQUAL(float(2199023255552000.0f), val.asFloat()); JSONTEST_ASSERT_EQUAL(float(2199023255552000.0f), val.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("2199023255552000.0", JSONTEST_ASSERT_STRING_EQUAL(
"2199023255552000.0",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// A very large floating point number. // A very large floating point number.
val = Json::Value(3.402823466385289e38); val = Json::Value(3.402823466385289e38);
JSONTEST_ASSERT_EQUAL(float(3.402823466385289e38), val.asFloat()); JSONTEST_ASSERT_EQUAL(float(3.402823466385289e38), val.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("3.402823466385289e+38", JSONTEST_ASSERT_STRING_EQUAL(
"3.402823466385289e+38",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
// An even larger floating point number. // An even larger floating point number.
val = Json::Value(1.2345678e300); val = Json::Value(1.2345678e300);
JSONTEST_ASSERT_EQUAL(double(1.2345678e300), val.asDouble()); JSONTEST_ASSERT_EQUAL(double(1.2345678e300), val.asDouble());
JSONTEST_ASSERT_STRING_EQUAL("1.2345678e+300", JSONTEST_ASSERT_STRING_EQUAL(
"1.2345678e+300",
normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString())));
} }
@ -1608,7 +1619,8 @@ JSONTEST_FIXTURE(ValueTest, StaticString) {
JSONTEST_FIXTURE(ValueTest, CommentBefore) { JSONTEST_FIXTURE(ValueTest, CommentBefore) {
Json::Value val; // fill val Json::Value val; // fill val
val.setComment(JSONCPP_STRING("// this comment should appear before"), Json::commentBefore); val.setComment(JSONCPP_STRING("// this comment should appear before"),
Json::commentBefore);
Json::StreamWriterBuilder wbuilder; Json::StreamWriterBuilder wbuilder;
wbuilder.settings_["commentStyle"] = "All"; wbuilder.settings_["commentStyle"] = "All";
{ {
@ -1635,8 +1647,8 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) {
JSONTEST_ASSERT_STRING_EQUAL("null\n", other.toStyledString()); JSONTEST_ASSERT_STRING_EQUAL("null\n", other.toStyledString());
} }
val = "hello"; val = "hello";
// val.setComment("// this comment should appear before", Json::CommentPlacement::commentBefore); // val.setComment("// this comment should appear before",
// Assignment over-writes comments. // Json::CommentPlacement::commentBefore); Assignment over-writes comments.
{ {
char const expected[] = "\"hello\""; char const expected[] = "\"hello\"";
JSONCPP_STRING result = Json::writeString(wbuilder, val); JSONCPP_STRING result = Json::writeString(wbuilder, val);
@ -1666,12 +1678,10 @@ JSONTEST_FIXTURE(ValueTest, zeroes) {
JSONTEST_ASSERT_STRING_EQUAL(binary, root[top].asString()); JSONTEST_ASSERT_STRING_EQUAL(binary, root[top].asString());
Json::Value removed; Json::Value removed;
bool did; bool did;
did = root.removeMember(top, top + sizeof(top) - 1U, did = root.removeMember(top, top + sizeof(top) - 1U, &removed);
&removed);
JSONTEST_ASSERT(did); JSONTEST_ASSERT(did);
JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString());
did = root.removeMember(top, top + sizeof(top) - 1U, did = root.removeMember(top, top + sizeof(top) - 1U, &removed);
&removed);
JSONTEST_ASSERT(!did); JSONTEST_ASSERT(!did);
JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); // still JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); // still
} }
@ -1687,7 +1697,8 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) {
JSONTEST_ASSERT_STRING_EQUAL("there", root[binary].asString()); JSONTEST_ASSERT_STRING_EQUAL("there", root[binary].asString());
JSONTEST_ASSERT(!root.isMember("h")); JSONTEST_ASSERT(!root.isMember("h"));
JSONTEST_ASSERT(root.isMember(binary)); JSONTEST_ASSERT(root.isMember(binary));
JSONTEST_ASSERT_STRING_EQUAL("there", root.get(binary, Json::Value::nullRef).asString()); JSONTEST_ASSERT_STRING_EQUAL(
"there", root.get(binary, Json::Value::nullRef).asString());
Json::Value removed; Json::Value removed;
bool did; bool did;
did = root.removeMember(binary.data(), binary.data() + binary.length(), did = root.removeMember(binary.data(), binary.data() + binary.length(),
@ -1699,7 +1710,8 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) {
JSONTEST_ASSERT(!did); JSONTEST_ASSERT(!did);
JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); // still JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); // still
JSONTEST_ASSERT(!root.isMember(binary)); JSONTEST_ASSERT(!root.isMember(binary));
JSONTEST_ASSERT_STRING_EQUAL("", root.get(binary, Json::Value::nullRef).asString()); JSONTEST_ASSERT_STRING_EQUAL(
"", root.get(binary, Json::Value::nullRef).asString());
} }
} }
@ -1727,7 +1739,7 @@ JSONTEST_FIXTURE(ValueTest, precision) {
Json::StreamWriterBuilder b; Json::StreamWriterBuilder b;
b.settings_["precision"] = 5; b.settings_["precision"] = 5;
Json::Value v = 100.0/3; Json::Value v = 100.0 / 3;
JSONCPP_STRING expected = "33.333"; JSONCPP_STRING expected = "33.333";
JSONCPP_STRING result = Json::writeString(b, v); JSONCPP_STRING result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result); JSONTEST_ASSERT_STRING_EQUAL(expected, result);
@ -1924,9 +1936,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) {
JSONCPP_STRING errs; JSONCPP_STRING errs;
Json::Value root; Json::Value root;
char const doc[] = "{ \"property\" : \"value\" }"; char const doc[] = "{ \"property\" : \"value\" }";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs.size() == 0); JSONTEST_ASSERT(errs.size() == 0);
delete reader; delete reader;
@ -1937,13 +1947,10 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : "
"{ \"property\" : [\"value\", \"value2\"], \"obj\" : "
"{ \"nested\" : 123, \"bool\" : true}, \"null\" : " "{ \"nested\" : 123, \"bool\" : true}, \"null\" : "
"null, \"false\" : false }"; "null, \"false\" : false }";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs.size() == 0); JSONTEST_ASSERT(errs.size() == 0);
delete reader; delete reader;
@ -1954,11 +1961,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "{ \"property\" :: \"value\" }";
"{ \"property\" :: \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT(errs == JSONTEST_ASSERT(errs ==
"* Line 1, Column 15\n Syntax error: value, object or array " "* Line 1, Column 15\n Syntax error: value, object or array "
@ -1971,11 +1975,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "{ \"pr佐藤erty\" :: \"value\" }";
"{ \"pr佐藤erty\" :: \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT(errs == JSONTEST_ASSERT(errs ==
"* Line 1, Column 19\n Syntax error: value, object or array " "* Line 1, Column 19\n Syntax error: value, object or array "
@ -1988,11 +1989,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "{ \"property\" : \"v\\alue\" }";
"{ \"property\" : \"v\\alue\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT(errs == JSONTEST_ASSERT(errs ==
"* Line 1, Column 16\n Bad escape sequence in string\nSee " "* Line 1, Column 16\n Bad escape sequence in string\nSee "
@ -2003,15 +2001,12 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) {
JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) {
Json::CharReaderBuilder b; Json::CharReaderBuilder b;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "{ \"property\" : \"value\" }";
"{ \"property\" : \"value\" }";
{ {
b.settings_["stackLimit"] = 2; b.settings_["stackLimit"] = 2;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL("value", root["property"]); JSONTEST_ASSERT_EQUAL("value", root["property"]);
@ -2021,9 +2016,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) {
b.settings_["stackLimit"] = 1; b.settings_["stackLimit"] = 1;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
JSONTEST_ASSERT_THROWS(reader->parse( JSONTEST_ASSERT_THROWS(
doc, doc + std::strlen(doc), reader->parse(doc, doc + std::strlen(doc), &root, &errs));
&root, &errs));
delete reader; delete reader;
} }
} }
@ -2039,12 +2033,9 @@ JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) {
b.strictMode(&b.settings_); b.strictMode(&b.settings_);
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT_STRING_EQUAL( JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 41\n"
"* Line 1, Column 41\n"
" Duplicate key: 'key'\n", " Duplicate key: 'key'\n",
errs); errs);
JSONTEST_ASSERT_EQUAL("val1", root["key"]); // so far JSONTEST_ASSERT_EQUAL("val1", root["key"]); // so far
@ -2057,15 +2048,12 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) {
// This is interpreted as a string value followed by a colon. // This is interpreted as a string value followed by a colon.
Json::CharReaderBuilder b; Json::CharReaderBuilder b;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = " \"property\" : \"value\" }";
" \"property\" : \"value\" }";
{ {
b.settings_["failIfExtra"] = false; b.settings_["failIfExtra"] = false;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL("property", root); JSONTEST_ASSERT_EQUAL("property", root);
@ -2075,9 +2063,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) {
b.settings_["failIfExtra"] = true; b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT_STRING_EQUAL(errs, JSONTEST_ASSERT_STRING_EQUAL(errs,
"* Line 1, Column 13\n" "* Line 1, Column 13\n"
@ -2090,9 +2076,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) {
b.strictMode(&b.settings_); b.strictMode(&b.settings_);
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT_STRING_EQUAL(errs, JSONTEST_ASSERT_STRING_EQUAL(errs,
"* Line 1, Column 13\n" "* Line 1, Column 13\n"
@ -2105,17 +2089,13 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) {
// This is interpreted as an int value followed by a colon. // This is interpreted as an int value followed by a colon.
Json::CharReaderBuilder b; Json::CharReaderBuilder b;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "1:2:3";
"1:2:3";
b.settings_["failIfExtra"] = true; b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(!ok);
JSONTEST_ASSERT_STRING_EQUAL( JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 2\n"
"* Line 1, Column 2\n"
" Extra non-whitespace after JSON value.\n", " Extra non-whitespace after JSON value.\n",
errs); errs);
JSONTEST_ASSERT_EQUAL(1, root.asInt()); JSONTEST_ASSERT_EQUAL(1, root.asInt());
@ -2125,14 +2105,11 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) {
Json::CharReaderBuilder b; Json::CharReaderBuilder b;
Json::Value root; Json::Value root;
{ {
char const doc[] = char const doc[] = "{ \"property\" : \"value\" } //trailing\n//comment\n";
"{ \"property\" : \"value\" } //trailing\n//comment\n";
b.settings_["failIfExtra"] = true; b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL("value", root["property"]); JSONTEST_ASSERT_EQUAL("value", root["property"]);
@ -2142,14 +2119,11 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) {
JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) {
Json::CharReaderBuilder b; Json::CharReaderBuilder b;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = "[ \"property\" , \"value\" ] //trailing\n//comment\n";
"[ \"property\" , \"value\" ] //trailing\n//comment\n";
b.settings_["failIfExtra"] = true; b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL("value", root[1u]); JSONTEST_ASSERT_EQUAL("value", root[1u]);
@ -2158,14 +2132,11 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) {
JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) {
Json::CharReaderBuilder b; Json::CharReaderBuilder b;
Json::Value root; Json::Value root;
char const doc[] = char const doc[] = " true /*trailing\ncomment*/";
" true /*trailing\ncomment*/";
b.settings_["failIfExtra"] = true; b.settings_["failIfExtra"] = true;
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
JSONCPP_STRING errs; JSONCPP_STRING errs;
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(true, root.asBool()); JSONTEST_ASSERT_EQUAL(true, root.asBool());
@ -2181,9 +2152,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
{ {
char const doc[] = "{\"a\":,\"b\":true}"; char const doc[] = "{\"a\":,\"b\":true}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
@ -2191,9 +2160,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
} }
{ {
char const doc[] = "{\"a\":}"; char const doc[] = "{\"a\":}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(1u, root.size()); JSONTEST_ASSERT_EQUAL(1u, root.size());
@ -2201,9 +2168,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
} }
{ {
char const doc[] = "[]"; char const doc[] = "[]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL(0u, root.size()); JSONTEST_ASSERT_EQUAL(0u, root.size());
@ -2211,90 +2176,70 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
} }
{ {
char const doc[] = "[null]"; char const doc[] = "[null]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL(1u, root.size()); JSONTEST_ASSERT_EQUAL(1u, root.size());
} }
{ {
char const doc[] = "[,]"; char const doc[] = "[,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
} }
{ {
char const doc[] = "[,,,]"; char const doc[] = "[,,,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(4u, root.size()); JSONTEST_ASSERT_EQUAL(4u, root.size());
} }
{ {
char const doc[] = "[null,]"; char const doc[] = "[null,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
} }
{ {
char const doc[] = "[,null]"; char const doc[] = "[,null]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
} }
{ {
char const doc[] = "[,,]"; char const doc[] = "[,,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(3u, root.size()); JSONTEST_ASSERT_EQUAL(3u, root.size());
} }
{ {
char const doc[] = "[null,,]"; char const doc[] = "[null,,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(3u, root.size()); JSONTEST_ASSERT_EQUAL(3u, root.size());
} }
{ {
char const doc[] = "[,null,]"; char const doc[] = "[,null,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(3u, root.size()); JSONTEST_ASSERT_EQUAL(3u, root.size());
} }
{ {
char const doc[] = "[,,null]"; char const doc[] = "[,,null]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL(3u, root.size()); JSONTEST_ASSERT_EQUAL(3u, root.size());
} }
{ {
char const doc[] = "[[],,,]"; char const doc[] = "[[],,,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(4u, root.size()); JSONTEST_ASSERT_EQUAL(4u, root.size());
@ -2302,9 +2247,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
} }
{ {
char const doc[] = "[,[],,]"; char const doc[] = "[,[],,]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(4u, root.size()); JSONTEST_ASSERT_EQUAL(4u, root.size());
@ -2312,9 +2255,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
} }
{ {
char const doc[] = "[,,,[]]"; char const doc[] = "[,,,[]]";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT(errs == "");
JSONTEST_ASSERT_EQUAL(4u, root.size()); JSONTEST_ASSERT_EQUAL(4u, root.size());
@ -2333,9 +2274,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
{ {
char const doc[] = "{'a':true,\"b\":true}"; char const doc[] = "{'a':true,\"b\":true}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
@ -2344,9 +2283,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) {
} }
{ {
char const doc[] = "{'a': 'x', \"b\":'y'}"; char const doc[] = "{'a': 'x', \"b\":'y'}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
@ -2366,9 +2303,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
{ {
char const doc[] = "{'a':true,\"b\":true}"; char const doc[] = "{'a':true,\"b\":true}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
@ -2377,9 +2312,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) {
} }
{ {
char const doc[] = "{'a': 'x', \"b\":'y'}"; char const doc[] = "{'a': 'x', \"b\":'y'}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
@ -2399,16 +2332,16 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) {
Json::CharReader* reader(b.newCharReader()); Json::CharReader* reader(b.newCharReader());
{ {
char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}"; char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(3u, root.size()); JSONTEST_ASSERT_EQUAL(3u, root.size());
double n = root["a"].asDouble(); double n = root["a"].asDouble();
JSONTEST_ASSERT(std::isnan(n)); JSONTEST_ASSERT(std::isnan(n));
JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), root.get("b", 0.0)); JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(),
JSONTEST_ASSERT_EQUAL(-std::numeric_limits<double>::infinity(), root.get("c", 0.0)); root.get("b", 0.0));
JSONTEST_ASSERT_EQUAL(-std::numeric_limits<double>::infinity(),
root.get("c", 0.0));
} }
struct TestData { struct TestData {
@ -2417,49 +2350,37 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) {
JSONCPP_STRING in; JSONCPP_STRING in;
}; };
const TestData test_data[] = { const TestData test_data[] = {
{__LINE__, 1, "{\"a\":9}"}, { __LINE__, 1, "{\"a\":9}" }, { __LINE__, 0, "{\"a\":0Infinity}" },
{__LINE__, 0, "{\"a\":0Infinity}"}, { __LINE__, 0, "{\"a\":1Infinity}" }, { __LINE__, 0, "{\"a\":9Infinity}" },
{__LINE__, 0, "{\"a\":1Infinity}"}, { __LINE__, 0, "{\"a\":0nfinity}" }, { __LINE__, 0, "{\"a\":1nfinity}" },
{__LINE__, 0, "{\"a\":9Infinity}"}, { __LINE__, 0, "{\"a\":9nfinity}" }, { __LINE__, 0, "{\"a\":nfinity}" },
{__LINE__, 0, "{\"a\":0nfinity}"}, { __LINE__, 0, "{\"a\":.nfinity}" }, { __LINE__, 0, "{\"a\":9nfinity}" },
{__LINE__, 0, "{\"a\":1nfinity}"}, { __LINE__, 0, "{\"a\":-nfinity}" }, { __LINE__, 1, "{\"a\":Infinity}" },
{__LINE__, 0, "{\"a\":9nfinity}"}, { __LINE__, 0, "{\"a\":.Infinity}" }, { __LINE__, 0, "{\"a\":_Infinity}" },
{__LINE__, 0, "{\"a\":nfinity}"}, { __LINE__, 0, "{\"a\":_nfinity}" }, { __LINE__, 1, "{\"a\":-Infinity}" }
{__LINE__, 0, "{\"a\":.nfinity}"},
{__LINE__, 0, "{\"a\":9nfinity}"},
{__LINE__, 0, "{\"a\":-nfinity}"},
{__LINE__, 1, "{\"a\":Infinity}"},
{__LINE__, 0, "{\"a\":.Infinity}"},
{__LINE__, 0, "{\"a\":_Infinity}"},
{__LINE__, 0, "{\"a\":_nfinity}"},
{__LINE__, 1, "{\"a\":-Infinity}"}
}; };
for (size_t tdi = 0; tdi < sizeof(test_data) / sizeof(*test_data); ++tdi) { for (size_t tdi = 0; tdi < sizeof(test_data) / sizeof(*test_data); ++tdi) {
const TestData& td = test_data[tdi]; const TestData& td = test_data[tdi];
bool ok = reader->parse(&*td.in.begin(), bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(),
&*td.in.begin() + td.in.size(),
&root, &errs); &root, &errs);
JSONTEST_ASSERT(td.ok == ok) JSONTEST_ASSERT(td.ok == ok) << "line:" << td.line << "\n"
<< "line:" << td.line << "\n"
<< " expected: {" << " expected: {"
<< "ok:" << td.ok << "ok:" << td.ok << ", in:\'" << td.in << "\'"
<< ", in:\'" << td.in << "\'"
<< "}\n" << "}\n"
<< " actual: {" << " actual: {"
<< "ok:" << ok << "ok:" << ok << "}\n";
<< "}\n";
} }
{ {
char const doc[] = "{\"posInf\": Infinity, \"NegInf\": -Infinity}"; char const doc[] = "{\"posInf\": Infinity, \"NegInf\": -Infinity}";
bool ok = reader->parse( bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs);
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok); JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_EQUAL(2u, root.size());
JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), root["posInf"].asDouble()); JSONTEST_ASSERT_EQUAL(std::numeric_limits<double>::infinity(),
JSONTEST_ASSERT_EQUAL(-std::numeric_limits<double>::infinity(), root["NegInf"].asDouble()); root["posInf"].asDouble());
JSONTEST_ASSERT_EQUAL(-std::numeric_limits<double>::infinity(),
root["NegInf"].asDouble());
} }
delete reader; delete reader;
} }
@ -2547,8 +2468,7 @@ JSONTEST_FIXTURE(IteratorTest, const) {
Json::Value value; Json::Value value;
for(int i = 9; i < 12; ++i) for (int i = 9; i < 12; ++i) {
{
JSONCPP_OSTRINGSTREAM out; JSONCPP_OSTRINGSTREAM out;
out << std::setw(2) << i; out << std::setw(2) << i;
JSONCPP_STRING str = out.str(); JSONCPP_STRING str = out.str();
@ -2556,10 +2476,9 @@ JSONTEST_FIXTURE(IteratorTest, const) {
} }
JSONCPP_OSTRINGSTREAM out; JSONCPP_OSTRINGSTREAM out;
//in old code, this will get a compile error // in old code, this will get a compile error
Json::Value::const_iterator iter = value.begin(); Json::Value::const_iterator iter = value.begin();
for(; iter != value.end(); ++iter) for (; iter != value.end(); ++iter) {
{
out << *iter << ','; out << *iter << ',';
} }
JSONCPP_STRING expected = "\" 9\",\"10\",\"11\","; JSONCPP_STRING expected = "\" 9\",\"10\",\"11\",";
@ -2573,7 +2492,8 @@ JSONTEST_FIXTURE(RValueTest, moveConstruction) {
Json::Value json; Json::Value json;
json["key"] = "value"; json["key"] = "value";
Json::Value moved = std::move(json); Json::Value moved = std::move(json);
JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not equal. JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not
// equal.
JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type()); JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type());
JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type()); JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type());
#endif #endif
@ -2605,7 +2525,7 @@ int main(int argc, const char* argv[]) {
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);
//JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls); // JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls);
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, ValueTest, specialFloats); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats);
@ -2616,15 +2536,15 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes);
JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithNoErrors); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithNoErrors);
JSONTEST_REGISTER_FIXTURE( JSONTEST_REGISTER_FIXTURE(runner, ReaderTest,
runner, ReaderTest, parseWithNoErrorsTestingOffsets); parseWithNoErrorsTestingOffsets);
JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithOneError);
JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseChineseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseChineseWithOneError);
JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithDetailError); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithDetailError);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithNoErrors); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithNoErrors);
JSONTEST_REGISTER_FIXTURE( JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest,
runner, CharReaderTest, parseWithNoErrorsTestingOffsets); parseWithNoErrorsTestingOffsets);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithOneError);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseChineseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseChineseWithOneError);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithDetailError); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithDetailError);
@ -2634,9 +2554,12 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue164); JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue164);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue107); JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue107);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterObject); JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest,
JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterArray); commentAfterObject);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterBool); JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest,
commentAfterArray);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest,
commentAfterBool);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178); JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178);