mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Update jsoncpp copy to 1.9.6
note: the version number is different due to https://github.com/open-source-parsers/jsoncpp/issues/1571
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
cd ..
 | 
			
		||||
git clone https://github.com/open-source-parsers/jsoncpp -b 1.9.5 --depth 1
 | 
			
		||||
git clone https://github.com/open-source-parsers/jsoncpp -b 1.9.6 --depth 1
 | 
			
		||||
cd jsoncpp
 | 
			
		||||
./amalgamate.py
 | 
			
		||||
cp -R dist/json ../json
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).
 | 
			
		||||
/// Json-cpp amalgamated forward header (https://github.com/open-source-parsers/jsoncpp/).
 | 
			
		||||
/// It is intended to be used with #include "json/json-forwards.h"
 | 
			
		||||
/// This header provides forward declaration for all JsonCpp types.
 | 
			
		||||
 | 
			
		||||
@@ -94,19 +94,18 @@ license you like.
 | 
			
		||||
// 3. /CMakeLists.txt
 | 
			
		||||
// IMPORTANT: also update the SOVERSION!!
 | 
			
		||||
 | 
			
		||||
#define JSONCPP_VERSION_STRING "1.9.5"
 | 
			
		||||
#define JSONCPP_VERSION_STRING "1.9.7"
 | 
			
		||||
#define JSONCPP_VERSION_MAJOR 1
 | 
			
		||||
#define JSONCPP_VERSION_MINOR 9
 | 
			
		||||
#define JSONCPP_VERSION_PATCH 5
 | 
			
		||||
#define JSONCPP_VERSION_PATCH 7
 | 
			
		||||
#define JSONCPP_VERSION_QUALIFIER
 | 
			
		||||
#define JSONCPP_VERSION_HEXA                                                   \
 | 
			
		||||
  ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) |             \
 | 
			
		||||
   (JSONCPP_VERSION_PATCH << 8))
 | 
			
		||||
 | 
			
		||||
#ifdef JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#undef JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#if !defined(JSONCPP_USE_SECURE_MEMORY)
 | 
			
		||||
#define JSONCPP_USE_SECURE_MEMORY 0
 | 
			
		||||
#endif
 | 
			
		||||
#define JSONCPP_USING_SECURE_MEMORY 0
 | 
			
		||||
// If non-zero, the library zeroes any memory that it has allocated before
 | 
			
		||||
// it frees its memory.
 | 
			
		||||
 | 
			
		||||
@@ -133,10 +132,12 @@ license you like.
 | 
			
		||||
#ifndef JSON_ALLOCATOR_H_INCLUDED
 | 
			
		||||
#define JSON_ALLOCATOR_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 8)
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
namespace Json {
 | 
			
		||||
template <typename T> class SecureAllocator {
 | 
			
		||||
@@ -164,8 +165,16 @@ public:
 | 
			
		||||
   * The memory block is filled with zeroes before being released.
 | 
			
		||||
   */
 | 
			
		||||
  void deallocate(pointer p, size_type n) {
 | 
			
		||||
    // memset_s is used because memset may be optimized away by the compiler
 | 
			
		||||
    // These constructs will not be removed by the compiler during optimization,
 | 
			
		||||
    // unlike memset.
 | 
			
		||||
#if defined(HAVE_MEMSET_S)
 | 
			
		||||
    memset_s(p, n * sizeof(T), 0, n * sizeof(T));
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    RtlSecureZeroMemory(p, n * sizeof(T));
 | 
			
		||||
#else
 | 
			
		||||
    std::fill_n(reinterpret_cast<volatile unsigned char*>(p), n, 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // free using "global operator delete"
 | 
			
		||||
    ::operator delete(p);
 | 
			
		||||
  }
 | 
			
		||||
@@ -195,7 +204,9 @@ public:
 | 
			
		||||
  // Boilerplate
 | 
			
		||||
  SecureAllocator() {}
 | 
			
		||||
  template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
 | 
			
		||||
  template <typename U> struct rebind { using other = SecureAllocator<U>; };
 | 
			
		||||
  template <typename U> struct rebind {
 | 
			
		||||
    using other = SecureAllocator<U>;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename U>
 | 
			
		||||
@@ -356,7 +367,7 @@ using LargestUInt = UInt64;
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using Allocator =
 | 
			
		||||
    typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>,
 | 
			
		||||
    typename std::conditional<JSONCPP_USE_SECURE_MEMORY, SecureAllocator<T>,
 | 
			
		||||
                              std::allocator<T>>::type;
 | 
			
		||||
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
 | 
			
		||||
using IStringStream =
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).
 | 
			
		||||
/// Json-cpp amalgamated header (https://github.com/open-source-parsers/jsoncpp/).
 | 
			
		||||
/// It is intended to be used with #include "json/json.h"
 | 
			
		||||
 | 
			
		||||
// //////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -93,19 +93,18 @@ license you like.
 | 
			
		||||
// 3. /CMakeLists.txt
 | 
			
		||||
// IMPORTANT: also update the SOVERSION!!
 | 
			
		||||
 | 
			
		||||
#define JSONCPP_VERSION_STRING "1.9.5"
 | 
			
		||||
#define JSONCPP_VERSION_STRING "1.9.7"
 | 
			
		||||
#define JSONCPP_VERSION_MAJOR 1
 | 
			
		||||
#define JSONCPP_VERSION_MINOR 9
 | 
			
		||||
#define JSONCPP_VERSION_PATCH 5
 | 
			
		||||
#define JSONCPP_VERSION_PATCH 7
 | 
			
		||||
#define JSONCPP_VERSION_QUALIFIER
 | 
			
		||||
#define JSONCPP_VERSION_HEXA                                                   \
 | 
			
		||||
  ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) |             \
 | 
			
		||||
   (JSONCPP_VERSION_PATCH << 8))
 | 
			
		||||
 | 
			
		||||
#ifdef JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#undef JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#if !defined(JSONCPP_USE_SECURE_MEMORY)
 | 
			
		||||
#define JSONCPP_USE_SECURE_MEMORY 0
 | 
			
		||||
#endif
 | 
			
		||||
#define JSONCPP_USING_SECURE_MEMORY 0
 | 
			
		||||
// If non-zero, the library zeroes any memory that it has allocated before
 | 
			
		||||
// it frees its memory.
 | 
			
		||||
 | 
			
		||||
@@ -132,10 +131,12 @@ license you like.
 | 
			
		||||
#ifndef JSON_ALLOCATOR_H_INCLUDED
 | 
			
		||||
#define JSON_ALLOCATOR_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 8)
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
namespace Json {
 | 
			
