mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2024-12-27 11:21:02 +08:00
Merge pull request #776 from BillyDonahue/apply_clang_format
Reapply clang format
This commit is contained in:
commit
cfab607c0d
@ -12,86 +12,77 @@
|
||||
#pragma pack(push, 8)
|
||||
|
||||
namespace Json {
|
||||
template<typename T>
|
||||
class SecureAllocator {
|
||||
public:
|
||||
// Type definitions
|
||||
using value_type = T;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
template <typename T> class SecureAllocator {
|
||||
public:
|
||||
// Type definitions
|
||||
using value_type = T;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
/**
|
||||
* Allocate memory for N items using the standard allocator.
|
||||
*/
|
||||
pointer allocate(size_type n) {
|
||||
// allocate using "global operator new"
|
||||
return static_cast<pointer>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
/**
|
||||
* Allocate memory for N items using the standard allocator.
|
||||
*/
|
||||
pointer allocate(size_type n) {
|
||||
// allocate using "global operator new"
|
||||
return static_cast<pointer>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Release memory which was allocated for N items at pointer P.
|
||||
*
|
||||
* The memory block is filled with zeroes before being released.
|
||||
* The pointer argument is tagged as "volatile" to prevent the
|
||||
* compiler optimizing out this critical step.
|
||||
*/
|
||||
void deallocate(volatile pointer p, size_type n) {
|
||||
std::memset(p, 0, n * sizeof(T));
|
||||
// free using "global operator delete"
|
||||
::operator delete(p);
|
||||
}
|
||||
/**
|
||||
* Release memory which was allocated for N items at pointer P.
|
||||
*
|
||||
* The memory block is filled with zeroes before being released.
|
||||
* The pointer argument is tagged as "volatile" to prevent the
|
||||
* compiler optimizing out this critical step.
|
||||
*/
|
||||
void deallocate(volatile pointer p, size_type n) {
|
||||
std::memset(p, 0, n * sizeof(T));
|
||||
// free using "global operator delete"
|
||||
::operator delete(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an item in-place at pointer P.
|
||||
*/
|
||||
template<typename... Args>
|
||||
void construct(pointer p, Args&&... args) {
|
||||
// construct using "placement new" and "perfect forwarding"
|
||||
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
|
||||
}
|
||||
/**
|
||||
* Construct an item in-place at pointer P.
|
||||
*/
|
||||
template <typename... Args> void construct(pointer p, Args&&... args) {
|
||||
// construct using "placement new" and "perfect forwarding"
|
||||
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return size_t(-1) / sizeof(T);
|
||||
}
|
||||
size_type max_size() const { return size_t(-1) / sizeof(T); }
|
||||
|
||||
pointer address( reference x ) const {
|
||||
return std::addressof(x);
|
||||
}
|
||||
pointer address(reference x) const { return std::addressof(x); }
|
||||
|
||||
const_pointer address( const_reference x ) const {
|
||||
return std::addressof(x);
|
||||
}
|
||||
const_pointer address(const_reference x) const { return std::addressof(x); }
|
||||
|
||||
/**
|
||||
* Destroy an item in-place at pointer P.
|
||||
*/
|
||||
void destroy(pointer p) {
|
||||
// destroy using "explicit destructor"
|
||||
p->~T();
|
||||
}
|
||||
/**
|
||||
* Destroy an item in-place at pointer P.
|
||||
*/
|
||||
void destroy(pointer p) {
|
||||
// destroy using "explicit destructor"
|
||||
p->~T();
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
SecureAllocator() {}
|
||||
template<typename U> SecureAllocator(const SecureAllocator<U>&) {}
|
||||
template<typename U> struct rebind { using other = SecureAllocator<U>; };
|
||||
// Boilerplate
|
||||
SecureAllocator() {}
|
||||
template <typename U> SecureAllocator(const 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>&) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
template <typename T, typename U>
|
||||
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
} //namespace Json
|
||||
} // namespace Json
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
|
||||
#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "config.h"
|
||||
@ -20,30 +20,35 @@
|
||||
#if JSON_USE_EXCEPTION
|
||||
|
||||
// @todo <= add detail about condition in exception
|
||||
# define JSON_ASSERT(condition) \
|
||||
{if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
|
||||
|
||||
# define JSON_FAIL_MESSAGE(message) \
|
||||
#define JSON_ASSERT(condition) \
|
||||
{ \
|
||||
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()); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#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
|
||||
// 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()); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define JSON_ASSERT_MESSAGE(condition, message) \
|
||||
|
@ -6,8 +6,8 @@
|
||||
#ifndef JSON_CONFIG_H_INCLUDED
|
||||
#define JSON_CONFIG_H_INCLUDED
|
||||
#include <stddef.h>
|
||||
#include <string> //typedef String
|
||||
#include <stdint.h> //typedef int64_t, uint64_t
|
||||
#include <string> //typedef String
|
||||
|
||||
/// If defined, indicates that json library is embedded in CppTL library.
|
||||
//# define JSON_IN_CPPTL 1
|
||||
@ -60,21 +60,21 @@
|
||||
// #define JSON_NO_INT64 1
|
||||
|
||||
#if defined(_MSC_VER) // MSVC
|
||||
# if _MSC_VER <= 1200 // MSVC 6
|
||||
// Microsoft Visual Studio 6 only support conversion from __int64 to double
|
||||
// (no conversion from unsigned __int64).
|
||||
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
|
||||
// characters in the debug information)
|
||||
// All projects I've ever seen with VS6 were using this globally (not bothering
|
||||
// with pragma push/pop).
|
||||
# pragma warning(disable : 4786)
|
||||
# endif // MSVC 6
|
||||
#if _MSC_VER <= 1200 // MSVC 6
|
||||
// Microsoft Visual Studio 6 only support conversion from __int64 to double
|
||||
// (no conversion from unsigned __int64).
|
||||
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
|
||||
// characters in the debug information)
|
||||
// All projects I've ever seen with VS6 were using this globally (not bothering
|
||||
// with pragma push/pop).
|
||||
#pragma warning(disable : 4786)
|
||||
#endif // MSVC 6
|
||||
|
||||
# if _MSC_VER >= 1500 // MSVC 2008
|
||||
/// Indicates that the following function is deprecated.
|
||||
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# endif
|
||||
#if _MSC_VER >= 1500 // MSVC 2008
|
||||
/// Indicates that the following function is deprecated.
|
||||
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
|
||||
#endif
|
||||
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
@ -82,25 +82,25 @@
|
||||
// is intended to override the base-class version. This makes the code more
|
||||
// manageable and fixes a set of common hard-to-find bugs.
|
||||
#if __cplusplus >= 201103L
|
||||
# define JSONCPP_OVERRIDE override
|
||||
# define JSONCPP_NOEXCEPT noexcept
|
||||
# define JSONCPP_OP_EXPLICIT explicit
|
||||
#define JSONCPP_OVERRIDE override
|
||||
#define JSONCPP_NOEXCEPT noexcept
|
||||
#define JSONCPP_OP_EXPLICIT explicit
|
||||
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
|
||||
# define JSONCPP_OVERRIDE override
|
||||
# define JSONCPP_NOEXCEPT throw()
|
||||
# if _MSC_VER >= 1800 // MSVC 2013
|
||||
# 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
|
||||
#define JSONCPP_OVERRIDE override
|
||||
#define JSONCPP_NOEXCEPT throw()
|
||||
#if _MSC_VER >= 1800 // MSVC 2013
|
||||
#define JSONCPP_OP_EXPLICIT explicit
|
||||
#else
|
||||
# define JSONCPP_OVERRIDE
|
||||
# define JSONCPP_NOEXCEPT throw()
|
||||
# define JSONCPP_OP_EXPLICIT
|
||||
#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
|
||||
#define JSONCPP_OVERRIDE
|
||||
#define JSONCPP_NOEXCEPT throw()
|
||||
#define JSONCPP_OP_EXPLICIT
|
||||
#endif
|
||||
|
||||
#ifndef JSON_HAS_RVALUE_REFERENCES
|
||||
@ -112,12 +112,12 @@
|
||||
#ifdef __clang__
|
||||
#if __has_feature(cxx_rvalue_references)
|
||||
#define JSON_HAS_RVALUE_REFERENCES 1
|
||||
#endif // has_feature
|
||||
#endif // has_feature
|
||||
|
||||
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
|
||||
#define JSON_HAS_RVALUE_REFERENCES 1
|
||||
#endif // GXX_EXPERIMENTAL
|
||||
#endif // GXX_EXPERIMENTAL
|
||||
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
||||
@ -128,15 +128,15 @@
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
# if __has_extension(attribute_deprecated_with_message)
|
||||
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
|
||||
# endif
|
||||
#if __has_extension(attribute_deprecated_with_message)
|
||||
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
#endif
|
||||
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
|
||||
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
||||
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
|
||||
# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
|
||||
# endif // GNUC version
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
||||
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
|
||||
#endif // GNUC version
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
||||
#if !defined(JSONCPP_DEPRECATED)
|
||||
@ -144,16 +144,16 @@
|
||||
#endif // if !defined(JSONCPP_DEPRECATED)
|
||||
|
||||
#if __GNUC__ >= 6
|
||||
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||
#endif
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
# include "version.h"
|
||||
#include "version.h"
|
||||
|
||||
# if JSONCPP_USING_SECURE_MEMORY
|
||||
# include "allocator.h" //typedef Allocator
|
||||
# endif
|
||||
#if JSONCPP_USING_SECURE_MEMORY
|
||||
#include "allocator.h" //typedef Allocator
|
||||
#endif
|
||||
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
@ -172,23 +172,28 @@ typedef unsigned __int64 UInt64;
|
||||
#else // if defined(_MSC_VER) // Other platforms, use long long
|
||||
typedef int64_t Int64;
|
||||
typedef uint64_t UInt64;
|
||||
#endif // if defined(_MSC_VER)
|
||||
#endif // if defined(_MSC_VER)
|
||||
typedef Int64 LargestInt;
|
||||
typedef UInt64 LargestUInt;
|
||||
#define JSON_HAS_INT64
|
||||
#endif // if defined(JSON_NO_INT64)
|
||||
#if JSONCPP_USING_SECURE_MEMORY
|
||||
#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
|
||||
#define JSONCPP_OSTRINGSTREAM 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_STRING \
|
||||
std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
|
||||
#define JSONCPP_OSTRINGSTREAM \
|
||||
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
|
||||
#else
|
||||
#define JSONCPP_STRING std::string
|
||||
#define JSONCPP_STRING std::string
|
||||
#define JSONCPP_OSTRINGSTREAM std::ostringstream
|
||||
#define JSONCPP_OSTREAM std::ostream
|
||||
#define JSONCPP_OSTREAM std::ostream
|
||||
#define JSONCPP_ISTRINGSTREAM std::istringstream
|
||||
#define JSONCPP_ISTREAM std::istream
|
||||
#define JSONCPP_ISTREAM std::istream
|
||||
#endif // if JSONCPP_USING_SECURE_MEMORY
|
||||
} // end namespace Json
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
#define JSON_JSON_H_INCLUDED
|
||||
|
||||
#include "autolink.h"
|
||||
#include "value.h"
|
||||
#include "reader.h"
|
||||
#include "writer.h"
|
||||
#include "features.h"
|
||||
#include "reader.h"
|
||||
#include "value.h"
|
||||
#include "writer.h"
|
||||
|
||||
#endif // JSON_JSON_H_INCLUDED
|
||||
|
@ -12,9 +12,9 @@
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <deque>
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
|
||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||
// be used by...
|
||||
@ -52,13 +52,13 @@ public:
|
||||
/** \brief Constructs a Reader allowing all features
|
||||
* for parsing.
|
||||
*/
|
||||
JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
|
||||
JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
|
||||
Reader();
|
||||
|
||||
/** \brief Constructs a Reader allowing the specified feature set
|
||||
* for parsing.
|
||||
*/
|
||||
JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
|
||||
JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
|
||||
Reader(const Features& features);
|
||||
|
||||
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
||||
@ -151,7 +151,9 @@ public:
|
||||
* \return \c true if the error was successfully added, \c false if either
|
||||
* Value offset exceeds the document size.
|
||||
*/
|
||||
bool pushError(const Value& value, const 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.
|
||||
* \return \c true if there are no errors to report \c false if
|
||||
@ -218,7 +220,8 @@ private:
|
||||
Location& current,
|
||||
Location end,
|
||||
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 addErrorAndRecover(const JSONCPP_STRING& message,
|
||||
Token& token,
|
||||
@ -247,7 +250,7 @@ private:
|
||||
JSONCPP_STRING commentsBefore_;
|
||||
Features features_;
|
||||
bool collectComments_;
|
||||
}; // Reader
|
||||
}; // Reader
|
||||
|
||||
/** Interface for reading JSON from a char array.
|
||||
*/
|
||||
@ -256,7 +259,8 @@ public:
|
||||
virtual ~CharReader() {}
|
||||
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
||||
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
|
||||
document to read.
|
||||
@ -271,9 +275,10 @@ public:
|
||||
* \return \c true if the document was successfully parsed, \c false if an
|
||||
error occurred.
|
||||
*/
|
||||
virtual bool parse(
|
||||
char const* beginDoc, char const* endDoc,
|
||||
Value* root, JSONCPP_STRING* errs) = 0;
|
||||
virtual bool parse(char const* beginDoc,
|
||||
char const* endDoc,
|
||||
Value* root,
|
||||
JSONCPP_STRING* errs) = 0;
|
||||
|
||||
class JSON_API Factory {
|
||||
public:
|
||||
@ -282,8 +287,8 @@ public:
|
||||
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||
*/
|
||||
virtual CharReader* newCharReader() const = 0;
|
||||
}; // Factory
|
||||
}; // CharReader
|
||||
}; // Factory
|
||||
}; // CharReader
|
||||
|
||||
/** \brief Build a CharReader implementation.
|
||||
|
||||
@ -313,7 +318,8 @@ public:
|
||||
- `"strictRoot": false or true`
|
||||
- true if root must be either an array or an object value
|
||||
- `"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`
|
||||
- true if numeric object keys are allowed.
|
||||
- `"allowSingleQuotes": false or true`
|
||||
@ -327,9 +333,10 @@ public:
|
||||
- If true, `parse()` returns false when extra non-whitespace trails
|
||||
the JSON value in the input string.
|
||||
- `"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`
|
||||
- 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.
|
||||
|
||||
You can examine 'settings_` yourself
|
||||
@ -368,13 +375,13 @@ public:
|
||||
};
|
||||
|
||||
/** Consume entire stream and use its begin/end.
|
||||
* Someday we might have a real StreamReader, but for now this
|
||||
* is convenient.
|
||||
*/
|
||||
bool JSON_API parseFromStream(
|
||||
CharReader::Factory const&,
|
||||
JSONCPP_ISTREAM&,
|
||||
Value* root, std::string* errs);
|
||||
* Someday we might have a real StreamReader, but for now this
|
||||
* is convenient.
|
||||
*/
|
||||
bool JSON_API parseFromStream(CharReader::Factory const&,
|
||||
JSONCPP_ISTREAM&,
|
||||
Value* root,
|
||||
std::string* errs);
|
||||
|
||||
/** \brief Read from 'sin' into 'root'.
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "forwards.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
|
||||
#ifndef JSON_USE_CPPTL_SMALLMAP
|
||||
#include <map>
|
||||
@ -22,17 +22,17 @@
|
||||
#include <cpptl/forwards.h>
|
||||
#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
|
||||
// b) possibly improve optimization opportunities.
|
||||
#if !defined(JSONCPP_NORETURN)
|
||||
# if defined(_MSC_VER)
|
||||
# define JSONCPP_NORETURN __declspec(noreturn)
|
||||
# elif defined(__GNUC__)
|
||||
# define JSONCPP_NORETURN __attribute__ ((__noreturn__))
|
||||
# else
|
||||
# define JSONCPP_NORETURN
|
||||
# endif
|
||||
#if defined(_MSC_VER)
|
||||
#define JSONCPP_NORETURN __declspec(noreturn)
|
||||
#elif defined(__GNUC__)
|
||||
#define JSONCPP_NORETURN __attribute__((__noreturn__))
|
||||
#else
|
||||
#define JSONCPP_NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||
@ -57,6 +57,7 @@ public:
|
||||
Exception(JSONCPP_STRING const& msg);
|
||||
~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
|
||||
char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
|
||||
|
||||
protected:
|
||||
JSONCPP_STRING msg_;
|
||||
};
|
||||
@ -183,6 +184,7 @@ private:
|
||||
*/
|
||||
class JSON_API Value {
|
||||
friend class ValueIteratorBase;
|
||||
|
||||
public:
|
||||
typedef std::vector<JSONCPP_STRING> Members;
|
||||
typedef ValueIterator iterator;
|
||||
@ -200,8 +202,10 @@ public:
|
||||
// Required for boost integration, e. g. BOOST_TEST
|
||||
typedef std::string value_type;
|
||||
|
||||
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
|
||||
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
|
||||
static const Value& null; ///< We regret this reference to a global instance;
|
||||
///< 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.
|
||||
|
||||
/// Minimum signed integer value that can be stored in a Json::Value.
|
||||
@ -241,11 +245,7 @@ private:
|
||||
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
|
||||
class CZString {
|
||||
public:
|
||||
enum DuplicationPolicy {
|
||||
noDuplication = 0,
|
||||
duplicate,
|
||||
duplicateOnCopy
|
||||
};
|
||||
enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
|
||||
CZString(ArrayIndex index);
|
||||
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
|
||||
CZString(CZString const& other);
|
||||
@ -262,7 +262,7 @@ private:
|
||||
bool operator<(CZString const& other) const;
|
||||
bool operator==(CZString const& other) const;
|
||||
ArrayIndex index() const;
|
||||
//const char* c_str() const; ///< \deprecated
|
||||
// const char* c_str() const; ///< \deprecated
|
||||
char const* data() const;
|
||||
unsigned length() const;
|
||||
bool isStaticString() const;
|
||||
@ -271,11 +271,11 @@ private:
|
||||
void swap(CZString& other);
|
||||
|
||||
struct StringStorage {
|
||||
unsigned policy_: 2;
|
||||
unsigned length_: 30; // 1GB max
|
||||
unsigned policy_ : 2;
|
||||
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
|
||||
union {
|
||||
ArrayIndex index_;
|
||||
StringStorage storage_;
|
||||
@ -332,7 +332,8 @@ Json::Value obj_value(Json::objectValue); // {}
|
||||
* \endcode
|
||||
*/
|
||||
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
|
||||
Value(const CppTL::ConstString& value);
|
||||
#endif
|
||||
@ -346,7 +347,8 @@ Json::Value obj_value(Json::objectValue); // {}
|
||||
~Value();
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Swap everything.
|
||||
@ -372,14 +374,14 @@ Json::Value obj_value(Json::objectValue); // {}
|
||||
|
||||
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
|
||||
#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
|
||||
JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
|
||||
/** Get raw char* of string-value.
|
||||
* \return false if !string. (Seg-fault if str or end are NULL.)
|
||||
*/
|
||||
bool getString(
|
||||
char const** begin, char const** end) const;
|
||||
bool getString(char const** begin, char const** end) const;
|
||||
#ifdef JSON_USE_CPPTL
|
||||
CppTL::ConstString asConstString() const;
|
||||
#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
|
||||
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.
|
||||
* Example of use:
|
||||
* \code
|
||||
@ -513,7 +516,8 @@ Json::Value obj_value(Json::objectValue); // {}
|
||||
/// Return the member named key if it exist, defaultValue otherwise.
|
||||
/// \note deep copy
|
||||
/// \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.
|
||||
/// \note deep copy
|
||||
/// \param key may contain embedded nulls.
|
||||
@ -646,12 +650,14 @@ private:
|
||||
LargestUInt uint_;
|
||||
double real_;
|
||||
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_;
|
||||
} value_;
|
||||
ValueType type_ : 8;
|
||||
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
|
||||
// If not allocated_, string_ must be null-terminated.
|
||||
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is
|
||||
// useless. If not allocated_, string_ must be
|
||||
// null-terminated.
|
||||
CommentInfo* comments_;
|
||||
|
||||
// [start, limit) byte offsets in the source JSON text from which this Value
|
||||
@ -673,11 +679,7 @@ public:
|
||||
PathArgument(const JSONCPP_STRING& key);
|
||||
|
||||
private:
|
||||
enum Kind {
|
||||
kindNone = 0,
|
||||
kindIndex,
|
||||
kindKey
|
||||
};
|
||||
enum Kind { kindNone = 0, kindIndex, kindKey };
|
||||
JSONCPP_STRING key_;
|
||||
ArrayIndex index_;
|
||||
Kind kind_;
|
||||
@ -745,7 +747,8 @@ public:
|
||||
/// Value.
|
||||
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;
|
||||
|
||||
/// 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
|
||||
/// objectValue.
|
||||
/// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
|
||||
/// \deprecated This cannot be used for UTF-8 strings, since there can be
|
||||
/// embedded nulls.
|
||||
JSONCPP_DEPRECATED("Use `key = name();` instead.")
|
||||
char const* memberName() const;
|
||||
/// 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:
|
||||
typedef const Value value_type;
|
||||
//typedef unsigned int size_t;
|
||||
//typedef int difference_type;
|
||||
// typedef unsigned int size_t;
|
||||
// typedef int difference_type;
|
||||
typedef const Value& reference;
|
||||
typedef const Value* pointer;
|
||||
typedef ValueConstIterator SelfType;
|
||||
@ -806,9 +810,10 @@ public:
|
||||
ValueConstIterator(ValueIterator const& other);
|
||||
|
||||
private:
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
*/
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
*/
|
||||
explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
|
||||
|
||||
public:
|
||||
SelfType& operator=(const ValueIteratorBase& other);
|
||||
|
||||
@ -857,9 +862,10 @@ public:
|
||||
ValueIterator(const ValueIterator& other);
|
||||
|
||||
private:
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
*/
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
*/
|
||||
explicit ValueIterator(const Value::ObjectValues::iterator& current);
|
||||
|
||||
public:
|
||||
SelfType& operator=(const SelfType& other);
|
||||
|
||||
|
@ -1,14 +1,16 @@
|
||||
// DO NOT EDIT. This file (and "version") is generated by CMake.
|
||||
// Run CMake configure step to update it.
|
||||
#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_MAJOR 1
|
||||
# define JSONCPP_VERSION_MINOR 8
|
||||
# define JSONCPP_VERSION_PATCH 4
|
||||
# define JSONCPP_VERSION_QUALIFIER
|
||||
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
|
||||
#define JSONCPP_VERSION_STRING "1.8.4"
|
||||
#define JSONCPP_VERSION_MAJOR 1
|
||||
#define JSONCPP_VERSION_MINOR 8
|
||||
#define JSONCPP_VERSION_PATCH 4
|
||||
#define JSONCPP_VERSION_QUALIFIER
|
||||
#define JSONCPP_VERSION_HEXA \
|
||||
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
|
||||
(JSONCPP_VERSION_PATCH << 8))
|
||||
|
||||
#ifdef JSONCPP_USING_SECURE_MEMORY
|
||||
#undef JSONCPP_USING_SECURE_MEMORY
|
||||
|
@ -9,9 +9,9 @@
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "value.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||
// be used by...
|
||||
@ -41,15 +41,15 @@ Usage:
|
||||
*/
|
||||
class JSON_API StreamWriter {
|
||||
protected:
|
||||
JSONCPP_OSTREAM* sout_; // not owned; will not delete
|
||||
JSONCPP_OSTREAM* sout_; // not owned; will not delete
|
||||
public:
|
||||
StreamWriter();
|
||||
virtual ~StreamWriter();
|
||||
/** Write Value into document as configured in sub-class.
|
||||
Do not take ownership of sout, but maintain a reference during function.
|
||||
\pre sout != NULL
|
||||
\return zero on success (For now, we always return zero, so check the stream instead.)
|
||||
\throw std::exception possibly, depending on configuration
|
||||
\return zero on success (For now, we always return zero, so check the
|
||||
stream instead.) \throw std::exception possibly, depending on configuration
|
||||
*/
|
||||
virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
|
||||
|
||||
@ -62,14 +62,14 @@ public:
|
||||
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||
*/
|
||||
virtual StreamWriter* newStreamWriter() const = 0;
|
||||
}; // Factory
|
||||
}; // StreamWriter
|
||||
}; // Factory
|
||||
}; // StreamWriter
|
||||
|
||||
/** \brief Write into stringstream, then return string, for convenience.
|
||||
* 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.
|
||||
|
||||
@ -104,8 +104,8 @@ public:
|
||||
browser can handle the output just fine.
|
||||
- "useSpecialFloats": false or true
|
||||
- If true, outputs non-finite floating point values in the following way:
|
||||
NaN values as "NaN", positive infinity as "Infinity", and negative infinity
|
||||
as "-Infinity".
|
||||
NaN values as "NaN", positive infinity as "Infinity", and negative
|
||||
infinity as "-Infinity".
|
||||
- "precision": int
|
||||
- Number of precision digits for formatting of real values.
|
||||
- "precisionType": "significant"(default) or "decimal"
|
||||
@ -163,9 +163,10 @@ public:
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996) // Deriving from deprecated class
|
||||
#pragma warning(disable : 4996) // Deriving from deprecated class
|
||||
#endif
|
||||
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer {
|
||||
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter
|
||||
: public Writer {
|
||||
public:
|
||||
FastWriter();
|
||||
~FastWriter() JSONCPP_OVERRIDE {}
|
||||
@ -222,9 +223,10 @@ private:
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996) // Deriving from deprecated class
|
||||
#pragma warning(disable : 4996) // Deriving from deprecated class
|
||||
#endif
|
||||
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer {
|
||||
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
|
||||
StyledWriter : public Writer {
|
||||
public:
|
||||
StyledWriter();
|
||||
~StyledWriter() JSONCPP_OVERRIDE {}
|
||||
@ -290,13 +292,14 @@ private:
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996) // Deriving from deprecated class
|
||||
#pragma warning(disable : 4996) // Deriving from deprecated class
|
||||
#endif
|
||||
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter {
|
||||
class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
|
||||
StyledStreamWriter {
|
||||
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() {}
|
||||
|
||||
@ -343,8 +346,10 @@ JSONCPP_STRING JSON_API valueToString(UInt value);
|
||||
#endif // if defined(JSON_HAS_INT64)
|
||||
JSONCPP_STRING JSON_API valueToString(LargestInt value);
|
||||
JSONCPP_STRING JSON_API valueToString(LargestUInt value);
|
||||
JSONCPP_STRING JSON_API valueToString(double value, unsigned int precision = Value::defaultRealPrecision,
|
||||
PrecisionType precisionType = PrecisionType::significantDigits);
|
||||
JSONCPP_STRING JSON_API
|
||||
valueToString(double value,
|
||||
unsigned int precision = Value::defaultRealPrecision,
|
||||
PrecisionType precisionType = PrecisionType::significantDigits);
|
||||
JSONCPP_STRING JSON_API valueToString(bool value);
|
||||
JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
|
||||
|
||||
|
@ -13,13 +13,12 @@
|
||||
/* This executable is used for testing parser/writer using real JSON files.
|
||||
*/
|
||||
|
||||
#include <json/json.h>
|
||||
#include <algorithm> // sort
|
||||
#include <json/json.h>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
struct Options
|
||||
{
|
||||
struct Options {
|
||||
JSONCPP_STRING path;
|
||||
Json::Features features;
|
||||
bool parseOnly;
|
||||
@ -45,8 +44,8 @@ static JSONCPP_STRING normalizeFloatingPointStr(double value) {
|
||||
JSONCPP_STRING::size_type indexDigit =
|
||||
s.find_first_not_of('0', exponentStartIndex);
|
||||
JSONCPP_STRING exponent = "0";
|
||||
if (indexDigit !=
|
||||
JSONCPP_STRING::npos) // There is an exponent different from 0
|
||||
if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different
|
||||
// from 0
|
||||
{
|
||||
exponent = s.substr(indexDigit);
|
||||
}
|
||||
@ -73,8 +72,9 @@ static JSONCPP_STRING readInputTestFile(const char* path) {
|
||||
return text;
|
||||
}
|
||||
|
||||
static void
|
||||
printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") {
|
||||
static void printValueTree(FILE* fout,
|
||||
Json::Value& value,
|
||||
const JSONCPP_STRING& path = ".") {
|
||||
if (value.hasComment(Json::commentBefore)) {
|
||||
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());
|
||||
break;
|
||||
case Json::intValue:
|
||||
fprintf(fout,
|
||||
"%s=%s\n",
|
||||
path.c_str(),
|
||||
fprintf(fout, "%s=%s\n", path.c_str(),
|
||||
Json::valueToString(value.asLargestInt()).c_str());
|
||||
break;
|
||||
case Json::uintValue:
|
||||
fprintf(fout,
|
||||
"%s=%s\n",
|
||||
path.c_str(),
|
||||
fprintf(fout, "%s=%s\n", path.c_str(),
|
||||
Json::valueToString(value.asLargestUInt()).c_str());
|
||||
break;
|
||||
case Json::realValue:
|
||||
fprintf(fout,
|
||||
"%s=%s\n",
|
||||
path.c_str(),
|
||||
fprintf(fout, "%s=%s\n", path.c_str(),
|
||||
normalizeFloatingPointStr(value.asDouble()).c_str());
|
||||
break;
|
||||
case Json::stringValue:
|
||||
@ -125,8 +119,7 @@ printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".")
|
||||
std::sort(members.begin(), members.end());
|
||||
JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : ".";
|
||||
for (Json::Value::Members::iterator it = members.begin();
|
||||
it != members.end();
|
||||
++it) {
|
||||
it != members.end(); ++it) {
|
||||
const JSONCPP_STRING name = *it;
|
||||
printValueTree(fout, value[name], path + suffix + name);
|
||||
}
|
||||
@ -145,13 +138,12 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input,
|
||||
const JSONCPP_STRING& kind,
|
||||
const Json::Features& features,
|
||||
bool parseOnly,
|
||||
Json::Value* root)
|
||||
{
|
||||
Json::Value* root) {
|
||||
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) {
|
||||
printf("Failed to parse %s file: \n%s\n",
|
||||
kind.c_str(),
|
||||
printf("Failed to parse %s file: \n%s\n", kind.c_str(),
|
||||
reader.getFormattedErrorMessages().c_str());
|
||||
return 1;
|
||||
}
|
||||
@ -171,32 +163,24 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input,
|
||||
// writer.enableYAMLCompatibility();
|
||||
// return writer.write(root);
|
||||
// }
|
||||
static JSONCPP_STRING useStyledWriter(
|
||||
Json::Value const& root)
|
||||
{
|
||||
static JSONCPP_STRING useStyledWriter(Json::Value const& root) {
|
||||
Json::StyledWriter writer;
|
||||
return writer.write(root);
|
||||
}
|
||||
static JSONCPP_STRING useStyledStreamWriter(
|
||||
Json::Value const& root)
|
||||
{
|
||||
static JSONCPP_STRING useStyledStreamWriter(Json::Value const& root) {
|
||||
Json::StyledStreamWriter writer;
|
||||
JSONCPP_OSTRINGSTREAM sout;
|
||||
writer.write(sout, root);
|
||||
return sout.str();
|
||||
}
|
||||
static JSONCPP_STRING useBuiltStyledStreamWriter(
|
||||
Json::Value const& root)
|
||||
{
|
||||
static JSONCPP_STRING useBuiltStyledStreamWriter(Json::Value const& root) {
|
||||
Json::StreamWriterBuilder builder;
|
||||
return Json::writeString(builder, root);
|
||||
}
|
||||
static int rewriteValueTree(
|
||||
const JSONCPP_STRING& rewritePath,
|
||||
const Json::Value& root,
|
||||
Options::writeFuncType write,
|
||||
JSONCPP_STRING* rewrite)
|
||||
{
|
||||
static int rewriteValueTree(const JSONCPP_STRING& rewritePath,
|
||||
const Json::Value& root,
|
||||
Options::writeFuncType write,
|
||||
JSONCPP_STRING* rewrite) {
|
||||
*rewrite = write(root);
|
||||
FILE* fout = fopen(rewritePath.c_str(), "wt");
|
||||
if (!fout) {
|
||||
@ -209,7 +193,7 @@ static int rewriteValueTree(
|
||||
}
|
||||
|
||||
static JSONCPP_STRING removeSuffix(const JSONCPP_STRING& path,
|
||||
const JSONCPP_STRING& extension) {
|
||||
const JSONCPP_STRING& extension) {
|
||||
if (extension.length() >= path.length())
|
||||
return JSONCPP_STRING("");
|
||||
JSONCPP_STRING suffix = path.substr(path.length() - extension.length());
|
||||
@ -232,9 +216,7 @@ static int printUsage(const char* argv[]) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int parseCommandLine(
|
||||
int argc, const char* argv[], Options* opts)
|
||||
{
|
||||
static int parseCommandLine(int argc, const char* argv[], Options* opts) {
|
||||
opts->parseOnly = false;
|
||||
opts->write = &useStyledWriter;
|
||||
if (argc < 2) {
|
||||
@ -270,8 +252,7 @@ static int parseCommandLine(
|
||||
opts->path = argv[index];
|
||||
return 0;
|
||||
}
|
||||
static int runTest(Options const& opts)
|
||||
{
|
||||
static int runTest(Options const& opts) {
|
||||
int exitCode = 0;
|
||||
|
||||
JSONCPP_STRING input = readInputTestFile(opts.path.c_str());
|
||||
@ -283,7 +264,7 @@ static int runTest(Options const& opts)
|
||||
JSONCPP_STRING basePath = removeSuffix(opts.path, ".json");
|
||||
if (!opts.parseOnly && basePath.empty()) {
|
||||
printf("Bad input path. Path does not end with '.expected':\n%s\n",
|
||||
opts.path.c_str());
|
||||
opts.path.c_str());
|
||||
return 3;
|
||||
}
|
||||
|
||||
@ -292,9 +273,8 @@ static int runTest(Options const& opts)
|
||||
JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite";
|
||||
|
||||
Json::Value root;
|
||||
exitCode = parseAndSaveValueTree(
|
||||
input, actualPath, "input",
|
||||
opts.features, opts.parseOnly, &root);
|
||||
exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features,
|
||||
opts.parseOnly, &root);
|
||||
if (exitCode || opts.parseOnly) {
|
||||
return exitCode;
|
||||
}
|
||||
@ -304,9 +284,8 @@ static int runTest(Options const& opts)
|
||||
return exitCode;
|
||||
}
|
||||
Json::Value rewriteRoot;
|
||||
exitCode = parseAndSaveValueTree(
|
||||
rewrite, rewriteActualPath, "rewrite",
|
||||
opts.features, opts.parseOnly, &rewriteRoot);
|
||||
exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite",
|
||||
opts.features, opts.parseOnly, &rewriteRoot);
|
||||
if (exitCode) {
|
||||
return exitCode;
|
||||
}
|
||||
@ -315,14 +294,13 @@ static int runTest(Options const& opts)
|
||||
int main(int argc, const char* argv[]) {
|
||||
Options opts;
|
||||
try {
|
||||
int exitCode = parseCommandLine(argc, argv, &opts);
|
||||
if (exitCode != 0) {
|
||||
printf("Failed to parse command-line.");
|
||||
return exitCode;
|
||||
}
|
||||
int exitCode = parseCommandLine(argc, argv, &opts);
|
||||
if (exitCode != 0) {
|
||||
printf("Failed to parse command-line.");
|
||||
return exitCode;
|
||||
}
|
||||
return runTest(opts);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
} catch (const std::exception& e) {
|
||||
printf("Unhandled exception:\n%s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
@ -5,39 +5,39 @@
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "json_tool.h"
|
||||
#include <json/assertions.h>
|
||||
#include <json/reader.h>
|
||||
#include <json/value.h>
|
||||
#include "json_tool.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <cstdio>
|
||||
#include <cstdio>
|
||||
|
||||
#if !defined(snprintf)
|
||||
#define snprintf std::snprintf
|
||||
#endif
|
||||
#if !defined(snprintf)
|
||||
#define snprintf std::snprintf
|
||||
#endif
|
||||
|
||||
#if !defined(sscanf)
|
||||
#define sscanf std::sscanf
|
||||
#endif
|
||||
#if !defined(sscanf)
|
||||
#define sscanf std::sscanf
|
||||
#endif
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
|
||||
#if !defined(snprintf)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
|
||||
#if !defined(snprintf)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
|
||||
@ -45,19 +45,21 @@
|
||||
#pragma warning(disable : 4996)
|
||||
#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)
|
||||
#define JSONCPP_DEPRECATED_STACK_LIMIT 1000
|
||||
#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 {
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
|
||||
typedef std::unique_ptr<CharReader> CharReaderPtr;
|
||||
#else
|
||||
typedef std::auto_ptr<CharReader> CharReaderPtr;
|
||||
typedef std::auto_ptr<CharReader> CharReaderPtr;
|
||||
#endif
|
||||
|
||||
// Implementation of class Features
|
||||
@ -101,8 +103,9 @@ Reader::Reader(const Features& features)
|
||||
lastValue_(), commentsBefore_(), features_(features), collectComments_() {
|
||||
}
|
||||
|
||||
bool
|
||||
Reader::parse(const std::string& document, Value& root, bool collectComments) {
|
||||
bool Reader::parse(const std::string& document,
|
||||
Value& root,
|
||||
bool collectComments) {
|
||||
document_.assign(document.begin(), document.end());
|
||||
const char* begin = document_.c_str();
|
||||
const char* end = begin + document_.length();
|
||||
@ -165,9 +168,11 @@ bool Reader::parse(const char* beginDoc,
|
||||
|
||||
bool Reader::readValue() {
|
||||
// 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().
|
||||
// parse() executes one nodes_.push(), so > instead of >=.
|
||||
if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||
// These methods execute nodes_.push() just before and nodes_.pop)() just
|
||||
// after calling readValue(). parse() executes one nodes_.push(), so > instead
|
||||
// of >=.
|
||||
if (nodes_.size() > stackLimit_g)
|
||||
throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
@ -193,30 +198,24 @@ bool Reader::readValue() {
|
||||
case tokenString:
|
||||
successful = decodeString(token);
|
||||
break;
|
||||
case tokenTrue:
|
||||
{
|
||||
case tokenTrue: {
|
||||
Value v(true);
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenFalse:
|
||||
{
|
||||
} break;
|
||||
case tokenFalse: {
|
||||
Value v(false);
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenNull:
|
||||
{
|
||||
} break;
|
||||
case tokenNull: {
|
||||
Value v;
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case tokenArraySeparator:
|
||||
case tokenObjectEnd:
|
||||
case tokenArrayEnd:
|
||||
@ -369,7 +368,8 @@ bool Reader::readComment() {
|
||||
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;
|
||||
normalized.reserve(static_cast<size_t>(end - begin));
|
||||
Reader::Location current = begin;
|
||||
@ -377,8 +377,8 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end
|
||||
char c = *current++;
|
||||
if (c == '\r') {
|
||||
if (current != end && *current == '\n')
|
||||
// convert dos EOL
|
||||
++current;
|
||||
// convert dos EOL
|
||||
++current;
|
||||
// convert Mac EOL
|
||||
normalized += '\n';
|
||||
} else {
|
||||
@ -388,8 +388,9 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end
|
||||
return normalized;
|
||||
}
|
||||
|
||||
void
|
||||
Reader::addComment(Location begin, Location end, CommentPlacement placement) {
|
||||
void Reader::addComment(Location begin,
|
||||
Location end,
|
||||
CommentPlacement placement) {
|
||||
assert(collectComments_);
|
||||
const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
|
||||
if (placement == commentAfterOnSameLine) {
|
||||
@ -426,7 +427,7 @@ bool Reader::readCppStyleComment() {
|
||||
}
|
||||
|
||||
void Reader::readNumber() {
|
||||
const char *p = current_;
|
||||
const char* p = current_;
|
||||
char c = '0'; // stopgap for already consumed character
|
||||
// integral part
|
||||
while (c >= '0' && c <= '9')
|
||||
@ -488,8 +489,8 @@ bool Reader::readObject(Token& tokenStart) {
|
||||
|
||||
Token colon;
|
||||
if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
|
||||
return addErrorAndRecover(
|
||||
"Missing ':' after object member name", colon, tokenObjectEnd);
|
||||
return addErrorAndRecover("Missing ':' after object member name", colon,
|
||||
tokenObjectEnd);
|
||||
}
|
||||
Value& value = currentValue()[name];
|
||||
nodes_.push(&value);
|
||||
@ -502,8 +503,8 @@ bool Reader::readObject(Token& tokenStart) {
|
||||
if (!readToken(comma) ||
|
||||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
|
||||
comma.type_ != tokenComment)) {
|
||||
return addErrorAndRecover(
|
||||
"Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
|
||||
return addErrorAndRecover("Missing ',' or '}' in object declaration",
|
||||
comma, tokenObjectEnd);
|
||||
}
|
||||
bool finalizeTokenOk = true;
|
||||
while (comma.type_ == tokenComment && finalizeTokenOk)
|
||||
@ -511,8 +512,8 @@ bool Reader::readObject(Token& tokenStart) {
|
||||
if (comma.type_ == tokenObjectEnd)
|
||||
return true;
|
||||
}
|
||||
return addErrorAndRecover(
|
||||
"Missing '}' or object member name", tokenName, tokenObjectEnd);
|
||||
return addErrorAndRecover("Missing '}' or object member name", tokenName,
|
||||
tokenObjectEnd);
|
||||
}
|
||||
|
||||
bool Reader::readArray(Token& tokenStart) {
|
||||
@ -544,8 +545,8 @@ bool Reader::readArray(Token& tokenStart) {
|
||||
bool badTokenType =
|
||||
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
|
||||
if (!ok || badTokenType) {
|
||||
return addErrorAndRecover(
|
||||
"Missing ',' or ']' in array declaration", token, tokenArrayEnd);
|
||||
return addErrorAndRecover("Missing ',' or ']' in array declaration",
|
||||
token, tokenArrayEnd);
|
||||
}
|
||||
if (token.type_ == tokenArrayEnd)
|
||||
break;
|
||||
@ -571,7 +572,8 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
|
||||
bool isNegative = *current == '-';
|
||||
if (isNegative)
|
||||
++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 =
|
||||
isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
|
||||
: Value::maxLargestUInt;
|
||||
@ -703,8 +705,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
|
||||
if (end - current < 6)
|
||||
return addError(
|
||||
"additional six characters expected to parse unicode surrogate pair.",
|
||||
token,
|
||||
current);
|
||||
token, current);
|
||||
unsigned int surrogatePair;
|
||||
if (*(current++) == '\\' && *(current++) == 'u') {
|
||||
if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
|
||||
@ -714,8 +715,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token,
|
||||
} else
|
||||
return addError("expecting another \\u token to begin the second half of "
|
||||
"a unicode surrogate pair",
|
||||
token,
|
||||
current);
|
||||
token, current);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -726,8 +726,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
|
||||
unsigned int& ret_unicode) {
|
||||
if (end - current < 4)
|
||||
return addError(
|
||||
"Bad unicode escape sequence in string: four digits expected.",
|
||||
token,
|
||||
"Bad unicode escape sequence in string: four digits expected.", token,
|
||||
current);
|
||||
int unicode = 0;
|
||||
for (int index = 0; index < 4; ++index) {
|
||||
@ -742,15 +741,15 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token,
|
||||
else
|
||||
return addError(
|
||||
"Bad unicode escape sequence in string: hexadecimal digit expected.",
|
||||
token,
|
||||
current);
|
||||
token, current);
|
||||
}
|
||||
ret_unicode = static_cast<unsigned int>(unicode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
|
||||
bool Reader::addError(const JSONCPP_STRING& message,
|
||||
Token& token,
|
||||
Location extra) {
|
||||
ErrorInfo info;
|
||||
info.token_ = token;
|
||||
info.message_ = message;
|
||||
@ -826,8 +825,7 @@ JSONCPP_STRING Reader::getFormatedErrorMessages() const {
|
||||
JSONCPP_STRING Reader::getFormattedErrorMessages() const {
|
||||
JSONCPP_STRING formattedMessage;
|
||||
for (Errors::const_iterator itError = errors_.begin();
|
||||
itError != errors_.end();
|
||||
++itError) {
|
||||
itError != errors_.end(); ++itError) {
|
||||
const ErrorInfo& error = *itError;
|
||||
formattedMessage +=
|
||||
"* " + 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> allErrors;
|
||||
for (Errors::const_iterator itError = errors_.begin();
|
||||
itError != errors_.end();
|
||||
++itError) {
|
||||
itError != errors_.end(); ++itError) {
|
||||
const ErrorInfo& error = *itError;
|
||||
Reader::StructuredError structured;
|
||||
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) {
|
||||
ptrdiff_t const length = end_ - begin_;
|
||||
if(value.getOffsetStart() > length
|
||||
|| value.getOffsetLimit() > length)
|
||||
if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
|
||||
return false;
|
||||
Token token;
|
||||
token.type_ = tokenError;
|
||||
@ -871,11 +867,12 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
|
||||
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_;
|
||||
if(value.getOffsetStart() > length
|
||||
|| value.getOffsetLimit() > length
|
||||
|| extra.getOffsetLimit() > length)
|
||||
if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
|
||||
extra.getOffsetLimit() > length)
|
||||
return false;
|
||||
Token token;
|
||||
token.type_ = tokenError;
|
||||
@ -889,9 +886,7 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Reader::good() const {
|
||||
return !errors_.size();
|
||||
}
|
||||
bool Reader::good() const { return !errors_.size(); }
|
||||
|
||||
// exact copy of Features
|
||||
class OurFeatures {
|
||||
@ -906,7 +901,7 @@ public:
|
||||
bool rejectDupKeys_;
|
||||
bool allowSpecialFloats_;
|
||||
int stackLimit_;
|
||||
}; // OurFeatures
|
||||
}; // OurFeatures
|
||||
|
||||
// exact copy of Implementation of class Features
|
||||
// ////////////////////////////////
|
||||
@ -935,12 +930,14 @@ public:
|
||||
JSONCPP_STRING getFormattedErrorMessages() const;
|
||||
std::vector<StructuredError> getStructuredErrors() const;
|
||||
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;
|
||||
|
||||
private:
|
||||
OurReader(OurReader const&); // no impl
|
||||
void operator=(OurReader const&); // no impl
|
||||
OurReader(OurReader const&); // no impl
|
||||
void operator=(OurReader const&); // no impl
|
||||
|
||||
enum TokenType {
|
||||
tokenEndOfStream = 0,
|
||||
@ -1004,7 +1001,8 @@ private:
|
||||
Location& current,
|
||||
Location end,
|
||||
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 addErrorAndRecover(const JSONCPP_STRING& message,
|
||||
Token& token,
|
||||
@ -1034,11 +1032,12 @@ private:
|
||||
|
||||
OurFeatures const features_;
|
||||
bool collectComments_;
|
||||
}; // OurReader
|
||||
}; // 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)
|
||||
if (*begin == '\n' || *begin == '\r')
|
||||
return true;
|
||||
@ -1047,14 +1046,13 @@ bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location e
|
||||
|
||||
OurReader::OurReader(OurFeatures const& features)
|
||||
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
|
||||
lastValue_(), commentsBefore_(),
|
||||
features_(features), collectComments_() {
|
||||
lastValue_(), commentsBefore_(), features_(features), collectComments_() {
|
||||
}
|
||||
|
||||
bool OurReader::parse(const char* beginDoc,
|
||||
const char* endDoc,
|
||||
Value& root,
|
||||
bool collectComments) {
|
||||
const char* endDoc,
|
||||
Value& root,
|
||||
bool collectComments) {
|
||||
if (!features_.allowComments_) {
|
||||
collectComments = false;
|
||||
}
|
||||
@ -1075,7 +1073,8 @@ bool OurReader::parse(const char* beginDoc,
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
@ -1100,7 +1099,8 @@ bool OurReader::parse(const char* beginDoc,
|
||||
|
||||
bool OurReader::readValue() {
|
||||
// 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;
|
||||
skipCommentTokens(token);
|
||||
bool successful = true;
|
||||
@ -1125,54 +1125,42 @@ bool OurReader::readValue() {
|
||||
case tokenString:
|
||||
successful = decodeString(token);
|
||||
break;
|
||||
case tokenTrue:
|
||||
{
|
||||
case tokenTrue: {
|
||||
Value v(true);
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenFalse:
|
||||
{
|
||||
} break;
|
||||
case tokenFalse: {
|
||||
Value v(false);
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenNull:
|
||||
{
|
||||
} break;
|
||||
case tokenNull: {
|
||||
Value v;
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenNaN:
|
||||
{
|
||||
} break;
|
||||
case tokenNaN: {
|
||||
Value v(std::numeric_limits<double>::quiet_NaN());
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenPosInf:
|
||||
{
|
||||
} break;
|
||||
case tokenPosInf: {
|
||||
Value v(std::numeric_limits<double>::infinity());
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
case tokenNegInf:
|
||||
{
|
||||
} break;
|
||||
case tokenNegInf: {
|
||||
Value v(-std::numeric_limits<double>::infinity());
|
||||
currentValue().swapPayload(v);
|
||||
currentValue().setOffsetStart(token.start_ - begin_);
|
||||
currentValue().setOffsetLimit(token.end_ - begin_);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case tokenArraySeparator:
|
||||
case tokenObjectEnd:
|
||||
case tokenArrayEnd:
|
||||
@ -1234,9 +1222,9 @@ bool OurReader::readToken(Token& token) {
|
||||
break;
|
||||
case '\'':
|
||||
if (features_.allowSingleQuotes_) {
|
||||
token.type_ = tokenString;
|
||||
ok = readStringSingleQuote();
|
||||
break;
|
||||
token.type_ = tokenString;
|
||||
ok = readStringSingleQuote();
|
||||
break;
|
||||
} // else fall through
|
||||
case '/':
|
||||
token.type_ = tokenComment;
|
||||
@ -1354,7 +1342,8 @@ bool OurReader::readComment() {
|
||||
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;
|
||||
normalized.reserve(static_cast<size_t>(end - begin));
|
||||
OurReader::Location current = begin;
|
||||
@ -1362,8 +1351,8 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc
|
||||
char c = *current++;
|
||||
if (c == '\r') {
|
||||
if (current != end && *current == '\n')
|
||||
// convert dos EOL
|
||||
++current;
|
||||
// convert dos EOL
|
||||
++current;
|
||||
// convert Mac EOL
|
||||
normalized += '\n';
|
||||
} else {
|
||||
@ -1373,8 +1362,9 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc
|
||||
return normalized;
|
||||
}
|
||||
|
||||
void
|
||||
OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
|
||||
void OurReader::addComment(Location begin,
|
||||
Location end,
|
||||
CommentPlacement placement) {
|
||||
assert(collectComments_);
|
||||
const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
|
||||
if (placement == commentAfterOnSameLine) {
|
||||
@ -1411,7 +1401,7 @@ bool OurReader::readCppStyleComment() {
|
||||
}
|
||||
|
||||
bool OurReader::readNumber(bool checkInf) {
|
||||
const char *p = current_;
|
||||
const char* p = current_;
|
||||
if (checkInf && p != end_ && *p == 'I') {
|
||||
current_ = ++p;
|
||||
return false;
|
||||
@ -1448,7 +1438,6 @@ bool OurReader::readString() {
|
||||
return c == '"';
|
||||
}
|
||||
|
||||
|
||||
bool OurReader::readStringSingleQuote() {
|
||||
Char c = 0;
|
||||
while (current_ != end_) {
|
||||
@ -1490,14 +1479,14 @@ bool OurReader::readObject(Token& tokenStart) {
|
||||
|
||||
Token colon;
|
||||
if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
|
||||
return addErrorAndRecover(
|
||||
"Missing ':' after object member name", colon, tokenObjectEnd);
|
||||
return addErrorAndRecover("Missing ':' after object member name", colon,
|
||||
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)) {
|
||||
JSONCPP_STRING msg = "Duplicate key: '" + name + "'";
|
||||
return addErrorAndRecover(
|
||||
msg, tokenName, tokenObjectEnd);
|
||||
return addErrorAndRecover(msg, tokenName, tokenObjectEnd);
|
||||
}
|
||||
Value& value = currentValue()[name];
|
||||
nodes_.push(&value);
|
||||
@ -1510,8 +1499,8 @@ bool OurReader::readObject(Token& tokenStart) {
|
||||
if (!readToken(comma) ||
|
||||
(comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
|
||||
comma.type_ != tokenComment)) {
|
||||
return addErrorAndRecover(
|
||||
"Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
|
||||
return addErrorAndRecover("Missing ',' or '}' in object declaration",
|
||||
comma, tokenObjectEnd);
|
||||
}
|
||||
bool finalizeTokenOk = true;
|
||||
while (comma.type_ == tokenComment && finalizeTokenOk)
|
||||
@ -1519,8 +1508,8 @@ bool OurReader::readObject(Token& tokenStart) {
|
||||
if (comma.type_ == tokenObjectEnd)
|
||||
return true;
|
||||
}
|
||||
return addErrorAndRecover(
|
||||
"Missing '}' or object member name", tokenName, tokenObjectEnd);
|
||||
return addErrorAndRecover("Missing '}' or object member name", tokenName,
|
||||
tokenObjectEnd);
|
||||
}
|
||||
|
||||
bool OurReader::readArray(Token& tokenStart) {
|
||||
@ -1552,8 +1541,8 @@ bool OurReader::readArray(Token& tokenStart) {
|
||||
bool badTokenType =
|
||||
(token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
|
||||
if (!ok || badTokenType) {
|
||||
return addErrorAndRecover(
|
||||
"Missing ',' or ']' in array declaration", token, tokenArrayEnd);
|
||||
return addErrorAndRecover("Missing ',' or ']' in array declaration",
|
||||
token, tokenArrayEnd);
|
||||
}
|
||||
if (token.type_ == tokenArrayEnd)
|
||||
break;
|
||||
@ -1579,7 +1568,8 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
|
||||
bool isNegative = *current == '-';
|
||||
if (isNegative)
|
||||
++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 =
|
||||
isNegative ? Value::LargestUInt(-Value::minLargestInt)
|
||||
: Value::maxLargestUInt;
|
||||
@ -1724,9 +1714,9 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) {
|
||||
}
|
||||
|
||||
bool OurReader::decodeUnicodeCodePoint(Token& token,
|
||||
Location& current,
|
||||
Location end,
|
||||
unsigned int& unicode) {
|
||||
Location& current,
|
||||
Location end,
|
||||
unsigned int& unicode) {
|
||||
|
||||
if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
|
||||
return false;
|
||||
@ -1735,8 +1725,7 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
|
||||
if (end - current < 6)
|
||||
return addError(
|
||||
"additional six characters expected to parse unicode surrogate pair.",
|
||||
token,
|
||||
current);
|
||||
token, current);
|
||||
unsigned int surrogatePair;
|
||||
if (*(current++) == '\\' && *(current++) == 'u') {
|
||||
if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
|
||||
@ -1746,20 +1735,18 @@ bool OurReader::decodeUnicodeCodePoint(Token& token,
|
||||
} else
|
||||
return addError("expecting another \\u token to begin the second half of "
|
||||
"a unicode surrogate pair",
|
||||
token,
|
||||
current);
|
||||
token, current);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OurReader::decodeUnicodeEscapeSequence(Token& token,
|
||||
Location& current,
|
||||
Location end,
|
||||
unsigned int& ret_unicode) {
|
||||
Location& current,
|
||||
Location end,
|
||||
unsigned int& ret_unicode) {
|
||||
if (end - current < 4)
|
||||
return addError(
|
||||
"Bad unicode escape sequence in string: four digits expected.",
|
||||
token,
|
||||
"Bad unicode escape sequence in string: four digits expected.", token,
|
||||
current);
|
||||
int unicode = 0;
|
||||
for (int index = 0; index < 4; ++index) {
|
||||
@ -1774,15 +1761,15 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token,
|
||||
else
|
||||
return addError(
|
||||
"Bad unicode escape sequence in string: hexadecimal digit expected.",
|
||||
token,
|
||||
current);
|
||||
token, current);
|
||||
}
|
||||
ret_unicode = static_cast<unsigned int>(unicode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
|
||||
bool OurReader::addError(const JSONCPP_STRING& message,
|
||||
Token& token,
|
||||
Location extra) {
|
||||
ErrorInfo info;
|
||||
info.token_ = token;
|
||||
info.message_ = message;
|
||||
@ -1805,8 +1792,8 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) {
|
||||
}
|
||||
|
||||
bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message,
|
||||
Token& token,
|
||||
TokenType skipUntilToken) {
|
||||
Token& token,
|
||||
TokenType skipUntilToken) {
|
||||
addError(message, token);
|
||||
return recoverFromError(skipUntilToken);
|
||||
}
|
||||
@ -1820,8 +1807,8 @@ OurReader::Char OurReader::getNextChar() {
|
||||
}
|
||||
|
||||
void OurReader::getLocationLineAndColumn(Location location,
|
||||
int& line,
|
||||
int& column) const {
|
||||
int& line,
|
||||
int& column) const {
|
||||
Location current = begin_;
|
||||
Location lastLineStart = current;
|
||||
line = 0;
|
||||
@ -1853,8 +1840,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const {
|
||||
JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
|
||||
JSONCPP_STRING formattedMessage;
|
||||
for (Errors::const_iterator itError = errors_.begin();
|
||||
itError != errors_.end();
|
||||
++itError) {
|
||||
itError != errors_.end(); ++itError) {
|
||||
const ErrorInfo& error = *itError;
|
||||
formattedMessage +=
|
||||
"* " + 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> allErrors;
|
||||
for (Errors::const_iterator itError = errors_.begin();
|
||||
itError != errors_.end();
|
||||
++itError) {
|
||||
itError != errors_.end(); ++itError) {
|
||||
const ErrorInfo& error = *itError;
|
||||
OurReader::StructuredError structured;
|
||||
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) {
|
||||
ptrdiff_t length = end_ - begin_;
|
||||
if(value.getOffsetStart() > length
|
||||
|| value.getOffsetLimit() > length)
|
||||
if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
|
||||
return false;
|
||||
Token token;
|
||||
token.type_ = tokenError;
|
||||
@ -1898,11 +1882,12 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
|
||||
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_;
|
||||
if(value.getOffsetStart() > length
|
||||
|| value.getOffsetLimit() > length
|
||||
|| extra.getOffsetLimit() > length)
|
||||
if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
|
||||
extra.getOffsetLimit() > length)
|
||||
return false;
|
||||
Token token;
|
||||
token.type_ = tokenError;
|
||||
@ -1916,24 +1901,19 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, con
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OurReader::good() const {
|
||||
return !errors_.size();
|
||||
}
|
||||
|
||||
bool OurReader::good() const { return !errors_.size(); }
|
||||
|
||||
class OurCharReader : public CharReader {
|
||||
bool const collectComments_;
|
||||
OurReader reader_;
|
||||
|
||||
public:
|
||||
OurCharReader(
|
||||
bool collectComments,
|
||||
OurFeatures const& features)
|
||||
: collectComments_(collectComments)
|
||||
, reader_(features)
|
||||
{}
|
||||
bool parse(
|
||||
char const* beginDoc, char const* endDoc,
|
||||
Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
|
||||
OurCharReader(bool collectComments, OurFeatures const& features)
|
||||
: collectComments_(collectComments), reader_(features) {}
|
||||
bool parse(char const* beginDoc,
|
||||
char const* endDoc,
|
||||
Value* root,
|
||||
JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
|
||||
bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
|
||||
if (errs) {
|
||||
*errs = reader_.getFormattedErrorMessages();
|
||||
@ -1942,19 +1922,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CharReaderBuilder::CharReaderBuilder()
|
||||
{
|
||||
setDefaults(&settings_);
|
||||
}
|
||||
CharReaderBuilder::~CharReaderBuilder()
|
||||
{}
|
||||
CharReader* CharReaderBuilder::newCharReader() const
|
||||
{
|
||||
CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }
|
||||
CharReaderBuilder::~CharReaderBuilder() {}
|
||||
CharReader* CharReaderBuilder::newCharReader() const {
|
||||
bool collectComments = settings_["collectComments"].asBool();
|
||||
OurFeatures features = OurFeatures::all();
|
||||
features.allowComments_ = settings_["allowComments"].asBool();
|
||||
features.strictRoot_ = settings_["strictRoot"].asBool();
|
||||
features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
|
||||
features.allowDroppedNullPlaceholders_ =
|
||||
settings_["allowDroppedNullPlaceholders"].asBool();
|
||||
features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
|
||||
features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
|
||||
features.stackLimit_ = settings_["stackLimit"].asInt();
|
||||
@ -1963,8 +1939,7 @@ CharReader* CharReaderBuilder::newCharReader() const
|
||||
features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
|
||||
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->insert("collectComments");
|
||||
valid_keys->insert("allowComments");
|
||||
@ -1977,10 +1952,10 @@ static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
|
||||
valid_keys->insert("rejectDupKeys");
|
||||
valid_keys->insert("allowSpecialFloats");
|
||||
}
|
||||
bool CharReaderBuilder::validate(Json::Value* invalid) const
|
||||
{
|
||||
bool CharReaderBuilder::validate(Json::Value* invalid) const {
|
||||
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;
|
||||
std::set<JSONCPP_STRING> valid_keys;
|
||||
getValidReaderKeys(&valid_keys);
|
||||
@ -1994,14 +1969,12 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const
|
||||
}
|
||||
return 0u == inv.size();
|
||||
}
|
||||
Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
|
||||
{
|
||||
Value& CharReaderBuilder::operator[](JSONCPP_STRING key) {
|
||||
return settings_[key];
|
||||
}
|
||||
// static
|
||||
void CharReaderBuilder::strictMode(Json::Value* settings)
|
||||
{
|
||||
//! [CharReaderBuilderStrictMode]
|
||||
void CharReaderBuilder::strictMode(Json::Value* settings) {
|
||||
//! [CharReaderBuilderStrictMode]
|
||||
(*settings)["allowComments"] = false;
|
||||
(*settings)["strictRoot"] = true;
|
||||
(*settings)["allowDroppedNullPlaceholders"] = false;
|
||||
@ -2011,12 +1984,11 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
|
||||
(*settings)["failIfExtra"] = true;
|
||||
(*settings)["rejectDupKeys"] = true;
|
||||
(*settings)["allowSpecialFloats"] = false;
|
||||
//! [CharReaderBuilderStrictMode]
|
||||
//! [CharReaderBuilderStrictMode]
|
||||
}
|
||||
// static
|
||||
void CharReaderBuilder::setDefaults(Json::Value* settings)
|
||||
{
|
||||
//! [CharReaderBuilderDefaults]
|
||||
void CharReaderBuilder::setDefaults(Json::Value* settings) {
|
||||
//! [CharReaderBuilderDefaults]
|
||||
(*settings)["collectComments"] = true;
|
||||
(*settings)["allowComments"] = true;
|
||||
(*settings)["strictRoot"] = false;
|
||||
@ -2027,16 +1999,16 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
|
||||
(*settings)["failIfExtra"] = false;
|
||||
(*settings)["rejectDupKeys"] = false;
|
||||
(*settings)["allowSpecialFloats"] = false;
|
||||
//! [CharReaderBuilderDefaults]
|
||||
//! [CharReaderBuilderDefaults]
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// global functions
|
||||
|
||||
bool parseFromStream(
|
||||
CharReader::Factory const& fact, JSONCPP_ISTREAM& sin,
|
||||
Value* root, JSONCPP_STRING* errs)
|
||||
{
|
||||
bool parseFromStream(CharReader::Factory const& fact,
|
||||
JSONCPP_ISTREAM& sin,
|
||||
Value* root,
|
||||
JSONCPP_STRING* errs) {
|
||||
JSONCPP_OSTRINGSTREAM ssin;
|
||||
ssin << sin.rdbuf();
|
||||
JSONCPP_STRING doc = ssin.str();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
|
||||
#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
|
||||
|
||||
#include <json/config.h>
|
||||
|
||||
// Also support old flag NO_LOCALE_SUPPORT
|
||||
#ifdef NO_LOCALE_SUPPORT
|
||||
@ -23,7 +24,7 @@
|
||||
*/
|
||||
|
||||
namespace Json {
|
||||
static char getDecimalPoint() {
|
||||
static inline char getDecimalPoint() {
|
||||
#ifdef JSONCPP_NO_LOCALE_SUPPORT
|
||||
return '\0';
|
||||
#else
|
||||
@ -88,8 +89,7 @@ static inline void uintToString(LargestUInt value, char*& current) {
|
||||
* We had a sophisticated way, but it did not work in WinCE.
|
||||
* @see https://github.com/open-source-parsers/jsoncpp/pull/9
|
||||
*/
|
||||
template <typename Iter>
|
||||
Iter fixNumericLocale(Iter begin, Iter end) {
|
||||
template <typename Iter> Iter fixNumericLocale(Iter begin, Iter end) {
|
||||
for (; begin != end; ++begin) {
|
||||
if (*begin == ',') {
|
||||
*begin = '.';
|
||||
@ -98,8 +98,7 @@ Iter fixNumericLocale(Iter begin, Iter end) {
|
||||
return begin;
|
||||
}
|
||||
|
||||
template <typename Iter>
|
||||
void fixNumericLocaleInput(Iter begin, Iter end) {
|
||||
template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
|
||||
char decimalPoint = getDecimalPoint();
|
||||
if (decimalPoint == '\0' || decimalPoint == '.') {
|
||||
return;
|
||||
@ -115,14 +114,13 @@ void fixNumericLocaleInput(Iter begin, Iter end) {
|
||||
* 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 '.'.
|
||||
*/
|
||||
template <typename Iter>
|
||||
Iter fixZerosInTheEnd(Iter begin, Iter end) {
|
||||
template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
|
||||
for (; begin != end; --end) {
|
||||
if (*(end-1) != '0') {
|
||||
if (*(end - 1) != '0') {
|
||||
return end;
|
||||
}
|
||||
// Don't delete the last zero before the decimal point.
|
||||
if (begin != (end-1) && *(end-2) == '.') {
|
||||
if (begin != (end - 1) && *(end - 2) == '.') {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
@ -8,20 +8,20 @@
|
||||
#include <json/value.h>
|
||||
#include <json/writer.h>
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#ifdef JSON_USE_CPPTL
|
||||
#include <cpptl/conststring.h>
|
||||
#endif
|
||||
#include <cstddef> // size_t
|
||||
#include <algorithm> // min()
|
||||
#include <cstddef> // size_t
|
||||
|
||||
// Disable warning C4702 : unreachable code
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above
|
||||
#pragma warning(disable:4702)
|
||||
#pragma warning(disable : 4702)
|
||||
#endif
|
||||
|
||||
#define JSON_ASSERT_UNREACHABLE assert(false)
|
||||
@ -36,20 +36,19 @@ namespace Json {
|
||||
#else
|
||||
#define ALIGNAS(byte_alignment)
|
||||
#endif
|
||||
//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
|
||||
//const unsigned char& kNullRef = kNull[0];
|
||||
//const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
|
||||
//const Value& Value::nullRef = null;
|
||||
// static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
|
||||
// const unsigned char& kNullRef = kNull[0];
|
||||
// const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
|
||||
// const Value& Value::nullRef = null;
|
||||
|
||||
// static
|
||||
Value const& Value::nullSingleton()
|
||||
{
|
||||
static Value const nullStatic;
|
||||
return nullStatic;
|
||||
Value const& Value::nullSingleton() {
|
||||
static Value const nullStatic;
|
||||
return nullStatic;
|
||||
}
|
||||
|
||||
// for backwards compatibility, we'll leave these global references around, but DO NOT
|
||||
// use them in JSONCPP library code any more!
|
||||
// for backwards compatibility, we'll leave these global references around, but
|
||||
// DO NOT use them in JSONCPP library code any more!
|
||||
Value const& Value::null = 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) {
|
||||
// The casts can lose precision, but we are looking only for
|
||||
// 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;
|
||||
}
|
||||
#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
|
||||
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) {
|
||||
@ -101,9 +101,7 @@ static inline bool InRange(double d, T min, U max) {
|
||||
* computed using strlen(value).
|
||||
* @return Pointer on the duplicate instance of string.
|
||||
*/
|
||||
static inline char* duplicateStringValue(const char* value,
|
||||
size_t length)
|
||||
{
|
||||
static inline char* duplicateStringValue(const char* value, size_t length) {
|
||||
// Avoid an integer overflow in the call to malloc below by limiting length
|
||||
// to a sane value.
|
||||
if (length >= static_cast<size_t>(Value::maxInt))
|
||||
@ -111,9 +109,8 @@ static inline char* duplicateStringValue(const char* value,
|
||||
|
||||
char* newString = static_cast<char*>(malloc(length + 1));
|
||||
if (newString == NULL) {
|
||||
throwRuntimeError(
|
||||
"in Json::Value::duplicateStringValue(): "
|
||||
"Failed to allocate string value buffer");
|
||||
throwRuntimeError("in Json::Value::duplicateStringValue(): "
|
||||
"Failed to allocate string value buffer");
|
||||
}
|
||||
memcpy(newString, value, length);
|
||||
newString[length] = 0;
|
||||
@ -122,31 +119,30 @@ static inline char* duplicateStringValue(const char* value,
|
||||
|
||||
/* Record the length as a prefix.
|
||||
*/
|
||||
static inline char* duplicateAndPrefixStringValue(
|
||||
const char* value,
|
||||
unsigned int length)
|
||||
{
|
||||
static inline char* duplicateAndPrefixStringValue(const char* value,
|
||||
unsigned int length) {
|
||||
// Avoid an integer overflow in the call to malloc below by limiting length
|
||||
// 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(): "
|
||||
"length too big for prefixing");
|
||||
unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
|
||||
char* newString = static_cast<char*>(malloc(actualLength));
|
||||
if (newString == 0) {
|
||||
throwRuntimeError(
|
||||
"in Json::Value::duplicateAndPrefixStringValue(): "
|
||||
"Failed to allocate string value buffer");
|
||||
throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): "
|
||||
"Failed to allocate string value buffer");
|
||||
}
|
||||
*reinterpret_cast<unsigned*>(newString) = 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;
|
||||
}
|
||||
inline static void decodePrefixedString(
|
||||
bool isPrefixed, char const* prefixed,
|
||||
unsigned* length, char const** value)
|
||||
{
|
||||
inline static void decodePrefixedString(bool isPrefixed,
|
||||
char const* prefixed,
|
||||
unsigned* length,
|
||||
char const** value) {
|
||||
if (!isPrefixed) {
|
||||
*length = static_cast<unsigned>(strlen(prefixed));
|
||||
*value = prefixed;
|
||||
@ -155,7 +151,8 @@ inline static void decodePrefixedString(
|
||||
*value = prefixed + sizeof(unsigned);
|
||||
}
|
||||
}
|
||||
/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
|
||||
/** Free the string duplicated by
|
||||
* duplicateStringValue()/duplicateAndPrefixStringValue().
|
||||
*/
|
||||
#if JSONCPP_USING_SECURE_MEMORY
|
||||
static inline void releasePrefixedStringValue(char* value) {
|
||||
@ -168,17 +165,13 @@ static inline void releasePrefixedStringValue(char* value) {
|
||||
}
|
||||
static inline void releaseStringValue(char* value, unsigned length) {
|
||||
// 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);
|
||||
free(value);
|
||||
}
|
||||
#else // !JSONCPP_USING_SECURE_MEMORY
|
||||
static inline void releasePrefixedStringValue(char* value) {
|
||||
free(value);
|
||||
}
|
||||
static inline void releaseStringValue(char* value, unsigned) {
|
||||
free(value);
|
||||
}
|
||||
#else // !JSONCPP_USING_SECURE_MEMORY
|
||||
static inline void releasePrefixedStringValue(char* value) { free(value); }
|
||||
static inline void releaseStringValue(char* value, unsigned) { free(value); }
|
||||
#endif // JSONCPP_USING_SECURE_MEMORY
|
||||
|
||||
} // namespace Json
|
||||
@ -197,27 +190,15 @@ static inline void releaseStringValue(char* value, unsigned) {
|
||||
|
||||
namespace Json {
|
||||
|
||||
Exception::Exception(JSONCPP_STRING const& msg)
|
||||
: msg_(msg)
|
||||
{}
|
||||
Exception::~Exception() JSONCPP_NOEXCEPT
|
||||
{}
|
||||
char const* Exception::what() const JSONCPP_NOEXCEPT
|
||||
{
|
||||
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)
|
||||
{
|
||||
Exception::Exception(JSONCPP_STRING const& msg) : msg_(msg) {}
|
||||
Exception::~Exception() JSONCPP_NOEXCEPT {}
|
||||
char const* Exception::what() const JSONCPP_NOEXCEPT { 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);
|
||||
}
|
||||
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
|
||||
{
|
||||
JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& 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() {
|
||||
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(char const* str, unsigned ulength, DuplicationPolicy allocate)
|
||||
Value::CZString::CZString(char const* str,
|
||||
unsigned ulength,
|
||||
DuplicationPolicy allocate)
|
||||
: cstr_(str) {
|
||||
// allocate != duplicate
|
||||
storage_.policy_ = allocate & 0x3;
|
||||
@ -272,25 +254,34 @@ Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy a
|
||||
|
||||
Value::CZString::CZString(const CZString& other) {
|
||||
cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
|
||||
? duplicateStringValue(other.cstr_, other.storage_.length_)
|
||||
: other.cstr_);
|
||||
storage_.policy_ = static_cast<unsigned>(other.cstr_
|
||||
? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
|
||||
? noDuplication : duplicate)
|
||||
: static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U;
|
||||
? duplicateStringValue(other.cstr_, other.storage_.length_)
|
||||
: other.cstr_);
|
||||
storage_.policy_ =
|
||||
static_cast<unsigned>(
|
||||
other.cstr_
|
||||
? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
|
||||
noDuplication
|
||||
? noDuplication
|
||||
: duplicate)
|
||||
: static_cast<DuplicationPolicy>(other.storage_.policy_)) &
|
||||
3U;
|
||||
storage_.length_ = other.storage_.length_;
|
||||
}
|
||||
|
||||
#if JSON_HAS_RVALUE_REFERENCES
|
||||
Value::CZString::CZString(CZString&& other)
|
||||
: cstr_(other.cstr_), index_(other.index_) {
|
||||
: cstr_(other.cstr_), index_(other.index_) {
|
||||
other.cstr_ = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
Value::CZString::~CZString() {
|
||||
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
|
||||
|
||||
bool Value::CZString::operator<(const CZString& other) const {
|
||||
if (!cstr_) return index_ < other.index_;
|
||||
//return strcmp(cstr_, other.cstr_) < 0;
|
||||
if (!cstr_)
|
||||
return index_ < other.index_;
|
||||
// return strcmp(cstr_, other.cstr_) < 0;
|
||||
// Assume both are strings.
|
||||
unsigned this_len = this->storage_.length_;
|
||||
unsigned other_len = other.storage_.length_;
|
||||
unsigned min_len = std::min<unsigned>(this_len, other_len);
|
||||
JSON_ASSERT(this->cstr_ && other.cstr_);
|
||||
int comp = memcmp(this->cstr_, other.cstr_, min_len);
|
||||
if (comp < 0) return true;
|
||||
if (comp > 0) return false;
|
||||
if (comp < 0)
|
||||
return true;
|
||||
if (comp > 0)
|
||||
return false;
|
||||
return (this_len < other_len);
|
||||
}
|
||||
|
||||
bool Value::CZString::operator==(const CZString& other) const {
|
||||
if (!cstr_) return index_ == other.index_;
|
||||
//return strcmp(cstr_, other.cstr_) == 0;
|
||||
if (!cstr_)
|
||||
return index_ == other.index_;
|
||||
// return strcmp(cstr_, other.cstr_) == 0;
|
||||
// Assume both are strings.
|
||||
unsigned this_len = this->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_);
|
||||
int comp = memcmp(this->cstr_, other.cstr_, this_len);
|
||||
return comp == 0;
|
||||
@ -342,10 +338,12 @@ bool Value::CZString::operator==(const CZString& other) const {
|
||||
|
||||
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_; }
|
||||
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) {
|
||||
initBasic(stringValue, true);
|
||||
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) {
|
||||
initBasic(stringValue, true);
|
||||
value_.string_ =
|
||||
duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
|
||||
value_.string_ = duplicateAndPrefixStringValue(
|
||||
beginValue, static_cast<unsigned>(endValue - beginValue));
|
||||
}
|
||||
|
||||
Value::Value(const JSONCPP_STRING& value) {
|
||||
initBasic(stringValue, true);
|
||||
value_.string_ =
|
||||
duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
|
||||
value_.string_ = duplicateAndPrefixStringValue(
|
||||
value.data(), static_cast<unsigned>(value.length()));
|
||||
}
|
||||
|
||||
Value::Value(const StaticString& value) {
|
||||
@ -439,7 +438,8 @@ Value::Value(const StaticString& value) {
|
||||
#ifdef JSON_USE_CPPTL
|
||||
Value::Value(const CppTL::ConstString& value) {
|
||||
initBasic(stringValue, true);
|
||||
value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
|
||||
value_.string_ = duplicateAndPrefixStringValue(
|
||||
value, static_cast<unsigned>(value.length()));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -527,23 +527,28 @@ bool Value::operator<(const Value& other) const {
|
||||
return value_.real_ < other.value_.real_;
|
||||
case booleanValue:
|
||||
return value_.bool_ < other.value_.bool_;
|
||||
case stringValue:
|
||||
{
|
||||
case stringValue: {
|
||||
if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
|
||||
if (other.value_.string_) return true;
|
||||
else return false;
|
||||
if (other.value_.string_)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
unsigned this_len;
|
||||
unsigned other_len;
|
||||
char const* this_str;
|
||||
char const* other_str;
|
||||
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
||||
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
|
||||
decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
|
||||
&this_str);
|
||||
decodePrefixedString(other.allocated_, other.value_.string_, &other_len,
|
||||
&other_str);
|
||||
unsigned min_len = std::min<unsigned>(this_len, other_len);
|
||||
JSON_ASSERT(this_str && other_str);
|
||||
int comp = memcmp(this_str, other_str, min_len);
|
||||
if (comp < 0) return true;
|
||||
if (comp > 0) return false;
|
||||
if (comp < 0)
|
||||
return true;
|
||||
if (comp > 0)
|
||||
return false;
|
||||
return (this_len < other_len);
|
||||
}
|
||||
case arrayValue:
|
||||
@ -584,8 +589,7 @@ bool Value::operator==(const Value& other) const {
|
||||
return value_.real_ == other.value_.real_;
|
||||
case booleanValue:
|
||||
return value_.bool_ == other.value_.bool_;
|
||||
case stringValue:
|
||||
{
|
||||
case stringValue: {
|
||||
if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
|
||||
return (value_.string_ == other.value_.string_);
|
||||
}
|
||||
@ -593,9 +597,12 @@ bool Value::operator==(const Value& other) const {
|
||||
unsigned other_len;
|
||||
char const* this_str;
|
||||
char const* other_str;
|
||||
decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
|
||||
decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
|
||||
if (this_len != other_len) return false;
|
||||
decodePrefixedString(this->allocated_, this->value_.string_, &this_len,
|
||||
&this_str);
|
||||
decodePrefixedString(other.allocated_, other.value_.string_, &other_len,
|
||||
&other_str);
|
||||
if (this_len != other_len)
|
||||
return false;
|
||||
JSON_ASSERT(this_str && other_str);
|
||||
int comp = memcmp(this_str, other_str, this_len);
|
||||
return comp == 0;
|
||||
@ -615,28 +622,34 @@ bool Value::operator!=(const Value& other) const { return !(*this == other); }
|
||||
const char* Value::asCString() const {
|
||||
JSON_ASSERT_MESSAGE(type_ == stringValue,
|
||||
"in Json::Value::asCString(): requires stringValue");
|
||||
if (value_.string_ == 0) return 0;
|
||||
if (value_.string_ == 0)
|
||||
return 0;
|
||||
unsigned this_len;
|
||||
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;
|
||||
}
|
||||
|
||||
#if JSONCPP_USING_SECURE_MEMORY
|
||||
unsigned Value::getCStringLength() const {
|
||||
JSON_ASSERT_MESSAGE(type_ == stringValue,
|
||||
"in Json::Value::asCString(): requires stringValue");
|
||||
if (value_.string_ == 0) return 0;
|
||||
"in Json::Value::asCString(): requires stringValue");
|
||||
if (value_.string_ == 0)
|
||||
return 0;
|
||||
unsigned this_len;
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Value::getString(char const** str, char const** cend) const {
|
||||
if (type_ != stringValue) return false;
|
||||
if (value_.string_ == 0) return false;
|
||||
if (type_ != stringValue)
|
||||
return false;
|
||||
if (value_.string_ == 0)
|
||||
return false;
|
||||
unsigned length;
|
||||
decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
|
||||
*cend = *str + length;
|
||||
@ -647,12 +660,13 @@ JSONCPP_STRING Value::asString() const {
|
||||
switch (type_) {
|
||||
case nullValue:
|
||||
return "";
|
||||
case stringValue:
|
||||
{
|
||||
if (value_.string_ == 0) return "";
|
||||
case stringValue: {
|
||||
if (value_.string_ == 0)
|
||||
return "";
|
||||
unsigned this_len;
|
||||
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);
|
||||
}
|
||||
case booleanValue:
|
||||
@ -672,8 +686,7 @@ JSONCPP_STRING Value::asString() const {
|
||||
CppTL::ConstString Value::asConstString() const {
|
||||
unsigned len;
|
||||
char const* str;
|
||||
decodePrefixedString(allocated_, value_.string_,
|
||||
&len, &str);
|
||||
decodePrefixedString(allocated_, value_.string_, &len, &str);
|
||||
return CppTL::ConstString(str, len);
|
||||
}
|
||||
#endif
|
||||
@ -911,7 +924,7 @@ bool Value::empty() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Value::operator bool() const { return ! isNull(); }
|
||||
Value::operator bool() const { return !isNull(); }
|
||||
|
||||
void Value::clear() {
|
||||
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
|
||||
@ -1013,8 +1026,7 @@ void Value::dupPayload(const Value& other) {
|
||||
if (other.value_.string_ && other.allocated_) {
|
||||
unsigned len;
|
||||
char const* str;
|
||||
decodePrefixedString(other.allocated_, other.value_.string_,
|
||||
&len, &str);
|
||||
decodePrefixedString(other.allocated_, other.value_.string_, &len, &str);
|
||||
value_.string_ = duplicateAndPrefixStringValue(str, len);
|
||||
allocated_ = true;
|
||||
} else {
|
||||
@ -1057,8 +1069,8 @@ void Value::dupMeta(const Value& other) {
|
||||
for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
|
||||
const CommentInfo& otherComment = other.comments_[comment];
|
||||
if (otherComment.comment_)
|
||||
comments_[comment].setComment(
|
||||
otherComment.comment_, strlen(otherComment.comment_));
|
||||
comments_[comment].setComment(otherComment.comment_,
|
||||
strlen(otherComment.comment_));
|
||||
}
|
||||
} else {
|
||||
comments_ = 0;
|
||||
@ -1076,8 +1088,8 @@ Value& Value::resolveReference(const char* key) {
|
||||
"in Json::Value::resolveReference(): requires objectValue");
|
||||
if (type_ == nullValue)
|
||||
*this = Value(objectValue);
|
||||
CZString actualKey(
|
||||
key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
|
||||
CZString actualKey(key, static_cast<unsigned>(strlen(key)),
|
||||
CZString::noDuplication); // NOTE!
|
||||
ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
|
||||
if (it != value_.map_->end() && (*it).first == actualKey)
|
||||
return (*it).second;
|
||||
@ -1089,15 +1101,14 @@ Value& Value::resolveReference(const char* key) {
|
||||
}
|
||||
|
||||
// @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(
|
||||
type_ == nullValue || type_ == objectValue,
|
||||
"in Json::Value::resolveReference(key, end): requires objectValue");
|
||||
if (type_ == nullValue)
|
||||
*this = Value(objectValue);
|
||||
CZString actualKey(
|
||||
key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
|
||||
CZString actualKey(key, static_cast<unsigned>(cend - key),
|
||||
CZString::duplicateOnCopy);
|
||||
ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
|
||||
if (it != value_.map_->end() && (*it).first == actualKey)
|
||||
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(); }
|
||||
|
||||
Value const* Value::find(char const* key, char const* cend) const
|
||||
{
|
||||
JSON_ASSERT_MESSAGE(
|
||||
type_ == nullValue || type_ == objectValue,
|
||||
"in Json::Value::find(key, end, found): requires objectValue or nullValue");
|
||||
if (type_ == nullValue) return NULL;
|
||||
CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
|
||||
Value const* Value::find(char const* key, char const* cend) const {
|
||||
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
|
||||
"in Json::Value::find(key, end, found): requires "
|
||||
"objectValue or nullValue");
|
||||
if (type_ == nullValue)
|
||||
return NULL;
|
||||
CZString actualKey(key, static_cast<unsigned>(cend - key),
|
||||
CZString::noDuplication);
|
||||
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;
|
||||
}
|
||||
const Value& Value::operator[](const char* key) const
|
||||
{
|
||||
const Value& Value::operator[](const char* key) const {
|
||||
Value const* found = find(key, key + strlen(key));
|
||||
if (!found) return nullSingleton();
|
||||
if (!found)
|
||||
return nullSingleton();
|
||||
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());
|
||||
if (!found) return nullSingleton();
|
||||
if (!found)
|
||||
return nullSingleton();
|
||||
return *found;
|
||||
}
|
||||
|
||||
@ -1155,10 +1168,10 @@ Value& Value::operator[](const StaticString& key) {
|
||||
Value& Value::operator[](const CppTL::ConstString& key) {
|
||||
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());
|
||||
if (!found) return nullSingleton();
|
||||
if (!found)
|
||||
return nullSingleton();
|
||||
return *found;
|
||||
}
|
||||
#endif
|
||||
@ -1166,30 +1179,30 @@ Value const& Value::operator[](CppTL::ConstString const& key) const
|
||||
Value& Value::append(const Value& value) { return (*this)[size()] = value; }
|
||||
|
||||
#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
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
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);
|
||||
if (it == value_.map_->end())
|
||||
return false;
|
||||
@ -1202,16 +1215,13 @@ bool Value::removeMember(const char* key, const char* cend, Value* removed)
|
||||
value_.map_->erase(it);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
void Value::removeMember(const char* key)
|
||||
{
|
||||
void Value::removeMember(const char* key) {
|
||||
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
|
||||
"in Json::Value::removeMember(): requires objectValue");
|
||||
if (type_ == nullValue)
|
||||
@ -1220,8 +1230,7 @@ void Value::removeMember(const char* key)
|
||||
CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
|
||||
value_.map_->erase(actualKey);
|
||||
}
|
||||
void Value::removeMember(const JSONCPP_STRING& key)
|
||||
{
|
||||
void Value::removeMember(const JSONCPP_STRING& key) {
|
||||
removeMember(key.c_str());
|
||||
}
|
||||
|
||||
@ -1237,7 +1246,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) {
|
||||
*removed = it->second;
|
||||
ArrayIndex oldSize = size();
|
||||
// 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);
|
||||
(*value_.map_)[keey] = (*this)[i + 1];
|
||||
}
|
||||
@ -1255,17 +1264,14 @@ Value Value::get(const CppTL::ConstString& key,
|
||||
}
|
||||
#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);
|
||||
return NULL != value;
|
||||
}
|
||||
bool Value::isMember(char const* key) const
|
||||
{
|
||||
bool Value::isMember(char const* key) const {
|
||||
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());
|
||||
}
|
||||
|
||||
@ -1286,8 +1292,7 @@ Value::Members Value::getMemberNames() const {
|
||||
ObjectValues::const_iterator it = value_.map_->begin();
|
||||
ObjectValues::const_iterator itEnd = value_.map_->end();
|
||||
for (; it != itEnd; ++it) {
|
||||
members.push_back(JSONCPP_STRING((*it).first.data(),
|
||||
(*it).first.length()));
|
||||
members.push_back(JSONCPP_STRING((*it).first.data(), (*it).first.length()));
|
||||
}
|
||||
return members;
|
||||
}
|
||||
@ -1410,25 +1415,29 @@ bool Value::isUInt64() const {
|
||||
|
||||
bool Value::isIntegral() const {
|
||||
switch (type_) {
|
||||
case intValue:
|
||||
case uintValue:
|
||||
return true;
|
||||
case realValue:
|
||||
case intValue:
|
||||
case uintValue:
|
||||
return true;
|
||||
case realValue:
|
||||
#if defined(JSON_HAS_INT64)
|
||||
// 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
|
||||
// require the value to be strictly less than the limit.
|
||||
return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
|
||||
// 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
|
||||
// require the value to be strictly less than the limit.
|
||||
return value_.real_ >= double(minInt64) &&
|
||||
value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
|
||||
#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
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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(); }
|
||||
|
||||
@ -1438,10 +1447,12 @@ bool Value::isArray() const { return type_ == arrayValue; }
|
||||
|
||||
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_)
|
||||
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.
|
||||
len -= 1;
|
||||
}
|
||||
@ -1452,7 +1463,8 @@ void Value::setComment(const char* comment, CommentPlacement 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);
|
||||
}
|
||||
|
||||
|
@ -4,76 +4,77 @@
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <json/writer.h>
|
||||
#include "json_tool.h"
|
||||
#include <json/writer.h>
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
#if !defined(isnan)
|
||||
#define isnan std::isnan
|
||||
#endif
|
||||
#if !defined(isnan)
|
||||
#define isnan std::isnan
|
||||
#endif
|
||||
|
||||
#if !defined(isfinite)
|
||||
#define isfinite std::isfinite
|
||||
#endif
|
||||
#if !defined(isfinite)
|
||||
#define isfinite std::isfinite
|
||||
#endif
|
||||
|
||||
#if !defined(snprintf)
|
||||
#define snprintf std::snprintf
|
||||
#endif
|
||||
#if !defined(snprintf)
|
||||
#define snprintf std::snprintf
|
||||
#endif
|
||||
#else
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if !defined(isnan)
|
||||
#include <float.h>
|
||||
#define isnan _isnan
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#if !defined(isnan)
|
||||
#include <float.h>
|
||||
#define isnan _isnan
|
||||
#endif
|
||||
|
||||
#if !defined(isfinite)
|
||||
#include <float.h>
|
||||
#define isfinite _finite
|
||||
#endif
|
||||
#if !defined(isfinite)
|
||||
#include <float.h>
|
||||
#define isfinite _finite
|
||||
#endif
|
||||
|
||||
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
|
||||
#if !defined(snprintf)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#endif
|
||||
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
|
||||
#if !defined(snprintf)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__sun) && defined(__SVR4) //Solaris
|
||||
#if !defined(isfinite)
|
||||
#include <ieeefp.h>
|
||||
#define isfinite finite
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__sun) && defined(__SVR4) // Solaris
|
||||
#if !defined(isfinite)
|
||||
#include <ieeefp.h>
|
||||
#define isfinite finite
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__hpux)
|
||||
#if !defined(isfinite)
|
||||
#if defined(__ia64) && !defined(finite)
|
||||
#define isfinite(x) ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x)))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__hpux)
|
||||
#if !defined(isfinite)
|
||||
#if defined(__ia64) && !defined(finite)
|
||||
#define isfinite(x) \
|
||||
((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x)))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(isnan)
|
||||
// IEEE standard states that NaN values will not compare to themselves
|
||||
#define isnan(x) (x!=x)
|
||||
#endif
|
||||
#if !defined(isnan)
|
||||
// IEEE standard states that NaN values will not compare to themselves
|
||||
#define isnan(x) (x != x)
|
||||
#endif
|
||||
|
||||
#if !defined(isfinite)
|
||||
#define isfinite finite
|
||||
#endif
|
||||
#if !defined(isfinite)
|
||||
#define isfinite finite
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
|
||||
@ -86,7 +87,7 @@ namespace Json {
|
||||
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
|
||||
typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
|
||||
#else
|
||||
typedef std::auto_ptr<StreamWriter> StreamWriterPtr;
|
||||
typedef std::auto_ptr<StreamWriter> StreamWriterPtr;
|
||||
#endif
|
||||
|
||||
JSONCPP_STRING valueToString(LargestInt value) {
|
||||
@ -126,30 +127,34 @@ JSONCPP_STRING valueToString(UInt value) {
|
||||
#endif // # if defined(JSON_HAS_INT64)
|
||||
|
||||
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
|
||||
// that always has a decimal point because JSON doesn't distinguish the
|
||||
// concepts of reals and integers.
|
||||
if (!isfinite(value)) {
|
||||
static const char* const reps[2][3] = {
|
||||
{"NaN", "-Infinity", "Infinity"},
|
||||
{"null", "-1e+9999", "1e+9999"}};
|
||||
return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2];
|
||||
static const char* const reps[2][3] = { { "NaN", "-Infinity", "Infinity" },
|
||||
{ "null", "-1e+9999", "1e+9999" } };
|
||||
return reps[useSpecialFloats ? 0 : 1]
|
||||
[isnan(value) ? 0 : (value < 0) ? 1 : 2];
|
||||
}
|
||||
|
||||
JSONCPP_STRING buffer(size_t(36), '\0');
|
||||
while (true) {
|
||||
int len = snprintf(&*buffer.begin(), buffer.size(),
|
||||
(precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
|
||||
precision, value);
|
||||
assert(len >= 0);
|
||||
size_t wouldPrint = static_cast<size_t>(len);
|
||||
if (wouldPrint >= buffer.size()) {
|
||||
buffer.resize(wouldPrint + 1);
|
||||
continue;
|
||||
}
|
||||
buffer.resize(wouldPrint);
|
||||
break;
|
||||
int len = snprintf(
|
||||
&*buffer.begin(), buffer.size(),
|
||||
(precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
|
||||
precision, value);
|
||||
assert(len >= 0);
|
||||
size_t wouldPrint = static_cast<size_t>(len);
|
||||
if (wouldPrint >= buffer.size()) {
|
||||
buffer.resize(wouldPrint + 1);
|
||||
continue;
|
||||
}
|
||||
buffer.resize(wouldPrint);
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
|
||||
@ -159,15 +164,18 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
|
||||
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) {
|
||||
buffer += ".0";
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
} // 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);
|
||||
}
|
||||
|
||||
@ -178,8 +186,8 @@ static bool isAnyCharRequiredQuoting(char const* s, size_t n) {
|
||||
|
||||
char const* const end = s + n;
|
||||
for (char const* cur = s; cur < end; ++cur) {
|
||||
if (*cur == '\\' || *cur == '\"' || *cur < ' '
|
||||
|| static_cast<unsigned char>(*cur) < 0x80)
|
||||
if (*cur == '\\' || *cur == '\"' || *cur < ' ' ||
|
||||
static_cast<unsigned char>(*cur) < 0x80)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -197,8 +205,8 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
|
||||
if (e - s < 2)
|
||||
return REPLACEMENT_CHARACTER;
|
||||
|
||||
unsigned int calculated = ((firstByte & 0x1F) << 6)
|
||||
| (static_cast<unsigned int>(s[1]) & 0x3F);
|
||||
unsigned int calculated =
|
||||
((firstByte & 0x1F) << 6) | (static_cast<unsigned int>(s[1]) & 0x3F);
|
||||
s += 1;
|
||||
// oversized encoded characters are invalid
|
||||
return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
|
||||
@ -208,9 +216,9 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
|
||||
if (e - s < 3)
|
||||
return REPLACEMENT_CHARACTER;
|
||||
|
||||
unsigned int calculated = ((firstByte & 0x0F) << 12)
|
||||
| ((static_cast<unsigned int>(s[1]) & 0x3F) << 6)
|
||||
| (static_cast<unsigned int>(s[2]) & 0x3F);
|
||||
unsigned int calculated = ((firstByte & 0x0F) << 12) |
|
||||
((static_cast<unsigned int>(s[1]) & 0x3F) << 6) |
|
||||
(static_cast<unsigned int>(s[2]) & 0x3F);
|
||||
s += 2;
|
||||
// surrogates aren't valid codepoints itself
|
||||
// shouldn't be UTF-8 encoded
|
||||
@ -224,10 +232,10 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
|
||||
if (e - s < 4)
|
||||
return REPLACEMENT_CHARACTER;
|
||||
|
||||
unsigned int calculated = ((firstByte & 0x07) << 18)
|
||||
| ((static_cast<unsigned int>(s[1]) & 0x3F) << 12)
|
||||
| ((static_cast<unsigned int>(s[2]) & 0x3F) << 6)
|
||||
| (static_cast<unsigned int>(s[3]) & 0x3F);
|
||||
unsigned int calculated = ((firstByte & 0x07) << 18) |
|
||||
((static_cast<unsigned int>(s[1]) & 0x3F) << 12) |
|
||||
((static_cast<unsigned int>(s[2]) & 0x3F) << 6) |
|
||||
(static_cast<unsigned int>(s[3]) & 0x3F);
|
||||
s += 3;
|
||||
// oversized encoded characters are invalid
|
||||
return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
|
||||
@ -236,23 +244,22 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
|
||||
return REPLACEMENT_CHARACTER;
|
||||
}
|
||||
|
||||
static const char hex2[] =
|
||||
"000102030405060708090a0b0c0d0e0f"
|
||||
"101112131415161718191a1b1c1d1e1f"
|
||||
"202122232425262728292a2b2c2d2e2f"
|
||||
"303132333435363738393a3b3c3d3e3f"
|
||||
"404142434445464748494a4b4c4d4e4f"
|
||||
"505152535455565758595a5b5c5d5e5f"
|
||||
"606162636465666768696a6b6c6d6e6f"
|
||||
"707172737475767778797a7b7c7d7e7f"
|
||||
"808182838485868788898a8b8c8d8e8f"
|
||||
"909192939495969798999a9b9c9d9e9f"
|
||||
"a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
|
||||
"b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
|
||||
"c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
|
||||
"d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
|
||||
"e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
|
||||
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
|
||||
static const char hex2[] = "000102030405060708090a0b0c0d0e0f"
|
||||
"101112131415161718191a1b1c1d1e1f"
|
||||
"202122232425262728292a2b2c2d2e2f"
|
||||
"303132333435363738393a3b3c3d3e3f"
|
||||
"404142434445464748494a4b4c4d4e4f"
|
||||
"505152535455565758595a5b5c5d5e5f"
|
||||
"606162636465666768696a6b6c6d6e6f"
|
||||
"707172737475767778797a7b7c7d7e7f"
|
||||
"808182838485868788898a8b8c8d8e8f"
|
||||
"909192939495969798999a9b9c9d9e9f"
|
||||
"a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
|
||||
"b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
|
||||
"c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
|
||||
"d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
|
||||
"e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
|
||||
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
|
||||
|
||||
static JSONCPP_STRING toHex16Bit(unsigned int x) {
|
||||
const unsigned int hi = (x >> 8) & 0xff;
|
||||
@ -274,8 +281,7 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
|
||||
// We have to walk value and escape any special characters.
|
||||
// Appending to JSONCPP_STRING is not efficient, but this should be rare.
|
||||
// (Note: forward slashes are *not* rare, but I am not escaping them.)
|
||||
JSONCPP_STRING::size_type maxsize =
|
||||
length * 2 + 3; // allescaped+quotes+NULL
|
||||
JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL
|
||||
JSONCPP_STRING result;
|
||||
result.reserve(maxsize); // to avoid lots of mallocs
|
||||
result += "\"";
|
||||
@ -312,25 +318,23 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
|
||||
// Should add a flag to allow this compatibility mode and prevent this
|
||||
// sequence from occurring.
|
||||
default: {
|
||||
unsigned int cp = utf8ToCodepoint(c, end);
|
||||
// don't escape non-control characters
|
||||
// (short escape sequence are applied above)
|
||||
if (cp < 0x80 && cp >= 0x20)
|
||||
result += static_cast<char>(cp);
|
||||
else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
|
||||
result += "\\u";
|
||||
result += toHex16Bit(cp);
|
||||
}
|
||||
else { // codepoint is not in Basic Multilingual Plane
|
||||
unsigned int cp = utf8ToCodepoint(c, end);
|
||||
// don't escape non-control characters
|
||||
// (short escape sequence are applied above)
|
||||
if (cp < 0x80 && cp >= 0x20)
|
||||
result += static_cast<char>(cp);
|
||||
else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
|
||||
result += "\\u";
|
||||
result += toHex16Bit(cp);
|
||||
} else { // codepoint is not in Basic Multilingual Plane
|
||||
// convert to surrogate pair first
|
||||
cp -= 0x10000;
|
||||
result += "\\u";
|
||||
result += toHex16Bit((cp >> 10) + 0xD800);
|
||||
result += "\\u";
|
||||
result += toHex16Bit((cp & 0x3FF) + 0xDC00);
|
||||
}
|
||||
cp -= 0x10000;
|
||||
result += "\\u";
|
||||
result += toHex16Bit((cp >> 10) + 0xD800);
|
||||
result += "\\u";
|
||||
result += toHex16Bit((cp & 0x3FF) + 0xDC00);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
result += "\"";
|
||||
@ -381,13 +385,13 @@ void FastWriter::writeValue(const Value& value) {
|
||||
case realValue:
|
||||
document_ += valueToString(value.asDouble());
|
||||
break;
|
||||
case stringValue:
|
||||
{
|
||||
case stringValue: {
|
||||
// Is NULL possible for value.string_? No.
|
||||
char const* str;
|
||||
char const* 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;
|
||||
}
|
||||
case booleanValue:
|
||||
@ -411,7 +415,8 @@ void FastWriter::writeValue(const Value& value) {
|
||||
const JSONCPP_STRING& name = *it;
|
||||
if (it != members.begin())
|
||||
document_ += ',';
|
||||
document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
|
||||
document_ += valueToQuotedStringN(name.data(),
|
||||
static_cast<unsigned>(name.length()));
|
||||
document_ += yamlCompatibilityEnabled_ ? ": " : ":";
|
||||
writeValue(value[name]);
|
||||
}
|
||||
@ -451,14 +456,15 @@ void StyledWriter::writeValue(const Value& value) {
|
||||
case realValue:
|
||||
pushValue(valueToString(value.asDouble()));
|
||||
break;
|
||||
case stringValue:
|
||||
{
|
||||
case stringValue: {
|
||||
// Is NULL possible for value.string_? No.
|
||||
char const* str;
|
||||
char const* end;
|
||||
bool ok = value.getString(&str, &end);
|
||||
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
|
||||
else pushValue("");
|
||||
if (ok)
|
||||
pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
|
||||
else
|
||||
pushValue("");
|
||||
break;
|
||||
}
|
||||
case booleanValue:
|
||||
@ -546,7 +552,7 @@ bool StyledWriter::isMultilineArray(const Value& value) {
|
||||
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
|
||||
const Value& childValue = value[index];
|
||||
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
|
||||
childValue.size() > 0);
|
||||
childValue.size() > 0);
|
||||
}
|
||||
if (!isMultiLine) // check if line length > max line length
|
||||
{
|
||||
@ -589,7 +595,9 @@ void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) {
|
||||
document_ += value;
|
||||
}
|
||||
|
||||
void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); }
|
||||
void StyledWriter::indent() {
|
||||
indentString_ += JSONCPP_STRING(indentSize_, ' ');
|
||||
}
|
||||
|
||||
void StyledWriter::unindent() {
|
||||
assert(indentString_.size() >= indentSize_);
|
||||
@ -606,8 +614,7 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) {
|
||||
JSONCPP_STRING::const_iterator iter = comment.begin();
|
||||
while (iter != comment.end()) {
|
||||
document_ += *iter;
|
||||
if (*iter == '\n' &&
|
||||
((iter+1) != comment.end() && *(iter + 1) == '/'))
|
||||
if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
|
||||
writeIndent();
|
||||
++iter;
|
||||
}
|
||||
@ -638,8 +645,7 @@ bool StyledWriter::hasCommentForValue(const Value& value) {
|
||||
|
||||
StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
|
||||
: document_(NULL), rightMargin_(74), indentation_(indentation),
|
||||
addChildValues_(), indented_(false)
|
||||
{}
|
||||
addChildValues_(), indented_(false) {}
|
||||
|
||||
void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
|
||||
document_ = &out;
|
||||
@ -647,7 +653,8 @@ void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
|
||||
indentString_.clear();
|
||||
indented_ = true;
|
||||
writeCommentBeforeValue(root);
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
indented_ = true;
|
||||
writeValue(root);
|
||||
writeCommentAfterValueOnSameLine(root);
|
||||
@ -669,14 +676,15 @@ void StyledStreamWriter::writeValue(const Value& value) {
|
||||
case realValue:
|
||||
pushValue(valueToString(value.asDouble()));
|
||||
break;
|
||||
case stringValue:
|
||||
{
|
||||
case stringValue: {
|
||||
// Is NULL possible for value.string_? No.
|
||||
char const* str;
|
||||
char const* end;
|
||||
bool ok = value.getString(&str, &end);
|
||||
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
|
||||
else pushValue("");
|
||||
if (ok)
|
||||
pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
|
||||
else
|
||||
pushValue("");
|
||||
break;
|
||||
}
|
||||
case booleanValue:
|
||||
@ -731,7 +739,8 @@ void StyledStreamWriter::writeArrayValue(const Value& value) {
|
||||
if (hasChildValue)
|
||||
writeWithIndent(childValues_[index]);
|
||||
else {
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
indented_ = true;
|
||||
writeValue(childValue);
|
||||
indented_ = false;
|
||||
@ -766,7 +775,7 @@ bool StyledStreamWriter::isMultilineArray(const Value& value) {
|
||||
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
|
||||
const Value& childValue = value[index];
|
||||
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
|
||||
childValue.size() > 0);
|
||||
childValue.size() > 0);
|
||||
}
|
||||
if (!isMultiLine) // check if line length > max line length
|
||||
{
|
||||
@ -802,7 +811,8 @@ void StyledStreamWriter::writeIndent() {
|
||||
}
|
||||
|
||||
void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) {
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
*document_ << value;
|
||||
indented_ = false;
|
||||
}
|
||||
@ -818,13 +828,13 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
|
||||
if (!root.hasComment(commentBefore))
|
||||
return;
|
||||
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
const JSONCPP_STRING& comment = root.getComment(commentBefore);
|
||||
JSONCPP_STRING::const_iterator iter = comment.begin();
|
||||
while (iter != comment.end()) {
|
||||
*document_ << *iter;
|
||||
if (*iter == '\n' &&
|
||||
((iter+1) != comment.end() && *(iter + 1) == '/'))
|
||||
if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
|
||||
// writeIndent(); // would include newline
|
||||
*document_ << indentString_;
|
||||
++iter;
|
||||
@ -856,24 +866,23 @@ bool StyledStreamWriter::hasCommentForValue(const Value& value) {
|
||||
struct CommentStyle {
|
||||
/// Decide whether to write comments.
|
||||
enum Enum {
|
||||
None, ///< Drop all comments.
|
||||
Most, ///< Recover odd behavior of previous versions (not implemented yet).
|
||||
All ///< Keep all comments.
|
||||
None, ///< Drop all comments.
|
||||
Most, ///< Recover odd behavior of previous versions (not implemented yet).
|
||||
All ///< Keep all comments.
|
||||
};
|
||||
};
|
||||
|
||||
struct BuiltStyledStreamWriter : public StreamWriter
|
||||
{
|
||||
BuiltStyledStreamWriter(
|
||||
JSONCPP_STRING const& indentation,
|
||||
CommentStyle::Enum cs,
|
||||
JSONCPP_STRING const& colonSymbol,
|
||||
JSONCPP_STRING const& nullSymbol,
|
||||
JSONCPP_STRING const& endingLineFeedSymbol,
|
||||
bool useSpecialFloats,
|
||||
unsigned int precision,
|
||||
PrecisionType precisionType);
|
||||
struct BuiltStyledStreamWriter : public StreamWriter {
|
||||
BuiltStyledStreamWriter(JSONCPP_STRING const& indentation,
|
||||
CommentStyle::Enum cs,
|
||||
JSONCPP_STRING const& colonSymbol,
|
||||
JSONCPP_STRING const& nullSymbol,
|
||||
JSONCPP_STRING const& endingLineFeedSymbol,
|
||||
bool useSpecialFloats,
|
||||
unsigned int precision,
|
||||
PrecisionType precisionType);
|
||||
int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
|
||||
|
||||
private:
|
||||
void writeValue(Value const& value);
|
||||
void writeArrayValue(Value const& value);
|
||||
@ -904,35 +913,27 @@ private:
|
||||
PrecisionType precisionType_;
|
||||
};
|
||||
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
|
||||
JSONCPP_STRING const& indentation,
|
||||
CommentStyle::Enum cs,
|
||||
JSONCPP_STRING const& colonSymbol,
|
||||
JSONCPP_STRING const& nullSymbol,
|
||||
JSONCPP_STRING const& endingLineFeedSymbol,
|
||||
bool useSpecialFloats,
|
||||
unsigned int precision,
|
||||
PrecisionType precisionType)
|
||||
: rightMargin_(74)
|
||||
, indentation_(indentation)
|
||||
, cs_(cs)
|
||||
, colonSymbol_(colonSymbol)
|
||||
, nullSymbol_(nullSymbol)
|
||||
, endingLineFeedSymbol_(endingLineFeedSymbol)
|
||||
, addChildValues_(false)
|
||||
, indented_(false)
|
||||
, useSpecialFloats_(useSpecialFloats)
|
||||
, precision_(precision)
|
||||
, precisionType_(precisionType)
|
||||
{
|
||||
}
|
||||
int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
|
||||
{
|
||||
JSONCPP_STRING const& indentation,
|
||||
CommentStyle::Enum cs,
|
||||
JSONCPP_STRING const& colonSymbol,
|
||||
JSONCPP_STRING const& nullSymbol,
|
||||
JSONCPP_STRING const& endingLineFeedSymbol,
|
||||
bool useSpecialFloats,
|
||||
unsigned int precision,
|
||||
PrecisionType precisionType)
|
||||
: rightMargin_(74), indentation_(indentation), cs_(cs),
|
||||
colonSymbol_(colonSymbol), nullSymbol_(nullSymbol),
|
||||
endingLineFeedSymbol_(endingLineFeedSymbol), addChildValues_(false),
|
||||
indented_(false), useSpecialFloats_(useSpecialFloats),
|
||||
precision_(precision), precisionType_(precisionType) {}
|
||||
int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) {
|
||||
sout_ = sout;
|
||||
addChildValues_ = false;
|
||||
indented_ = true;
|
||||
indentString_.clear();
|
||||
writeCommentBeforeValue(root);
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
indented_ = true;
|
||||
writeValue(root);
|
||||
writeCommentAfterValueOnSameLine(root);
|
||||
@ -952,16 +953,18 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
|
||||
pushValue(valueToString(value.asLargestUInt()));
|
||||
break;
|
||||
case realValue:
|
||||
pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_, precisionType_));
|
||||
pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_,
|
||||
precisionType_));
|
||||
break;
|
||||
case stringValue:
|
||||
{
|
||||
case stringValue: {
|
||||
// Is NULL is possible for value.string_? No.
|
||||
char const* str;
|
||||
char const* end;
|
||||
bool ok = value.getString(&str, &end);
|
||||
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
|
||||
else pushValue("");
|
||||
if (ok)
|
||||
pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
|
||||
else
|
||||
pushValue("");
|
||||
break;
|
||||
}
|
||||
case booleanValue:
|
||||
@ -982,7 +985,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
|
||||
JSONCPP_STRING const& name = *it;
|
||||
Value const& childValue = value[name];
|
||||
writeCommentBeforeValue(childValue);
|
||||
writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
|
||||
writeWithIndent(valueToQuotedStringN(
|
||||
name.data(), static_cast<unsigned>(name.length())));
|
||||
*sout_ << colonSymbol_;
|
||||
writeValue(childValue);
|
||||
if (++it == members.end()) {
|
||||
@ -1016,7 +1020,8 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
|
||||
if (hasChildValue)
|
||||
writeWithIndent(childValues_[index]);
|
||||
else {
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
indented_ = true;
|
||||
writeValue(childValue);
|
||||
indented_ = false;
|
||||
@ -1034,13 +1039,15 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
|
||||
{
|
||||
assert(childValues_.size() == size);
|
||||
*sout_ << "[";
|
||||
if (!indentation_.empty()) *sout_ << " ";
|
||||
if (!indentation_.empty())
|
||||
*sout_ << " ";
|
||||
for (unsigned index = 0; index < size; ++index) {
|
||||
if (index > 0)
|
||||
*sout_ << ((!indentation_.empty()) ? ", " : ",");
|
||||
*sout_ << childValues_[index];
|
||||
}
|
||||
if (!indentation_.empty()) *sout_ << " ";
|
||||
if (!indentation_.empty())
|
||||
*sout_ << " ";
|
||||
*sout_ << "]";
|
||||
}
|
||||
}
|
||||
@ -1053,7 +1060,7 @@ bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) {
|
||||
for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
|
||||
Value const& childValue = value[index];
|
||||
isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
|
||||
childValue.size() > 0);
|
||||
childValue.size() > 0);
|
||||
}
|
||||
if (!isMultiLine) // check if line length > max line length
|
||||
{
|
||||
@ -1093,7 +1100,8 @@ void BuiltStyledStreamWriter::writeIndent() {
|
||||
}
|
||||
|
||||
void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) {
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
*sout_ << value;
|
||||
indented_ = false;
|
||||
}
|
||||
@ -1106,17 +1114,18 @@ void BuiltStyledStreamWriter::unindent() {
|
||||
}
|
||||
|
||||
void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
|
||||
if (cs_ == CommentStyle::None) return;
|
||||
if (cs_ == CommentStyle::None)
|
||||
return;
|
||||
if (!root.hasComment(commentBefore))
|
||||
return;
|
||||
|
||||
if (!indented_) writeIndent();
|
||||
if (!indented_)
|
||||
writeIndent();
|
||||
const JSONCPP_STRING& comment = root.getComment(commentBefore);
|
||||
JSONCPP_STRING::const_iterator iter = comment.begin();
|
||||
while (iter != comment.end()) {
|
||||
*sout_ << *iter;
|
||||
if (*iter == '\n' &&
|
||||
((iter+1) != comment.end() && *(iter + 1) == '/'))
|
||||
if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
|
||||
// writeIndent(); // would write extra newline
|
||||
*sout_ << indentString_;
|
||||
++iter;
|
||||
@ -1124,8 +1133,10 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
|
||||
indented_ = false;
|
||||
}
|
||||
|
||||
void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
|
||||
if (cs_ == CommentStyle::None) return;
|
||||
void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
|
||||
Value const& root) {
|
||||
if (cs_ == CommentStyle::None)
|
||||
return;
|
||||
if (root.hasComment(commentAfterOnSameLine))
|
||||
*sout_ << " " + root.getComment(commentAfterOnSameLine);
|
||||
|
||||
@ -1145,29 +1156,18 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
|
||||
///////////////
|
||||
// StreamWriter
|
||||
|
||||
StreamWriter::StreamWriter()
|
||||
: sout_(NULL)
|
||||
{
|
||||
}
|
||||
StreamWriter::~StreamWriter()
|
||||
{
|
||||
}
|
||||
StreamWriter::Factory::~Factory()
|
||||
{}
|
||||
StreamWriterBuilder::StreamWriterBuilder()
|
||||
{
|
||||
setDefaults(&settings_);
|
||||
}
|
||||
StreamWriterBuilder::~StreamWriterBuilder()
|
||||
{}
|
||||
StreamWriter* StreamWriterBuilder::newStreamWriter() const
|
||||
{
|
||||
StreamWriter::StreamWriter() : sout_(NULL) {}
|
||||
StreamWriter::~StreamWriter() {}
|
||||
StreamWriter::Factory::~Factory() {}
|
||||
StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); }
|
||||
StreamWriterBuilder::~StreamWriterBuilder() {}
|
||||
StreamWriter* StreamWriterBuilder::newStreamWriter() const {
|
||||
JSONCPP_STRING indentation = settings_["indentation"].asString();
|
||||
JSONCPP_STRING cs_str = settings_["commentStyle"].asString();
|
||||
JSONCPP_STRING pt_str = settings_["precisionType"].asString();
|
||||
bool eyc = settings_["enableYAMLCompatibility"].asBool();
|
||||
bool dnp = settings_["dropNullPlaceholders"].asBool();
|
||||
bool usf = settings_["useSpecialFloats"].asBool();
|
||||
bool usf = settings_["useSpecialFloats"].asBool();
|
||||
unsigned int pre = settings_["precision"].asUInt();
|
||||
CommentStyle::Enum cs = CommentStyle::All;
|
||||
if (cs_str == "All") {
|
||||
@ -1195,14 +1195,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
|
||||
if (dnp) {
|
||||
nullSymbol.clear();
|
||||
}
|
||||
if (pre > 17) pre = 17;
|
||||
if (pre > 17)
|
||||
pre = 17;
|
||||
JSONCPP_STRING endingLineFeedSymbol;
|
||||
return new BuiltStyledStreamWriter(
|
||||
indentation, cs,
|
||||
colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre, precisionType);
|
||||
return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol,
|
||||
endingLineFeedSymbol, usf, pre,
|
||||
precisionType);
|
||||
}
|
||||
static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
|
||||
{
|
||||
static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys) {
|
||||
valid_keys->clear();
|
||||
valid_keys->insert("indentation");
|
||||
valid_keys->insert("commentStyle");
|
||||
@ -1212,10 +1212,10 @@ static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
|
||||
valid_keys->insert("precision");
|
||||
valid_keys->insert("precisionType");
|
||||
}
|
||||
bool StreamWriterBuilder::validate(Json::Value* invalid) const
|
||||
{
|
||||
bool StreamWriterBuilder::validate(Json::Value* invalid) const {
|
||||
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;
|
||||
std::set<JSONCPP_STRING> valid_keys;
|
||||
getValidWriterKeys(&valid_keys);
|
||||
@ -1229,13 +1229,11 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const
|
||||
}
|
||||
return 0u == inv.size();
|
||||
}
|
||||
Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
|
||||
{
|
||||
Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) {
|
||||
return settings_[key];
|
||||
}
|
||||
// static
|
||||
void StreamWriterBuilder::setDefaults(Json::Value* settings)
|
||||
{
|
||||
void StreamWriterBuilder::setDefaults(Json::Value* settings) {
|
||||
//! [StreamWriterBuilderDefaults]
|
||||
(*settings)["commentStyle"] = "All";
|
||||
(*settings)["indentation"] = "\t";
|
||||
@ -1247,7 +1245,8 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
|
||||
//! [StreamWriterBuilderDefaults]
|
||||
}
|
||||
|
||||
JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) {
|
||||
JSONCPP_STRING writeString(StreamWriter::Factory const& builder,
|
||||
Value const& root) {
|
||||
JSONCPP_OSTRINGSTREAM sout;
|
||||
StreamWriterPtr const writer(builder.newStreamWriter());
|
||||
writer->write(root, &sout);
|
||||
|
@ -93,8 +93,8 @@ TestResult::addFailure(const char* file, unsigned int line, const char* expr) {
|
||||
if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext
|
||||
{
|
||||
lastUsedPredicateId_ = lastNode->id_;
|
||||
addFailureInfo(
|
||||
lastNode->file_, lastNode->line_, lastNode->expr_, nestingLevel);
|
||||
addFailureInfo(lastNode->file_, lastNode->line_, lastNode->expr_,
|
||||
nestingLevel);
|
||||
// Link the PredicateContext to the failure for message target when
|
||||
// popping the PredicateContext.
|
||||
lastNode->failure_ = &(failures_.back());
|
||||
@ -180,7 +180,7 @@ void TestResult::printFailure(bool printTestName) const {
|
||||
}
|
||||
|
||||
JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text,
|
||||
const JSONCPP_STRING& indent) {
|
||||
const JSONCPP_STRING& indent) {
|
||||
JSONCPP_STRING reindented;
|
||||
JSONCPP_STRING::size_type lastIndex = 0;
|
||||
while (lastIndex < text.size()) {
|
||||
@ -257,8 +257,7 @@ void Runner::runTestAt(unsigned int index, TestResult& result) const {
|
||||
#endif // if JSON_USE_EXCEPTION
|
||||
test->run(result);
|
||||
#if JSON_USE_EXCEPTION
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
} catch (const std::exception& e) {
|
||||
result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:")
|
||||
<< e.what();
|
||||
}
|
||||
@ -294,9 +293,7 @@ bool Runner::runAllTest(bool printSummary) const {
|
||||
if (printSummary) {
|
||||
unsigned int failedCount = static_cast<unsigned int>(failures.size());
|
||||
unsigned int passedCount = count - failedCount;
|
||||
printf("%d/%d tests passed (%d failure(s))\n",
|
||||
passedCount,
|
||||
count,
|
||||
printf("%d/%d tests passed (%d failure(s))\n", passedCount, count,
|
||||
failedCount);
|
||||
}
|
||||
return false;
|
||||
@ -398,8 +395,8 @@ void Runner::preventDialogOnCrash() {
|
||||
_CrtSetReportHook(&msvcrtSilentReportHook);
|
||||
#endif // if defined(_MSC_VER)
|
||||
|
||||
// @todo investigate this handler (for buffer overflow)
|
||||
// _set_security_error_handler
|
||||
// @todo investigate this handler (for buffer overflow)
|
||||
// _set_security_error_handler
|
||||
|
||||
#if defined(_WIN32)
|
||||
// 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);
|
||||
}
|
||||
|
||||
JSONCPP_STRING ToJsonString(JSONCPP_STRING in) {
|
||||
return in;
|
||||
}
|
||||
JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { return in; }
|
||||
|
||||
#if JSONCPP_USING_SECURE_MEMORY
|
||||
JSONCPP_STRING ToJsonString(std::string in) {
|
||||
|
@ -6,12 +6,12 @@
|
||||
#ifndef JSONTEST_H_INCLUDED
|
||||
#define JSONTEST_H_INCLUDED
|
||||
|
||||
#include <deque>
|
||||
#include <json/config.h>
|
||||
#include <json/value.h>
|
||||
#include <json/writer.h>
|
||||
#include <stdio.h>
|
||||
#include <deque>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
// //////////////////////////////////////////////////////////////////
|
||||
@ -104,7 +104,7 @@ private:
|
||||
const char* expr,
|
||||
unsigned int nestingLevel);
|
||||
static JSONCPP_STRING indentText(const JSONCPP_STRING& text,
|
||||
const JSONCPP_STRING& indent);
|
||||
const JSONCPP_STRING& indent);
|
||||
|
||||
typedef std::deque<Failure> Failures;
|
||||
Failures failures_;
|
||||
@ -212,7 +212,7 @@ TestResult& checkStringEqual(TestResult& result,
|
||||
#define JSONTEST_ASSERT(expr) \
|
||||
if (expr) { \
|
||||
} else \
|
||||
result_->addFailure(__FILE__, __LINE__, #expr)
|
||||
result_->addFailure(__FILE__, __LINE__, #expr)
|
||||
|
||||
/// \brief Asserts that the given predicate is true.
|
||||
/// The predicate may do other assertions and be a member function of the
|
||||
@ -231,21 +231,14 @@ TestResult& checkStringEqual(TestResult& result,
|
||||
|
||||
/// \brief Asserts that two values are equals.
|
||||
#define JSONTEST_ASSERT_EQUAL(expected, actual) \
|
||||
JsonTest::checkEqual(*result_, \
|
||||
expected, \
|
||||
actual, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
JsonTest::checkEqual(*result_, expected, actual, __FILE__, __LINE__, \
|
||||
#expected " == " #actual)
|
||||
|
||||
/// \brief Asserts that two values are equals.
|
||||
#define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \
|
||||
JsonTest::checkStringEqual(*result_, \
|
||||
JsonTest::ToJsonString(expected), \
|
||||
JsonTest::ToJsonString(actual), \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#expected " == " #actual)
|
||||
JsonTest::checkStringEqual(*result_, JsonTest::ToJsonString(expected), \
|
||||
JsonTest::ToJsonString(actual), __FILE__, \
|
||||
__LINE__, #expected " == " #actual)
|
||||
|
||||
/// \brief Asserts that a given expression throws an exception
|
||||
#define JSONTEST_ASSERT_THROWS(expr) \
|
||||
@ -253,13 +246,12 @@ TestResult& checkStringEqual(TestResult& result,
|
||||
bool _threw = false; \
|
||||
try { \
|
||||
expr; \
|
||||
} \
|
||||
catch (...) { \
|
||||
} catch (...) { \
|
||||
_threw = true; \
|
||||
} \
|
||||
if (!_threw) \
|
||||
result_->addFailure( \
|
||||
__FILE__, __LINE__, "expected exception thrown: " #expr); \
|
||||
result_->addFailure(__FILE__, __LINE__, \
|
||||
"expected exception thrown: " #expr); \
|
||||
}
|
||||
|
||||
/// \brief Begin a fixture test case.
|
||||
@ -270,9 +262,11 @@ TestResult& checkStringEqual(TestResult& result,
|
||||
return new Test##FixtureType##name(); \
|
||||
} \
|
||||
\
|
||||
public: /* overridden from TestCase */ \
|
||||
const char* testName() const JSONCPP_OVERRIDE { return #FixtureType "/" #name; } \
|
||||
void runTestCase() JSONCPP_OVERRIDE; \
|
||||
public: /* overridden from TestCase */ \
|
||||
const char* testName() const JSONCPP_OVERRIDE { \
|
||||
return #FixtureType "/" #name; \
|
||||
} \
|
||||
void runTestCase() JSONCPP_OVERRIDE; \
|
||||
}; \
|
||||
\
|
||||
void Test##FixtureType##name::runTestCase()
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user