From d2c205206d6ca9d753aee12351302fbcc201757d Mon Sep 17 00:00:00 2001 From: chenguoping Date: Thu, 30 Apr 2020 11:24:36 +0800 Subject: [PATCH] Rewrite and revert some code to build in pre-C++11 Rewerite and revert some code that this library can be built in pre-C++11 and C++11 env. Main Change List: 1. using -> typedef 2. not using auto & decltype 3. not using raw string literals 4. ..., other c++11 features will be chosen to compile, depending on env. --- example/readFromStream/readFromStream.cpp | 1 + example/readFromString/readFromString.cpp | 10 +- example/streamWrite/streamWrite.cpp | 4 +- example/stringWrite/stringWrite.cpp | 3 +- include/json/assertions.h | 6 + include/json/config.h | 96 +++++-- include/json/forwards.h | 2 +- include/json/json_features.h | 8 +- include/json/reader.h | 31 +- include/json/value.h | 152 +++++----- include/json/version.h | 8 +- include/json/writer.h | 34 +-- src/jsontestrunner/main.cpp | 20 +- src/lib_json/json_reader.cpp | 140 +++++---- src/lib_json/json_tool.h | 2 +- src/lib_json/json_value.cpp | 188 ++++++------ src/lib_json/json_valueiterator.inl | 13 +- src/lib_json/json_writer.cpp | 72 ++--- src/test_lib_json/fuzz.cpp | 9 +- src/test_lib_json/jsontest.cpp | 29 +- src/test_lib_json/jsontest.h | 38 +-- src/test_lib_json/main.cpp | 333 +++++++++++++--------- 22 files changed, 688 insertions(+), 511 deletions(-) diff --git a/example/readFromStream/readFromStream.cpp b/example/readFromStream/readFromStream.cpp index 358d2ca..c4d0dcc 100644 --- a/example/readFromStream/readFromStream.cpp +++ b/example/readFromStream/readFromStream.cpp @@ -1,4 +1,5 @@ #include "json/json.h" +#include #include #include /** \brief Parse from stream, collect comments and capture error info. diff --git a/example/readFromString/readFromString.cpp b/example/readFromString/readFromString.cpp index c27bbd5..2c4c8a8 100644 --- a/example/readFromString/readFromString.cpp +++ b/example/readFromString/readFromString.cpp @@ -1,4 +1,5 @@ #include "json/json.h" +#include #include /** * \brief Parse a raw string into Value object using the CharReaderBuilder @@ -10,9 +11,9 @@ * 20 */ int main() { - const std::string rawJson = R"({"Age": 20, "Name": "colin"})"; - const auto rawJsonLength = static_cast(rawJson.length()); - constexpr bool shouldUseOldWay = false; + const std::string rawJson = "{\"Age\": 20, \"Name\": \"colin\"}"; + const int rawJsonLength = static_cast(rawJson.length()); + JSONCPP_CONST bool shouldUseOldWay = false; JSONCPP_STRING err; Json::Value root; @@ -21,12 +22,13 @@ int main() { reader.parse(rawJson, root); } else { Json::CharReaderBuilder builder; - const std::unique_ptr reader(builder.newCharReader()); + Json::CharReader* reader(builder.newCharReader()); if (!reader->parse(rawJson.c_str(), rawJson.c_str() + rawJsonLength, &root, &err)) { std::cout << "error" << std::endl; return EXIT_FAILURE; } + delete reader; } const std::string name = root["Name"].asString(); const int age = root["Age"].asInt(); diff --git a/example/streamWrite/streamWrite.cpp b/example/streamWrite/streamWrite.cpp index 6f7f797..461bebb 100644 --- a/example/streamWrite/streamWrite.cpp +++ b/example/streamWrite/streamWrite.cpp @@ -12,11 +12,11 @@ int main() { Json::Value root; Json::StreamWriterBuilder builder; - const std::unique_ptr writer(builder.newStreamWriter()); + Json::StreamWriter* writer(builder.newStreamWriter()); root["Name"] = "robin"; root["Age"] = 20; writer->write(root, &std::cout); - + delete writer; return EXIT_SUCCESS; } diff --git a/example/stringWrite/stringWrite.cpp b/example/stringWrite/stringWrite.cpp index d501ba9..05b1307 100644 --- a/example/stringWrite/stringWrite.cpp +++ b/example/stringWrite/stringWrite.cpp @@ -1,4 +1,5 @@ #include "json/json.h" +#include #include /** \brief Write a Value object to a string. * Example Usage: @@ -15,7 +16,7 @@ int main() { Json::Value root; Json::Value data; - constexpr bool shouldUseOldWay = false; + JSONCPP_CONST bool shouldUseOldWay = false; root["action"] = "run"; data["number"] = 1; root["data"] = data; diff --git a/include/json/assertions.h b/include/json/assertions.h index 666fa7f..3bdbf8a 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -58,4 +58,10 @@ } \ } while (0) +#if JSONCPP_CXX_STD_11 +#define JSONCPP_STATIC_ASSERT static_assert +#else +#define JSONCPP_STATIC_ASSERT JSON_ASSERT_MESSAGE +#endif + #endif // JSON_ASSERTIONS_H_INCLUDED diff --git a/include/json/config.h b/include/json/config.h index 6359273..7f9ac69 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -5,14 +5,20 @@ #ifndef JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED -#include -#include + #include #include #include #include #include -#include + +#if JSONCPP_CXX_STD_11 +#include // typedef ptrdiff_t +#include // typedef int64_t, uint64_t +#else +#include +#include +#endif // If non-zero, the library uses exceptions to report bad input instead of C // assertion macros. The default is to use exceptions. @@ -50,11 +56,6 @@ #define JSON_API #endif -#if defined(_MSC_VER) && _MSC_VER < 1800 -#error \ - "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" -#endif - #if defined(_MSC_VER) && _MSC_VER < 1900 // As recommended at // https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 @@ -70,10 +71,41 @@ extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, // Storages, and 64 bits integer support is disabled. // #define JSON_NO_INT64 1 -// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. -// C++11 should be used directly in JSONCPP. -#define JSONCPP_OVERRIDE override +#if __cplusplus >= 201103L || defined(_MSC_VER) +#define JSONCPP_OP_EXPLICIT explicit +#else +#define JSONCPP_OP_EXPLICIT +#endif +// These Macros are maintained for backwards compatibility of external tools. +#if (defined(_MSC_VER) && _MSC_VER >= 1900) || \ + (defined(__GNUC__) && __cplusplus >= 201103L) || \ + (defined(__clang__) && __clang_major__ == 3 && __clang_minor__ >= 3) + +#define JSONCPP_CXX_STD_11 1 +#else +#define JSONCPP_CXX_STD_11 0 +#endif + +#if JSONCPP_CXX_STD_11 +#define JSONCPP_NULL nullptr +#define JSONCPP_CONST constexpr +#define JSONCPP_CTOR_DELETE = delete +#define JSONCPP_NOEXCEPT noexcept +#define JSONCPP_OVERRIDE override +#define JSONCPP_MOVE(value) std::move(value) +#else +#define JSONCPP_NULL NULL +#define JSONCPP_CONST const +#define JSONCPP_CTOR_DELETE +#define JSONCPP_NOEXCEPT throw() +#define JSONCPP_OVERRIDE +#define JSONCPP_MOVE(value) value +#endif + +// Define *deprecated* attribute +// [[deprecated]] is in C++14 or in Visual Studio 2015 and later +// For compatibility, [[deprecated]] is not used #ifdef __clang__ #if __has_extension(attribute_deprecated_with_message) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) @@ -98,33 +130,36 @@ extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, #endif #if !defined(JSON_IS_AMALGAMATION) - +#if JSONCPP_CXX_STD_11 #include "allocator.h" +#endif #include "version.h" #endif // if !defined(JSON_IS_AMALGAMATION) namespace Json { -using Int = int; -using UInt = unsigned int; + +typedef int Int; +typedef unsigned int UInt; #if defined(JSON_NO_INT64) -using LargestInt = int; -using LargestUInt = unsigned int; +typedef int LargestInt; +typedef unsigned int LargestUInt; #undef JSON_HAS_INT64 #else // if defined(JSON_NO_INT64) // For Microsoft Visual use specific types as long long is not supported #if defined(_MSC_VER) // Microsoft Visual Studio -using Int64 = __int64; -using UInt64 = unsigned __int64; +typedef __int64 Int64; +typedef unsigned __int64 UInt64; #else // if defined(_MSC_VER) // Other platforms, use long long -using Int64 = int64_t; -using UInt64 = uint64_t; +typedef int64_t Int64; +typedef uint64_t UInt64; #endif // if defined(_MSC_VER) -using LargestInt = Int64; -using LargestUInt = UInt64; +typedef Int64 LargestInt; +typedef UInt64 LargestUInt; #define JSON_HAS_INT64 #endif // if defined(JSON_NO_INT64) +#if JSONCPP_CXX_STD_11 template using Allocator = typename std::conditional, @@ -138,13 +173,20 @@ using OStringStream = String::allocator_type>; using IStream = std::istream; using OStream = std::ostream; +#else +typedef std::string String; +typedef std::istringstream IStringStream; +typedef std::ostringstream OStringStream; +typedef std::istream IStream; +typedef std::ostream OStream; +#endif // JSONCPP_CXX_STD_11 } // namespace Json // Legacy names (formerly macros). -using JSONCPP_STRING = Json::String; -using JSONCPP_ISTRINGSTREAM = Json::IStringStream; -using JSONCPP_OSTRINGSTREAM = Json::OStringStream; -using JSONCPP_ISTREAM = Json::IStream; -using JSONCPP_OSTREAM = Json::OStream; +typedef Json::String JSONCPP_STRING; +typedef Json::IStringStream JSONCPP_ISTRINGSTREAM; +typedef Json::OStringStream JSONCPP_OSTRINGSTREAM; +typedef Json::IStream JSONCPP_ISTREAM; +typedef Json::OStream JSONCPP_OSTREAM; #endif // JSON_CONFIG_H_INCLUDED diff --git a/include/json/forwards.h b/include/json/forwards.h index affe33a..b0d981b 100644 --- a/include/json/forwards.h +++ b/include/json/forwards.h @@ -29,7 +29,7 @@ class CharReaderBuilder; class Features; // value.h -using ArrayIndex = unsigned int; +typedef unsigned int ArrayIndex; class StaticString; class Path; class PathArgument; diff --git a/include/json/json_features.h b/include/json/json_features.h index 7c7e9f5..1d7bb42 100644 --- a/include/json/json_features.h +++ b/include/json/json_features.h @@ -41,17 +41,17 @@ public: Features(); /// \c true if comments are allowed. Default: \c true. - bool allowComments_{true}; + bool allowComments_; /// \c true if root must be either an array or an object value. Default: \c /// false. - bool strictRoot_{false}; + bool strictRoot_; /// \c true if dropped null placeholders are allowed. Default: \c false. - bool allowDroppedNullPlaceholders_{false}; + bool allowDroppedNullPlaceholders_; /// \c true if numeric object key are allowed. Default: \c false. - bool allowNumericKeys_{false}; + bool allowNumericKeys_; }; } // namespace Json diff --git a/include/json/reader.h b/include/json/reader.h index 9175466..75f10b4 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -36,8 +36,8 @@ namespace Json { class JSONCPP_DEPRECATED( "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { public: - using Char = char; - using Location = const Char*; + typedef char Char; + typedef const Char* Location; /** \brief An error tagged with where in the JSON text it was encountered. * @@ -187,7 +187,7 @@ private: Location extra_; }; - using Errors = std::deque; + typedef std::deque Errors; bool readToken(Token& token); void skipSpaces(); @@ -210,7 +210,8 @@ private: unsigned int& unicode); bool decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, unsigned int& unicode); - bool addError(const String& message, Token& token, Location extra = nullptr); + bool addError(const String& message, Token& token, + Location extra = JSONCPP_NULL); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); @@ -226,25 +227,25 @@ private: static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); - using Nodes = std::stack; + typedef std::stack Nodes; Nodes nodes_; Errors errors_; String document_; - Location begin_{}; - Location end_{}; - Location current_{}; - Location lastValueEnd_{}; - Value* lastValue_{}; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value* lastValue_; String commentsBefore_; Features features_; - bool collectComments_{}; + bool collectComments_; }; // Reader /** Interface for reading JSON from a char array. */ class JSON_API CharReader { public: - virtual ~CharReader() = default; + virtual ~CharReader() {} /** \brief Read a Value from a JSON * document. The document must be a UTF-8 encoded string containing the * document to read. @@ -266,7 +267,7 @@ public: class JSON_API Factory { public: - virtual ~Factory() = default; + virtual ~Factory() {} /** \brief Allocate a CharReader via operator new(). * \throw std::exception if something goes wrong (e.g. invalid settings) */ @@ -332,9 +333,9 @@ public: Json::Value settings_; CharReaderBuilder(); - ~CharReaderBuilder() override; + ~CharReaderBuilder() JSONCPP_OVERRIDE; - CharReader* newCharReader() const override; + CharReader* newCharReader() const JSONCPP_OVERRIDE; /** \return true if 'settings' are legal and consistent; * otherwise, indicate bad settings via 'invalid'. diff --git a/include/json/value.h b/include/json/value.h index dffc51a..988a22c 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -13,13 +13,16 @@ // Conditional NORETURN attribute on the throw functions would: // a) suppress false positives from static code analysis // b) possibly improve optimization opportunities. +// For compatibility, [[noreturn]] is not used #if !defined(JSONCPP_NORETURN) -#if defined(_MSC_VER) && _MSC_VER == 1800 +#if defined(_MSC_VER) #define JSONCPP_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) || defined(__clang__) +#define JSONCPP_NORETURN __attribute__((noreturn)) #else -#define JSONCPP_NORETURN [[noreturn]] -#endif +#define JSONCPP_NORETURN #endif +#endif // if !defined(JSONCPP_NORETURN) // Support for '= delete' with template declarations was a late addition // to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2 @@ -39,10 +42,15 @@ #endif #endif -#include +#if JSONCPP_CXX_STD_11 +#else +#undef JSONCPP_TEMPLATE_DELETE +#define JSONCPP_TEMPLATE_DELETE +#include +#endif + #include #include -#include #include #include @@ -67,8 +75,8 @@ namespace Json { class JSON_API Exception : public std::exception { public: Exception(String msg); - ~Exception() noexcept override; - char const* what() const noexcept override; + ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; + char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; protected: String msg_; @@ -146,7 +154,7 @@ enum PrecisionType { */ class JSON_API StaticString { public: - explicit StaticString(const char* czstring) : c_str_(czstring) {} + JSONCPP_OP_EXPLICIT StaticString(const char* czstring) : c_str_(czstring) {} operator const char*() const { return c_str_; } @@ -194,21 +202,21 @@ class JSON_API Value { friend class ValueIteratorBase; public: - using Members = std::vector; - using iterator = ValueIterator; - using const_iterator = ValueConstIterator; - using UInt = Json::UInt; - using Int = Json::Int; + typedef std::vector Members; + typedef ValueIterator iterator; + typedef ValueConstIterator const_iterator; + typedef Json::UInt UInt; + typedef Json::Int Int; #if defined(JSON_HAS_INT64) - using UInt64 = Json::UInt64; - using Int64 = Json::Int64; + typedef Json::UInt64 UInt64; + typedef Json::Int64 Int64; #endif // defined(JSON_HAS_INT64) - using LargestInt = Json::LargestInt; - using LargestUInt = Json::LargestUInt; - using ArrayIndex = Json::ArrayIndex; + typedef Json::LargestInt LargestInt; + typedef Json::LargestUInt LargestUInt; + typedef Json::ArrayIndex ArrayIndex; // Required for boost integration, e. g. BOOST_TEST - using value_type = std::string; + typedef std::string value_type; #if JSON_USE_NULLREF // Binary compatibility kludges, do not use. @@ -220,34 +228,35 @@ public: static Value const& nullSingleton(); /// Minimum signed integer value that can be stored in a Json::Value. - static constexpr LargestInt minLargestInt = + static JSONCPP_CONST LargestInt minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); /// Maximum signed integer value that can be stored in a Json::Value. - static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2); + static JSONCPP_CONST LargestInt maxLargestInt = + LargestInt(LargestUInt(-1) / 2); /// Maximum unsigned integer value that can be stored in a Json::Value. - static constexpr LargestUInt maxLargestUInt = LargestUInt(-1); + static JSONCPP_CONST LargestUInt maxLargestUInt = LargestUInt(-1); /// Minimum signed int value that can be stored in a Json::Value. - static constexpr Int minInt = Int(~(UInt(-1) / 2)); + static JSONCPP_CONST Int minInt = Int(~(UInt(-1) / 2)); /// Maximum signed int value that can be stored in a Json::Value. - static constexpr Int maxInt = Int(UInt(-1) / 2); + static JSONCPP_CONST Int maxInt = Int(UInt(-1) / 2); /// Maximum unsigned int value that can be stored in a Json::Value. - static constexpr UInt maxUInt = UInt(-1); + static JSONCPP_CONST UInt maxUInt = UInt(-1); #if defined(JSON_HAS_INT64) /// Minimum signed 64 bits int value that can be stored in a Json::Value. - static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2)); + static JSONCPP_CONST Int64 minInt64 = Int64(~(UInt64(-1) / 2)); /// Maximum signed 64 bits int value that can be stored in a Json::Value. - static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2); + static JSONCPP_CONST Int64 maxInt64 = Int64(UInt64(-1) / 2); /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. - static constexpr UInt64 maxUInt64 = UInt64(-1); + static JSONCPP_CONST UInt64 maxUInt64 = UInt64(-1); #endif // defined(JSON_HAS_INT64) /// Default precision for real value for string representation. - static constexpr UInt defaultRealPrecision = 17; + static JSONCPP_CONST UInt defaultRealPrecision = 17; // The constant is hard-coded because some compiler have trouble // converting Value::maxUInt64 to a double correctly (AIX/xlC). // Assumes that UInt64 is a 64 bits integer. - static constexpr double maxUInt64AsDouble = 18446744073709551615.0; + static JSONCPP_CONST double maxUInt64AsDouble = 18446744073709551615.0; // Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler // when using gcc and clang backend compilers. CZString // cannot be defined as private. See issue #486 @@ -263,11 +272,14 @@ private: CZString(ArrayIndex index); CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(CZString const& other); +#if JSONCPP_CXX_STD_11 CZString(CZString&& other); +#endif ~CZString(); CZString& operator=(const CZString& other); +#if JSONCPP_CXX_STD_11 CZString& operator=(CZString&& other); - +#endif bool operator<(CZString const& other) const; bool operator==(CZString const& other) const; ArrayIndex index() const; @@ -343,13 +355,17 @@ public: Value(const String& value); Value(bool value); Value(const Value& other); +#if JSONCPP_CXX_STD_11 Value(Value&& other); +#endif ~Value(); /// \note Overwrite existing comments. To preserve comments, use /// #swapPayload(). Value& operator=(const Value& other); +#if JSONCPP_CXX_STD_11 Value& operator=(Value&& other); +#endif /// Swap everything. void swap(Value& other); @@ -421,7 +437,7 @@ public: bool empty() const; /// Return !isNull() - explicit operator bool() const; + JSONCPP_OP_EXPLICIT operator bool() const; /// Remove all object members and array elements. /// \pre type() is arrayValue, objectValue, or nullValue @@ -462,11 +478,15 @@ public: /// /// Equivalent to jsonvalue[jsonvalue.size()] = value; Value& append(const Value& value); +#if JSONCPP_CXX_STD_11 Value& append(Value&& value); +#endif /// \brief Insert value in array at specific index bool insert(ArrayIndex index, const Value& newValue); +#if JSONCPP_CXX_STD_11 bool insert(ArrayIndex index, Value&& newValue); +#endif /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. @@ -562,15 +582,11 @@ public: /// \deprecated Always pass len. JSONCPP_DEPRECATED("Use setComment(String const&) instead.") - void setComment(const char* comment, CommentPlacement placement) { - setComment(String(comment, strlen(comment)), placement); - } + void setComment(const char* comment, CommentPlacement placement); /// Comments must be //... or /* ... */ - void setComment(const char* comment, size_t len, CommentPlacement placement) { - setComment(String(comment, len), placement); - } + void setComment(const char* comment, size_t len, CommentPlacement placement); /// Comments must be //... or /* ... */ - void setComment(String comment, CommentPlacement placement); + void setComment(const String& comment, CommentPlacement placement); bool hasComment(CommentPlacement placement) const; /// Include delimiters and embedded newlines. String getComment(CommentPlacement placement) const; @@ -632,18 +648,15 @@ private: class Comments { public: - Comments() = default; + Comments() {} Comments(const Comments& that); - Comments(Comments&& that); Comments& operator=(const Comments& that); - Comments& operator=(Comments&& that); bool has(CommentPlacement slot) const; String get(CommentPlacement slot) const; - void set(CommentPlacement slot, String comment); + void set(CommentPlacement slot, String s); private: - using Array = std::array; - std::unique_ptr ptr_; + String ptr_[numberOfCommentPlacement]; }; Comments comments_; @@ -698,8 +711,8 @@ public: private: enum Kind { kindNone = 0, kindIndex, kindKey }; String key_; - ArrayIndex index_{}; - Kind kind_{kindNone}; + ArrayIndex index_; + Kind kind_; }; /** \brief Experimental and untested: represents a "path" to access a node. @@ -728,8 +741,8 @@ public: Value& make(Value& root) const; private: - using InArgs = std::vector; - using Args = std::vector; + typedef std::vector InArgs; + typedef std::vector Args; void makePath(const String& path, const InArgs& in); void addPathInArg(const String& path, const InArgs& in, @@ -744,10 +757,10 @@ private: */ class JSON_API ValueIteratorBase { public: - using iterator_category = std::bidirectional_iterator_tag; - using size_t = unsigned int; - using difference_type = int; - using SelfType = ValueIteratorBase; + typedef std::bidirectional_iterator_tag iterator_category; + typedef unsigned int size_t; + typedef int difference_type; + typedef ValueIteratorBase SelfType; bool operator==(const SelfType& other) const { return isEqual(other); } @@ -804,13 +817,14 @@ protected: private: Value::ObjectValues::iterator current_; // Indicates that iterator is for a null value. - bool isNull_{true}; + bool isNull_; public: // For some reason, BORLAND needs these at the end, rather // than earlier. No idea why. ValueIteratorBase(); - explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); + JSONCPP_OP_EXPLICIT + ValueIteratorBase(const Value::ObjectValues::iterator& current); }; /** \brief const iterator for object and array value. @@ -820,12 +834,12 @@ class JSON_API ValueConstIterator : public ValueIteratorBase { friend class Value; public: - using value_type = const Value; + typedef const Value value_type; // typedef unsigned int size_t; // typedef int difference_type; - using reference = const Value&; - using pointer = const Value*; - using SelfType = ValueConstIterator; + typedef const Value& reference; + typedef const Value* pointer; + typedef ValueConstIterator SelfType; ValueConstIterator(); ValueConstIterator(ValueIterator const& other); @@ -833,7 +847,8 @@ public: private: /*! \internal Use by Value to create an iterator. */ - explicit ValueConstIterator(const Value::ObjectValues::iterator& current); + JSONCPP_OP_EXPLICIT + ValueConstIterator(const Value::ObjectValues::iterator& current); public: SelfType& operator=(const ValueIteratorBase& other); @@ -871,21 +886,22 @@ class JSON_API ValueIterator : public ValueIteratorBase { friend class Value; public: - using value_type = Value; - using size_t = unsigned int; - using difference_type = int; - using reference = Value&; - using pointer = Value*; - using SelfType = ValueIterator; + typedef Value value_type; + typedef unsigned int size_t; + typedef int difference_type; + typedef Value& reference; + typedef Value* pointer; + typedef ValueIterator SelfType; ValueIterator(); - explicit ValueIterator(const ValueConstIterator& other); + JSONCPP_OP_EXPLICIT ValueIterator(const ValueConstIterator& other); ValueIterator(const ValueIterator& other); private: /*! \internal Use by Value to create an iterator. */ - explicit ValueIterator(const Value::ObjectValues::iterator& current); + JSONCPP_OP_EXPLICIT + ValueIterator(const Value::ObjectValues::iterator& current); public: SelfType& operator=(const SelfType& other); diff --git a/include/json/version.h b/include/json/version.h index 0f29834..fa681e8 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -9,10 +9,10 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.3" -#define JSONCPP_VERSION_MAJOR 1 -#define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 3 +#define JSONCPP_VERSION_STRING "00.11.0" +#define JSONCPP_VERSION_MAJOR 00 +#define JSONCPP_VERSION_MINOR 11 +#define JSONCPP_VERSION_PATCH 0 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ diff --git a/include/json/writer.h b/include/json/writer.h index fb0852a..e851c37 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -119,12 +119,12 @@ public: Json::Value settings_; StreamWriterBuilder(); - ~StreamWriterBuilder() override; + ~StreamWriterBuilder() JSONCPP_OVERRIDE; /** * \throw std::exception if something goes wrong (e.g. invalid settings) */ - StreamWriter* newStreamWriter() const override; + StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE; /** \return true if 'settings' are legal and consistent; * otherwise, indicate bad settings via 'invalid'. @@ -169,7 +169,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { public: FastWriter(); - ~FastWriter() override = default; + ~FastWriter() JSONCPP_OVERRIDE {} void enableYAMLCompatibility(); @@ -183,15 +183,15 @@ public: void omitEndingLineFeed(); public: // overridden from Writer - String write(const Value& root) override; + String write(const Value& root) JSONCPP_OVERRIDE; private: void writeValue(const Value& value); String document_; - bool yamlCompatibilityEnabled_{false}; - bool dropNullPlaceholders_{false}; - bool omitEndingLineFeed_{false}; + bool yamlCompatibilityEnabled_; + bool dropNullPlaceholders_; + bool omitEndingLineFeed_; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -229,14 +229,14 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { public: StyledWriter(); - ~StyledWriter() override = default; + ~StyledWriter() JSONCPP_OVERRIDE {} public: // overridden from Writer /** \brief Serialize a Value in JSON format. * \param root Value to serialize. * \return String containing the JSON document that represents the root value. */ - String write(const Value& root) override; + String write(const Value& root) JSONCPP_OVERRIDE; private: void writeValue(const Value& value); @@ -252,14 +252,14 @@ private: static bool hasCommentForValue(const Value& value); static String normalizeEOL(const String& text); - using ChildValues = std::vector; + typedef std::vector ChildValues; ChildValues childValues_; String document_; String indentString_; - unsigned int rightMargin_{74}; - unsigned int indentSize_{3}; - bool addChildValues_{false}; + unsigned int rightMargin_; + unsigned int indentSize_; + bool addChildValues_; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -301,7 +301,7 @@ public: * \param indentation Each level will be indented by this amount extra. */ StyledStreamWriter(String indentation = "\t"); - ~StyledStreamWriter() = default; + ~StyledStreamWriter() {} public: /** \brief Serialize a Value in JSON format. @@ -326,12 +326,12 @@ private: static bool hasCommentForValue(const Value& value); static String normalizeEOL(const String& text); - using ChildValues = std::vector; + typedef std::vector ChildValues; ChildValues childValues_; OStream* document_; String indentString_; - unsigned int rightMargin_{74}; + unsigned int rightMargin_; String indentation_; bool addChildValues_ : 1; bool indented_ : 1; @@ -348,7 +348,7 @@ String JSON_API valueToString(LargestInt value); String JSON_API valueToString(LargestUInt value); String JSON_API valueToString( double value, unsigned int precision = Value::defaultRealPrecision, - PrecisionType precisionType = PrecisionType::significantDigits); + PrecisionType precisionType = significantDigits); String JSON_API valueToString(bool value); String JSON_API valueToQuotedString(const char* value); diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 3452c59..5657c93 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -24,7 +24,9 @@ struct Options { Json::String path; Json::Features features; bool parseOnly; - using writeFuncType = Json::String (*)(Json::Value const&); + + typedef Json::String (*writeFuncType)(Json::Value const&); + writeFuncType write; }; @@ -57,11 +59,11 @@ static Json::String readInputTestFile(const char* path) { if (!file) return ""; fseek(file, 0, SEEK_END); - auto const size = ftell(file); - auto const usize = static_cast(size); + long const size = ftell(file); + size_t const usize = static_cast(size); fseek(file, 0, SEEK_SET); - auto buffer = new char[size + 1]; - buffer[size] = 0; + char* buffer = new char[usize + 1]; + buffer[usize] = 0; Json::String text; if (fread(buffer, 1, usize, file) == usize) text = buffer; @@ -111,7 +113,9 @@ static void printValueTree(FILE* fout, Json::Value& value, Json::Value::Members members(value.getMemberNames()); std::sort(members.begin(), members.end()); Json::String suffix = *(path.end() - 1) == '.' ? "" : "."; - for (const auto& name : members) { + for (Json::Value::Members::const_iterator it = members.begin(); + it != members.end(); it++) { + const Json::String& name = *it; printValueTree(fout, value[name], path + suffix + name); } } break; @@ -138,7 +142,7 @@ static int parseAndSaveValueTree(const Json::String& input, features.allowDroppedNullPlaceholders_; builder.settings_["allowNumericKeys"] = features.allowNumericKeys_; - std::unique_ptr reader(builder.newCharReader()); + Json::CharReader* reader(builder.newCharReader()); Json::String errors; const bool parsingSuccessful = reader->parse(input.data(), input.data() + input.size(), root, &errors); @@ -148,7 +152,7 @@ static int parseAndSaveValueTree(const Json::String& input, << errors << std::endl; return 1; } - + delete reader; // We may instead check the legacy implementation (to ensure it doesn't // randomly get broken). } else { diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 02a7d54..f233abb 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -51,18 +51,15 @@ static size_t const stackLimit_g = namespace Json { -#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) -using CharReaderPtr = std::unique_ptr; -#else -using CharReaderPtr = std::auto_ptr; -#endif +typedef CharReader* CharReaderPtr; // Implementation of class Features // //////////////////////////////// -Features::Features() = default; - -Features Features::all() { return {}; } +Features::Features() + : allowComments_(true), strictRoot_(false), + allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} +Features Features::all() { return Features(); } Features Features::strictMode() { Features features; @@ -86,9 +83,15 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { // Class Reader // ////////////////////////////////////////////////////////////////// -Reader::Reader() : features_(Features::all()) {} +Reader::Reader() + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(Features::all()), + collectComments_() {} -Reader::Reader(const Features& features) : features_(features) {} +Reader::Reader(const Features& features) + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(features), collectComments_() { +} bool Reader::parse(const std::string& document, Value& root, bool collectComments) { @@ -121,8 +124,8 @@ bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, end_ = endDoc; collectComments_ = collectComments; current_ = begin_; - lastValueEnd_ = nullptr; - lastValue_ = nullptr; + lastValueEnd_ = JSONCPP_NULL; + lastValue_ = JSONCPP_NULL; commentsBefore_.clear(); errors_.clear(); while (!nodes_.empty()) @@ -376,7 +379,7 @@ void Reader::addComment(Location begin, Location end, assert(collectComments_); const String& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(lastValue_ != nullptr); + assert(lastValue_ != JSONCPP_NULL); lastValue_->setComment(normalized, placement); } else { commentsBefore_ += normalized; @@ -565,7 +568,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { Char c = *current++; if (c < '0' || c > '9') return decodeDouble(token, decoded); - auto digit(static_cast(c - '0')); + Value::UInt digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, b) this is the last digit, and @@ -798,7 +801,9 @@ String Reader::getFormatedErrorMessages() const { String Reader::getFormattedErrorMessages() const { String formattedMessage; - for (const auto& error : errors_) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); ++itError) { + const ErrorInfo& error = *itError; formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; @@ -811,7 +816,9 @@ String Reader::getFormattedErrorMessages() const { std::vector Reader::getStructuredErrors() const { std::vector allErrors; - for (const auto& error : errors_) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); ++itError) { + const ErrorInfo& error = *itError; Reader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; @@ -832,7 +839,7 @@ bool Reader::pushError(const Value& value, const String& message) { ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = nullptr; + info.extra_ = JSONCPP_NULL; errors_.push_back(info); return true; } @@ -875,7 +882,7 @@ public: size_t stackLimit_; }; // OurFeatures -OurFeatures OurFeatures::all() { return {}; } +OurFeatures OurFeatures::all() { return OurFeatures(); } // Implementation of class Reader // //////////////////////////////// @@ -884,15 +891,15 @@ OurFeatures OurFeatures::all() { return {}; } // for implementing JSON reading. class OurReader { public: - using Char = char; - using Location = const Char*; + typedef char Char; + typedef const Char* Location; struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; String message; }; - explicit OurReader(OurFeatures const& features); + JSONCPP_OP_EXPLICIT OurReader(OurFeatures const& features); bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); String getFormattedErrorMessages() const; @@ -936,7 +943,7 @@ private: Location extra_; }; - using Errors = std::deque; + typedef std::deque Errors; bool readToken(Token& token); void skipSpaces(); @@ -961,7 +968,8 @@ private: unsigned int& unicode); bool decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, unsigned int& unicode); - bool addError(const String& message, Token& token, Location extra = nullptr); + bool addError(const String& message, Token& token, + Location extra = JSONCPP_NULL); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); @@ -977,21 +985,21 @@ private: static String normalizeEOL(Location begin, Location end); static bool containsNewLine(Location begin, Location end); - using Nodes = std::stack; + typedef std::stack Nodes; - Nodes nodes_{}; - Errors errors_{}; - String document_{}; - Location begin_ = nullptr; - Location end_ = nullptr; - Location current_ = nullptr; - Location lastValueEnd_ = nullptr; - Value* lastValue_ = nullptr; - bool lastValueHasAComment_ = false; - String commentsBefore_{}; + Nodes nodes_; + Errors errors_; + String document_; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value* lastValue_; + bool lastValueHasAComment_; + String commentsBefore_; OurFeatures const features_; - bool collectComments_ = false; + bool collectComments_; }; // OurReader // complete copy of Read impl, for OurReader @@ -1004,7 +1012,11 @@ bool OurReader::containsNewLine(OurReader::Location begin, return false; } -OurReader::OurReader(OurFeatures const& features) : features_(features) {} +OurReader::OurReader(OurFeatures const& features) + : errors_(), document_(), begin_(JSONCPP_NULL), end_(JSONCPP_NULL), + current_(JSONCPP_NULL), lastValueEnd_(JSONCPP_NULL), + lastValue_(JSONCPP_NULL), lastValueHasAComment_(false), commentsBefore_(), + features_(features), collectComments_(false) {} bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments) { @@ -1016,8 +1028,8 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, end_ = endDoc; collectComments_ = collectComments; current_ = begin_; - lastValueEnd_ = nullptr; - lastValue_ = nullptr; + lastValueEnd_ = JSONCPP_NULL; + lastValue_ = JSONCPP_NULL; commentsBefore_.clear(); errors_.clear(); while (!nodes_.empty()) @@ -1352,7 +1364,7 @@ void OurReader::addComment(Location begin, Location end, assert(collectComments_); const String& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(lastValue_ != nullptr); + assert(lastValue_ != JSONCPP_NULL); lastValue_->setComment(normalized, placement); } else { commentsBefore_ += normalized; @@ -1568,32 +1580,36 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { // We assume we can represent the largest and smallest integer types as // unsigned integers with separate sign. This is only true if they can fit // into an unsigned integer. - static_assert(Value::maxLargestInt <= Value::maxLargestUInt, - "Int must be smaller than UInt"); - + JSONCPP_STATIC_ASSERT(LargestUInt(Value::maxLargestInt) <= + Value::maxLargestUInt, + "Int must be smaller than Uint"); // We need to convert minLargestInt into a positive number. The easiest way // to do this conversion is to assume our "threshold" value of minLargestInt // divided by 10 can fit in maxLargestInt when absolute valued. This should // be a safe assumption. - static_assert(Value::minLargestInt <= -Value::maxLargestInt, - "The absolute value of minLargestInt must be greater than or " - "equal to maxLargestInt"); - static_assert(Value::minLargestInt / 10 >= -Value::maxLargestInt, - "The absolute value of minLargestInt must be only 1 magnitude " - "larger than maxLargest Int"); + JSONCPP_STATIC_ASSERT( + Value::minLargestInt <= -Value::maxLargestInt, + "The absolute value of minLargestInt must ve greater than or" + "equal to maxLargestInt"); - static constexpr Value::LargestUInt positive_threshold = + JSONCPP_STATIC_ASSERT( + Value::minLargestInt / 10 >= -Value::maxLargestInt, + "The absolute value of minLargestInt must be only 1 magnitude" + "larger than maxLargestInt"); + + static JSONCPP_CONST Value::LargestUInt positive_threshold = Value::maxLargestUInt / 10; - static constexpr Value::UInt positive_last_digit = Value::maxLargestUInt % 10; + static JSONCPP_CONST Value::UInt positive_last_digit = + Value::maxLargestUInt % 10; // For the negative values, we have to be more careful. Since typically // -Value::minLargestInt will cause an overflow, we first divide by 10 and // then take the inverse. This assumes that minLargestInt is only a single // power of 10 different in magnitude, which we check above. For the last // digit, we take the modulus before negating for the same reason. - static constexpr auto negative_threshold = + static JSONCPP_CONST Value::LargestUInt negative_threshold = Value::LargestUInt(-(Value::minLargestInt / 10)); - static constexpr auto negative_last_digit = + static JSONCPP_CONST Value::UInt negative_last_digit = Value::UInt(-(Value::minLargestInt % 10)); const Value::LargestUInt threshold = @@ -1607,7 +1623,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { if (c < '0' || c > '9') return decodeDouble(token, decoded); - const auto digit(static_cast(c - '0')); + const Value::UInt digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, meaing value == threshold, @@ -1624,7 +1640,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { if (isNegative) { // We use the same magnitude assumption here, just in case. - const auto last_digit = static_cast(value % 10); + const Value::UInt last_digit = static_cast(value % 10); decoded = -Value::LargestInt(value / 10) * 10 - last_digit; } else if (value <= Value::LargestUInt(Value::maxLargestInt)) { decoded = Value::LargestInt(value); @@ -1840,7 +1856,9 @@ String OurReader::getLocationLineAndColumn(Location location) const { String OurReader::getFormattedErrorMessages() const { String formattedMessage; - for (const auto& error : errors_) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); ++itError) { + const ErrorInfo& error = *itError; formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; @@ -1853,7 +1871,9 @@ String OurReader::getFormattedErrorMessages() const { std::vector OurReader::getStructuredErrors() const { std::vector allErrors; - for (const auto& error : errors_) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); ++itError) { + const ErrorInfo& error = *itError; OurReader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; @@ -1871,7 +1891,7 @@ public: OurCharReader(bool collectComments, OurFeatures const& features) : collectComments_(collectComments), reader_(features) {} bool parse(char const* beginDoc, char const* endDoc, Value* root, - String* errs) override { + String* errs) JSONCPP_OVERRIDE { bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { *errs = reader_.getFormattedErrorMessages(); @@ -1881,7 +1901,7 @@ public: }; CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); } -CharReaderBuilder::~CharReaderBuilder() = default; +CharReaderBuilder::~CharReaderBuilder() {} CharReader* CharReaderBuilder::newCharReader() const { bool collectComments = settings_["collectComments"].asBool(); OurFeatures features = OurFeatures::all(); @@ -1983,7 +2003,9 @@ bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root, char const* end = begin + doc.size(); // Note that we do not actually need a null-terminator. CharReaderPtr const reader(fact.newCharReader()); - return reader->parse(begin, end, root, errs); + bool ret = reader->parse(begin, end, root, errs); + delete reader; + return ret; } IStream& operator>>(IStream& sin, Value& root) { diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 2d7b7d9..5c13f1f 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -71,7 +71,7 @@ enum { }; // Defines a char buffer for use with uintToString(). -using UIntToStringBuffer = char[uintToStringBufferSize]; +typedef char UIntToStringBuffer[uintToStringBufferSize]; /** Converts an unsigned integer to string. * @param value Unsigned integer to convert to string diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 0872ff5..2938ea5 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -48,14 +48,6 @@ int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, size_t size, #define JSON_ASSERT_UNREACHABLE assert(false) namespace Json { -template -static std::unique_ptr cloneUnique(const std::unique_ptr& p) { - std::unique_ptr r; - if (p) { - r = std::unique_ptr(new T(*p)); - } - return r; -} // This is a walkaround to avoid the static initialization of Value::null. // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of @@ -118,8 +110,8 @@ static inline char* duplicateStringValue(const char* value, size_t length) { if (length >= static_cast(Value::maxInt)) length = Value::maxInt - 1; - auto newString = static_cast(malloc(length + 1)); - if (newString == nullptr) { + char* newString = static_cast(malloc(length + 1)); + if (newString == JSONCPP_NULL) { throwRuntimeError("in Json::Value::duplicateStringValue(): " "Failed to allocate string value buffer"); } @@ -139,8 +131,8 @@ static inline char* duplicateAndPrefixStringValue(const char* value, "in Json::Value::duplicateAndPrefixStringValue(): " "length too big for prefixing"); size_t actualLength = sizeof(length) + length + 1; - auto newString = static_cast(malloc(actualLength)); - if (newString == nullptr) { + char* newString = static_cast(malloc(actualLength)); + if (newString == JSONCPP_NULL) { throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " "Failed to allocate string value buffer"); } @@ -200,9 +192,9 @@ static inline void releaseStringValue(char* value, unsigned) { free(value); } namespace Json { #if JSON_USE_EXCEPTION -Exception::Exception(String msg) : msg_(std::move(msg)) {} -Exception::~Exception() noexcept = default; -char const* Exception::what() const noexcept { return msg_.c_str(); } +Exception::Exception(String msg) : msg_(JSONCPP_MOVE(msg)) {} +Exception::~Exception() JSONCPP_NOEXCEPT {} +char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} LogicError::LogicError(String const& msg) : Exception(msg) {} JSONCPP_NORETURN void throwRuntimeError(String const& msg) { @@ -233,7 +225,8 @@ JSONCPP_NORETURN void throwLogicError(String const& msg) { // Notes: policy_ indicates if the string was allocated when // a string is stored. -Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {} +Value::CZString::CZString(ArrayIndex index) + : cstr_(JSONCPP_NULL), index_(index) {} Value::CZString::CZString(char const* str, unsigned length, DuplicationPolicy allocate) @@ -244,9 +237,10 @@ Value::CZString::CZString(char const* str, unsigned length, } Value::CZString::CZString(const CZString& other) { - cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr - ? duplicateStringValue(other.cstr_, other.storage_.length_) - : other.cstr_); + cstr_ = + (other.storage_.policy_ != noDuplication && other.cstr_ != JSONCPP_NULL + ? duplicateStringValue(other.cstr_, other.storage_.length_) + : other.cstr_); storage_.policy_ = static_cast( other.cstr_ @@ -258,12 +252,12 @@ Value::CZString::CZString(const CZString& other) { 3U; storage_.length_ = other.storage_.length_; } - +#if JSONCPP_CXX_STD_11 Value::CZString::CZString(CZString&& other) : cstr_(other.cstr_), index_(other.index_) { - other.cstr_ = nullptr; + other.cstr_ = JSONCPP_NULL; } - +#endif Value::CZString::~CZString() { if (cstr_ && storage_.policy_ == duplicate) { releaseStringValue(const_cast(cstr_), @@ -284,14 +278,14 @@ Value::CZString& Value::CZString::operator=(const CZString& other) { index_ = other.index_; return *this; } - +#if JSONCPP_CXX_STD_11 Value::CZString& Value::CZString::operator=(CZString&& other) { cstr_ = other.cstr_; index_ = other.index_; - other.cstr_ = nullptr; + other.cstr_ = JSONCPP_NULL; return *this; } - +#endif bool Value::CZString::operator<(const CZString& other) const { if (!cstr_) return index_ < other.index_; @@ -400,7 +394,7 @@ Value::Value(double value) { Value::Value(const char* value) { initBasic(stringValue, true); - JSON_ASSERT_MESSAGE(value != nullptr, + JSON_ASSERT_MESSAGE(value != JSONCPP_NULL, "Null Value Passed to Value Constructor"); value_.string_ = duplicateAndPrefixStringValue( value, static_cast(strlen(value))); @@ -432,11 +426,12 @@ Value::Value(const Value& other) { dupPayload(other); dupMeta(other); } - +#if JSONCPP_CXX_STD_11 Value::Value(Value&& other) { initBasic(nullValue); swap(other); } +#endif Value::~Value() { releasePayload(); @@ -447,11 +442,12 @@ Value& Value::operator=(const Value& other) { Value(other).swap(*this); return *this; } - +#if JSONCPP_CXX_STD_11 Value& Value::operator=(Value&& other) { other.swap(*this); return *this; } +#endif void Value::swapPayload(Value& other) { std::swap(bits_, other.bits_); @@ -503,8 +499,9 @@ bool Value::operator<(const Value& other) const { case booleanValue: return value_.bool_ < other.value_.bool_; case stringValue: { - if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { - return other.value_.string_ != nullptr; + if ((value_.string_ == JSONCPP_NULL) || + (other.value_.string_ == JSONCPP_NULL)) { + return other.value_.string_ != JSONCPP_NULL; } unsigned this_len; unsigned other_len; @@ -525,8 +522,8 @@ bool Value::operator<(const Value& other) const { } case arrayValue: case objectValue: { - auto thisSize = value_.map_->size(); - auto otherSize = other.value_.map_->size(); + long unsigned int thisSize = value_.map_->size(); + long unsigned int otherSize = other.value_.map_->size(); if (thisSize != otherSize) return thisSize < otherSize; return (*value_.map_) < (*other.value_.map_); @@ -558,7 +555,8 @@ bool Value::operator==(const Value& other) const { case booleanValue: return value_.bool_ == other.value_.bool_; case stringValue: { - if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { + if ((value_.string_ == JSONCPP_NULL) || + (other.value_.string_ == JSONCPP_NULL)) { return (value_.string_ == other.value_.string_); } unsigned this_len; @@ -590,8 +588,8 @@ 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_ == nullptr) - return nullptr; + if (value_.string_ == JSONCPP_NULL) + return JSONCPP_NULL; unsigned this_len; char const* this_str; decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, @@ -616,7 +614,7 @@ unsigned Value::getCStringLength() const { bool Value::getString(char const** begin, char const** end) const { if (type() != stringValue) return false; - if (value_.string_ == nullptr) + if (value_.string_ == JSONCPP_NULL) return false; unsigned length; decodePrefixedString(this->isAllocated(), this->value_.string_, &length, @@ -630,7 +628,7 @@ String Value::asString() const { case nullValue: return ""; case stringValue: { - if (value_.string_ == nullptr) + if (value_.string_ == JSONCPP_NULL) return ""; unsigned this_len; char const* this_str; @@ -813,7 +811,7 @@ bool Value::asBool() const { return value_.uint_ != 0; case realValue: { // According to JavaScript language zero or NaN is regarded as false - const auto value_classification = std::fpclassify(value_.real_); + const int value_classification = std::fpclassify(value_.real_); return value_classification != FP_ZERO && value_classification != FP_NAN; } default: @@ -928,7 +926,7 @@ Value& Value::operator[](ArrayIndex index) { if (type() == nullValue) *this = Value(arrayValue); CZString key(index); - auto it = value_.map_->lower_bound(key); + ObjectValues::iterator it = value_.map_->lower_bound(key); if (it != value_.map_->end() && (*it).first == key) return (*it).second; @@ -967,7 +965,7 @@ const Value& Value::operator[](int index) const { void Value::initBasic(ValueType type, bool allocated) { setType(type); setIsAllocated(allocated); - comments_ = Comments{}; + comments_ = Comments(); start_ = 0; limit_ = 0; } @@ -1042,7 +1040,7 @@ Value& Value::resolveReference(const char* key) { *this = Value(objectValue); CZString actualKey(key, static_cast(strlen(key)), CZString::noDuplication); // NOTE! - auto it = value_.map_->lower_bound(actualKey); + ObjectValues::iterator it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) return (*it).second; @@ -1061,7 +1059,7 @@ Value& Value::resolveReference(char const* key, char const* end) { *this = Value(objectValue); CZString actualKey(key, static_cast(end - key), CZString::duplicateOnCopy); - auto it = value_.map_->lower_bound(actualKey); + ObjectValues::iterator it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) return (*it).second; @@ -1083,12 +1081,12 @@ Value const* Value::find(char const* begin, char const* end) const { "in Json::Value::find(begin, end): requires " "objectValue or nullValue"); if (type() == nullValue) - return nullptr; + return JSONCPP_NULL; CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); ObjectValues::const_iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) - return nullptr; + return JSONCPP_NULL; return &(*it).second; } Value* Value::demand(char const* begin, char const* end) { @@ -1122,8 +1120,8 @@ Value& Value::operator[](const StaticString& key) { return resolveReference(key.c_str()); } +#if JSONCPP_CXX_STD_11 Value& Value::append(const Value& value) { return append(Value(value)); } - Value& Value::append(Value&& value) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, "in Json::Value::append: requires arrayValue"); @@ -1132,12 +1130,19 @@ Value& Value::append(Value&& value) { } return this->value_.map_->emplace(size(), std::move(value)).first->second; } +#else +Value& Value::append(const Value& value) { return (*this)[size()] = value; } +#endif +#if JSONCPP_CXX_STD_11 bool Value::insert(ArrayIndex index, const Value& newValue) { return insert(index, Value(newValue)); } bool Value::insert(ArrayIndex index, Value&& newValue) { +#else +bool Value::insert(ArrayIndex index, const Value& newValue) { +#endif JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, "in Json::Value::insert: requires arrayValue"); ArrayIndex length = size(); @@ -1145,12 +1150,11 @@ bool Value::insert(ArrayIndex index, Value&& newValue) { return false; } for (ArrayIndex i = length; i > index; i--) { - (*this)[i] = std::move((*this)[i - 1]); + (*this)[i] = JSONCPP_MOVE((*this)[i - 1]); } - (*this)[index] = std::move(newValue); + (*this)[index] = JSONCPP_MOVE(newValue); return true; } - Value Value::get(char const* begin, char const* end, Value const& defaultValue) const { Value const* found = find(begin, end); @@ -1169,11 +1173,11 @@ bool Value::removeMember(const char* begin, const char* end, Value* removed) { } CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); - auto it = value_.map_->find(actualKey); + ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) return false; if (removed) - *removed = std::move(it->second); + *removed = JSONCPP_MOVE(it->second); value_.map_->erase(it); return true; } @@ -1199,7 +1203,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { return false; } CZString key(index); - auto it = value_.map_->find(key); + ObjectValues::iterator it = value_.map_->find(key); if (it == value_.map_->end()) { return false; } @@ -1213,14 +1217,14 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { } // erase the last one ("leftover") CZString keyLast(oldSize - 1); - auto itLast = value_.map_->find(keyLast); + ObjectValues::iterator itLast = value_.map_->find(keyLast); value_.map_->erase(itLast); return true; } bool Value::isMember(char const* begin, char const* end) const { Value const* value = find(begin, end); - return nullptr != value; + return JSONCPP_NULL != value; } bool Value::isMember(char const* key) const { return isMember(key, key + strlen(key)); @@ -1370,53 +1374,44 @@ bool Value::isArray() const { return type() == arrayValue; } bool Value::isObject() const { return type() == objectValue; } -Value::Comments::Comments(const Comments& that) - : ptr_{cloneUnique(that.ptr_)} {} - -Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {} - +Value::Comments::Comments(const Comments& that) { + for (size_t i = 0; i < numberOfCommentPlacement; i++) { + ptr_[i] = that.ptr_[i]; + } +} Value::Comments& Value::Comments::operator=(const Comments& that) { - ptr_ = cloneUnique(that.ptr_); + for (size_t i = 0; i < numberOfCommentPlacement; i++) { + ptr_[i] = that.ptr_[i]; + } return *this; } - -Value::Comments& Value::Comments::operator=(Comments&& that) { - ptr_ = std::move(that.ptr_); - return *this; -} - bool Value::Comments::has(CommentPlacement slot) const { - return ptr_ && !(*ptr_)[slot].empty(); + return !ptr_[slot].empty(); } -String Value::Comments::get(CommentPlacement slot) const { - if (!ptr_) - return {}; - return (*ptr_)[slot]; -} +String Value::Comments::get(CommentPlacement slot) const { return ptr_[slot]; } void Value::Comments::set(CommentPlacement slot, String comment) { - if (!ptr_) { - ptr_ = std::unique_ptr(new Array()); - } // check comments array boundry. - if (slot < CommentPlacement::numberOfCommentPlacement) { - (*ptr_)[slot] = std::move(comment); + if (slot < numberOfCommentPlacement) { + ptr_[slot] = comment; } } -void Value::setComment(String comment, CommentPlacement placement) { - if (!comment.empty() && (comment.back() == '\n')) { +void Value::setComment(const char* comment, CommentPlacement placement) { + setComment(comment, strlen(comment), placement); +} +void Value::setComment(const char* comment, size_t len, + CommentPlacement placement) { + if ((len > 0) && (comment[len - 1] == '\n')) { // Always discard trailing newline, to aid indentation. - comment.pop_back(); + len -= 1; } - JSON_ASSERT(!comment.empty()); - JSON_ASSERT_MESSAGE( - comment[0] == '\0' || comment[0] == '/', - "in Json::Value::setComment(): Comments must start with /"); - comments_.set(placement, std::move(comment)); + comments_.set(placement, String(comment, len)); +} +void Value::setComment(const String& comment, CommentPlacement placement) { + setComment(comment.c_str(), comment.length(), placement); } - bool Value::hasComment(CommentPlacement placement) const { return comments_.has(placement); } @@ -1453,7 +1448,7 @@ Value::const_iterator Value::begin() const { default: break; } - return {}; + return const_iterator(); } Value::const_iterator Value::end() const { @@ -1466,7 +1461,7 @@ Value::const_iterator Value::end() const { default: break; } - return {}; + return const_iterator(); } Value::iterator Value::begin() { @@ -1498,14 +1493,15 @@ Value::iterator Value::end() { // class PathArgument // ////////////////////////////////////////////////////////////////// -PathArgument::PathArgument() = default; +PathArgument::PathArgument() {} PathArgument::PathArgument(ArrayIndex index) : index_(index), kind_(kindIndex) {} PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {} -PathArgument::PathArgument(String key) : key_(std::move(key)), kind_(kindKey) {} +PathArgument::PathArgument(String key) + : key_(JSONCPP_MOVE(key)), kind_(kindKey) {} // class Path // ////////////////////////////////////////////////////////////////// @@ -1526,7 +1522,7 @@ Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2, void Path::makePath(const String& path, const InArgs& in) { const char* current = path.c_str(); const char* end = current + path.length(); - auto itInArg = in.begin(); + InArgs::const_iterator itInArg = in.begin(); while (current != end) { if (*current == '[') { ++current; @@ -1572,7 +1568,9 @@ void Path::invalidPath(const String& /*path*/, int /*location*/) { const Value& Path::resolve(const Value& root) const { const Value* node = &root; - for (const auto& arg : args_) { + for (Args::const_iterator itArg = args_.begin(); itArg != args_.end(); + ++itArg) { + const PathArgument& arg = *itArg; if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) { // Error: unable to resolve path (array value expected at position... ) @@ -1597,7 +1595,9 @@ const Value& Path::resolve(const Value& root) const { Value Path::resolve(const Value& root, const Value& defaultValue) const { const Value* node = &root; - for (const auto& arg : args_) { + for (Args::const_iterator itArg = args_.begin(); itArg != args_.end(); + ++itArg) { + const PathArgument& arg = *itArg; if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) return defaultValue; @@ -1615,7 +1615,9 @@ Value Path::resolve(const Value& root, const Value& defaultValue) const { Value& Path::make(Value& root) const { Value* node = &root; - for (const auto& arg : args_) { + for (Args::const_iterator itArg = args_.begin(); itArg != args_.end(); + ++itArg) { + const PathArgument& arg = *itArg; if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray()) { // Error: node is not an array at position ... diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index d6128b8..9b65584 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -15,7 +15,7 @@ namespace Json { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -ValueIteratorBase::ValueIteratorBase() : current_() {} +ValueIteratorBase::ValueIteratorBase() : current_(), isNull_(true) {} ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator& current) @@ -98,8 +98,8 @@ char const* ValueIteratorBase::memberName() const { char const* ValueIteratorBase::memberName(char const** end) const { const char* cname = (*current_).first.data(); if (!cname) { - *end = nullptr; - return nullptr; + *end = JSONCPP_NULL; + return JSONCPP_NULL; } *end = cname + (*current_).first.length(); return cname; @@ -113,7 +113,7 @@ char const* ValueIteratorBase::memberName(char const** end) const { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -ValueConstIterator::ValueConstIterator() = default; +ValueConstIterator::ValueConstIterator() {} ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator& current) @@ -136,7 +136,7 @@ operator=(const ValueIteratorBase& other) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -ValueIterator::ValueIterator() = default; +ValueIterator::ValueIterator() {} ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) : ValueIteratorBase(current) {} @@ -146,7 +146,8 @@ ValueIterator::ValueIterator(const ValueConstIterator& other) throwRuntimeError("ConstIterator to Iterator should never be allowed."); } -ValueIterator::ValueIterator(const ValueIterator& other) = default; +ValueIterator::ValueIterator(const ValueIterator& other) + : ValueIteratorBase(other) {} ValueIterator& ValueIterator::operator=(const SelfType& other) { copy(other); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 56195dc..6602920 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -83,11 +83,7 @@ namespace Json { -#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) -using StreamWriterPtr = std::unique_ptr; -#else -using StreamWriterPtr = std::auto_ptr; -#endif +typedef StreamWriter* StreamWriterPtr; String valueToString(LargestInt value) { UIntToStringBuffer buffer; @@ -136,12 +132,12 @@ String valueToString(double value, bool useSpecialFloats, String buffer(size_t(36), '\0'); while (true) { - int len = jsoncpp_snprintf( - &*buffer.begin(), buffer.size(), - (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", - precision, value); + int len = + jsoncpp_snprintf(&*buffer.begin(), buffer.size(), + (precisionType == significantDigits) ? "%.*g" : "%.*f", + precision, value); assert(len >= 0); - auto wouldPrint = static_cast(len); + size_t wouldPrint = static_cast(len); if (wouldPrint >= buffer.size()) { buffer.resize(wouldPrint + 1); continue; @@ -153,7 +149,7 @@ String valueToString(double value, bool useSpecialFloats, buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); // strip the zero padding from the right - if (precisionType == PrecisionType::decimalPlaces) { + if (precisionType == decimalPlaces) { buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); } @@ -267,7 +263,7 @@ static String toHex16Bit(unsigned int x) { static String valueToQuotedStringN(const char* value, unsigned length, bool emitUTF8 = false) { - if (value == nullptr) + if (value == JSONCPP_NULL) return ""; if (!isAnyCharRequiredQuoting(value, length)) @@ -351,14 +347,14 @@ String valueToQuotedString(const char* value) { // Class Writer // ////////////////////////////////////////////////////////////////// -Writer::~Writer() = default; +Writer::~Writer() {} // Class FastWriter // ////////////////////////////////////////////////////////////////// FastWriter::FastWriter() - - = default; + : yamlCompatibilityEnabled_(false), dropNullPlaceholders_(false), + omitEndingLineFeed_(false) {} void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; } @@ -414,7 +410,8 @@ void FastWriter::writeValue(const Value& value) { case objectValue: { Value::Members members(value.getMemberNames()); document_ += '{'; - for (auto it = members.begin(); it != members.end(); ++it) { + for (Value::Members::const_iterator it = members.begin(); + it != members.end(); ++it) { const String& name = *it; if (it != members.begin()) document_ += ','; @@ -431,7 +428,8 @@ void FastWriter::writeValue(const Value& value) { // Class StyledWriter // ////////////////////////////////////////////////////////////////// -StyledWriter::StyledWriter() = default; +StyledWriter::StyledWriter() + : rightMargin_(74), indentSize_(3), addChildValues_() {} String StyledWriter::write(const Value& root) { document_.clear(); @@ -482,7 +480,7 @@ void StyledWriter::writeValue(const Value& value) { else { writeWithIndent("{"); indent(); - auto it = members.begin(); + Value::Members::const_iterator it = members.begin(); for (;;) { const String& name = *it; const Value& childValue = value[name]; @@ -644,8 +642,9 @@ bool StyledWriter::hasCommentForValue(const Value& value) { // ////////////////////////////////////////////////////////////////// StyledStreamWriter::StyledStreamWriter(String indentation) - : document_(nullptr), indentation_(std::move(indentation)), - addChildValues_(), indented_(false) {} + : document_(JSONCPP_NULL), rightMargin_(74), + indentation_(JSONCPP_MOVE(indentation)), addChildValues_(), + indented_(false) {} void StyledStreamWriter::write(OStream& out, const Value& root) { document_ = &out; @@ -659,7 +658,7 @@ void StyledStreamWriter::write(OStream& out, const Value& root) { writeValue(root); writeCommentAfterValueOnSameLine(root); *document_ << "\n"; - document_ = nullptr; // Forget the stream, for safety. + document_ = JSONCPP_NULL; // Forget the stream, for safety. } void StyledStreamWriter::writeValue(const Value& value) { @@ -700,7 +699,7 @@ void StyledStreamWriter::writeValue(const Value& value) { else { writeWithIndent("{"); indent(); - auto it = members.begin(); + Value::Members::const_iterator it = members.begin(); for (;;) { const String& name = *it; const Value& childValue = value[name]; @@ -878,7 +877,7 @@ struct BuiltStyledStreamWriter : public StreamWriter { String endingLineFeedSymbol, bool useSpecialFloats, bool emitUTF8, unsigned int precision, PrecisionType precisionType); - int write(Value const& root, OStream* sout) override; + int write(Value const& root, OStream* sout) JSONCPP_OVERRIDE; private: void writeValue(Value const& value); @@ -893,7 +892,7 @@ private: void writeCommentAfterValueOnSameLine(Value const& root); static bool hasCommentForValue(const Value& value); - using ChildValues = std::vector; + typedef std::vector ChildValues; ChildValues childValues_; String indentString_; @@ -914,9 +913,10 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter( String indentation, CommentStyle::Enum cs, String colonSymbol, String nullSymbol, String endingLineFeedSymbol, bool useSpecialFloats, bool emitUTF8, unsigned int precision, PrecisionType precisionType) - : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), - colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), - endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), + : rightMargin_(74), indentation_(JSONCPP_MOVE(indentation)), cs_(cs), + colonSymbol_(JSONCPP_MOVE(colonSymbol)), + nullSymbol_(JSONCPP_MOVE(nullSymbol)), + endingLineFeedSymbol_(JSONCPP_MOVE(endingLineFeedSymbol)), addChildValues_(false), indented_(false), useSpecialFloats_(useSpecialFloats), emitUTF8_(emitUTF8), precision_(precision), precisionType_(precisionType) {} @@ -932,7 +932,7 @@ int BuiltStyledStreamWriter::write(Value const& root, OStream* sout) { writeValue(root); writeCommentAfterValueOnSameLine(root); *sout_ << endingLineFeedSymbol_; - sout_ = nullptr; + sout_ = JSONCPP_NULL; return 0; } void BuiltStyledStreamWriter::writeValue(Value const& value) { @@ -975,7 +975,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { else { writeWithIndent("{"); indent(); - auto it = members.begin(); + Value::Members::const_iterator it = members.begin(); for (;;) { String const& name = *it; Value const& childValue = value[name]; @@ -1151,11 +1151,11 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { /////////////// // StreamWriter -StreamWriter::StreamWriter() : sout_(nullptr) {} -StreamWriter::~StreamWriter() = default; -StreamWriter::Factory::~Factory() = default; +StreamWriter::StreamWriter() : sout_(JSONCPP_NULL) {} +StreamWriter::~StreamWriter() {} +StreamWriter::Factory::~Factory() {} StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } -StreamWriterBuilder::~StreamWriterBuilder() = default; +StreamWriterBuilder::~StreamWriterBuilder() {} StreamWriter* StreamWriterBuilder::newStreamWriter() const { const String indentation = settings_["indentation"].asString(); const String cs_str = settings_["commentStyle"].asString(); @@ -1175,9 +1175,9 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { } PrecisionType precisionType(significantDigits); if (pt_str == "significant") { - precisionType = PrecisionType::significantDigits; + precisionType = significantDigits; } else if (pt_str == "decimal") { - precisionType = PrecisionType::decimalPlaces; + precisionType = decimalPlaces; } else { throwRuntimeError("precisionType must be 'significant' or 'decimal'"); } @@ -1247,6 +1247,7 @@ String writeString(StreamWriter::Factory const& factory, Value const& root) { OStringStream sout; StreamWriterPtr const writer(factory.newStreamWriter()); writer->write(root, &sout); + delete writer; return sout.str(); } @@ -1254,6 +1255,7 @@ OStream& operator<<(OStream& sout, Value const& root) { StreamWriterBuilder builder; StreamWriterPtr const writer(builder.newStreamWriter()); writer->write(root, &sout); + delete writer; return sout; } diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index 5b75c22..8dfc929 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -5,7 +5,6 @@ #include "fuzz.h" -#include #include #include #include @@ -41,14 +40,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { builder.settings_["collectComments"] = hash_settings & (1 << 9); builder.settings_["allowTrailingCommas_"] = hash_settings & (1 << 10); - std::unique_ptr reader(builder.newCharReader()); - + Json::CharReader* reader(builder.newCharReader()); Json::Value root; - const auto data_str = reinterpret_cast(data); + const char* data_str = reinterpret_cast(data); try { - reader->parse(data_str, data_str + size, &root, nullptr); + reader->parse(data_str, data_str + size, &root, JSONCPP_NULL); } catch (Json::Exception const&) { } + delete reader; // Whether it succeeded or not doesn't matter. return 0; } diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 0b7d12b..93718ad 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -73,10 +73,11 @@ namespace JsonTest { // class TestResult // ////////////////////////////////////////////////////////////////// -TestResult::TestResult() { +TestResult::TestResult() + : predicateId_(1), lastUsedPredicateId_(0), messageTarget_(JSONCPP_NULL) { // The root predicate has id 0 rootPredicateNode_.id_ = 0; - rootPredicateNode_.next_ = nullptr; + rootPredicateNode_.next_ = JSONCPP_NULL; predicateStackTail_ = &rootPredicateNode_; } @@ -88,7 +89,7 @@ TestResult& TestResult::addFailure(const char* file, unsigned int line, /// added. unsigned int nestingLevel = 0; PredicateContext* lastNode = rootPredicateNode_.next_; - for (; lastNode != nullptr; lastNode = lastNode->next_) { + for (; lastNode != JSONCPP_NULL; lastNode = lastNode->next_) { if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext { lastUsedPredicateId_ = lastNode->id_; @@ -121,17 +122,18 @@ void TestResult::addFailureInfo(const char* file, unsigned int line, TestResult& TestResult::popPredicateContext() { PredicateContext* lastNode = &rootPredicateNode_; - while (lastNode->next_ != nullptr && lastNode->next_->next_ != nullptr) { + while (lastNode->next_ != JSONCPP_NULL && + lastNode->next_->next_ != JSONCPP_NULL) { lastNode = lastNode->next_; } // Set message target to popped failure PredicateContext* tail = lastNode->next_; - if (tail != nullptr && tail->failure_ != nullptr) { + if (tail != JSONCPP_NULL && tail->failure_ != JSONCPP_NULL) { messageTarget_ = tail->failure_; } // Remove tail from list predicateStackTail_ = lastNode; - lastNode->next_ = nullptr; + lastNode->next_ = JSONCPP_NULL; return *this; } @@ -147,7 +149,9 @@ void TestResult::printFailure(bool printTestName) const { } // Print in reverse to display the callstack in the right order - for (const auto& failure : failures_) { + for (Failures::const_iterator it = failures_.begin(); it != failures_.end(); + ++it) { + const Failure& failure = *it; Json::String indent(failure.nestingLevel_ * 2, ' '); if (failure.file_) { printf("%s%s(%u): ", indent.c_str(), failure.file_, failure.line_); @@ -181,7 +185,7 @@ Json::String TestResult::indentText(const Json::String& text, } TestResult& TestResult::addToLastFailure(const Json::String& message) { - if (messageTarget_ != nullptr) { + if (messageTarget_ != JSONCPP_NULL) { messageTarget_->message_ += message; } return *this; @@ -202,9 +206,9 @@ TestResult& TestResult::operator<<(bool value) { // class TestCase // ////////////////////////////////////////////////////////////////// -TestCase::TestCase() = default; +TestCase::TestCase() : result_(JSONCPP_NULL) {} -TestCase::~TestCase() = default; +TestCase::~TestCase() {} void TestCase::run(TestResult& result) { result_ = &result; @@ -214,7 +218,7 @@ void TestCase::run(TestResult& result) { // class Runner // ////////////////////////////////////////////////////////////////// -Runner::Runner() = default; +Runner::Runner() {} Runner& Runner::add(TestCaseFactory factory) { tests_.push_back(factory); @@ -268,7 +272,8 @@ bool Runner::runAllTest(bool printSummary) const { } return true; } - for (auto& result : failures) { + for (size_t index = 0; index < failures.size(); ++index) { + TestResult& result = failures[index]; result.printFailure(count > 1); } diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 4e8af0f..9e2bcc0 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -42,7 +42,7 @@ public: /// Must be a POD to allow inline initialisation without stepping /// into the debugger. struct PredicateContext { - using Id = unsigned int; + typedef unsigned int Id; Id id_; const char* file_; unsigned int line_; @@ -61,7 +61,7 @@ public: /// Not encapsulated to prevent step into when debugging failed assertions /// Incremented by one on assertion predicate entry, decreased by one /// by addPredicateContext(). - PredicateContext::Id predicateId_{1}; + PredicateContext::Id predicateId_; /// \internal Implementation detail for predicate macros PredicateContext* predicateStackTail_; @@ -70,7 +70,7 @@ public: /// Adds an assertion failure. TestResult& addFailure(const char* file, unsigned int line, - const char* expr = nullptr); + const char* expr = JSONCPP_NULL); /// Removes the last PredicateContext added to the predicate stack /// chained list. @@ -84,7 +84,9 @@ public: // Generic operator that will work with anything ostream can deal with. template TestResult& operator<<(const T& value) { Json::OStringStream oss; - oss << std::setprecision(16) << std::hexfloat << value; + oss.precision(16); + oss.setf(std::ios_base::floatfield); + oss << value; return addToLastFailure(oss.str()); } @@ -102,13 +104,13 @@ private: static Json::String indentText(const Json::String& text, const Json::String& indent); - using Failures = std::deque; + typedef std::deque Failures; Failures failures_; Json::String name_; PredicateContext rootPredicateNode_; - PredicateContext::Id lastUsedPredicateId_{0}; + PredicateContext::Id lastUsedPredicateId_; /// Failure which is the target of the messages added using operator << - Failure* messageTarget_{nullptr}; + Failure* messageTarget_; }; class TestCase { @@ -122,14 +124,14 @@ public: virtual const char* testName() const = 0; protected: - TestResult* result_{nullptr}; + TestResult* result_; private: virtual void runTestCase() = 0; }; /// Function pointer type for TestCase factory -using TestCaseFactory = TestCase* (*)(); +typedef TestCase* (*TestCaseFactory)(); class Runner { public: @@ -159,8 +161,8 @@ public: static void printUsage(const char* appName); private: // prevents copy construction and assignment - Runner(const Runner& other) = delete; - Runner& operator=(const Runner& other) = delete; + Runner(const Runner& other) JSONCPP_CTOR_DELETE; + Runner& operator=(const Runner& other) JSONCPP_CTOR_DELETE; private: void listTests() const; @@ -168,7 +170,7 @@ private: static void preventDialogOnCrash(); private: - using Factories = std::deque; + typedef std::deque Factories; Factories tests_; }; @@ -251,8 +253,10 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, } \ \ public: /* overridden from TestCase */ \ - const char* testName() const override { return #FixtureType "/" #name; } \ - void runTestCase() override; \ + const char* testName() const JSONCPP_OVERRIDE { \ + return #FixtureType "/" #name; \ + } \ + void runTestCase() JSONCPP_OVERRIDE; \ }; \ \ void Test##FixtureType##name::runTestCase() @@ -276,8 +280,10 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, } \ \ public: /* overridden from TestCase */ \ - const char* testName() const override { return #FixtureType "/" #name; } \ - void runTestCase() override; \ + const char* testName() const JSONCPP_OVERRIDE { \ + return #FixtureType "/" #name; \ + } \ + void runTestCase() JSONCPP_OVERRIDE; \ }; \ \ static bool test##FixtureType##name##collect = \ diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index e6fe43d..229944a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -25,7 +25,7 @@ #include #include -using CharReaderPtr = std::unique_ptr; +typedef Json::CharReader* CharReaderPtr; // Make numeric limits more convenient to talk about. // Assumes int type in 32 bits. @@ -65,22 +65,27 @@ static std::deque local_; struct ValueTest : JsonTest::TestCase { Json::Value null_; - Json::Value emptyArray_{Json::arrayValue}; - Json::Value emptyObject_{Json::objectValue}; - Json::Value integer_{123456789}; - Json::Value unsignedInteger_{34567890}; - Json::Value smallUnsignedInteger_{Json::Value::UInt(Json::Value::maxInt)}; - Json::Value real_{1234.56789}; - Json::Value float_{0.00390625f}; + Json::Value emptyArray_; + Json::Value emptyObject_; + Json::Value integer_; + Json::Value unsignedInteger_; + Json::Value smallUnsignedInteger_; + Json::Value real_; + Json::Value float_; Json::Value array1_; Json::Value object1_; - Json::Value emptyString_{""}; - Json::Value string1_{"a"}; - Json::Value string_{"sometext with space"}; - Json::Value true_{true}; - Json::Value false_{false}; + Json::Value emptyString_; + Json::Value string1_; + Json::Value string_; + Json::Value true_; + Json::Value false_; - ValueTest() { + ValueTest() + : emptyArray_(Json::arrayValue), emptyObject_(Json::objectValue), + integer_(123456789), unsignedInteger_(34567890u), + smallUnsignedInteger_(Json::Value::UInt(Json::Value::maxInt)), + real_(1234.56789), float_(0.00390625f), emptyString_(""), string1_("a"), + string_("sometext with space"), true_(true), false_(false) { array1_.append(1234); object1_["id"] = 1234; } @@ -89,19 +94,19 @@ struct ValueTest : JsonTest::TestCase { /// Initialize all checks to \c false by default. IsCheck(); - bool isObject_{false}; - bool isArray_{false}; - bool isBool_{false}; - bool isString_{false}; - bool isNull_{false}; + bool isObject_; + bool isArray_; + bool isBool_; + bool isString_; + bool isNull_; - bool isInt_{false}; - bool isInt64_{false}; - bool isUInt_{false}; - bool isUInt64_{false}; - bool isIntegral_{false}; - bool isDouble_{false}; - bool isNumeric_{false}; + bool isInt_; + bool isInt64_; + bool isUInt_; + bool isUInt64_; + bool isIntegral_; + bool isDouble_; + bool isNumeric_; }; void checkConstMemberCount(const Json::Value& value, @@ -121,13 +126,14 @@ struct ValueTest : JsonTest::TestCase { }; Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { - auto index = s.find_last_of("eE"); + std::string::size_type index = s.find_last_of("eE"); if (index == s.npos) return s; std::size_t signWidth = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - auto exponentStartIndex = index + 1 + signWidth; + std::string::size_type exponentStartIndex = index + 1 + signWidth; Json::String normalized = s.substr(0, exponentStartIndex); - auto indexDigit = s.find_first_not_of('0', exponentStartIndex); + std::string::size_type indexDigit = + s.find_first_not_of('0', exponentStartIndex); Json::String exponent = "0"; if (indexDigit != s.npos) { // nonzero exponent exponent = s.substr(indexDigit); @@ -157,7 +163,9 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, checkNormalizeFloatingPointStr) { {"1234e+100", "1234e+100"}, {"1234e-100", "1234e-100"}, }; - for (const auto& td : testData) { + for (unsigned int index = 0; index < sizeof(testData) / sizeof(testData[0]); + ++index) { + const struct TestData td = testData[index]; JSONTEST_ASSERT_STRING_EQUAL(normalizeFloatingPointStr(td.in), td.out); } } @@ -215,22 +223,22 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { // Access through find() const char idKey[] = "id"; const Json::Value* foundId = object1_.find(idKey, idKey + strlen(idKey)); - JSONTEST_ASSERT(foundId != nullptr); + JSONTEST_ASSERT(foundId != JSONCPP_NULL); JSONTEST_ASSERT_EQUAL(Json::Value(1234), *foundId); const char unknownIdKey[] = "unknown id"; const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); - JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); + JSONTEST_ASSERT(JSONCPP_NULL == foundUnknownId); // Access through demand() const char yetAnotherIdKey[] = "yet another id"; const Json::Value* foundYetAnotherId = object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); - JSONTEST_ASSERT_EQUAL(nullptr, foundYetAnotherId); + JSONTEST_ASSERT(JSONCPP_NULL == foundYetAnotherId); Json::Value* demandedYetAnotherId = object1_.demand( yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); - JSONTEST_ASSERT(demandedYetAnotherId != nullptr); + JSONTEST_ASSERT(demandedYetAnotherId != JSONCPP_NULL); *demandedYetAnotherId = "baz"; JSONTEST_ASSERT_EQUAL(Json::Value("baz"), object1_["yet another id"]); @@ -255,9 +263,9 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { JSONTEST_ASSERT_EQUAL(false, did); object1_["some other id"] = "foo"; - Json::Value* gotPtr = nullptr; + Json::Value* gotPtr = JSONCPP_NULL; did = object1_.removeMember("some other id", gotPtr); - JSONTEST_ASSERT_EQUAL(nullptr, gotPtr); + JSONTEST_ASSERT(JSONCPP_NULL == gotPtr); JSONTEST_ASSERT_EQUAL(true, did); // Using other removeMember interfaces, the test idea is the same as above. @@ -1182,7 +1190,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, integers) { normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // 10^19 - const auto ten_to_19 = static_cast(1e19); + const Json::UInt64 ten_to_19 = static_cast(1e19); val = Json::Value(Json::UInt64(ten_to_19)); JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); @@ -1476,7 +1484,11 @@ void ValueTest::checkMemberCount(Json::Value& value, JSONTEST_ASSERT_PRED(checkConstMemberCount(value, expectedCount)); } -ValueTest::IsCheck::IsCheck() = default; +ValueTest::IsCheck::IsCheck() + : isObject_(false), isArray_(false), isBool_(false), isString_(false), + isNull_(false), isInt_(false), isInt64_(false), isUInt_(false), + isUInt64_(false), isIntegral_(false), isDouble_(false), + isNumeric_(false) {} void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_ASSERT_EQUAL(check.isObject_, value.isObject()); @@ -1661,19 +1673,19 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, CopyObject) { Json::Value srcObject, objectCopy, otherObject; srcObject["key0"] = 10; objectCopy.copy(srcObject); - JSONTEST_ASSERT(srcObject["key0"] == 10); - JSONTEST_ASSERT(objectCopy["key0"] == 10); + JSONTEST_ASSERT(srcObject["key0"].asInt() == 10); + JSONTEST_ASSERT(objectCopy["key0"].asInt() == 10); JSONTEST_ASSERT(srcObject.getMemberNames().size() == 1); JSONTEST_ASSERT(objectCopy.getMemberNames().size() == 1); otherObject["key1"] = 15; otherObject["key2"] = 16; JSONTEST_ASSERT(otherObject.getMemberNames().size() == 2); objectCopy.copy(otherObject); - JSONTEST_ASSERT(objectCopy["key1"] == 15); - JSONTEST_ASSERT(objectCopy["key2"] == 16); + JSONTEST_ASSERT(objectCopy["key1"].asInt() == 15); + JSONTEST_ASSERT(objectCopy["key2"].asInt() == 16); JSONTEST_ASSERT(objectCopy.getMemberNames().size() == 2); otherObject["key1"] = 20; - JSONTEST_ASSERT(objectCopy["key1"] == 15); + JSONTEST_ASSERT(objectCopy["key1"].asInt() == 15); } } @@ -1817,7 +1829,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, StaticString) { JSONTEST_FIXTURE_LOCAL(ValueTest, WideString) { // https://github.com/open-source-parsers/jsoncpp/issues/756 - const std::string uni = u8"\u5f0f\uff0c\u8fdb"; // "式,进" + const std::string uni = "\u5f0f\uff0c\u8fdb"; // "式,进" std::string styled; { Json::Value v; @@ -2592,7 +2604,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, indentation) { JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeZeroes) { Json::String binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); - Json::String expected(R"("hi\u0000")"); // unicoded zero + Json::String expected("\"hi\\u0000\""); // unicoded zero Json::StreamWriterBuilder b; { Json::Value root; @@ -2639,7 +2651,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, unicode) { "{\n\t\"test\" : " "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); } - +#if JSONCPP_CXX_STD_11 struct ReaderTest : JsonTest::TestCase { void setStrictMode() { reader = std::unique_ptr( @@ -2688,43 +2700,43 @@ struct ReaderTest : JsonTest::TestCase { }; JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { - checkParse(R"({ "property" : "value" })"); + checkParse("{ \"property\" : \"value\" }"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseObject) { - checkParse(R"({"property"})", + checkParse("{\"property\"}", {{11, 12, "Missing ':' after object member name"}}, "* Line 1, Column 12\n Missing ':' after object member name\n"); checkParse( - R"({"property" : "value" )", + "{\"property\" : \"value\" ", {{22, 22, "Missing ',' or '}' in object declaration"}}, "* Line 1, Column 23\n Missing ',' or '}' in object declaration\n"); - checkParse(R"({"property" : "value", )", + checkParse("{\"property\" : \"value\", ", {{23, 23, "Missing '}' or object member name"}}, "* Line 1, Column 24\n Missing '}' or object member name\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseArray) { checkParse( - R"([ "value" )", {{10, 10, "Missing ',' or ']' in array declaration"}}, + "[ \"value\" ", {{10, 10, "Missing ',' or ']' in array declaration"}}, "* Line 1, Column 11\n Missing ',' or ']' in array declaration\n"); checkParse( - R"([ "value1" "value2" ] )", + "[ \"value1\" \"value2\" ] ", {{11, 19, "Missing ',' or ']' in array declaration"}}, "* Line 1, Column 12\n Missing ',' or ']' in array declaration\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) { - checkParse(R"([ "\u8a2a" ])"); + checkParse("[ \"\u8a2a\" ]"); checkParse( - R"([ "\ud801" ])", + "[ \"\\ud801\" ]", {{2, 10, "additional six characters expected to parse unicode surrogate " "pair."}}, "* Line 1, Column 3\n" " additional six characters expected to parse unicode surrogate pair.\n" "See Line 1, Column 10 for detail.\n"); - checkParse(R"([ "\ud801\d1234" ])", + checkParse("[ \"\\ud801\\d1234\" ]", {{2, 16, "expecting another \\u token to begin the " "second half of a unicode surrogate pair"}}, @@ -2732,7 +2744,7 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) { " expecting another \\u token to begin the " "second half of a unicode surrogate pair\n" "See Line 1, Column 12 for detail.\n"); - checkParse(R"([ "\ua3t@" ])", + checkParse("[ \"\\ua3t@\" ]", {{2, 10, "Bad unicode escape sequence in string: " "hexadecimal digit expected."}}, @@ -2741,7 +2753,7 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) { "hexadecimal digit expected.\n" "See Line 1, Column 9 for detail.\n"); checkParse( - R"([ "\ua3t" ])", + "[ \"\\ua3t\" ]", {{2, 9, "Bad unicode escape sequence in string: four digits expected."}}, "* Line 1, Column 3\n" " Bad unicode escape sequence in string: four digits expected.\n" @@ -2750,29 +2762,29 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) { JSONTEST_FIXTURE_LOCAL(ReaderTest, parseComment) { checkParse( - R"({ /*commentBeforeValue*/ "property" : "value" }//commentAfterValue)" + "{ /*commentBeforeValue*/ \"property\" : \"value\" }//commentAfterValue" "\n"); checkParse(" true //comment1\n//comment2\r//comment3\r\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, streamParseWithNoErrors) { - std::string styled = R"({ "property" : "value" })"; + std::string styled = "{ \"property\" : \"value\" }"; std::istringstream iss(styled); checkParse(iss); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { - checkParse(R"({)" - R"( "property" : ["value", "value2"],)" - R"( "obj" : { "nested" : -6.2e+15, "bool" : true},)" - R"( "null" : null,)" - R"( "false" : false)" - R"( })"); + checkParse("{" + " \"property\" : [\"value\", \"value2\"]," + " \"obj\" : { \"nested\" : -6.2e+15, \"bool\" : true}," + " \"null\" : null," + " \"false\" : false" + "}"); auto checkOffsets = [&](const Json::Value& v, int start, int limit) { JSONTEST_ASSERT_EQUAL(start, v.getOffsetStart()); JSONTEST_ASSERT_EQUAL(limit, v.getOffsetLimit()); }; - checkOffsets(root, 0, 115); + checkOffsets(root, 0, 114); checkOffsets(root["property"], 15, 34); checkOffsets(root["property"][0], 16, 23); checkOffsets(root["property"][1], 25, 33); @@ -2784,7 +2796,7 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { - checkParse(R"({ "property" :: "value" })", + checkParse("{ \"property\" :: \"value\" }", {{14, 15, "Syntax error: value, object or array expected."}}, "* Line 1, Column 15\n Syntax error: value, object or array " "expected.\n"); @@ -2794,11 +2806,11 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseSpecialFloat) { - checkParse(R"({ "a" : Infi })", + checkParse("{ \"a\" : Infi }", {{8, 9, "Syntax error: value, object or array expected."}}, "* Line 1, Column 9\n Syntax error: value, object or array " "expected.\n"); - checkParse(R"({ "a" : Infiniaa })", + checkParse("{ \"a\" : Infiniaa }", {{8, 9, "Syntax error: value, object or array expected."}}, "* Line 1, Column 9\n Syntax error: value, object or array " "expected.\n"); @@ -2815,16 +2827,20 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, strictModeParseNumber) { } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) { - checkParse(R"({ "pr)" + checkParse("{ \"pr" +#if JSONCPP_CXX_STD_11 u8"\u4f50\u85e4" // 佐藤 - R"(erty" :: "value" })", +#else + "\u4f50\u85e4" // 佐藤 +#endif + "erty\" :: \"value\" }", {{18, 19, "Syntax error: value, object or array expected."}}, "* Line 1, Column 19\n Syntax error: value, object or array " "expected.\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) { - checkParse(R"({ "property" : "v\alue" })", + checkParse("{ \"property\" : \"v\\alue\" }", {{15, 23, "Bad escape sequence in string"}}, "* Line 1, Column 16\n" " Bad escape sequence in string\n" @@ -2832,7 +2848,7 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) { } JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) { - checkParse(R"({ "AUTHOR" : 123 })"); + checkParse("{ \"AUTHOR\" : 123 }"); if (!root["AUTHOR"].isString()) { JSONTEST_ASSERT( reader->pushError(root["AUTHOR"], "AUTHOR must be a string")); @@ -2841,7 +2857,7 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) { "* Line 1, Column 14\n" " AUTHOR must be a string\n"); - checkParse(R"({ "AUTHOR" : 123 })"); + checkParse("{ \"AUTHOR\" : 123 }"); if (!root["AUTHOR"].isString()) { JSONTEST_ASSERT(reader->pushError(root["AUTHOR"], "AUTHOR must be a string", root["AUTHOR"])); @@ -2856,9 +2872,9 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, allowNumericKeysTest) { Json::Features features; features.allowNumericKeys_ = true; setFeatures(features); - checkParse(R"({ 123 : "abc" })"); + checkParse("{ 123 : \"abc\" }"); } - +#endif // JSONCPP_CXX_STD_11 struct CharReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { @@ -2866,10 +2882,11 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; - char const doc[] = R"({ "property" : "value" })"; + char const doc[] = "{ \"property\" : \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrorsTestingOffsets) { @@ -2883,6 +2900,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrorsTestingOffsets) { bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseNumber) { @@ -2899,6 +2917,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseNumber) { JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(1.1111111111111111e+020, root[0]); } + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { @@ -2914,14 +2933,18 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { JSONTEST_ASSERT_EQUAL("", root[0]); } { - char const doc[] = R"(["\u8A2a"])"; + char const doc[] = "[\"\\u8A2a\"]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); +#if JSONCPP_CXX_STD_11 JSONTEST_ASSERT_EQUAL(u8"\u8A2a", root[0].asString()); // "訪" +#else + JSONTEST_ASSERT_EQUAL("\u8A2a", root[0].asString()); // "訪" +#endif // JSONCPP_CXX_STD_11 } { - char const doc[] = R"([ "\uD801" ])"; + char const doc[] = "[ \"\\uD801\" ]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" @@ -2930,7 +2953,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { "See Line 1, Column 10 for detail.\n"); } { - char const doc[] = R"([ "\uD801\d1234" ])"; + char const doc[] = "[ \"\\uD801\\d1234\" ]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" @@ -2939,7 +2962,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { "See Line 1, Column 12 for detail.\n"); } { - char const doc[] = R"([ "\ua3t@" ])"; + char const doc[] = "[ \"\\ua3t@\" ]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" @@ -2948,7 +2971,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { "See Line 1, Column 9 for detail.\n"); } { - char const doc[] = R"([ "\ua3t" ])"; + char const doc[] = "[ \"\\ua3t\" ]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT( @@ -2957,16 +2980,18 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { " Bad unicode escape sequence in string: four digits expected.\n" "See Line 1, Column 6 for detail.\n"); } + delete reader; { b.settings_["allowSingleQuotes"] = true; - CharReaderPtr charreader(b.newCharReader()); - char const doc[] = R"({'a': 'x\ty', "b":'x\\y'})"; - bool ok = charreader->parse(doc, doc + std::strlen(doc), &root, &errs); + CharReaderPtr charReader(b.newCharReader()); + char const doc[] = "{'a': 'x\\ty', \"b\":'x\\\\y'}"; + bool ok = charReader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); JSONTEST_ASSERT_STRING_EQUAL("x\ty", root["a"].asString()); JSONTEST_ASSERT_STRING_EQUAL("x\\y", root["b"].asString()); + delete charReader; } } @@ -2999,6 +3024,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseComment) { JSONTEST_ASSERT_EQUAL("value", root[0]); JSONTEST_ASSERT_EQUAL(true, root[1]); } + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { @@ -3007,7 +3033,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { Json::Value root; Json::String errs; { - char const doc[] = R"({ "property" : "value" )"; + char const doc[] = "{ \"property\" : \"value\" "; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 24\n" @@ -3015,13 +3041,14 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { JSONTEST_ASSERT_EQUAL("value", root["property"]); } { - char const doc[] = R"({ "property" : "value" ,)"; + char const doc[] = "{ \"property\" : \"value\" ,"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 25\n" " Missing '}' or object member name\n"); JSONTEST_ASSERT_EQUAL("value", root["property"]); } + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseArrayWithErrors) { @@ -3038,13 +3065,14 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseArrayWithErrors) { JSONTEST_ASSERT_EQUAL("value", root[0]); } { - char const doc[] = R"([ "value1" "value2" ])"; + char const doc[] = "[ \"value1\" \"value2\" ]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 12\n" " Missing ',' or ']' in array declaration\n"); JSONTEST_ASSERT_EQUAL("value1", root[0]); } + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { @@ -3052,12 +3080,13 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; - char const doc[] = R"({ "property" :: "value" })"; + char const doc[] = "{ \"property\" :: \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 15\n Syntax error: value, object or array " "expected.\n"); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseChineseWithOneError) { @@ -3071,6 +3100,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseChineseWithOneError) { JSONTEST_ASSERT(errs == "* Line 1, Column 19\n Syntax error: value, object or array " "expected.\n"); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { @@ -3078,18 +3108,19 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; - char const doc[] = R"({ "property" : "v\alue" })"; + char const doc[] = "{ \"property\" : \"v\\alue\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 16\n Bad escape sequence in string\nSee " "Line 1, Column 20 for detail.\n"); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { Json::CharReaderBuilder b; Json::Value root; - char const doc[] = R"({ "property" : "value" })"; + char const doc[] = "{ \"property\" : \"value\" }"; { b.settings_["stackLimit"] = 2; CharReaderPtr reader(b.newCharReader()); @@ -3098,6 +3129,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL("value", root["property"]); + delete reader; } { b.settings_["stackLimit"] = 1; @@ -3105,11 +3137,12 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { Json::String errs; JSONTEST_ASSERT_THROWS( reader->parse(doc, doc + std::strlen(doc), &root, &errs)); + delete reader; } } JSONTEST_FIXTURE_LOCAL(CharReaderTest, testOperator) { - const std::string styled = R"({ "property" : "value" })"; + const std::string styled = "{ \"property\" : \"value\" }"; std::istringstream iss(styled); Json::Value root; iss >> root; @@ -3122,7 +3155,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = - R"({ "property" : "value", "key" : "val1", "key" : "val2" })"; + "{ \"property\" : \"value\", \"key\" : \"val1\", \"key\" : \"val2\" }"; { b.strictMode(&b.settings_); CharReaderPtr reader(b.newCharReader()); @@ -3133,6 +3166,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { " Duplicate key: 'key'\n", errs); JSONTEST_ASSERT_EQUAL("val1", root["key"]); // so far + delete reader; } } struct CharReaderFailIfExtraTest : JsonTest::TestCase {}; @@ -3141,7 +3175,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { // This is interpreted as a string value followed by a colon. Json::CharReaderBuilder b; Json::Value root; - char const doc[] = R"( "property" : "value" })"; + char const doc[] = " \"property\" : \"value\" }"; { b.settings_["failIfExtra"] = false; CharReaderPtr reader(b.newCharReader()); @@ -3150,6 +3184,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } { b.settings_["failIfExtra"] = true; @@ -3161,6 +3196,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { " Extra non-whitespace after JSON value.\n", errs); JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } { b.strictMode(&b.settings_); @@ -3172,6 +3208,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { " Extra non-whitespace after JSON value.\n", errs); JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } { b.strictMode(&b.settings_); @@ -3185,6 +3222,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { " A valid JSON document must be either an array or an object value.\n", errs); JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } } @@ -3202,6 +3240,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { " Extra non-whitespace after JSON value.\n", errs); JSONTEST_ASSERT_EQUAL(1, root.asInt()); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterObject) { Json::CharReaderBuilder b; @@ -3215,6 +3254,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterObject) { JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL("value", root["property"]); + delete reader; } } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterArray) { @@ -3228,6 +3268,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterArray) { JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL("value", root[1u]); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterBool) { Json::CharReaderBuilder b; @@ -3240,6 +3281,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterBool) { JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(true, root.asBool()); + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, parseComment) { @@ -3273,11 +3315,12 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, parseComment) { errs); JSONTEST_ASSERT_EQUAL(true, root.asBool()); } + delete reader; } - +#if JSONCPP_CXX_STD_11 struct CharReaderAllowDropNullTest : JsonTest::TestCase { - using Value = Json::Value; - using ValueCheck = std::function; + typedef Json::Value Value; + typedef std::function ValueCheck; Value nullValue = Value{Json::nullValue}; Value emptyArray = Value{Json::arrayValue}; @@ -3303,19 +3346,19 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { ValueCheck onRoot; }; const TestSpec specs[] = { - {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, - {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, - {__LINE__, R"({"a":})", 1, objGetAnd("a", checkEq(nullValue))}, + {__LINE__, "{\"a\":,\"b\":true}", 2, objGetAnd("a", checkEq(nullValue))}, + {__LINE__, "{\"a\":,\"b\":true}", 2, objGetAnd("a", checkEq(nullValue))}, + {__LINE__, "{\"a\":}", 1, objGetAnd("a", checkEq(nullValue))}, {__LINE__, "[]", 0, checkEq(emptyArray)}, - {__LINE__, "[null]", 1, nullptr}, - {__LINE__, "[,]", 2, nullptr}, - {__LINE__, "[,,,]", 4, nullptr}, - {__LINE__, "[null,]", 2, nullptr}, - {__LINE__, "[,null]", 2, nullptr}, - {__LINE__, "[,,]", 3, nullptr}, - {__LINE__, "[null,,]", 3, nullptr}, - {__LINE__, "[,null,]", 3, nullptr}, - {__LINE__, "[,,null]", 3, nullptr}, + {__LINE__, "[null]", 1, JSONCPP_NULL}, + {__LINE__, "[,]", 2, JSONCPP_NULL}, + {__LINE__, "[,,,]", 4, JSONCPP_NULL}, + {__LINE__, "[null,]", 2, JSONCPP_NULL}, + {__LINE__, "[,null]", 2, JSONCPP_NULL}, + {__LINE__, "[,,]", 3, JSONCPP_NULL}, + {__LINE__, "[null,,]", 3, JSONCPP_NULL}, + {__LINE__, "[,null,]", 3, JSONCPP_NULL}, + {__LINE__, "[,,null]", 3, JSONCPP_NULL}, {__LINE__, "[[],,,]", 4, arrGetAnd(0, checkEq(emptyArray))}, {__LINE__, "[,[],,]", 4, arrGetAnd(1, checkEq(emptyArray))}, {__LINE__, "[,,,[]]", 4, arrGetAnd(3, checkEq(emptyArray))}, @@ -3336,7 +3379,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { } } } - +#endif // JSONCPP_CXX_STD_11 struct CharReaderAllowNumericKeysTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderAllowNumericKeysTest, allowNumericKeys) { @@ -3353,6 +3396,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowNumericKeysTest, allowNumericKeys) { JSONTEST_ASSERT_EQUAL(true, root.get("15", false)); JSONTEST_ASSERT_EQUAL(true, root.get("-16", false)); JSONTEST_ASSERT_EQUAL(true, root.get("12.01", false)); + delete reader; } struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {}; @@ -3381,6 +3425,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSingleQuotesTest, issue182) { JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString()); JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString()); } + delete reader; } struct CharReaderAllowZeroesTest : JsonTest::TestCase {}; @@ -3409,6 +3454,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowZeroesTest, issue176) { JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString()); JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString()); } + delete reader; } struct CharReaderAllowSpecialFloatsTest : JsonTest::TestCase {}; @@ -3436,6 +3482,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, specialFloat) { " Syntax error: value, object or array expected.\n", errs); } + delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { @@ -3445,7 +3492,8 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { Json::String errs; CharReaderPtr reader(b.newCharReader()); { - char const doc[] = R"({"a":NaN,"b":Infinity,"c":-Infinity,"d":+Infinity})"; + char const doc[] = + "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity,\"d\":+Infinity}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -3484,7 +3532,9 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { {__LINE__, true, "{\"a\":-Infinity}"}, // {__LINE__, true, "{\"a\":+Infinity}"} // }; - for (const auto& td : test_data) { + for (unsigned int index = 0; index < sizeof(test_data) / sizeof(test_data[0]); + ++index) { + const struct TestData td = test_data[index]; bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), &root, &errs); JSONTEST_ASSERT(td.ok == ok) << "line:" << td.line << "\n" @@ -3496,7 +3546,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { } { - char const doc[] = R"({"posInf": +Infinity, "NegInf": -Infinity})"; + char const doc[] = "{\"posInf\": +Infinity, \"NegInf\": -Infinity}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -3506,6 +3556,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root["NegInf"].asDouble()); } + delete reader; } struct EscapeSequenceTest : JsonTest::TestCase {}; @@ -3533,6 +3584,7 @@ JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, charReaderParseEscapeSequence) { bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); + delete reader; } JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, writeEscapeSequence) { @@ -3608,7 +3660,7 @@ struct IteratorTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(IteratorTest, convert) { Json::Value j; const Json::Value& cj = j; - auto it = j.begin(); + Json::Value::const_iterator it = j.begin(); Json::Value::const_iterator cit; cit = it; JSONTEST_ASSERT(cit == cj.begin()); @@ -3619,11 +3671,17 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, decrement) { json["k1"] = "a"; json["k2"] = "b"; std::vector values; - for (auto it = json.end(); it != json.begin();) { + std::vector expected; + expected.push_back("b"); + expected.push_back("a"); + for (Json::Value::const_iterator it = json.end(); it != json.begin();) { --it; values.push_back(it->asString()); } - JSONTEST_ASSERT((values == std::vector{"b", "a"})); + JSONTEST_ASSERT(values.size() == expected.size()); + for (unsigned int i = 0; i < expected.size(); i++) { + JSONTEST_ASSERT(values.at(i) == expected.at(i)); + } } JSONTEST_FIXTURE_LOCAL(IteratorTest, reverseIterator) { @@ -3631,12 +3689,19 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, reverseIterator) { json["k1"] = "a"; json["k2"] = "b"; std::vector values; - using Iter = decltype(json.begin()); - auto re = std::reverse_iterator(json.begin()); - for (auto it = std::reverse_iterator(json.end()); it != re; ++it) { + typedef Json::Value::const_iterator Iter; + std::reverse_iterator re = std::reverse_iterator(json.begin()); + for (std::reverse_iterator it = std::reverse_iterator(json.end()); + it != re; ++it) { values.push_back(it->asString()); } - JSONTEST_ASSERT((values == std::vector{"b", "a"})); + std::vector expected; + expected.push_back("b"); + expected.push_back("a"); + JSONTEST_ASSERT(values.size() == expected.size()); + for (unsigned int i = 0; i < expected.size(); i++) { + JSONTEST_ASSERT(values.at(i) == expected.at(i)); + } } JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { @@ -3645,9 +3710,9 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { json["k1"] = "a"; json["k2"] = "b"; int i = 0; - auto it = json.begin(); + Json::Value::const_iterator it = json.begin(); for (;; ++it, ++i) { - auto dist = it - json.begin(); + Json::ValueIteratorBase::difference_type dist = it - json.begin(); JSONTEST_ASSERT_EQUAL(i, dist); if (it == json.end()) break; @@ -3663,8 +3728,8 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { JSONTEST_FIXTURE_LOCAL(IteratorTest, nullValues) { { Json::Value json; - auto end = json.end(); - auto endCopy = end; + Json::Value::const_iterator end = json.end(); + Json::Value::const_iterator endCopy = end; JSONTEST_ASSERT(endCopy == end); endCopy = end; JSONTEST_ASSERT(endCopy == end); @@ -3672,8 +3737,8 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, nullValues) { { // Same test, now with const Value. const Json::Value json; - auto end = json.end(); - auto endCopy = end; + Json::Value::const_iterator end = json.end(); + Json::Value::const_iterator endCopy = end; JSONTEST_ASSERT(endCopy == end); endCopy = end; JSONTEST_ASSERT(endCopy == end); @@ -3744,10 +3809,10 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, constness) { for (; iter != value.end(); ++iter) { out << *iter << ','; } - Json::String expected = R"(" 9","10","11",)"; + Json::String expected = "\" 9\",\"10\",\"11\","; JSONTEST_ASSERT_STRING_EQUAL(expected, out.str()); } - +#if JSONCPP_CXX_STD_11 struct RValueTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(RValueTest, moveConstruction) { @@ -3759,7 +3824,7 @@ JSONTEST_FIXTURE_LOCAL(RValueTest, moveConstruction) { JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type()); JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type()); } - +#endif // JSONCPP_CXX_STD_11 struct FuzzTest : JsonTest::TestCase {}; // Build and run the fuzz test without any fuzzer, so that it's guaranteed not @@ -3775,13 +3840,14 @@ JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) { int main(int argc, const char* argv[]) { JsonTest::Runner runner; - for (auto& local : local_) { + for (unsigned int index = 0; index < local_.size(); ++index) { + JsonTest::TestCaseFactory local = local_[index]; runner.add(local); } return runner.runCommandLine(argc, argv); } - +#if JSONCPP_CXX_STD_11 struct MemberTemplateAs : JsonTest::TestCase { template JsonTest::TestResult& EqEval(T v, F f) const { @@ -3810,12 +3876,13 @@ JSONTEST_FIXTURE_LOCAL(MemberTemplateAs, BehavesSameAsNamedAs) { EqEval(false, [](const Json::Value& j) { return j.asBool(); }); EqEval(true, [](const Json::Value& j) { return j.asBool(); }); } - +#endif // JSONCPP_CXX_STD_11 class MemberTemplateIs : public JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(MemberTemplateIs, BehavesSameAsNamedIs) { const Json::Value values[] = {true, 142, 40.63, "hello world"}; - for (const Json::Value& j : values) { + for (size_t index = 0; index < sizeof(values) / sizeof(values[0]); index++) { + const Json::Value& j = values[index]; JSONTEST_ASSERT_EQUAL(j.is(), j.isBool()); JSONTEST_ASSERT_EQUAL(j.is(), j.isInt()); JSONTEST_ASSERT_EQUAL(j.is(), j.isInt64());