		||||
template <typename T> class SecureAllocator {
 | 
			
		||||
@@ -163,8 +164,16 @@ public:
 | 
			
		||||
   * The memory block is filled with zeroes before being released.
 | 
			
		||||
   */
 | 
			
		||||
  void deallocate(pointer p, size_type n) {
 | 
			
		||||
    // memset_s is used because memset may be optimized away by the compiler
 | 
			
		||||
    // These constructs will not be removed by the compiler during optimization,
 | 
			
		||||
    // unlike memset.
 | 
			
		||||
#if defined(HAVE_MEMSET_S)
 | 
			
		||||
    memset_s(p, n * sizeof(T), 0, n * sizeof(T));
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    RtlSecureZeroMemory(p, n * sizeof(T));
 | 
			
		||||
#else
 | 
			
		||||
    std::fill_n(reinterpret_cast<volatile unsigned char*>(p), n, 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // free using "global operator delete"
 | 
			
		||||
    ::operator delete(p);
 | 
			
		||||
  }
 | 
			
		||||
@@ -194,7 +203,9 @@ public:
 | 
			
		||||
  // Boilerplate
 | 
			
		||||
  SecureAllocator() {}
 | 
			
		||||
  template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
 | 
			
		||||
  template <typename U> struct rebind { using other = SecureAllocator<U>; };
 | 
			
		||||
  template <typename U> struct rebind {
 | 
			
		||||
    using other = SecureAllocator<U>;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename U>
 | 
			
		||||
@@ -355,7 +366,7 @@ using LargestUInt = UInt64;
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using Allocator =
 | 
			
		||||
    typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>,
 | 
			
		||||
    typename std::conditional<JSONCPP_USE_SECURE_MEMORY, SecureAllocator<T>,
 | 
			
		||||
                              std::allocator<T>>::type;
 | 
			
		||||
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
 | 
			
		||||
using IStringStream =
 | 
			
		||||
@@ -459,7 +470,8 @@ class ValueConstIterator;
 | 
			
		||||
#include "forwards.h"
 | 
			
		||||
#endif // if !defined(JSON_IS_AMALGAMATION)
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 8)
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
namespace Json {
 | 
			
		||||
 | 
			
		||||
@@ -527,8 +539,8 @@ public:
 | 
			
		||||
// recognized in your jurisdiction.
 | 
			
		||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
 | 
			
		||||
 | 
			
		||||
#ifndef JSON_H_INCLUDED
 | 
			
		||||
#define JSON_H_INCLUDED
 | 
			
		||||
#ifndef JSON_VALUE_H_INCLUDED
 | 
			
		||||
#define JSON_VALUE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if !defined(JSON_IS_AMALGAMATION)
 | 
			
		||||
#include "forwards.h"
 | 
			
		||||
@@ -577,7 +589,8 @@ public:
 | 
			
		||||
#pragma warning(disable : 4251 4275)
 | 
			
		||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 8)
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
/** \brief JSON (JavaScript Object Notation).
 | 
			
		||||
 */
 | 
			
		||||
@@ -898,7 +911,7 @@ public:
 | 
			
		||||
  int compare(const Value& other) const;
 | 
			
		||||
 | 
			
		||||
  const char* asCString() const; ///< Embedded zeroes could cause you trouble!
 | 
			
		||||
#if JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#if JSONCPP_USE_SECURE_MEMORY
 | 
			
		||||
  unsigned getCStringLength() const; // Allows you to understand the length of
 | 
			
		||||
                                     // the CString
 | 
			
		||||
#endif
 | 
			
		||||
@@ -960,7 +973,7 @@ public:
 | 
			
		||||
  /// \post type() is arrayValue
 | 
			
		||||
  void resize(ArrayIndex newSize);
 | 
			
		||||
 | 
			
		||||
  //@{
 | 
			
		||||
  ///@{
 | 
			
		||||
  /// Access an array element (zero based index). If the array contains less
 | 
			
		||||
  /// than index element, then null value are inserted in the array so that
 | 
			
		||||
  /// its size is index+1.
 | 
			
		||||
@@ -968,15 +981,15 @@ public:
 | 
			
		||||
  /// this from the operator[] which takes a string.)
 | 
			
		||||
  Value& operator[](ArrayIndex index);
 | 
			
		||||
  Value& operator[](int index);
 | 
			
		||||
  //@}
 | 
			
		||||
  ///@}
 | 
			
		||||
 | 
			
		||||
  //@{
 | 
			
		||||
  ///@{
 | 
			
		||||
  /// Access an array element (zero based index).
 | 
			
		||||
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
 | 
			
		||||
  /// this from the operator[] which takes a string.)
 | 
			
		||||
  const Value& operator[](ArrayIndex index) const;
 | 
			
		||||
  const Value& operator[](int index) const;
 | 
			
		||||
  //@}
 | 
			
		||||
  ///@}
 | 
			
		||||
 | 
			
		||||
  /// If the array contains at least index+1 elements, returns the element
 | 
			
		||||
  /// value, otherwise returns defaultValue.
 | 
			
		||||
@@ -1036,6 +1049,9 @@ public:
 | 
			
		||||
  /// and operator[]const
 | 
			
		||||
  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
 | 
			
		||||
  Value const* find(char const* begin, char const* end) const;
 | 
			
		||||
  /// Most general and efficient version of isMember()const, get()const,
 | 
			
		||||
  /// and operator[]const
 | 
			
		||||
  Value const* find(const String& key) const;
 | 
			
		||||
  /// Most general and efficient version of object-mutators.
 | 
			
		||||
  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
 | 
			
		||||
  /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
 | 
			
		||||
@@ -1108,6 +1124,26 @@ public:
 | 
			
		||||
  iterator begin();
 | 
			
		||||
  iterator end();
 | 
			
		||||
 | 
			
		||||
  /// \brief Returns a reference to the first element in the `Value`.
 | 
			
		||||
  /// Requires that this value holds an array or json object, with at least one
 | 
			
		||||
  /// element.
 | 
			
		||||
  const Value& front() const;
 | 
			
		||||
 | 
			
		||||
  /// \brief Returns a reference to the first element in the `Value`.
 | 
			
		||||
  /// Requires that this value holds an array or json object, with at least one
 | 
			
		||||
  /// element.
 | 
			
		||||
  Value& front();
 | 
			
		||||
 | 
			
		||||
  /// \brief Returns a reference to the last element in the `Value`.
 | 
			
		||||
  /// Requires that value holds an array or json object, with at least one
 | 
			
		||||
  /// element.
 | 
			
		||||
  const Value& back() const;
 | 
			
		||||
 | 
			
		||||
  /// \brief Returns a reference to the last element in the `Value`.
 | 
			
		||||
  /// Requires that this value holds an array or json object, with at least one
 | 
			
		||||
  /// element.
 | 
			
		||||
  Value& back();
 | 
			
		||||
 | 
			
		||||
  // Accessors for the [start, limit) range of bytes within the JSON text from
 | 
			
		||||
  // which this value was parsed, if any.
 | 
			
		||||
  void setOffsetStart(ptrdiff_t start);
 | 
			
		||||
@@ -1448,6 +1484,14 @@ public:
 | 
			
		||||
 | 
			
		||||
inline void swap(Value& a, Value& b) { a.swap(b); }
 | 
			
		||||
 | 
			
		||||
inline const Value& Value::front() const { return *begin(); }
 | 
			
		||||
 | 
			
		||||
inline Value& Value::front() { return *begin(); }
 | 
			
		||||
 | 
			
		||||
inline const Value& Value::back() const { return *(--end()); }
 | 
			
		||||
 | 
			
		||||
inline Value& Value::back() { return *(--end()); }
 | 
			
		||||
 | 
			
		||||
} // namespace Json
 | 
			
		||||
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
@@ -1496,7 +1540,8 @@ inline void swap(Value& a, Value& b) { a.swap(b); }
 | 
			
		||||
#pragma warning(disable : 4251)
 | 
			
		||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 8)
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
namespace Json {
 | 
			
		||||
 | 
			
		||||
@@ -1523,12 +1568,12 @@ public:
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /** \brief Constructs a Reader allowing all features for parsing.
 | 
			
		||||
    * \deprecated Use CharReader and CharReaderBuilder.
 | 
			
		||||
   * \deprecated Use CharReader and CharReaderBuilder.
 | 
			
		||||
   */
 | 
			
		||||
  Reader();
 | 
			
		||||
 | 
			
		||||
  /** \brief Constructs a Reader allowing the specified feature set for parsing.
 | 
			
		||||
    * \deprecated Use CharReader and CharReaderBuilder.
 | 
			
		||||
   * \deprecated Use CharReader and CharReaderBuilder.
 | 
			
		||||
   */
 | 
			
		||||
  Reader(const Features& features);
 | 
			
		||||
 | 
			
		||||
@@ -1662,6 +1707,7 @@ private:
 | 
			
		||||
  using Errors = std::deque<ErrorInfo>;
 | 
			
		||||
 | 
			
		||||
  bool readToken(Token& token);
 | 
			
		||||
  bool readTokenSkippingComments(Token& token);
 | 
			
		||||
  void skipSpaces();
 | 
			
		||||
  bool match(const Char* pattern, int patternLength);
 | 
			
		||||
  bool readComment();
 | 
			
		||||
@@ -1693,7 +1739,6 @@ private:
 | 
			
		||||
                                int& column) const;
 | 
			
		||||
  String getLocationLineAndColumn(Location location) const;
 | 
			
		||||
  void addComment(Location begin, Location end, CommentPlacement placement);
 | 
			
		||||
  void skipCommentTokens(Token& token);
 | 
			
		||||
 | 
			
		||||
  static bool containsNewLine(Location begin, Location end);
 | 
			
		||||
  static String normalizeEOL(Location begin, Location end);
 | 
			
		||||
@@ -1716,6 +1761,12 @@ private:
 | 
			
		||||
 */
 | 
			
		||||
class JSON_API CharReader {
 | 
			
		||||
public:
 | 
			
		||||
  struct JSON_API StructuredError {
 | 
			
		||||
    ptrdiff_t offset_start;
 | 
			
		||||
    ptrdiff_t offset_limit;
 | 
			
		||||
    String message;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  virtual ~CharReader() = default;
 | 
			
		||||
  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
 | 
			
		||||
   * document. The document must be a UTF-8 encoded string containing the
 | 
			
		||||
@@ -1734,7 +1785,12 @@ public:
 | 
			
		||||
   * error occurred.
 | 
			
		||||
   */
 | 
			
		||||
  virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
 | 
			
		||||
                     String* errs) = 0;
 | 
			
		||||
                     String* errs);
 | 
			
		||||
 | 
			
		||||
  /** \brief Returns a vector of structured errors encountered while parsing.
 | 
			
		||||
   * Each parse call resets the stored list of errors.
 | 
			
		||||
   */
 | 
			
		||||
  std::vector<StructuredError> getStructuredErrors() const;
 | 
			
		||||
 | 
			
		||||
  class JSON_API Factory {
 | 
			
		||||
  public:
 | 
			
		||||
@@ -1744,7 +1800,21 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    virtual CharReader* newCharReader() const = 0;
 | 
			
		||||
  }; // Factory
 | 
			
		||||
};   // CharReader
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  class Impl {
 | 
			
		||||
  public:
 | 
			
		||||
    virtual ~Impl() = default;
 | 
			
		||||
    virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
 | 
			
		||||
                       String* errs) = 0;
 | 
			
		||||
    virtual std::vector<StructuredError> getStructuredErrors() const = 0;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  explicit CharReader(std::unique_ptr<Impl> impl) : _impl(std::move(impl)) {}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  std::unique_ptr<Impl> _impl;
 | 
			
		||||
}; // CharReader
 | 
			
		||||
 | 
			
		||||
/** \brief Build a CharReader implementation.
 | 
			
		||||
 *
 | 
			
		||||
@@ -1832,6 +1902,12 @@ public:
 | 
			
		||||
   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
 | 
			
		||||
   */
 | 
			
		||||
  static void strictMode(Json::Value* settings);
 | 
			
		||||
  /** ECMA-404 mode.
 | 
			
		||||
   * \pre 'settings' != NULL (but Json::null is fine)
 | 
			
		||||
   * \remark Defaults:
 | 
			
		||||
   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode
 | 
			
		||||
   */
 | 
			
		||||
  static void ecma404Mode(Json::Value* settings);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Consume entire stream and use its begin/end.
 | 
			
		||||
@@ -1912,7 +1988,8 @@ JSON_API IStream& operator>>(IStream&, Value&);
 | 
			
		||||
#pragma warning(disable : 4251)
 | 
			
		||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 8)
 | 
			
		||||
#pragma pack(push)
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
namespace Json {
 | 
			
		||||
 | 
			
		||||
@@ -1955,7 +2032,7 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    virtual StreamWriter* newStreamWriter() const = 0;
 | 
			
		||||
  }; // Factory
 | 
			
		||||
};   // StreamWriter
 | 
			
		||||
}; // StreamWriter
 | 
			
		||||
 | 
			
		||||
/** \brief Write into stringstream, then return string, for convenience.
 | 
			
		||||
 * A StreamWriter will be created from the factory, used, and then deleted.
 | 
			
		||||
@@ -2059,8 +2136,7 @@ public:
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
#pragma warning(disable : 4996) // Deriving from deprecated class
 | 
			
		||||
#endif
 | 
			
		||||
class JSON_API FastWriter
 | 
			
		||||
    : public Writer {
 | 
			
		||||
class JSON_API FastWriter : public Writer {
 | 
			
		||||
public:
 | 
			
		||||
  FastWriter();
 | 
			
		||||
  ~FastWriter() override = default;
 | 
			
		||||
@@ -2109,7 +2185,7 @@ private:
 | 
			
		||||
 *     - otherwise, it the values do not fit on one line, or the array contains
 | 
			
		||||
 *       object or non empty array, then print one value per line.
 | 
			
		||||
 *
 | 
			
		||||
 * If the Value have comments then they are outputed according to their
 | 
			
		||||
 * If the Value have comments then they are outputted according to their
 | 
			
		||||
 *#CommentPlacement.
 | 
			
		||||
 *
 | 
			
		||||
 * \sa Reader, Value, Value::setComment()
 | 
			
		||||
@@ -2119,8 +2195,7 @@ private:
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
#pragma warning(disable : 4996) // Deriving from deprecated class
 | 
			
		||||
#endif
 | 
			
		||||
class JSON_API
 | 
			
		||||
    StyledWriter : public Writer {
 | 
			
		||||
class JSON_API StyledWriter : public Writer {
 | 
			
		||||
public:
 | 
			
		||||
  StyledWriter();
 | 
			
		||||
  ~StyledWriter() override = default;
 | 
			
		||||
@@ -2178,7 +2253,7 @@ private:
 | 
			
		||||
 *     - otherwise, it the values do not fit on one line, or the array contains
 | 
			
		||||
 *       object or non empty array, then print one value per line.
 | 
			
		||||
 *
 | 
			
		||||
 * If the Value have comments then they are outputed according to their
 | 
			
		||||
 * If the Value have comments then they are outputted according to their
 | 
			
		||||
 #CommentPlacement.
 | 
			
		||||
 *
 | 
			
		||||
 * \sa Reader, Value, Value::setComment()
 | 
			
		||||
@@ -2188,8 +2263,7 @@ private:
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
#pragma warning(disable : 4996) // Deriving from deprecated class
 | 
			
		||||
#endif
 | 
			
		||||
class JSON_API
 | 
			
		||||
    StyledStreamWriter {
 | 
			
		||||
class JSON_API StyledStreamWriter {
 | 
			
		||||
public:
 | 
			
		||||
  /**
 | 
			
		||||
   * \param indentation Each level will be indented by this amount extra.
 | 
			
		||||
@@ -2245,6 +2319,7 @@ String JSON_API valueToString(
 | 
			
		||||
    PrecisionType precisionType = PrecisionType::significantDigits);
 | 
			
		||||
String JSON_API valueToString(bool value);
 | 
			
		||||
String JSON_API valueToQuotedString(const char* value);
 | 
			
		||||
String JSON_API valueToQuotedString(const char* value, size_t length);
 | 
			
		||||
 | 
			
		||||
/// \brief Output using the StyledStreamWriter.
 | 
			
		||||
/// \see Json::operator>>()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).
 | 
			
		||||
/// Json-cpp amalgamated source (https://github.com/open-source-parsers/jsoncpp/).
 | 
			
		||||
/// It is intended to be used with #include "json/json.h"
 | 
			
		||||
 | 
			
		||||
// //////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -250,6 +250,7 @@ Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) {
 | 
			
		||||
#endif // if !defined(JSON_IS_AMALGAMATION)
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <istream>
 | 
			
		||||
@@ -366,7 +367,7 @@ bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root,
 | 
			
		||||
 | 
			
		||||
  bool successful = readValue();
 | 
			
		||||
  Token token;
 | 
			
		||||
  skipCommentTokens(token);
 | 
			
		||||
  readTokenSkippingComments(token);
 | 
			
		||||
  if (collectComments_ && !commentsBefore_.empty())
 | 
			
		||||
    root.setComment(commentsBefore_, commentAfter);
 | 
			
		||||
  if (features_.strictRoot_) {
 | 
			
		||||
@@ -394,7 +395,7 @@ bool Reader::readValue() {
 | 
			
		||||
    throwRuntimeError("Exceeded stackLimit in readValue().");
 | 
			
		||||
 | 
			
		||||
  Token token;
 | 
			
		||||
  skipCommentTokens(token);
 | 
			
		||||
  readTokenSkippingComments(token);
 | 
			
		||||
  bool successful = true;
 | 
			
		||||
 | 
			
		||||
  if (collectComments_ && !commentsBefore_.empty()) {
 | 
			
		||||
@@ -462,14 +463,14 @@ bool Reader::readValue() {
 | 
			
		||||
  return successful;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Reader::skipCommentTokens(Token& token) {
 | 
			
		||||
bool Reader::readTokenSkippingComments(Token& token) {
 | 
			
		||||
  bool success = readToken(token);
 | 
			
		||||
  if (features_.allowComments_) {
 | 
			
		||||
    do {
 | 
			
		||||
      readToken(token);
 | 
			
		||||
    } while (token.type_ == tokenComment);
 | 
			
		||||
  } else {
 | 
			
		||||
    readToken(token);
 | 
			
		||||
    while (success && token.type_ == tokenComment) {
 | 
			
		||||
      success = readToken(token);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Reader::readToken(Token& token) {
 | 
			
		||||
@@ -683,12 +684,7 @@ bool Reader::readObject(Token& token) {
 | 
			
		||||
  Value init(objectValue);
 | 
			
		||||
  currentValue().swapPayload(init);
 | 
			
		||||
  currentValue().setOffsetStart(token.start_ - begin_);
 | 
			
		||||
  while (readToken(tokenName)) {
 | 
			
		||||
    bool initialTokenOk = true;
 | 
			
		||||
    while (tokenName.type_ == tokenComment && initialTokenOk)
 | 
			
		||||
      initialTokenOk = readToken(tokenName);
 | 
			
		||||
    if (!initialTokenOk)
 | 
			
		||||
      break;
 | 
			
		||||
  while (readTokenSkippingComments(tokenName)) {
 | 
			
		||||
    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
 | 
			
		||||
      return true;
 | 
			
		||||
    name.clear();
 | 
			
		||||
@@ -717,15 +713,11 @@ bool Reader::readObject(Token& token) {
 | 
			
		||||
      return recoverFromError(tokenObjectEnd);
 | 
			
		||||
 | 
			
		||||
    Token comma;
 | 
			
		||||
    if (!readToken(comma) ||
 | 
			
		||||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
 | 
			
		||||
         comma.type_ != tokenComment)) {
 | 
			
		||||
    if (!readTokenSkippingComments(comma) ||
 | 
			
		||||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) {
 | 
			
		||||
      return addErrorAndRecover("Missing ',' or '}' in object declaration",
 | 
			
		||||
                                comma, tokenObjectEnd);
 | 
			
		||||
    }
 | 
			
		||||
    bool finalizeTokenOk = true;
 | 
			
		||||
    while (comma.type_ == tokenComment && finalizeTokenOk)
 | 
			
		||||
      finalizeTokenOk = readToken(comma);
 | 
			
		||||
    if (comma.type_ == tokenObjectEnd)
 | 
			
		||||
      return true;
 | 
			
		||||
  }
 | 
			
		||||
@@ -755,10 +747,7 @@ bool Reader::readArray(Token& token) {
 | 
			
		||||
 | 
			
		||||
    Token currentToken;
 | 
			
		||||
    // Accept Comment after last item in the array.
 | 
			
		||||
    ok = readToken(currentToken);
 | 
			
		||||
    while (currentToken.type_ == tokenComment && ok) {
 | 
			
		||||
      ok = readToken(currentToken);
 | 
			
		||||
    }
 | 
			
		||||
    ok = readTokenSkippingComments(currentToken);
 | 
			
		||||
    bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
 | 
			
		||||
                         currentToken.type_ != tokenArrayEnd);
 | 
			
		||||
    if (!ok || badTokenType) {
 | 
			
		||||
@@ -836,11 +825,16 @@ bool Reader::decodeDouble(Token& token) {
 | 
			
		||||
 | 
			
		||||
bool Reader::decodeDouble(Token& token, Value& decoded) {
 | 
			
		||||
  double value = 0;
 | 
			
		||||
  String buffer(token.start_, token.end_);
 | 
			
		||||
  IStringStream is(buffer);
 | 
			
		||||
  if (!(is >> value))
 | 
			
		||||
    return addError(
 | 
			
		||||
        "'" + String(token.start_, token.end_) + "' is not a number.", token);
 | 
			
		||||
  IStringStream is(String(token.start_, token.end_));
 | 
			
		||||
  if (!(is >> value)) {
 | 
			
		||||
    if (value == std::numeric_limits<double>::max())
 | 
			
		||||
      value = std::numeric_limits<double>::infinity();
 | 
			
		||||
    else if (value == std::numeric_limits<double>::lowest())
 | 
			
		||||
      value = -std::numeric_limits<double>::infinity();
 | 
			
		||||
    else if (!std::isinf(value))
 | 
			
		||||
      return addError(
 | 
			
		||||
          "'" + String(token.start_, token.end_) + "' is not a number.", token);
 | 
			
		||||
  }
 | 
			
		||||
  decoded = value;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -1004,7 +998,7 @@ void Reader::getLocationLineAndColumn(Location location, int& line,
 | 
			
		||||
  while (current < location && current != end_) {
 | 
			
		||||
    Char c = *current++;
 | 
			
		||||
    if (c == '\r') {
 | 
			
		||||
      if (*current == '\n')
 | 
			
		||||
      if (current != end_ && *current == '\n')
 | 
			
		||||
        ++current;
 | 
			
		||||
      lastLineStart = current;
 | 
			
		||||
      ++line;
 | 
			
		||||
@@ -1121,17 +1115,12 @@ class OurReader {
 | 
			
		||||
public:
 | 
			
		||||
  using Char = char;
 | 
			
		||||
  using Location = const Char*;
 | 
			
		||||
  struct StructuredError {
 | 
			
		||||
    ptrdiff_t offset_start;
 | 
			
		||||
    ptrdiff_t offset_limit;
 | 
			
		||||
    String message;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  explicit OurReader(OurFeatures const& features);
 | 
			
		||||
  bool parse(const char* beginDoc, const char* endDoc, Value& root,
 | 
			
		||||
             bool collectComments = true);
 | 
			
		||||
  String getFormattedErrorMessages() const;
 | 
			
		||||
  std::vector<StructuredError> getStructuredErrors() const;
 | 
			
		||||
  std::vector<CharReader::StructuredError> getStructuredErrors() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  OurReader(OurReader const&);      // no impl
 | 
			
		||||
@@ -1174,6 +1163,7 @@ private:
 | 
			
		||||
  using Errors = std::deque<ErrorInfo>;
 | 
			
		||||
 | 
			
		||||
  bool readToken(Token& token);
 | 
			
		||||
  bool readTokenSkippingComments(Token& token);
 | 
			
		||||
  void skipSpaces();
 | 
			
		||||
  void skipBom(bool skipBom);
 | 
			
		||||
  bool match(const Char* pattern, int patternLength);
 | 
			
		||||
@@ -1207,7 +1197,6 @@ private:
 | 
			
		||||
                                int& column) const;
 | 
			
		||||
  String getLocationLineAndColumn(Location location) const;
 | 
			
		||||
  void addComment(Location begin, Location end, CommentPlacement placement);
 | 
			
		||||
  void skipCommentTokens(Token& token);
 | 
			
		||||
 | 
			
		||||
  static String normalizeEOL(Location begin, Location end);
 | 
			
		||||
  static bool containsNewLine(Location begin, Location end);
 | 
			
		||||
@@ -1261,7 +1250,7 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root,
 | 
			
		||||
  bool successful = readValue();
 | 
			
		||||
  nodes_.pop();
 | 
			
		||||
  Token token;
 | 
			
		||||
  skipCommentTokens(token);
 | 
			
		||||
  readTokenSkippingComments(token);
 | 
			
		||||
  if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) {
 | 
			
		||||
    addError("Extra non-whitespace after JSON value.", token);
 | 
			
		||||
    return false;
 | 
			
		||||
@@ -1289,7 +1278,7 @@ bool OurReader::readValue() {
 | 
			
		||||
  if (nodes_.size() > features_.stackLimit_)
 | 
			
		||||
    throwRuntimeError("Exceeded stackLimit in readValue().");
 | 
			
		||||
  Token token;
 | 
			
		||||
  skipCommentTokens(token);
 | 
			
		||||
  readTokenSkippingComments(token);
 | 
			
		||||
  bool successful = true;
 | 
			
		||||
 | 
			
		||||
  if (collectComments_ && !commentsBefore_.empty()) {
 | 
			
		||||
@@ -1376,14 +1365,14 @@ bool OurReader::readValue() {
 | 
			
		||||
  return successful;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OurReader::skipCommentTokens(Token& token) {
 | 
			
		||||
bool OurReader::readTokenSkippingComments(Token& token) {
 | 
			
		||||
  bool success = readToken(token);
 | 
			
		||||
  if (features_.allowComments_) {
 | 
			
		||||
    do {
 | 
			
		||||
      readToken(token);
 | 
			
		||||
    } while (token.type_ == tokenComment);
 | 
			
		||||
  } else {
 | 
			
		||||
    readToken(token);
 | 
			
		||||
    while (success && token.type_ == tokenComment) {
 | 
			
		||||
      success = readToken(token);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool OurReader::readToken(Token& token) {
 | 
			
		||||
@@ -1680,12 +1669,7 @@ bool OurReader::readObject(Token& token) {
 | 
			
		||||
  Value init(objectValue);
 | 
			
		||||
  currentValue().swapPayload(init);
 | 
			
		||||
  currentValue().setOffsetStart(token.start_ - begin_);
 | 
			
		||||
  while (readToken(tokenName)) {
 | 
			
		||||
    bool initialTokenOk = true;
 | 
			
		||||
    while (tokenName.type_ == tokenComment && initialTokenOk)
 | 
			
		||||
      initialTokenOk = readToken(tokenName);
 | 
			
		||||
    if (!initialTokenOk)
 | 
			
		||||
      break;
 | 
			
		||||
  while (readTokenSkippingComments(tokenName)) {
 | 
			
		||||
    if (tokenName.type_ == tokenObjectEnd &&
 | 
			
		||||
        (name.empty() ||
 | 
			
		||||
         features_.allowTrailingCommas_)) // empty object or trailing comma
 | 
			
		||||
@@ -1722,15 +1706,11 @@ bool OurReader::readObject(Token& token) {
 | 
			
		||||
      return recoverFromError(tokenObjectEnd);
 | 
			
		||||
 | 
			
		||||
    Token comma;
 | 
			
		||||
    if (!readToken(comma) ||
 | 
			
		||||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
 | 
			
		||||
         comma.type_ != tokenComment)) {
 | 
			
		||||
    if (!readTokenSkippingComments(comma) ||
 | 
			
		||||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) {
 | 
			
		||||
      return addErrorAndRecover("Missing ',' or '}' in object declaration",
 | 
			
		||||
                                comma, tokenObjectEnd);
 | 
			
		||||
    }
 | 
			
		||||
    bool finalizeTokenOk = true;
 | 
			
		||||
    while (comma.type_ == tokenComment && finalizeTokenOk)
 | 
			
		||||
      finalizeTokenOk = readToken(comma);
 | 
			
		||||
    if (comma.type_ == tokenObjectEnd)
 | 
			
		||||
      return true;
 | 
			
		||||
  }
 | 
			
		||||
@@ -1764,10 +1744,7 @@ bool OurReader::readArray(Token& token) {
 | 
			
		||||
 | 
			
		||||
    Token currentToken;
 | 
			
		||||
    // Accept Comment after last item in the array.
 | 
			
		||||
    ok = readToken(currentToken);
 | 
			
		||||
    while (currentToken.type_ == tokenComment && ok) {
 | 
			
		||||
      ok = readToken(currentToken);
 | 
			
		||||
    }
 | 
			
		||||
    ok = readTokenSkippingComments(currentToken);
 | 
			
		||||
    bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
 | 
			
		||||
                         currentToken.type_ != tokenArrayEnd);
 | 
			
		||||
    if (!ok || badTokenType) {
 | 
			
		||||
@@ -1845,7 +1822,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
 | 
			
		||||
    const auto digit(static_cast<Value::UInt>(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,
 | 
			
		||||
      // a) we've only just touched the limit, meaning value == threshold,
 | 
			
		||||
      // b) this is the last digit, or
 | 
			
		||||
      // c) it's small enough to fit in that rounding delta, we're okay.
 | 
			
		||||
      // Otherwise treat this number as a double to avoid overflow.
 | 
			
		||||
@@ -1882,11 +1859,15 @@ bool OurReader::decodeDouble(Token& token) {
 | 
			
		||||
 | 
			
		||||
bool OurReader::decodeDouble(Token& token, Value& decoded) {
 | 
			
		||||
  double value = 0;
 | 
			
		||||
  const String buffer(token.start_, token.end_);
 | 
			
		||||
  IStringStream is(buffer);
 | 
			
		||||
  IStringStream is(String(token.start_, token.end_));
 | 
			
		||||
  if (!(is >> value)) {
 | 
			
		||||
    return addError(
 | 
			
		||||
        "'" + String(token.start_, token.end_) + "' is not a number.", token);
 | 
			
		||||
    if (value == std::numeric_limits<double>::max())
 | 
			
		||||
      value = std::numeric_limits<double>::infinity();
 | 
			
		||||
    else if (value == std::numeric_limits<double>::lowest())
 | 
			
		||||
      value = -std::numeric_limits<double>::infinity();
 | 
			
		||||
    else if (!std::isinf(value))
 | 
			
		||||
      return addError(
 | 
			
		||||
          "'" + String(token.start_, token.end_) + "' is not a number.", token);
 | 
			
		||||
  }
 | 
			
		||||
  decoded = value;
 | 
			
		||||
  return true;
 | 
			
		||||
@@ -2051,7 +2032,7 @@ void OurReader::getLocationLineAndColumn(Location location, int& line,
 | 
			
		||||
  while (current < location && current != end_) {
 | 
			
		||||
    Char c = *current++;
 | 
			
		||||
    if (c == '\r') {
 | 
			
		||||
      if (*current == '\n')
 | 
			
		||||
      if (current != end_ && *current == '\n')
 | 
			
		||||
        ++current;
 | 
			
		||||
      lastLineStart = current;
 | 
			
		||||
      ++line;
 | 
			
		||||
@@ -2086,10 +2067,11 @@ String OurReader::getFormattedErrorMessages() const {
 | 
			
		||||
  return formattedMessage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
 | 
			
		||||
  std::vector<OurReader::StructuredError> allErrors;
 | 
			
		||||
std::vector<CharReader::StructuredError>
 | 
			
		||||
OurReader::getStructuredErrors() const {
 | 
			
		||||
  std::vector<CharReader::StructuredError> allErrors;
 | 
			
		||||
  for (const auto& error : errors_) {
 | 
			
		||||
    OurReader::StructuredError structured;
 | 
			
		||||
    CharReader::StructuredError structured;
 | 
			
		||||
    structured.offset_start = error.token_.start_ - begin_;
 | 
			
		||||
    structured.offset_limit = error.token_.end_ - begin_;
 | 
			
		||||
    structured.message = error.message_;
 | 
			
		||||
@@ -2099,20 +2081,36 @@ std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class OurCharReader : public CharReader {
 | 
			
		||||
  bool const collectComments_;
 | 
			
		||||
  OurReader reader_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  OurCharReader(bool collectComments, OurFeatures const& features)
 | 
			
		||||
      : collectComments_(collectComments), reader_(features) {}
 | 
			
		||||
  bool parse(char const* beginDoc, char const* endDoc, Value* root,
 | 
			
		||||
             String* errs) override {
 | 
			
		||||
    bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
 | 
			
		||||
    if (errs) {
 | 
			
		||||
      *errs = reader_.getFormattedErrorMessages();
 | 
			
		||||
      : CharReader(
 | 
			
		||||
            std::unique_ptr<OurImpl>(new OurImpl(collectComments, features))) {}
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  class OurImpl : public Impl {
 | 
			
		||||
  public:
 | 
			
		||||
    OurImpl(bool collectComments, OurFeatures const& features)
 | 
			
		||||
        : collectComments_(collectComments), reader_(features) {}
 | 
			
		||||
 | 
			
		||||
    bool parse(char const* beginDoc, char const* endDoc, Value* root,
 | 
			
		||||
               String* errs) override {
 | 
			
		||||
      bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
 | 
			
		||||
      if (errs) {
 | 
			
		||||
        *errs = reader_.getFormattedErrorMessages();
 | 
			
		||||
      }
 | 
			
		||||
      return ok;
 | 
			
		||||
    }
 | 
			
		||||
    return ok;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    std::vector<CharReader::StructuredError>
 | 
			
		||||
    getStructuredErrors() const override {
 | 
			
		||||
      return reader_.getStructuredErrors();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    bool const collectComments_;
 | 
			
		||||
    OurReader reader_;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }
 | 
			
		||||
@@ -2201,6 +2199,32 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) {
 | 
			
		||||
  (*settings)["skipBom"] = true;
 | 
			
		||||
  //! [CharReaderBuilderDefaults]
 | 
			
		||||
}
 | 
			
		||||
// static
 | 
			
		||||
void CharReaderBuilder::ecma404Mode(Json::Value* settings) {
 | 
			
		||||
  //! [CharReaderBuilderECMA404Mode]
 | 
			
		||||
  (*settings)["allowComments"] = false;
 | 
			
		||||
  (*settings)["allowTrailingCommas"] = false;
 | 
			
		||||
  (*settings)["strictRoot"] = false;
 | 
			
		||||
  (*settings)["allowDroppedNullPlaceholders"] = false;
 | 
			
		||||
  (*settings)["allowNumericKeys"] = false;
 | 
			
		||||
  (*settings)["allowSingleQuotes"] = false;
 | 
			
		||||
  (*settings)["stackLimit"] = 1000;
 | 
			
		||||
  (*settings)["failIfExtra"] = true;
 | 
			
		||||
  (*settings)["rejectDupKeys"] = false;
 | 
			
		||||
  (*settings)["allowSpecialFloats"] = false;
 | 
			
		||||
  (*settings)["skipBom"] = false;
 | 
			
		||||
  //! [CharReaderBuilderECMA404Mode]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<CharReader::StructuredError>
 | 
			
		||||
CharReader::getStructuredErrors() const {
 | 
			
		||||
  return _impl->getStructuredErrors();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CharReader::parse(char const* beginDoc, char const* endDoc, Value* root,
 | 
			
		||||
                       String* errs) {
 | 
			
		||||
  return _impl->parse(beginDoc, endDoc, root, errs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////
 | 
			
		||||
// global functions
 | 
			
		||||
@@ -2209,7 +2233,7 @@ bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root,
 | 
			
		||||
                     String* errs) {
 | 
			
		||||
  OStringStream ssin;
 | 
			
		||||
  ssin << sin.rdbuf();
 | 
			
		||||
  String doc = ssin.str();
 | 
			
		||||
  String doc = std::move(ssin).str();
 | 
			
		||||
  char const* begin = doc.data();
 | 
			
		||||
  char const* end = begin + doc.size();
 | 
			
		||||
  // Note that we do not actually need a null-terminator.
 | 
			
		||||
@@ -2501,7 +2525,8 @@ template <typename T, typename U>
 | 
			
		||||
static inline bool InRange(double d, T min, U max) {
 | 
			
		||||
  // The casts can lose precision, but we are looking only for
 | 
			
		||||
  // an approximate range. Might fail on edge cases though. ~cdunn
 | 
			
		||||
  return d >= static_cast<double>(min) && d <= static_cast<double>(max);
 | 
			
		||||
  return d >= static_cast<double>(min) && d <= static_cast<double>(max) &&
 | 
			
		||||
         !(static_cast<U>(d) == min && d != static_cast<double>(min));
 | 
			
		||||
}
 | 
			
		||||
#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
 | 
			
		||||
static inline double integerToDouble(Json::UInt64 value) {
 | 
			
		||||
@@ -2515,7 +2540,8 @@ template <typename T> static inline double integerToDouble(T value) {
 | 
			
		||||
 | 
			
		||||
template <typename T, typename U>
 | 
			
		||||
static inline bool InRange(double d, T min, U max) {
 | 
			
		||||
  return d >= integerToDouble(min) && d <= integerToDouble(max);
 | 
			
		||||
  return d >= integerToDouble(min) && d <= integerToDouble(max) &&
 | 
			
		||||
         !(static_cast<U>(d) == min && d != integerToDouble(min));
 | 
			
		||||
}
 | 
			
		||||
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
 | 
			
		||||
 | 
			
		||||
@@ -2577,7 +2603,7 @@ inline static void decodePrefixedString(bool isPrefixed, char const* prefixed,
 | 
			
		||||
/** Free the string duplicated by
 | 
			
		||||
 * duplicateStringValue()/duplicateAndPrefixStringValue().
 | 
			
		||||
 */
 | 
			
		||||
#if JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#if JSONCPP_USE_SECURE_MEMORY
 | 
			
		||||
static inline void releasePrefixedStringValue(char* value) {
 | 
			
		||||
  unsigned length = 0;
 | 
			
		||||
  char const* valueDecoded;
 | 
			
		||||
@@ -2592,10 +2618,10 @@ static inline void releaseStringValue(char* value, unsigned length) {
 | 
			
		||||
  memset(value, 0, size);
 | 
			
		||||
  free(value);
 | 
			
		||||
}
 | 
			
		||||
#else  // !JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#else  // !JSONCPP_USE_SECURE_MEMORY
 | 
			
		||||
static inline void releasePrefixedStringValue(char* value) { free(value); }
 | 
			
		||||
static inline void releaseStringValue(char* value, unsigned) { free(value); }
 | 
			
		||||
#endif // JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#endif // JSONCPP_USE_SECURE_MEMORY
 | 
			
		||||
 | 
			
		||||
} // namespace Json
 | 
			
		||||
 | 
			
		||||
@@ -3013,7 +3039,7 @@ const char* Value::asCString() const {
 | 
			
		||||
  return this_str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if JSONCPP_USING_SECURE_MEMORY
 | 
			
		||||
#if JSONCPP_USE_SECURE_MEMORY
 | 
			
		||||
unsigned Value::getCStringLength() const {
 | 
			
		||||
  JSON_ASSERT_MESSAGE(type() == stringValue,
 | 
			
		||||
                      "in Json::Value::asCString(): requires stringValue");
 | 
			
		||||
@@ -3119,6 +3145,11 @@ Value::Int64 Value::asInt64() const {
 | 
			
		||||
    JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
 | 
			
		||||
    return Int64(value_.uint_);
 | 
			
		||||
  case realValue:
 | 
			
		||||
    // If the double value is in proximity to minInt64, it will be rounded to
 | 
			
		||||
    // minInt64. The correct value in this scenario is indeterminable
 | 
			
		||||
    JSON_ASSERT_MESSAGE(
 | 
			
		||||
        value_.real_ != minInt64,
 | 
			
		||||
        "Double value is minInt64, precise value cannot be determined");
 | 
			
		||||
    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
 | 
			
		||||
                        "double out of Int64 range");
 | 
			
		||||
    return Int64(value_.real_);
 | 
			
		||||
@@ -3506,6 +3537,9 @@ Value const* Value::find(char const* begin, char const* end) const {
 | 
			
		||||
    return nullptr;
 | 
			
		||||
  return &(*it).second;
 | 
			
		||||
}
 | 
			
		||||
Value const* Value::find(const String& key) const {
 | 
			
		||||
  return find(key.data(), key.data() + key.length());
 | 
			
		||||
}
 | 
			
		||||
Value* Value::demand(char const* begin, char const* end) {
 | 
			
		||||
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
 | 
			
		||||
                      "in Json::Value::demand(begin, end): requires "
 | 
			
		||||
@@ -3519,7 +3553,7 @@ const Value& Value::operator[](const char* key) const {
 | 
			
		||||
  return *found;
 | 
			
		||||
}
 | 
			
		||||
Value const& Value::operator[](const String& key) const {
 | 
			
		||||
  Value const* found = find(key.data(), key.data() + key.length());
 | 
			
		||||
  Value const* found = find(key);
 | 
			
		||||
  if (!found)
 | 
			
		||||
    return nullSingleton();
 | 
			
		||||
  return *found;
 | 
			
		||||
@@ -3619,7 +3653,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (removed)
 | 
			
		||||
    *removed = it->second;
 | 
			
		||||
    *removed = std::move(it->second);
 | 
			
		||||
  ArrayIndex oldSize = size();
 | 
			
		||||
  // shift left all items left, into the place of the "removed"
 | 
			
		||||
  for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
 | 
			
		||||
@@ -3722,8 +3756,12 @@ bool Value::isInt64() const {
 | 
			
		||||
    // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
 | 
			
		||||
    // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
 | 
			
		||||
    // require the value to be strictly less than the limit.
 | 
			
		||||
    return value_.real_ >= double(minInt64) &&
 | 
			
		||||
           value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
 | 
			
		||||
    // minInt64 is -2^63 which can be represented as a double, but since double
 | 
			
		||||
    // values in its proximity are also rounded to -2^63, we require the value
 | 
			
		||||
    // to be strictly greater than the limit to avoid returning 'true' for
 | 
			
		||||
    // values that are not in the range
 | 
			
		||||
    return value_.real_ > double(minInt64) && value_.real_ < double(maxInt64) &&
 | 
			
		||||
           IsIntegral(value_.real_);
 | 
			
		||||
  default:
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
@@ -3761,7 +3799,11 @@ bool Value::isIntegral() const {
 | 
			
		||||
    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
 | 
			
		||||
    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
 | 
			
		||||
    // require the value to be strictly less than the limit.
 | 
			
		||||
    return value_.real_ >= double(minInt64) &&
 | 
			
		||||
    // minInt64 is -2^63 which can be represented as a double, but since double
 | 
			
		||||
    // values in its proximity are also rounded to -2^63, we require the value
 | 
			
		||||
    // to be strictly greater than the limit to avoid returning 'true' for
 | 
			
		||||
    // values that are not in the range
 | 
			
		||||
    return value_.real_ > double(minInt64) &&
 | 
			
		||||
           value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
 | 
			
		||||
#else
 | 
			
		||||
    return value_.real_ >= minInt && value_.real_ <= maxUInt &&
 | 
			
		||||
@@ -3824,9 +3866,8 @@ void Value::setComment(String comment, CommentPlacement placement) {
 | 
			
		||||
    // Always discard trailing newline, to aid indentation.
 | 
			
		||||
    comment.pop_back();
 | 
			
		||||
  }
 | 
			
		||||
  JSON_ASSERT(!comment.empty());
 | 
			
		||||
  JSON_ASSERT_MESSAGE(
 | 
			
		||||
      comment[0] == '\0' || comment[0] == '/',
 | 
			
		||||
      comment.empty() || comment[0] == '/',
 | 
			
		||||
      "in Json::Value::setComment(): Comments must start with /");
 | 
			
		||||
  comments_.set(placement, std::move(comment));
 | 
			
		||||
}
 | 
			
		||||
@@ -4194,8 +4235,9 @@ String valueToString(double value, bool useSpecialFloats,
 | 
			
		||||
  if (!isfinite(value)) {
 | 
			
		||||
    static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"},
 | 
			
		||||
                                           {"null", "-1e+9999", "1e+9999"}};
 | 
			
		||||
    return reps[useSpecialFloats ? 0 : 1]
 | 
			
		||||
               [isnan(value) ? 0 : (value < 0) ? 1 : 2];
 | 
			
		||||
    return reps[useSpecialFloats ? 0 : 1][isnan(value)  ? 0
 | 
			
		||||
                                          : (value < 0) ? 1
 | 
			
		||||
                                                        : 2];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String buffer(size_t(36), '\0');
 | 
			
		||||
@@ -4415,6 +4457,10 @@ String valueToQuotedString(const char* value) {
 | 
			
		||||
  return valueToQuotedStringN(value, strlen(value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String valueToQuotedString(const char* value, size_t length) {
 | 
			
		||||
  return valueToQuotedStringN(value, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Class Writer
 | 
			
		||||
// //////////////////////////////////////////////////////////////////
 | 
			
		||||
Writer::~Writer() = default;
 | 
			
		||||
@@ -4552,7 +4598,7 @@ void StyledWriter::writeValue(const Value& value) {
 | 
			
		||||
        const String& name = *it;
 | 
			
		||||
        const Value& childValue = value[name];
 | 
			
		||||
        writeCommentBeforeValue(childValue);
 | 
			
		||||
        writeWithIndent(valueToQuotedString(name.c_str()));
 | 
			
		||||
        writeWithIndent(valueToQuotedString(name.c_str(), name.size()));
 | 
			
		||||
        document_ += " : ";
 | 
			
		||||
        writeValue(childValue);
 | 
			
		||||
        if (++it == members.end()) {
 | 
			
		||||
@@ -4770,7 +4816,7 @@ void StyledStreamWriter::writeValue(const Value& value) {
 | 
			
		||||
        const String& name = *it;
 | 
			
		||||
        const Value& childValue = value[name];
 | 
			
		||||
        writeCommentBeforeValue(childValue);
 | 
			
		||||
        writeWithIndent(valueToQuotedString(name.c_str()));
 | 
			
		||||
        writeWithIndent(valueToQuotedString(name.c_str(), name.size()));
 | 
			
		||||
        *document_ << " : ";
 | 
			
		||||
        writeValue(childValue);
 | 
			
		||||
        if (++it == members.end()) {
 | 
			
		||||
@@ -5308,7 +5354,7 @@ String writeString(StreamWriter::Factory const& factory, Value const& root) {
 | 
			
		||||
  OStringStream sout;
 | 
			
		||||
  StreamWriterPtr const writer(factory.newStreamWriter());
 | 
			
		||||
  writer->write(root, &sout);
 | 
			
		||||
  return sout.str();
 | 
			
		||||
  return std::move(sout).str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OStream& operator<<(OStream& sout, Value const& root) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user