jsonCPP 开源库详解

发布于:2025-07-07 ⋅ 阅读:(33) ⋅ 点赞:(0)

        JsonCpp 是一个C++库,用于解析和生成 JSON 数据。它具有以下特点:

  • 轻量级且易于集成
  • 支持 STL 容器
  • 提供 DOM 风格的 API
  • 支持 JSON 指针和 JSON 补丁(部分版本)

主要功能​

  • 解析JSON字符串为 C++ 对象
  • 将 C++ 对象序列化为 JSON 字符串
  • 访问和修改 JSON 数据
  • 支持 JSON 数组和对象

1、下载jsonCPP

源码下载:git clone https://github.com/open-source-parsers/jsoncpp.git

源码编译:

cd jsoncpp

mkdir build

cd build

cmake -DCMAKE_BUILD_TYPE=release -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF ../

make

成功编译出 libjsoncpp.a库文件。

2、jsonCPP的使用

下面用一段代码说明jsonCPP的使用

#include <iostream>
#include <string>
#include <memory>
#include "json.h"

using namespace std;

/*如何使用jsoncpp库文件*/
string jsonStr = R"(
	{
        "name": "John Doe",
        "age": 30,
        "is_student": false,
        "courses": ["Math", "Physics"],
        "address": {
            "street": "123 Main St",
            "city": "New York"
        }
    }
)";


int main()
{
	Json::Value root;

	Json::CharReaderBuilder readerBuilder;
	unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
	string errs;

	bool parsingSuccessful = reader->parse(jsonStr.c_str(),jsonStr.c_str()+jsonStr.size(),
		&root,&errs);


	if(!parsingSuccessful) 
		cout << "failed to parse JSON:" << errs << endl;

	/*获取字符串值*/
	string name = root["name"].asString();
	cout << "name:" << name << endl;

	/*获取数值*/
	int age = root["age"].asInt();
	cout << "age:" << age << endl;

	/*获取布尔值*/
	bool isStudent = root["is_student"].asBool();
	cout << "is_student:" << isStudent << endl;

	/*获取数组*/
	const Json::Value& courses = root["courses"];
	for(Json::ArrayIndex i = 0; i<courses.size(); i++)
		cout << courses[i].asString() << endl;

	/*获取嵌套对象*/	
	const Json::Value& address = root["address"];
	string street = address["street"].asString();
	string city = address["city"].asString();
	cout << "address:" << street << ',' << city << endl;

	/*修改内容*/
	root["age"] = 31;
	root["email"] = "john.doe@example.com";

	root["courses"].append("chemistry");
	root["address"]["city"] = "Boston";


	/*生成JSON字符串*/
	Json::StreamWriterBuilder writerBuilder;
	unique_ptr<Json::StreamWriter> writer(writerBuilder.newStreamWriter());
	ostringstream oss;

	writer->write(root,&oss);
	string outputJson = oss.str();

	/*
	{
		"address" : 
		{
			"city" : "Boston",
			"street" : "123 Main St"
		},
		"age" : 31,
		"courses" : 
		[
			"Math",
			"Physics",
			"chemistry"
		],
		"email" : "john.doe@example.com",
		"is_student" : false,
		"name" : "John Doe"
	}
	*/
	cout << outputJson << endl;

    //可以直接使用ostream代替ostringstream类型
	cout << "直接输出JSON数据内容:" << endl;
	writer->write(root,&cout);
	cout << endl;

    //代码中针对Json::Value类重载了输出运算符<<,所以我们可以直接使用cout输出json内容
	cout << "cout的方式输出JSON数据:" << endl;
	cout << root << endl;
	
	return 1;
}

编译时记得链接 libjsoncpp.a 库文件以及-I 指定josn.h头文件的位置。

3、jsonCPP源码详解

        jsonCPP源码主要完成两个功能:

        一是解析json数据并且将解析后的数据通过map进行存储。其中作者非常巧妙的对Value类重载了好几个版本的下标运算符[]使得我们可以通过下标运算符来获取对应的值,如下所示:

string name = root["name"].asString();

bool isStudent = root["is_student"].asBool();

        二是打印json数据,我们可以随意的修改json中的数据并将最终的结果打印出来。如下所示:

root["age"] = 31;
root["email"] = "john.doe@example.com";

由于jsonCPP的源码内容不是很长,阅读的难度也不是很大,鼓励大家去进行阅读。大家阅读时可以从Value类开始,因为这个类是核心重点。最后我将jsonCPP注释过的源码放在文章中,需要的同学自行阅读。

value.h内容如下:

// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef JSON_VALUE_H_INCLUDED
#define JSON_VALUE_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)

// Conditional NORETURN attribute on the throw functions would:
// a) suppress false positives from static code analysis
// b) possibly improve optimization opportunities.
#if !defined(JSONCPP_NORETURN)
#if defined(_MSC_VER) && _MSC_VER == 1800
#define JSONCPP_NORETURN __declspec(noreturn)
#else
#define JSONCPP_NORETURN [[noreturn]]
#endif
#endif

// 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
// even though these declare themselves to be c++11 compilers.
#if !defined(JSONCPP_TEMPLATE_DELETE)
#if defined(__clang__) && defined(__apple_build_version__)
#if __apple_build_version__ <= 8000042
#define JSONCPP_TEMPLATE_DELETE
#endif
#elif defined(__clang__)
#if __clang_major__ == 3 && __clang_minor__ <= 8
#define JSONCPP_TEMPLATE_DELETE
#endif
#endif
#if !defined(JSONCPP_TEMPLATE_DELETE)
#define JSONCPP_TEMPLATE_DELETE = delete
#endif
#endif

#if __cplusplus >= 201703L
#define JSONCPP_HAS_STRING_VIEW 1
#endif

#include <array>
#include <exception>
#include <map>
#include <memory>
#include <string>
#include <vector>

#ifdef JSONCPP_HAS_STRING_VIEW
#include <string_view>
#endif

// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251 4275)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

#pragma pack(push)
#pragma pack()

/** \brief JSON (JavaScript Object Notation).
 */
namespace Json {

#if JSON_USE_EXCEPTION
/** Base class for all exceptions we throw.
 *
 * We use nothing but these internally. Of course, STL can throw others.
 */
class JSON_API Exception : public std::exception {
public:
  Exception(String msg);
  ~Exception() noexcept override;
  char const* what() const noexcept override;

protected:
  String msg_;
};

/** Exceptions which the user cannot easily avoid.
 *
 * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
 *
 * \remark derived from Json::Exception
 */
class JSON_API RuntimeError : public Exception {
public:
  RuntimeError(String const& msg);
};

/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
 *
 * These are precondition-violations (user bugs) and internal errors (our bugs).
 *
 * \remark derived from Json::Exception
 */
class JSON_API LogicError : public Exception {
public:
  LogicError(String const& msg);
};
#endif

/// used internally
JSONCPP_NORETURN void throwRuntimeError(String const& msg);
/// used internally
JSONCPP_NORETURN void throwLogicError(String const& msg);

/** \brief Type of the value held by a Value object.
 */
/*Value能够存放的数据类型*/
enum ValueType {
  nullValue = 0, ///< 'null' value
  intValue,      ///< signed integer value
  uintValue,     ///< unsigned integer value
  realValue,     ///< double value
  stringValue,   ///< UTF-8 string value
  booleanValue,  ///< bool value
  arrayValue,    ///< array value (ordered list)
  objectValue    ///< object value (collection of name/value pairs).
};

enum CommentPlacement {
  // /*注释*/
  // a = 5;
  commentBefore = 0,      ///< a comment placed on the line before a value
  // a = 5; /*注释*/
  commentAfterOnSameLine, ///< a comment just after a value on the same line
  // a = 5;
  // /*注释*/
  commentAfter, ///< a comment on the line after a value (only make sense for
  /// root value)
  numberOfCommentPlacement
};

/** \brief Type of precision for formatting of real values.
 */
enum PrecisionType {
  significantDigits = 0, ///< we set max number of significant digits in string
  decimalPlaces          ///< we set max number of digits after "." in string
};

/** \brief Lightweight wrapper to tag static string.
 *
 * Value constructor and objectValue member assignment takes advantage of the
 * StaticString and avoid the cost of string duplication when storing the
 * string or the member name.
 *
 * Example of usage:
 * \code
 * Json::Value aValue( StaticString("some text") );
 * Json::Value object;
 * static const StaticString code("code");
 * object[code] = 1234;
 * \endcode
 */
class JSON_API StaticString {
public:
  explicit StaticString(const char* czstring) : c_str_(czstring) {}

  /*定义了一个类型转换运算符,将对象转换为 const char* 类型*/
  operator const char*() const { return c_str_; }

  const char* c_str() const { return c_str_; }

private:
  const char* c_str_;
};

/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
 *
 * This class is a discriminated union wrapper that can represents a:
 * - signed integer [range: Value::minInt - Value::maxInt]
 * - unsigned integer (range: 0 - Value::maxUInt)
 * - double
 * - UTF-8 string
 * - boolean
 * - 'null'
 * - an ordered list of Value
 * - collection of name/value pairs (javascript object)
 *
 * The type of the held value is represented by a #ValueType and
 * can be obtained using type().
 *
 * Values of an #objectValue or #arrayValue can be accessed using operator[]()
 * methods.
 * Non-const methods will automatically create the a #nullValue element
 * if it does not exist.
 * The sequence of an #arrayValue will be automatically resized and initialized
 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
 *
 * The get() methods can be used to obtain default value in the case the
 * required element does not exist.
 *
 * It is possible to iterate over the list of member keys of an object using
 * the getMemberNames() method.
 *
 * \note #Value string-length fit in size_t, but keys must be < 2^30.
 * (The reason is an implementation detail.) A #CharReader will raise an
 * exception if a bound is exceeded to avoid security holes in your app,
 * but the Value API does *not* check bounds. That is the responsibility
 * of the caller.
 */
/*
  Value类
JSON 数据由以下两种基本结构组成:
键值对集合(对象):用花括号 {} 包裹,键值对之间用逗号 , 分隔,键和值用冒号 : 分隔。
  键:必须是字符串(用双引号 "" 包裹)。
  值:可以是字符串、数字、布尔值、null、对象或数组。
值的有序列表(数组):用方括号 [] 包裹,元素之间用逗号 , 分隔。
  元素类型可以是字符串、数字、布尔值、null、对象或数组。
*/
class JSON_API Value {
  /*友元类*/
  friend class ValueIteratorBase;

public:
  /*打印JSON时使用*/
  using Members = std::vector<String>;
  using iterator = ValueIterator;
  using const_iterator = ValueConstIterator;
  using UInt = Json::UInt;
  using Int = Json::Int;
#if defined(JSON_HAS_INT64)
  using UInt64 = Json::UInt64;
  using Int64 = Json::Int64;
#endif // defined(JSON_HAS_INT64)
  using LargestInt = Json::LargestInt;
  using LargestUInt = Json::LargestUInt;
  using ArrayIndex = Json::ArrayIndex;

  // Required for boost integration, e. g. BOOST_TEST
  using value_type = std::string;

  /*静态成员*/
#if JSON_USE_NULLREF
  // Binary compatibility kludges, do not use.
  /*null和nullRef的类型是const Value&而非指针*/
  static const Value& null;
  static const Value& nullRef;
#endif

  // null and nullRef are deprecated, use this instead.
  static Value const& nullSingleton();

  /// Minimum signed integer value that can be stored in a Json::Value.
  /*能够存储的最小有符号整数,/2可以视为右移一位*/
  static constexpr 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);
  /// Maximum unsigned integer value that can be stored in a Json::Value.
  static constexpr LargestUInt maxLargestUInt = LargestUInt(-1);

  /// Minimum signed int value that can be stored in a Json::Value.
  static constexpr 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);
  /// Maximum unsigned int value that can be stored in a Json::Value.
  static constexpr 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));
  /// Maximum signed 64 bits int value that can be stored in a Json::Value.
  static constexpr 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);
#endif // defined(JSON_HAS_INT64)
  /// Default precision for real value for string representation.
  static constexpr 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;
// 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
#ifdef __NVCC__
public:
#else
private:
#endif
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
  /*Value类里面包含了CZString类*/
  class CZString {
  public:
    /*复制策略*/
    enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
    CZString(ArrayIndex index);
    CZString(char const* str, unsigned length, DuplicationPolicy allocate);
    /*拷贝构造函数*/
    CZString(CZString const& other);
    /*移动构造函数*/
    CZString(CZString&& other) noexcept;
    /*析构函数*/
    ~CZString();
    /*拷贝赋值运算符*/
    CZString& operator=(const CZString& other);
    /*移动赋值运算符*/
    CZString& operator=(CZString&& other) noexcept;

    /*实现为成员函数*/
    bool operator<(CZString const& other) const;
    bool operator==(CZString const& other) const;
    ArrayIndex index() const;
    // const char* c_str() const; ///< \deprecated
    char const* data() const;
    unsigned length() const;
    bool isStaticString() const;

  private:
    void swap(CZString& other);

    struct StringStorage {
      unsigned policy_ : 2;
      unsigned length_ : 30; // 1GB max
    };

    char const* cstr_; // actually, a prefixed string, unless policy is noDup
    union {
      ArrayIndex index_;
      StringStorage storage_;
    };
  };

public:
  /*使用map key-value对来存储*/
  typedef std::map<CZString, Value> ObjectValues;
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION

public:
  /**
   * \brief Create a default Value of the given type.
   *
   * This is a very useful constructor.
   * To create an empty array, pass arrayValue.
   * To create an empty object, pass objectValue.
   * Another Value can then be set to this one by assignment.
   * This is useful since clear() and resize() will not alter types.
   *
   * Examples:
   *   \code
   *   Json::Value null_value; // null
   *   Json::Value arr_value(Json::arrayValue); // []
   *   Json::Value obj_value(Json::objectValue); // {}
   *   \endcode
   */
  /*Value类的构造函数,支持整形,浮点数,布尔类型,字符串*/
  Value(ValueType type = nullValue);
  Value(Int value);
  Value(UInt value);
#if defined(JSON_HAS_INT64)
  Value(Int64 value);
  Value(UInt64 value);
#endif // if defined(JSON_HAS_INT64)
  Value(double value);
  Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
  Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
  /**
   * \brief Constructs a value from a static string.
   *
   * Like other value string constructor but do not duplicate the string for
   * internal storage. The given string must remain alive after the call to
   * this constructor.
   *
   * \note This works only for null-terminated strings. (We cannot change the
   * size of this class, so we have nowhere to store the length, which might be
   * computed later for various operations.)
   *
   * Example of usage:
   *   \code
   *   static StaticString foo("some text");
   *   Json::Value aValue(foo);
   *   \endcode
   */
  Value(const StaticString& value);
  Value(const String& value);
#ifdef JSONCPP_HAS_STRING_VIEW
  Value(std::string_view value);
#endif
  Value(bool value);
  Value(std::nullptr_t ptr) = delete;
  /*拷贝构造函数*/
  Value(const Value& other);
  /*移动构造函数*/
  Value(Value&& other) noexcept;
  ~Value();

  /// \note Overwrite existing comments. To preserve comments, use
  /// #swapPayload().
  /*赋值运算符*/
  Value& operator=(const Value& other);
  /*移动运算符*/
  Value& operator=(Value&& other) noexcept;

  /// Swap everything.
  void swap(Value& other);
  /// Swap values but leave comments and source offsets in place.
  void swapPayload(Value& other);

  /// copy everything.
  void copy(const Value& other);
  /// copy values but leave comments and source offsets in place.
  void copyPayload(const Value& other);

  ValueType type() const;

  /// Compare payload only, not comments etc.
  bool operator<(const Value& other) const;
  bool operator<=(const Value& other) const;
  bool operator>=(const Value& other) const;
  bool operator>(const Value& other) const;
  bool operator==(const Value& other) const;
  bool operator!=(const Value& other) const;
  int compare(const Value& other) const;

  const char* asCString() const; ///< Embedded zeroes could cause you trouble!
#if JSONCPP_USE_SECURE_MEMORY
  unsigned getCStringLength() const; // Allows you to understand the length of
                                     // the CString
#endif
  String asString() const; ///< Embedded zeroes are possible.
  /** Get raw char* of string-value.
   *  \return false if !string. (Seg-fault if str or end are NULL.)
   */
  bool getString(char const** begin, char const** end) const;
#ifdef JSONCPP_HAS_STRING_VIEW
  /** Get string_view of string-value.
   *  \return false if !string. (Seg-fault if str is NULL.)
   */
  bool getString(std::string_view* str) const;
#endif
  Int asInt() const;
  UInt asUInt() const;
#if defined(JSON_HAS_INT64)
  Int64 asInt64() const;
  UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)
  LargestInt asLargestInt() const;
  LargestUInt asLargestUInt() const;
  float asFloat() const;
  double asDouble() const;
  bool asBool() const;

  bool isNull() const;
  bool isBool() const;
  bool isInt() const;
  bool isInt64() const;
  bool isUInt() const;
  bool isUInt64() const;
  bool isIntegral() const;
  bool isDouble() const;
  bool isNumeric() const;
  bool isString() const;
  bool isArray() const;
  bool isObject() const;

  /// The `as<T>` and `is<T>` member function templates and specializations.
  template <typename T> T as() const JSONCPP_TEMPLATE_DELETE;
  template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE;

  bool isConvertibleTo(ValueType other) const;

  /// Number of values in array or object
  ArrayIndex size() const;

  /// \brief Return true if empty array, empty object, or null;
  /// otherwise, false.
  bool empty() const;

  /// Return !isNull()
  explicit operator bool() const;

  /// Remove all object members and array elements.
  /// \pre type() is arrayValue, objectValue, or nullValue
  /// \post type() is unchanged
  void clear();

  /// Resize the array to newSize elements.
  /// New elements are initialized to null.
  /// May only be called on nullValue or arrayValue.
  /// \pre type() is arrayValue or nullValue
  /// \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.
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  /// 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.
  Value get(ArrayIndex index, const Value& defaultValue) const;
  /// Return true if index < size().
  bool isValidIndex(ArrayIndex index) const;
  /// \brief Append value to array at the end.
  ///
  /// Equivalent to jsonvalue[jsonvalue.size()] = value;
  Value& append(const Value& value);
  Value& append(Value&& value);

  /// \brief Insert value in array at specific index
  bool insert(ArrayIndex index, const Value& newValue);
  bool insert(ArrayIndex index, Value&& newValue);

#ifdef JSONCPP_HAS_STRING_VIEW
  /// Access an object value by name, create a null member if it does not exist.
  /// \param key may contain embedded nulls.
  Value& operator[](std::string_view key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  /// \param key may contain embedded nulls.
  const Value& operator[](std::string_view key) const;
#else
  /// 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.
  /// Exceeding that will cause an exception.
  Value& operator[](const char* key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  const Value& operator[](const char* key) const;
  /// Access an object value by name, create a null member if it does not exist.
  /// \param key may contain embedded nulls.
  Value& operator[](const String& key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  /// \param key may contain embedded nulls.
  const Value& operator[](const String& key) const;
#endif
  /** \brief Access an object value by name, create a null member if it does not
   * exist.
   *
   * If the object has no entry for that name, then the member name used to
   * store the new entry is not duplicated.
   * Example of use:
   *   \code
   *   Json::Value object;
   *   static const StaticString code("code");
   *   object[code] = 1234;
   *   \endcode
   */
  Value& operator[](const StaticString& key);
#ifdef JSONCPP_HAS_STRING_VIEW
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  Value get(std::string_view key, const Value& defaultValue) const;
#else
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  Value get(const char* key, const Value& defaultValue) const;
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  /// \param key may contain embedded nulls.
  Value get(const String& key, const Value& defaultValue) const;
#endif
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  /// \note key may contain embedded nulls.
  Value get(const char* begin, const char* end,
            const Value& defaultValue) const;
  /// Most general and efficient version of isMember()const, get()const,
  /// 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;

  /// Calls find and only returns a valid pointer if the type is found
  template <typename T, bool (T::*TMemFn)() const>
  Value const* findValue(const String& key) const {
    Value const* found = find(key);
    if (!found || !(found->*TMemFn)())
      return nullptr;
    return found;
  }

  Value const* findNull(const String& key) const;
  Value const* findBool(const String& key) const;
  Value const* findInt(const String& key) const;
  Value const* findInt64(const String& key) const;
  Value const* findUInt(const String& key) const;
  Value const* findUInt64(const String& key) const;
  Value const* findIntegral(const String& key) const;
  Value const* findDouble(const String& key) const;
  Value const* findNumeric(const String& key) const;
  Value const* findString(const String& key) const;
  Value const* findArray(const String& key) const;
  Value const* findObject(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.
  Value* demand(char const* begin, char const* end);
  /// \brief Remove and return the named member.
  ///
  /// Do nothing if it did not exist.
  /// \pre type() is objectValue or nullValue
  /// \post type() is unchanged
#if JSONCPP_HAS_STRING_VIEW
  void removeMember(std::string_view key);
#else
  void removeMember(const char* key);
  /// Same as removeMember(const char*)
  /// \param key may contain embedded nulls.
  void removeMember(const String& key);
#endif
  /** \brief Remove the named map member.
   *
   *  Update 'removed' iff removed.
   *  \param key may contain embedded nulls.
   *  \return true iff removed (no exceptions)
   */
#if JSONCPP_HAS_STRING_VIEW
  bool removeMember(std::string_view key, Value* removed);
#else
  bool removeMember(String const& key, Value* removed);
  /// Same as removeMember(const char* begin, const char* end, Value* removed),
  /// but 'key' is null-terminated.
  bool removeMember(const char* key, Value* removed);
#endif
  /// Same as removeMember(String const& key, Value* removed)
  bool removeMember(const char* begin, const char* end, Value* removed);
  /** \brief Remove the indexed array element.
   *
   *  O(n) expensive operations.
   *  Update 'removed' iff removed.
   *  \return true if removed (no exceptions)
   */
  bool removeIndex(ArrayIndex index, Value* removed);

#ifdef JSONCPP_HAS_STRING_VIEW
  /// Return true if the object has a member named key.
  /// \param key may contain embedded nulls.
  bool isMember(std::string_view key) const;
#else
  /// Return true if the object has a member named key.
  /// \note 'key' must be null-terminated.
  bool isMember(const char* key) const;
  /// Return true if the object has a member named key.
  /// \param key may contain embedded nulls.
  bool isMember(const String& key) const;
#endif
  /// Same as isMember(String const& key)const
  bool isMember(const char* begin, const char* end) const;

  /// \brief Return a list of the member names.
  ///
  /// If null, return an empty list.
  /// \pre type() is objectValue or nullValue
  /// \post if type() was nullValue, it remains nullValue
  Members getMemberNames() const;

  /// \deprecated Always pass len.
  JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
  void setComment(const char* comment, CommentPlacement placement) {
    setComment(String(comment, strlen(comment)), placement);
  }
  /// Comments must be //... or /* ... */
  void setComment(const char* comment, size_t len, CommentPlacement placement) {
    setComment(String(comment, len), placement);
  }
  /// Comments must be //... or /* ... */
  void setComment(String comment, CommentPlacement placement);
  bool hasComment(CommentPlacement placement) const;
  /// Include delimiters and embedded newlines.
  String getComment(CommentPlacement placement) const;

  String toStyledString() const;

  const_iterator begin() const;
  const_iterator end() const;

  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);
  void setOffsetLimit(ptrdiff_t limit);
  ptrdiff_t getOffsetStart() const;
  ptrdiff_t getOffsetLimit() const;

private:
  void setType(ValueType v) {
    bits_.value_type_ = static_cast<unsigned char>(v);
  }
  bool isAllocated() const { return bits_.allocated_; }
  void setIsAllocated(bool v) { bits_.allocated_ = v; }

  /*initBasic在声明时参数allocated存在默认参数*/
  void initBasic(ValueType type, bool allocated = false);
  void dupPayload(const Value& other);
  void releasePayload();
  void dupMeta(const Value& other);

  Value& resolveReference(const char* key);
  Value& resolveReference(const char* key, const char* end);

  // struct MemberNamesTransform
  //{
  //   typedef const char *result_type;
  //   const char *operator()( const CZString &name ) const
  //   {
  //      return name.c_str();
  //   }
  //};

  /*存放值,因为需要各种类型的json数据,使用联合类型来存放*/
  union ValueHolder {
    LargestInt int_;
    LargestUInt uint_;
    double real_;
    bool bool_;
    /*只有bits_.allocated为1时,string中的内容才有效*/
    char* string_; // if allocated_, ptr to { unsigned, char[] }.
    ObjectValues* map_;
  } value_;

  struct {
    // Really a ValueType, but types should agree for bitfield packing.
    /*表明数据类型,int bool,double,char *,map<>*/
    unsigned int value_type_ : 8;
    // Unless allocated_, string_ must be null-terminated.
    unsigned int allocated_ : 1;
  } bits_;

  class Comments {
  public:
    /*使用编译器生成的无参构造函数*/
    Comments() = default;
    Comments(const Comments& that);
    Comments(Comments&& that) noexcept;
    Comments& operator=(const Comments& that);
    Comments& operator=(Comments&& that) noexcept;
    bool has(CommentPlacement slot) const;
    String get(CommentPlacement slot) const;
    void set(CommentPlacement slot, String comment);

  private:

    using Array = std::array<String, numberOfCommentPlacement>;
    std::unique_ptr<Array> ptr_; /*ptr_存放注释内容??*/
  };
  Comments comments_;

  // [start, limit) byte offsets in the source JSON text from which this Value
  // was extracted.
  ptrdiff_t start_;
  ptrdiff_t limit_;
}; //Value类结束

template <> inline bool Value::as<bool>() const { return asBool(); }
template <> inline bool Value::is<bool>() const { return isBool(); }

template <> inline Int Value::as<Int>() const { return asInt(); }
template <> inline bool Value::is<Int>() const { return isInt(); }

template <> inline UInt Value::as<UInt>() const { return asUInt(); }
template <> inline bool Value::is<UInt>() const { return isUInt(); }

#if defined(JSON_HAS_INT64)
template <> inline Int64 Value::as<Int64>() const { return asInt64(); }
template <> inline bool Value::is<Int64>() const { return isInt64(); }

template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); }
template <> inline bool Value::is<UInt64>() const { return isUInt64(); }
#endif

template <> inline double Value::as<double>() const { return asDouble(); }
template <> inline bool Value::is<double>() const { return isDouble(); }

template <> inline String Value::as<String>() const { return asString(); }
template <> inline bool Value::is<String>() const { return isString(); }

/// These `as` specializations are type conversions, and do not have a
/// corresponding `is`.
template <> inline float Value::as<float>() const { return asFloat(); }
template <> inline const char* Value::as<const char*>() const {
  return asCString();
}

/** \brief Experimental and untested: represents an element of the "path" to
 * access a node.
 */
class JSON_API PathArgument {
public:
  friend class Path;

  PathArgument();
  PathArgument(ArrayIndex index);
  PathArgument(const char* key);
  PathArgument(String key);

private:
  enum Kind { kindNone = 0, kindIndex, kindKey };
  String key_;
  ArrayIndex index_{};
  Kind kind_{kindNone};
};

/** \brief Experimental and untested: represents a "path" to access a node.
 *
 * Syntax:
 * - "." => root node
 * - ".[n]" => elements at index 'n' of root node (an array value)
 * - ".name" => member named 'name' of root node (an object value)
 * - ".name1.name2.name3"
 * - ".[0][1][2].name1[3]"
 * - ".%" => member name is provided as parameter
 * - ".[%]" => index is provided as parameter
 */
class JSON_API Path {
public:
  Path(const String& path, const PathArgument& a1 = PathArgument(),
       const PathArgument& a2 = PathArgument(),
       const PathArgument& a3 = PathArgument(),
       const PathArgument& a4 = PathArgument(),
       const PathArgument& a5 = PathArgument());

  const Value& resolve(const Value& root) const;
  Value resolve(const Value& root, const Value& defaultValue) const;
  /// Creates the "path" to access the specified node and returns a reference on
  /// the node.
  Value& make(Value& root) const;

private:
  using InArgs = std::vector<const PathArgument*>;
  using Args = std::vector<PathArgument>;

  void makePath(const String& path, const InArgs& in);
  void addPathInArg(const String& path, const InArgs& in,
                    InArgs::const_iterator& itInArg, PathArgument::Kind kind);
  static void invalidPath(const String& path, int location);

  Args args_;
};

/** \brief base class for Value iterators.
 *
 */
class JSON_API ValueIteratorBase {
public:
  using iterator_category = std::bidirectional_iterator_tag;
  using size_t = unsigned int;
  using difference_type = int;
  using SelfType = ValueIteratorBase;

  bool operator==(const SelfType& other) const { return isEqual(other); }

  bool operator!=(const SelfType& other) const { return !isEqual(other); }

  difference_type operator-(const SelfType& other) const {
    return other.computeDistance(*this);
  }

  /// Return either the index or the member name of the referenced value as a
  /// Value.
  Value key() const;

  /// Return the index of the referenced Value, or -1 if it is not an
  /// arrayValue.
  UInt index() const;

  /// Return the member name of the referenced Value, or "" if it is not an
  /// objectValue.
  /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
  String name() const;

  /// Return the member name of the referenced Value. "" if it is not an
  /// objectValue.
  /// \deprecated This cannot be used for UTF-8 strings, since there can be
  /// embedded nulls.
  JSONCPP_DEPRECATED("Use `key = name();` instead.")
  char const* memberName() const;
  /// Return the member name of the referenced Value, or NULL if it is not an
  /// objectValue.
  /// \note Better version than memberName(). Allows embedded nulls.
  char const* memberName(char const** end) const;

protected:
  /*! Internal utility functions to assist with implementing
   *   other iterator functions. The const and non-const versions
   *   of the "deref" protected methods expose the protected
   *   current_ member variable in a way that can often be
   *   optimized away by the compiler.
   */
  const Value& deref() const;
  Value& deref();

  void increment();

  void decrement();

  difference_type computeDistance(const SelfType& other) const;

  bool isEqual(const SelfType& other) const;

  void copy(const SelfType& other);

private:
  Value::ObjectValues::iterator current_;
  // Indicates that iterator is for a null value.
  bool isNull_{true};

public:
  // For some reason, BORLAND needs these at the end, rather
  // than earlier. No idea why.
  ValueIteratorBase();
  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
};

/** \brief const iterator for object and array value.
 *
 */
class JSON_API ValueConstIterator : public ValueIteratorBase {
  friend class Value;

public:
  using value_type = const Value;
  // typedef unsigned int size_t;
  // typedef int difference_type;
  using reference = const Value&;
  using pointer = const Value*;
  using SelfType = ValueConstIterator;

  ValueConstIterator();
  ValueConstIterator(ValueIterator const& other);

private:
  /*! \internal Use by Value to create an iterator.
   */
  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);

public:
  SelfType& operator=(const ValueIteratorBase& other);

  SelfType operator++(int) {
    SelfType temp(*this);
    ++*this;
    return temp;
  }

  SelfType operator--(int) {
    SelfType temp(*this);
    --*this;
    return temp;
  }

  SelfType& operator--() {
    decrement();
    return *this;
  }

  SelfType& operator++() {
    increment();
    return *this;
  }

  reference operator*() const { return deref(); }

  pointer operator->() const { return &deref(); }
};

/** \brief Iterator for object and array value.
 */
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;

  ValueIterator();
  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);

public:
  SelfType& operator=(const SelfType& other);

  SelfType operator++(int) {
    SelfType temp(*this);
    ++*this;
    return temp;
  }

  SelfType operator--(int) {
    SelfType temp(*this);
    --*this;
    return temp;
  }

  SelfType& operator--() {
    decrement();
    return *this;
  }

  SelfType& operator++() {
    increment();
    return *this;
  }

  /*! The return value of non-const iterators can be
   *  changed, so the these functions are not const
   *  because the returned references/pointers can be used
   *  to change state of the base class.
   */
  reference operator*() const { return const_cast<reference>(deref()); }
  pointer operator->() const { return const_cast<pointer>(&deref()); }
};

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)

#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

#endif // JSON_H_INCLUDED

json_value.cpp内容如下:

// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#if !defined(JSON_IS_AMALGAMATION)
#include <json/assertions.h>
#include <json/value.h>
#include <json/writer.h>
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstring>
#include <iostream>
#include <sstream>
#include <utility>

#ifdef JSONCPP_HAS_STRING_VIEW
#include <string_view>
#endif

// Provide implementation equivalent of std::snprintf for older _MSC compilers
#if defined(_MSC_VER) && _MSC_VER < 1900
#include <stdarg.h>
static int msvc_pre1900_c99_vsnprintf(char* outBuf, size_t size,
                                      const char* format, va_list ap) {
  int count = -1;
  if (size != 0)
    count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
  if (count == -1)
    count = _vscprintf(format, ap);
  return count;
}

int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
                                       const char* format, ...) {
  va_list ap;
  va_start(ap, format);
  const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap);
  va_end(ap);
  return count;
}
#endif

// Disable warning C4702 : unreachable code
#if defined(_MSC_VER)
#pragma warning(disable : 4702)
#endif

#define JSON_ASSERT_UNREACHABLE assert(false)

namespace Json {
template <typename T>
static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) {
  std::unique_ptr<T> r; /*临时对象*/
  if (p) {
    /*unique_ptr不支持赋值运算符,这里只能是移动赋值运算符*/
    r = std::unique_ptr<T>(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
// 8 (instead of 4) as a bit of future-proofing.
#if defined(__ARMEL__)
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#else
#define ALIGNAS(byte_alignment)
#endif

// static
Value const& Value::nullSingleton() {
  static Value const nullStatic;
  return nullStatic;
}

#if JSON_USE_NULLREF
// for backwards compatibility, we'll leave these global references around, but
// DO NOT use them in JSONCPP library code any more!
// static
Value const& Value::null = Value::nullSingleton();

// static
Value const& Value::nullRef = Value::nullSingleton();
#endif

#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
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) &&
         !(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) {
  /*
    double是64位浮点数,遵循IEEE 754标准,其有效数字约为15-17位十进制数。
    Json::UInt64是64位无符号整数,范围是0到18446744073709551615(约20位十进制数)。
​    结论​:当value超过2^52 时,直接转换为double会丢失精度(因为 double的尾数部分只能精确表示52位二进制数)。
    
    这个代码写的很隐晦,将value拆分为整数部分和余数部分来处理,value / 2  ,value % 2(value & 1)
    但是还是不能避免精度丢失的情况 
  */
  return static_cast<double>(Int64(value / 2)) * 2.0 +
         static_cast<double>(Int64(value & 1));
}

/*函数模板*/
template <typename T> static inline double integerToDouble(T value) {
  return static_cast<double>(value);
}

/*函数模板*/
template <typename T, typename U>
static inline bool InRange(double d, T min, U max) {
  return d >= integerToDouble(min) && d <= integerToDouble(max)/*d在将min和max转换为double的范围内*/ &&
         !(static_cast<U>(d) == min/*将d转为min的类型*/ && d != integerToDouble(min)/*将min转换为d的double类型*/);
}
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)

/** Duplicates the specified string value.
 * @param value Pointer to the string to duplicate. Must be zero-terminated if
 *              length is "unknown".
 * @param length Length of the value. if equals to unknown, then it will be
 *               computed using strlen(value).
 * @return Pointer on the duplicate instance of string.
 */
/*将value所指内存中的数据拷贝到新内存中,并返回新内存空间地址*/
static inline char* duplicateStringValue(const char* value, size_t length) {
  // Avoid an integer overflow in the call to malloc below by limiting length
  // to a sane value.
  if (length >= static_cast<size_t>(Value::maxInt))
    length = Value::maxInt - 1;

  auto newString = static_cast<char*>(malloc(length + 1));
  if (newString == nullptr) {
    throwRuntimeError("in Json::Value::duplicateStringValue(): "
                      "Failed to allocate string value buffer");
  }
  memcpy(newString, value, length);
  newString[length] = 0;
  return newString;
}

/* Record the length as a prefix.
 */
static inline char* duplicateAndPrefixStringValue(const char* value,
                                                  unsigned int length) {
  // Avoid an integer overflow in the call to malloc below by limiting length
  // to a sane value.
  JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) -
                                    sizeof(unsigned) - 1U,
                      "in Json::Value::duplicateAndPrefixStringValue(): "
                      "length too big for prefixing");
  size_t actualLength = sizeof(length) + length + 1;
  auto newString = static_cast<char*>(malloc(actualLength));
  if (newString == nullptr) {
    throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): "
                      "Failed to allocate string value buffer");
  }
  
  /*先存放字符长度再存放字符串数据*/
  *reinterpret_cast<unsigned*>(newString) = length;
  memcpy(newString + sizeof(unsigned), value, length);
  newString[actualLength - 1U] =
      0; // to avoid buffer over-run accidents by users later
  return newString;
}

inline static void decodePrefixedString(bool isPrefixed, char const* prefixed,
                                        unsigned* length, char const** value) {
  if (!isPrefixed) { /*不存在前缀长度字段*/
    *length = static_cast<unsigned>(strlen(prefixed));
    *value = prefixed;
  } else { /*存在前缀长度字段*/
    *length = *reinterpret_cast<unsigned const*>(prefixed); /*获取前缀长度*/
    *value = prefixed + sizeof(unsigned);
  }
}
/** Free the string duplicated by
 * duplicateStringValue()/duplicateAndPrefixStringValue().
 */
#if JSONCPP_USE_SECURE_MEMORY
/*释放内存空间*/
static inline void releasePrefixedStringValue(char* value) {
  unsigned length = 0;
  char const* valueDecoded;
  decodePrefixedString(true, value, &length, &valueDecoded);
  size_t const size = sizeof(unsigned) + length + 1U;
  memset(value, 0, size);
  free(value);
}

static inline void releaseStringValue(char* value, unsigned length) {
  // length==0 => we allocated the strings memory
  size_t size = (length == 0) ? strlen(value) : length;
  memset(value, 0, size);
  free(value);
}

#else  // !JSONCPP_USE_SECURE_MEMORY
static inline void releasePrefixedStringValue(char* value) { free(value); }
static inline void releaseStringValue(char* value, unsigned) { free(value); }
#endif // JSONCPP_USE_SECURE_MEMORY

} // namespace Json

// //
// //
// //
// ValueInternals...
// //
// //
// //
#if !defined(JSON_IS_AMALGAMATION)

#include "json_valueiterator.inl"
#endif // if !defined(JSON_IS_AMALGAMATION)

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(); }
RuntimeError::RuntimeError(String const& msg) : Exception(msg) {}
LogicError::LogicError(String const& msg) : Exception(msg) {}
JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
  throw RuntimeError(msg);
}
JSONCPP_NORETURN void throwLogicError(String const& msg) {
  throw LogicError(msg);
}
#else // !JSON_USE_EXCEPTION
JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
  std::cerr << msg << std::endl;
  abort();
}
JSONCPP_NORETURN void throwLogicError(String const& msg) {
  std::cerr << msg << std::endl;
  abort();
}
#endif

// //
// //
// //
// class Value::CZString
// //
// //
// //

// Notes: policy_ indicates if the string was allocated when
// a string is stored.

/*CZString类构造函数实现*/

Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {}

Value::CZString::CZString(char const* str, unsigned length,
                          DuplicationPolicy allocate)
    : cstr_(str) {
  // allocate != duplicate
  storage_.policy_ = allocate & 0x3;
  storage_.length_ = length & 0x3FFFFFFF;
}

/*拷贝构造函数*/
Value::CZString::CZString(const CZString& other) {
  /*如果other的存储策略为不允许复制的化,则使用同一片存储空间,如果申请一块新的内存空间将other的值拷贝到该空间并返回空间地址*/
  cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr
               ? duplicateStringValue(other.cstr_, other.storage_.length_)
               : other.cstr_);
  storage_.policy_ =
      static_cast<unsigned>(
          other.cstr_
              ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
                         noDuplication
                     ? noDuplication
                     : duplicate)
              : static_cast<DuplicationPolicy>(other.storage_.policy_)) &
      3U;
  storage_.length_ = other.storage_.length_;
}

/*移动构造函数*/
Value::CZString::CZString(CZString&& other) noexcept
    : cstr_(other.cstr_), index_(other.index_) {
  other.cstr_ = nullptr;
}

/*析构函数*/
Value::CZString::~CZString() {
  if (cstr_ && storage_.policy_ == duplicate) { /*析构函数中只有policy为duplicate时才能释放分配的内存空间*/
    releaseStringValue(const_cast<char*>(cstr_),
                       storage_.length_ + 1U); // +1 for null terminating
                                               // character for sake of
                                               // completeness but not actually
                                               // necessary
  }
}

void Value::CZString::swap(CZString& other) {
  std::swap(cstr_, other.cstr_);
  std::swap(index_, other.index_);
}

/*赋值运算符*/
Value::CZString& Value::CZString::operator=(const CZString& other) {
  cstr_ = other.cstr_;
  index_ = other.index_;
  return *this;
}

/*移动赋值运算符*/
Value::CZString& Value::CZString::operator=(CZString&& other) noexcept {
  cstr_ = other.cstr_;
  index_ = other.index_;
  other.cstr_ = nullptr;
  return *this;
}

/*因为Value类的map中的键值为CZString类,所以CZString类必须实现比较运算符*/
/*<运算符*/
bool Value::CZString::operator<(const CZString& other) const {
  if (!cstr_) /*如果cstr_无效则直接比较index*/
    return index_ < other.index_;
  // return strcmp(cstr_, other.cstr_) < 0;
  // Assume both are strings.
  unsigned this_len = this->storage_.length_;
  unsigned other_len = other.storage_.length_;
  /*取两者之间长度最小的长度作为比较长度*/
  unsigned min_len = std::min<unsigned>(this_len, other_len);
  JSON_ASSERT(this->cstr_ && other.cstr_);
  int comp = memcmp(this->cstr_, other.cstr_, min_len);
  if (comp < 0)
    return true;
  if (comp > 0)
    return false;
  return (this_len < other_len);
}

/*==运算符*/
bool Value::CZString::operator==(const CZString& other) const {
  if (!cstr_)  /*如果cstr_无效则直接比较index*/
    return index_ == other.index_;
  // return strcmp(cstr_, other.cstr_) == 0;
  // Assume both are strings.
  unsigned this_len = this->storage_.length_;
  unsigned other_len = other.storage_.length_;
  if (this_len != other_len)
    return false;
  JSON_ASSERT(this->cstr_ && other.cstr_);
  int comp = memcmp(this->cstr_, other.cstr_, this_len);
  return comp == 0;
}

ArrayIndex Value::CZString::index() const { return index_; }

// const char* Value::CZString::c_str() const { return cstr_; }
const char* Value::CZString::data() const { return cstr_; }
unsigned Value::CZString::length() const { return storage_.length_; }
bool Value::CZString::isStaticString() const {
  return storage_.policy_ == noDuplication;
}

// //
// //
// //
// class Value::Value
// //
// //
// //

/*! \internal Default constructor initialization must be equivalent to:
 * memset( this, 0, sizeof(Value) )
 * This optimization is used in ValueInternalMap fast allocator.
 */
/*Value类构造函数实现*/
Value::Value(ValueType type) {
  static char const emptyString[] = "";
  initBasic(type);
  switch (type) {
  case nullValue:
    break;
  case intValue:
  case uintValue:
    value_.int_ = 0;
    break;
  case realValue:
    value_.real_ = 0.0;
    break;
  case stringValue:
    // allocated_ == false, so this is safe.
    value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
    break;
  case arrayValue:
  case objectValue:
    value_.map_ = new ObjectValues();
    break;
  case booleanValue:
    value_.bool_ = false;
    break;
  default:
    JSON_ASSERT_UNREACHABLE;
  }
}

Value::Value(Int value) {
  initBasic(intValue);
  value_.int_ = value;
}

Value::Value(UInt value) {
  initBasic(uintValue);
  value_.uint_ = value;
}
#if defined(JSON_HAS_INT64)
Value::Value(Int64 value) {
  initBasic(intValue);
  value_.int_ = value;
}
Value::Value(UInt64 value) {
  initBasic(uintValue);
  value_.uint_ = value;
}
#endif // defined(JSON_HAS_INT64)

Value::Value(double value) {
  initBasic(realValue);
  value_.real_ = value;
}

Value::Value(const char* value) {
  initBasic(stringValue, true);
  JSON_ASSERT_MESSAGE(value != nullptr,
                      "Null Value Passed to Value Constructor");
  /*存在前缀即字符串的长度*/
  value_.string_ = duplicateAndPrefixStringValue(
      value, static_cast<unsigned>(strlen(value))/*使用C++的强制类型转换*/);
}

Value::Value(const char* begin, const char* end) {
  initBasic(stringValue, true);
  value_.string_ =
      duplicateAndPrefixStringValue(begin, static_cast<unsigned>(end - begin));
}

Value::Value(const String& value) {
  initBasic(stringValue, true);
  value_.string_ = duplicateAndPrefixStringValue(
      value.data(), static_cast<unsigned>(value.length()));
}

#ifdef JSONCPP_HAS_STRING_VIEW
Value::Value(std::string_view value) {
  initBasic(stringValue, true);
  value_.string_ = duplicateAndPrefixStringValue(
      value.data(), static_cast<unsigned>(value.length()));
}
#endif

Value::Value(const StaticString& value) {
  initBasic(stringValue);
  value_.string_ = const_cast<char*>(value.c_str());
}

Value::Value(bool value) {
  initBasic(booleanValue);
  value_.bool_ = value;
}

/*拷贝构造函数*/
Value::Value(const Value& other) {
  dupPayload(other);
  dupMeta(other);
}

/*移动构造函数*/
Value::Value(Value&& other) noexcept {
  initBasic(nullValue);
  swap(other);
}

/*析构函数*/
Value::~Value() {
  releasePayload();
  value_.uint_ = 0;
}

/*赋值运算符*/
Value& Value::operator=(const Value& other) {
  Value(other).swap(*this);
  return *this;
}

/*移动赋值运算符*/
Value& Value::operator=(Value&& other) noexcept {
  other.swap(*this);
  return *this;
}

/*交换bits和value数据成员*/
void Value::swapPayload(Value& other) {
  std::swap(bits_, other.bits_);
  std::swap(value_, other.value_);
}

void Value::copyPayload(const Value& other) {
  /*释放this中存放的数据*/
  releasePayload(); 
  dupPayload(other);
}

/*实现Value类的swap函数*/
void Value::swap(Value& other) {
  swapPayload(other);
  std::swap(comments_, other.comments_);
  std::swap(start_, other.start_);
  std::swap(limit_, other.limit_);
}

void Value::copy(const Value& other) {
  copyPayload(other);
  dupMeta(other);
}

ValueType Value::type() const {
  return static_cast<ValueType>(bits_.value_type_);
}

int Value::compare(const Value& other) const {
  if (*this < other)
    return -1;
  if (*this > other)
    return 1;
  return 0;
}

/*<运算符*/
bool Value::operator<(const Value& other) const {
  int typeDelta = type() - other.type();
  if (typeDelta) /*类型不同原则上不能进行比较*/
    return typeDelta < 0;  
  switch (type()) {
  case nullValue:
    return false;
  case intValue:
    return value_.int_ < other.value_.int_;
  case uintValue:
    return value_.uint_ < other.value_.uint_;
  case realValue:
    return value_.real_ < other.value_.real_;
  case booleanValue:
    return value_.bool_ < other.value_.bool_;
  case stringValue: {
    if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
      return other.value_.string_ != nullptr;
    }
    unsigned this_len;
    unsigned other_len;
    char const* this_str;
    char const* other_str;
    decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
                         &this_str);
    decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
                         &other_str);
    /*感觉具有一定的意义,先比较min长度部分的字符,再根据长度来判断*/
    unsigned min_len = std::min<unsigned>(this_len, other_len);
    JSON_ASSERT(this_str && other_str);
    int comp = memcmp(this_str, other_str, min_len);
    if (comp < 0)
      return true;
    if (comp > 0)
      return false;
    return (this_len < other_len);
  }
  case arrayValue:
  case objectValue: {
    auto thisSize = value_.map_->size();
    auto otherSize = other.value_.map_->size();
    if (thisSize != otherSize)
      return thisSize < otherSize;
    return (*value_.map_) < (*other.value_.map_);
  }
  default:
    JSON_ASSERT_UNREACHABLE;
  }
  return false; // unreachable
}

/*下面运算符的实现基于前面的<小于运算符*/
bool Value::operator<=(const Value& other) const { return !(other < *this); }

bool Value::operator>=(const Value& other) const { return !(*this < other); }

bool Value::operator>(const Value& other) const { return other < *this; }

bool Value::operator==(const Value& other) const {
  if (type() != other.type())
    return false; /*原则上类型相同才能进行比较*/
  switch (type()) {
  case nullValue:
    return true;
  case intValue:
    return value_.int_ == other.value_.int_;
  case uintValue:
    return value_.uint_ == other.value_.uint_;
  case realValue:
    return value_.real_ == other.value_.real_;
  case booleanValue:
    return value_.bool_ == other.value_.bool_;
  case stringValue: {
    if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
      return (value_.string_ == other.value_.string_);
    }
    unsigned this_len;
    unsigned other_len;
    char const* this_str;
    char const* other_str;
    decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
                         &this_str);
    decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
                         &other_str);
    if (this_len != other_len)
      return false;
    JSON_ASSERT(this_str && other_str);
    int comp = memcmp(this_str, other_str, this_len);
    return comp == 0;
  }
  case arrayValue:
  case objectValue:
    return value_.map_->size() == other.value_.map_->size() &&
           (*value_.map_) == (*other.value_.map_);
  default:
    JSON_ASSERT_UNREACHABLE;
  }
  return false; // unreachable
}

bool Value::operator!=(const Value& other) const { return !(*this == other); }

/*返回Value中的字符串类型的数据*/
const char* Value::asCString() const {
  JSON_ASSERT_MESSAGE(type() == stringValue,
                      "in Json::Value::asCString(): requires stringValue");
  if (value_.string_ == nullptr)
    return nullptr;
  unsigned this_len;
  char const* this_str;
  /*返回解码出有效字符串的位置*/
  decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
                       &this_str);
  return this_str;
}

#if JSONCPP_USE_SECURE_MEMORY
unsigned Value::getCStringLength() const {
  JSON_ASSERT_MESSAGE(type() == stringValue,
                      "in Json::Value::asCString(): requires stringValue");
  if (value_.string_ == 0)
    return 0;
  unsigned this_len;
  char const* this_str;
  decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
                       &this_str);
  return this_len;
}
#endif

/*
返回Value中字符串类型数据的起始和结束位置
注意:begin和end为二级指针
*/
bool Value::getString(char const** begin, char const** end) const {
  if (type() != stringValue)
    return false;
  if (value_.string_ == nullptr)
    return false;
  unsigned length;
  decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
                       begin);
  *end = *begin + length;
  return true;
}

#ifdef JSONCPP_HAS_STRING_VIEW
bool Value::getString(std::string_view* str) const {
  if (type() != stringValue)
    return false;
  if (value_.string_ == nullptr)
    return false;
  const char* begin;
  unsigned length;
  decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
                       &begin);
  *str = std::string_view(begin, length);
  return true;
}
#endif

/*返回的类型为String*/
String Value::asString() const {
  switch (type()) {
  case nullValue:
    return "";
  case stringValue: {
    if (value_.string_ == nullptr)
      return "";
    unsigned this_len;
    char const* this_str;
    decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
                         &this_str);
    /*返回匿名对象String*/
    return String(this_str, this_len); 
  }
  case booleanValue:
    return value_.bool_ ? "true" : "false";
  case intValue:
    return valueToString(value_.int_);
  case uintValue:
    return valueToString(value_.uint_);
  case realValue:
    return valueToString(value_.real_);
  default:
    JSON_FAIL_MESSAGE("Type is not convertible to string");
  }
}

/*返回的类型为int*/
Value::Int Value::asInt() const {
  switch (type()) {
  case intValue:
    JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
    return Int(value_.int_);
  case uintValue:
    JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
    return Int(value_.uint_);
  case realValue:
    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
                        "double out of Int range");
    return Int(value_.real_);
  case nullValue:
    return 0;
  case booleanValue:
    return value_.bool_ ? 1 : 0;
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to Int.");
}

/*返回的类型为uint*/
Value::UInt Value::asUInt() const {
  switch (type()) {
  case intValue:
    JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
    return UInt(value_.int_);
  case uintValue:
    JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
    return UInt(value_.uint_);
  case realValue:
    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0u, maxUInt),
                        "double out of UInt range");
    return UInt(value_.real_);
  case nullValue:
    return 0;
  case booleanValue:
    return value_.bool_ ? 1 : 0;
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
}

#if defined(JSON_HAS_INT64)

Value::Int64 Value::asInt64() const {
  switch (type()) {
  case intValue:
    return Int64(value_.int_);
  case uintValue:
    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_);
  case nullValue:
    return 0;
  case booleanValue:
    return value_.bool_ ? 1 : 0;
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
}

Value::UInt64 Value::asUInt64() const {
  switch (type()) {
  case intValue:
    JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
    return UInt64(value_.int_);
  case uintValue:
    return UInt64(value_.uint_);
  case realValue:
    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0u, maxUInt64),
                        "double out of UInt64 range");
    return UInt64(value_.real_);
  case nullValue:
    return 0;
  case booleanValue:
    return value_.bool_ ? 1 : 0;
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
}
#endif // if defined(JSON_HAS_INT64)

LargestInt Value::asLargestInt() const {
#if defined(JSON_NO_INT64)
  return asInt();
#else
  return asInt64();
#endif
}

LargestUInt Value::asLargestUInt() const {
#if defined(JSON_NO_INT64)
  return asUInt();
#else
  return asUInt64();
#endif
}

double Value::asDouble() const {
  switch (type()) {
  case intValue:
    return static_cast<double>(value_.int_);
  case uintValue:
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    return static_cast<double>(value_.uint_);
#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    return integerToDouble(value_.uint_);
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
  case realValue:
    return value_.real_;
  case nullValue:
    return 0.0; /*空指针返回0.0*/
  case booleanValue:
    return value_.bool_ ? 1.0 : 0.0; /*bool类型*/
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to double.");
}

float Value::asFloat() const {
  switch (type()) {
  case intValue:
    return static_cast<float>(value_.int_);
  case uintValue:
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    return static_cast<float>(value_.uint_);
#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
    // This can fail (silently?) if the value is bigger than MAX_FLOAT.
    return static_cast<float>(integerToDouble(value_.uint_));
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
  case realValue:
    return static_cast<float>(value_.real_);
  case nullValue:
    return 0.0;
  case booleanValue:
    return value_.bool_ ? 1.0F : 0.0F;
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to float.");
}

/*将value的值返回为bool类型*/
bool Value::asBool() const {
  switch (type()) {
  case booleanValue:
    return value_.bool_;
  case nullValue:
    return false;
  case intValue:
    return value_.int_ != 0;
  case uintValue:
    return value_.uint_ != 0;
  case realValue: {
    // According to JavaScript language zero or NaN is regarded as false
    /*
      NaN(Not a Number)是浮点数的特殊值,表示“未定义或不可表示的数值”(如 0/0、sqrt(-1))。
      在布尔上下文中,NaN会被隐式转换为false,但这是通过operator bool()的隐式转换规则实现的,而非直接比较。

      std::fpclassify是C++标准库(<cmath>)中的一个函数,用于对浮点数进行分类,判断其属于哪一类特殊值(如正常数、零、无穷大、NaN 等)。
      它是处理浮点数状态检测的核心工具之一。
    */

    /*浮点数是否为bool的判断方法*/
    const auto value_classification = std::fpclassify(value_.real_);
    return value_classification != FP_ZERO && value_classification != FP_NAN;
  }
  default:
    break;
  }
  JSON_FAIL_MESSAGE("Value is not convertible to bool.");
}

/*Value的值能够转换为other的类型*/
bool Value::isConvertibleTo(ValueType other) const {
  switch (other) {
  case nullValue:
    return (isNumeric() && asDouble() == 0.0) ||
           (type() == booleanValue && !value_.bool_)/*bool类型,值为false*/ ||
           (type() == stringValue && asString().empty())/*字符串类型,为空*/ ||
           (type() == arrayValue && value_.map_->empty()) ||
           (type() == objectValue && value_.map_->empty()) ||
           type() == nullValue;
  case intValue:
    return isInt() ||
           (type() == realValue && InRange(value_.real_, minInt, maxInt)) ||
           type() == booleanValue || type() == nullValue;
  case uintValue:
    return isUInt() ||
           (type() == realValue && InRange(value_.real_, 0u, maxUInt)) ||
           type() == booleanValue || type() == nullValue;
  case realValue:
    return isNumeric() || type() == booleanValue || type() == nullValue;
  case booleanValue:
    return isNumeric() || type() == booleanValue || type() == nullValue;
  case stringValue:
    return isNumeric() || type() == booleanValue || type() == stringValue ||
           type() == nullValue;
  case arrayValue:
    return type() == arrayValue || type() == nullValue;
  case objectValue:
    return type() == objectValue || type() == nullValue;
  }
  JSON_ASSERT_UNREACHABLE;
  return false;
}

/// Number of values in array or object
ArrayIndex Value::size() const {
  switch (type()) {
  case nullValue:
  case intValue:
  case uintValue:
  case realValue:
  case booleanValue:
  case stringValue:
    return 0;
  case arrayValue: // size of the array is highest index + 1
    if (!value_.map_->empty()) { /*map中存在数据*/
      ObjectValues::const_iterator itLast = value_.map_->end();
      --itLast;
      return (*itLast).first.index() + 1; /*+1?? index是从0开始计数*/
    }
    return 0;
  case objectValue:
    return ArrayIndex(value_.map_->size());
  }
  JSON_ASSERT_UNREACHABLE;
  return 0; // unreachable;
}

bool Value::empty() const {
  if (isNull() || isArray() || isObject())
    return size() == 0U;
  return false;
}

/*强制类型转换操作符bool*/
Value::operator bool() const { return !isNull(); }

void Value::clear() {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue ||
                          type() == objectValue,
                      "in Json::Value::clear(): requires complex value");
  start_ = 0;
  limit_ = 0;
  switch (type()) {
  case arrayValue:
  case objectValue:
    value_.map_->clear();
    break;
  default:
    break;
  }
}

void Value::resize(ArrayIndex newSize) {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
                      "in Json::Value::resize(): requires arrayValue");
  if (type() == nullValue)
    *this = Value(arrayValue);
  ArrayIndex oldSize = size();
  if (newSize == 0)
    clear();
  else if (newSize > oldSize)
    for (ArrayIndex i = oldSize; i < newSize; ++i)
      (*this)[i]; /*下标运算符的操作*/
  else {
    for (ArrayIndex index = newSize; index < oldSize; ++index) {
      value_.map_->erase(index);
    }
    JSON_ASSERT(size() == newSize);
  }
}


/*
  []下标运算符,通过index来查找对应
  下面四个函数构成下标运算符[]的重载
*/
Value& Value::operator[](ArrayIndex index) {
  JSON_ASSERT_MESSAGE(
      type() == nullValue || type() == arrayValue,
      "in Json::Value::operator[](ArrayIndex): requires arrayValue");
  if (type() == nullValue)
    *this = Value(arrayValue);
  CZString key(index); /*使用index初始化CZString key*/
  auto it = value_.map_->lower_bound(key);  /*再从map中查找key,那么类需要实现<等比较运算符*/
  if (it != value_.map_->end() && (*it).first == key)
    return (*it).second; /*返回key对应的Value值*/

  /*没有找到则构造一个默认初始化的pair<key,value>到map中*/
  ObjectValues::value_type defaultValue(key, nullSingleton());
  it = value_.map_->insert(it, defaultValue);
  return (*it).second;
}

/*[]下标运算符重载,这个[]调用前面实现的[]运算符*/
Value& Value::operator[](int index) {
  JSON_ASSERT_MESSAGE(
      index >= 0,
      "in Json::Value::operator[](int index): index cannot be negative");
  return (*this)[ArrayIndex(index)]; /*将index强转为ArrayIndex来调用前面实现的下标运算符[]*/
}

const Value& Value::operator[](ArrayIndex index) const {
  JSON_ASSERT_MESSAGE(
      type() == nullValue || type() == arrayValue,
      "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
  if (type() == nullValue)
    return nullSingleton();
  CZString key(index);
  ObjectValues::const_iterator it = value_.map_->find(key);
  if (it == value_.map_->end())
    return nullSingleton();
  return (*it).second;
}

const Value& Value::operator[](int index) const {
  JSON_ASSERT_MESSAGE(
      index >= 0,
      "in Json::Value::operator[](int index) const: index cannot be negative");
  return (*this)[ArrayIndex(index)];
}

void Value::initBasic(ValueType type, bool allocated) {
  setType(type);
  setIsAllocated(allocated);
  comments_ = Comments{}; /*匿名对象*/
  start_ = 0;
  limit_ = 0;
}

void Value::dupPayload(const Value& other) {
  setType(other.type());
  setIsAllocated(false);
  switch (type()) {
  case nullValue:
  case intValue:
  case uintValue:
  case realValue:
  case booleanValue:
    value_ = other.value_;
    break;
  case stringValue:
    if (other.value_.string_ && other.isAllocated()) {
      unsigned len;
      char const* str;
      decodePrefixedString(other.isAllocated(), other.value_.string_, &len,
                           &str);
      value_.string_ = duplicateAndPrefixStringValue(str, len);
      setIsAllocated(true);
    } else {
      value_.string_ = other.value_.string_;
    }
    break;
  case arrayValue:
  case objectValue:
    value_.map_ = new ObjectValues(*other.value_.map_);
    break;
  default:
    JSON_ASSERT_UNREACHABLE;
  }
}

void Value::releasePayload() {
  switch (type()) {
  case nullValue:
  case intValue:
  case uintValue:
  case realValue:
  case booleanValue:
    break;
  case stringValue:
    if (isAllocated())
      releasePrefixedStringValue(value_.string_);
    break;
  case arrayValue:
  case objectValue:
    delete value_.map_; //使用new分配的空间,这里使用delete进行释放
    break;
  default:
    JSON_ASSERT_UNREACHABLE;
  }
}

void Value::dupMeta(const Value& other) {
  comments_ = other.comments_;
  start_ = other.start_;
  limit_ = other.limit_;
}

// Access an object value by name, create a null member if it does not exist.
// @pre Type of '*this' is object or null.
// @param key is null-terminated.
Value& Value::resolveReference(const char* key) {
  JSON_ASSERT_MESSAGE(
      type() == nullValue || type() == objectValue,
      "in Json::Value::resolveReference(): requires objectValue");
  if (type() == nullValue)
    *this = Value(objectValue);
  CZString actualKey(key, static_cast<unsigned>(strlen(key)),
                     CZString::noDuplication); /*policy为noDuplication,不进行空间分配*/
  auto it = value_.map_->lower_bound(actualKey);
  if (it != value_.map_->end() && (*it).first == actualKey)
    return (*it).second;

  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
  it = value_.map_->insert(it, defaultValue);
  Value& value = (*it).second;
  return value;
}

// @param key is not null-terminated.
Value& Value::resolveReference(char const* key, char const* end) {
  JSON_ASSERT_MESSAGE(
      type() == nullValue || type() == objectValue,
      "in Json::Value::resolveReference(key, end): requires objectValue");
  if (type() == nullValue)
    *this = Value(objectValue);
  CZString actualKey(key, static_cast<unsigned>(end - key),
                     CZString::duplicateOnCopy);
  auto it = value_.map_->lower_bound(actualKey);
  if (it != value_.map_->end() && (*it).first == actualKey)
    return (*it).second;

  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
  it = value_.map_->insert(it, defaultValue);
  Value& value = (*it).second;
  return value;
}

Value Value::get(ArrayIndex index, const Value& defaultValue) const {
  const Value* value = &((*this)[index]);
  return value == &nullSingleton() ? defaultValue : *value;
}

bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }

Value const* Value::find(char const* begin, char const* end) const {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
                      "in Json::Value::find(begin, end): requires "
                      "objectValue or nullValue");
  if (type() == nullValue)
    return nullptr;
  CZString actualKey(begin, static_cast<unsigned>(end - begin),
                     CZString::noDuplication);
  ObjectValues::const_iterator it = value_.map_->find(actualKey);
  if (it == value_.map_->end())
    return nullptr;
  return &(*it).second;
}

Value const* Value::find(const String& key) const {
  return find(key.data(), key.data() + key.length());
}

Value const* Value::findNull(const String& key) const {
  return findValue<Value, &Value::isNull>(key);
}
Value const* Value::findBool(const String& key) const {
  return findValue<Value, &Value::isBool>(key);
}
Value const* Value::findInt(const String& key) const {
  return findValue<Value, &Value::isInt>(key);
}
Value const* Value::findInt64(const String& key) const {
  return findValue<Value, &Value::isInt64>(key);
}
Value const* Value::findUInt(const String& key) const {
  return findValue<Value, &Value::isUInt>(key);
}
Value const* Value::findUInt64(const String& key) const {
  return findValue<Value, &Value::isUInt64>(key);
}
Value const* Value::findIntegral(const String& key) const {
  return findValue<Value, &Value::isIntegral>(key);
}
Value const* Value::findDouble(const String& key) const {
  return findValue<Value, &Value::isDouble>(key);
}
Value const* Value::findNumeric(const String& key) const {
  return findValue<Value, &Value::isNumeric>(key);
}
Value const* Value::findString(const String& key) const {
  return findValue<Value, &Value::isString>(key);
}
Value const* Value::findArray(const String& key) const {
  return findValue<Value, &Value::isArray>(key);
}
Value const* Value::findObject(const String& key) const {
  return findValue<Value, &Value::isObject>(key);
}

Value* Value::demand(char const* begin, char const* end) {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
                      "in Json::Value::demand(begin, end): requires "
                      "objectValue or nullValue");
  return &resolveReference(begin, end);
}
#ifdef JSONCPP_HAS_STRING_VIEW
const Value& Value::operator[](std::string_view key) const {
  Value const* found = find(key.data(), key.data() + key.length());
  if (!found)
    return nullSingleton();
  return *found;
}
Value& Value::operator[](std::string_view key) {
  return resolveReference(key.data(), key.data() + key.length());
}
#else

/*
  const Value& 和 Value const& 写法上是等价的表示两者都表示一个对Value类型对象的常量引用
*/
const Value& Value::operator[](const char* key) const {
  Value const* found = find(key, key + strlen(key));
  if (!found)
    return nullSingleton();
  return *found;
}

Value const& Value::operator[](const String& key) const {
  Value const* found = find(key);
  if (!found)
    return nullSingleton();
  return *found;
}

Value& Value::operator[](const char* key) {
  return resolveReference(key, key + strlen(key));
}

Value& Value::operator[](const String& key) {
  return resolveReference(key.data(), key.data() + key.length());
}
#endif

Value& Value::operator[](const StaticString& key) {
  return resolveReference(key.c_str());
}

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");
  if (type() == nullValue) {
    *this = Value(arrayValue);
  }
  return this->value_.map_->emplace(size(), std::move(value)).first->second;
}

bool Value::insert(ArrayIndex index, const Value& newValue) {
  return insert(index, Value(newValue));
}

bool Value::insert(ArrayIndex index, Value&& newValue) {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
                      "in Json::Value::insert: requires arrayValue");
  ArrayIndex length = size();
  if (index > length) { /*越界判断*/
    return false;
  }

  /*length处的数据是不是丢失了????*/
  for (ArrayIndex i = length; i > index; i--) {
    (*this)[i] = std::move((*this)[i - 1]);
  }
  (*this)[index] = std::move(newValue);
  return true;
}

Value Value::get(char const* begin, char const* end,
                 Value const& defaultValue) const {
  Value const* found = find(begin, end);
  return !found ? defaultValue : *found;
}
#ifdef JSONCPP_HAS_STRING_VIEW
Value Value::get(std::string_view key, const Value& defaultValue) const {
  return get(key.data(), key.data() + key.length(), defaultValue);
}
#else
Value Value::get(char const* key, Value const& defaultValue) const {
  return get(key, key + strlen(key), defaultValue);
}
Value Value::get(String const& key, Value const& defaultValue) const {
  return get(key.data(), key.data() + key.length(), defaultValue);
}
#endif

bool Value::removeMember(const char* begin, const char* end, Value* removed) {
  if (type() != objectValue) {
    return false;
  }
  CZString actualKey(begin, static_cast<unsigned>(end - begin),
                     CZString::noDuplication);
  auto it = value_.map_->find(actualKey);
  if (it == value_.map_->end())
    return false;
  if (removed)
    *removed = std::move(it->second);
  value_.map_->erase(it);
  return true;
}
#ifdef JSONCPP_HAS_STRING_VIEW
bool Value::removeMember(std::string_view key, Value* removed) {
  return removeMember(key.data(), key.data() + key.length(), removed);
}
#else
bool Value::removeMember(const char* key, Value* removed) {
  return removeMember(key, key + strlen(key), removed);
}
bool Value::removeMember(String const& key, Value* removed) {
  return removeMember(key.data(), key.data() + key.length(), removed);
}
#endif

#ifdef JSONCPP_HAS_STRING_VIEW
void Value::removeMember(std::string_view key) {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
                      "in Json::Value::removeMember(): requires objectValue");
  if (type() == nullValue)
    return;

  CZString actualKey(key.data(), unsigned(key.length()),
                     CZString::noDuplication);
  value_.map_->erase(actualKey);
}
#else
void Value::removeMember(const char* key) {
  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
                      "in Json::Value::removeMember(): requires objectValue");
  if (type() == nullValue)
    return;

  CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
  value_.map_->erase(actualKey);
}
void Value::removeMember(const String& key) { removeMember(key.c_str()); }
#endif

bool Value::removeIndex(ArrayIndex index, Value* removed) {
  if (type() != arrayValue) {
    return false;
  }
  CZString key(index);
  auto it = value_.map_->find(key);
  if (it == value_.map_->end()) {
    return false;
  }
  if (removed)
    *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) {
    CZString keey(i);
    (*value_.map_)[keey] = (*this)[i + 1];
  }
  // erase the last one ("leftover")
  CZString keyLast(oldSize - 1);
  auto 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;
}
#ifdef JSONCPP_HAS_STRING_VIEW
bool Value::isMember(std::string_view key) const {
  return isMember(key.data(), key.data() + key.length());
}
#else
bool Value::isMember(char const* key) const {
  return isMember(key, key + strlen(key));
}
bool Value::isMember(String const& key) const {
  return isMember(key.data(), key.data() + key.length());
}
#endif

Value::Members Value::getMemberNames() const {
  JSON_ASSERT_MESSAGE(
      type() == nullValue || type() == objectValue,
      "in Json::Value::getMemberNames(), value must be objectValue");
  if (type() == nullValue)
    return Value::Members();
  Members members;
  members.reserve(value_.map_->size());
  ObjectValues::const_iterator it = value_.map_->begin();
  ObjectValues::const_iterator itEnd = value_.map_->end();
  for (; it != itEnd; ++it) {
    members.push_back(String((*it).first.data(), (*it).first.length()));
  }
  return members;
}

/*
modf是C/C++标准库中的一个数学函数,用于分解浮点数为整数部分和小数部分,两部分的符号与原浮点数相同。
double modf(double x, double* intpart);  
float modff(float x, float* intpart);    
long double modfl(long double x, long double* intpart); 
*/

static bool IsIntegral(double d) {
  double integral_part;
  /*将浮点数d的整数部分和小数部分进行拆分后来判断小数部分是不是等于0.0*/
  return modf(d, &integral_part) == 0.0;
}

bool Value::isNull() const { return type() == nullValue; }

bool Value::isBool() const { return type() == booleanValue; }

bool Value::isInt() const {
  switch (type()) {
  case intValue:
#if defined(JSON_HAS_INT64)
    return value_.int_ >= minInt && value_.int_ <= maxInt;
#else
    return true;
#endif
  case uintValue:
    return value_.uint_ <= UInt(maxInt);
  case realValue:
    return value_.real_ >= minInt && value_.real_ <= maxInt &&
           IsIntegral(value_.real_); /*整数*/
  default:
    break;
  }
  return false;
}

bool Value::isUInt() const {
  switch (type()) {
  case intValue:
#if defined(JSON_HAS_INT64)
    return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
#else
    return value_.int_ >= 0;
#endif
  case uintValue:
#if defined(JSON_HAS_INT64)
    return value_.uint_ <= maxUInt;
#else
    return true;
#endif
  case realValue:
    return value_.real_ >= 0 && value_.real_ <= maxUInt &&
           IsIntegral(value_.real_);
  default:
    break;
  }
  return false;
}

bool Value::isInt64() const {
#if defined(JSON_HAS_INT64)
  switch (type()) {
  case intValue:
    return true;
  case uintValue:
    return value_.uint_ <= UInt64(maxInt64);
  case realValue:
    // 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.
    // 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;
  }
#endif // JSON_HAS_INT64
  return false;
}

bool Value::isUInt64() const {
#if defined(JSON_HAS_INT64)
  switch (type()) {
  case intValue:
    return value_.int_ >= 0;
  case uintValue:
    return true;
  case realValue:
    // 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_ >= 0 && value_.real_ < maxUInt64AsDouble &&
           IsIntegral(value_.real_);
  default:
    break;
  }
#endif // JSON_HAS_INT64
  return false;
}

bool Value::isIntegral() const {
  switch (type()) {
  case intValue:
  case uintValue:
    return true;
  case realValue:
#if defined(JSON_HAS_INT64)
    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
    // require the value to be strictly less than the limit.
    // 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 &&
           IsIntegral(value_.real_);
#endif // JSON_HAS_INT64
  default:
    break;
  }
  return false;
}

bool Value::isDouble() const {
  /*整数也算double*/
  return type() == intValue || type() == uintValue || type() == realValue;
}

bool Value::isNumeric() const { return isDouble(); }

bool Value::isString() const { return type() == stringValue; }

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) noexcept
    : ptr_{std::move(that.ptr_)} {}

Value::Comments& Value::Comments::operator=(const Comments& that) {
  ptr_ = cloneUnique(that.ptr_);
  return *this;
}

Value::Comments& Value::Comments::operator=(Comments&& that) noexcept {
  ptr_ = std::move(that.ptr_);
  return *this;
}

bool Value::Comments::has(CommentPlacement slot) const {
  return ptr_ && !(*ptr_)[slot].empty();
}

String Value::Comments::get(CommentPlacement slot) const {
  if (!ptr_)
    return {};
  return (*ptr_)[slot];
}

void Value::Comments::set(CommentPlacement slot, String comment) {
  if (slot >= CommentPlacement::numberOfCommentPlacement)
    return;
  if (!ptr_)
    ptr_ = std::unique_ptr<Array>(new Array());
  (*ptr_)[slot] = std::move(comment);
}

void Value::setComment(String comment, CommentPlacement placement) {
  if (!comment.empty() && (comment.back() == '\n')) {
    // Always discard trailing newline, to aid indentation.
    comment.pop_back();
  }
  JSON_ASSERT_MESSAGE(
      comment.empty() || comment[0] == '/',
      "in Json::Value::setComment(): Comments must start with /");
  comments_.set(placement, std::move(comment));
}

bool Value::hasComment(CommentPlacement placement) const {
  return comments_.has(placement);
}

String Value::getComment(CommentPlacement placement) const {
  return comments_.get(placement);
}

void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }

void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }

ptrdiff_t Value::getOffsetStart() const { return start_; }

ptrdiff_t Value::getOffsetLimit() const { return limit_; }

String Value::toStyledString() const {
  StreamWriterBuilder builder;

  String out = this->hasComment(commentBefore) ? "\n" : "";
  out += Json::writeString(builder, *this);
  out += '\n';

  return out;
}

Value::const_iterator Value::begin() const {
  switch (type()) {
  case arrayValue:
  case objectValue:
    if (value_.map_)
      return const_iterator(value_.map_->begin());
    break;
  default:
    break;
  }
  return {};
}

Value::const_iterator Value::end() const {
  switch (type()) {
  case arrayValue:
  case objectValue:
    if (value_.map_)
      return const_iterator(value_.map_->end());
    break;
  default:
    break;
  }
  return {};
}

Value::iterator Value::begin() {
  switch (type()) {
  case arrayValue:
  case objectValue:
    if (value_.map_)
      return iterator(value_.map_->begin());
    break;
  default:
    break;
  }
  return iterator();
}

Value::iterator Value::end() {
  switch (type()) {
  case arrayValue:
  case objectValue:
    if (value_.map_)
      return iterator(value_.map_->end());
    break;
  default:
    break;
  }
  return iterator();
}

// class PathArgument
// //

PathArgument::PathArgument() = default;

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) {}

// class Path
// //

Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2,
           const PathArgument& a3, const PathArgument& a4,
           const PathArgument& a5) {
  InArgs in;
  in.reserve(5);
  in.push_back(&a1);
  in.push_back(&a2);
  in.push_back(&a3);
  in.push_back(&a4);
  in.push_back(&a5);
  makePath(path, in);
}

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();
  while (current != end) {
    if (*current == '[') {
      ++current;
      if (*current == '%')
        addPathInArg(path, in, itInArg, PathArgument::kindIndex);
      else {
        ArrayIndex index = 0;
        for (; current != end && *current >= '0' && *current <= '9'; ++current)
          index = index * 10 + ArrayIndex(*current - '0');
        args_.push_back(index);
      }
      if (current == end || *++current != ']')
        invalidPath(path, int(current - path.c_str()));
    } else if (*current == '%') {
      addPathInArg(path, in, itInArg, PathArgument::kindKey);
      ++current;
    } else if (*current == '.' || *current == ']') {
      ++current;
    } else {
      const char* beginName = current;
      while (current != end && !strchr("[.", *current))
        ++current;
      args_.push_back(String(beginName, current));
    }
  }
}

void Path::addPathInArg(const String& /*path*/, const InArgs& in,
                        InArgs::const_iterator& itInArg,
                        PathArgument::Kind kind) {
  if (itInArg == in.end()) {
    // Error: missing argument %d
  } else if ((*itInArg)->kind_ != kind) {
    // Error: bad argument type
  } else {
    args_.push_back(**itInArg++);
  }
}

void Path::invalidPath(const String& /*path*/, int /*location*/) {
  // Error: invalid path.
}

const Value& Path::resolve(const Value& root) const {
  const Value* node = &root;
  for (const auto& arg : args_) {
    if (arg.kind_ == PathArgument::kindIndex) {
      if (!node->isArray() || !node->isValidIndex(arg.index_)) {
        // Error: unable to resolve path (array value expected at position... )
        return Value::nullSingleton();
      }
      node = &((*node)[arg.index_]);
    } else if (arg.kind_ == PathArgument::kindKey) {
      if (!node->isObject()) {
        // Error: unable to resolve path (object value expected at position...)
        return Value::nullSingleton();
      }
      node = &((*node)[arg.key_]);
      if (node == &Value::nullSingleton()) {
        // Error: unable to resolve path (object has no member named '' at
        // position...)
        return Value::nullSingleton();
      }
    }
  }
  return *node;
}

Value Path::resolve(const Value& root, const Value& defaultValue) const {
  const Value* node = &root;
  for (const auto& arg : args_) {
    if (arg.kind_ == PathArgument::kindIndex) {
      if (!node->isArray() || !node->isValidIndex(arg.index_))
        return defaultValue;
      node = &((*node)[arg.index_]);
    } else if (arg.kind_ == PathArgument::kindKey) {
      if (!node->isObject())
        return defaultValue;
      node = &((*node)[arg.key_]);
      if (node == &Value::nullSingleton())
        return defaultValue;
    }
  }
  return *node;
}

Value& Path::make(Value& root) const {
  Value* node = &root;
  for (const auto& arg : args_) {
    if (arg.kind_ == PathArgument::kindIndex) {
      if (!node->isArray()) {
        // Error: node is not an array at position ...
      }
      node = &((*node)[arg.index_]);
    } else if (arg.kind_ == PathArgument::kindKey) {
      if (!node->isObject()) {
        // Error: node is not an object at position...
      }
      node = &((*node)[arg.key_]);
    }
  }
  return *node;
}

} // namespace Json

 json_reader.cpp内容如下:

// Copyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors
// Copyright (C) 2016 InfoTeCS JSC. All rights reserved.
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#if !defined(JSON_IS_AMALGAMATION)
#include "json_tool.h"
#include <json/assertions.h>
#include <json/reader.h>
#include <json/value.h>
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iostream>
#include <istream>
#include <limits>
#include <memory>
#include <set>
#include <sstream>
#include <utility>

#include <cstdio>

#if defined(_MSC_VER)
#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
#endif //_MSC_VER

#if defined(_MSC_VER)
// Disable warning about strdup being deprecated.
#pragma warning(disable : 4996)
#endif

// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile
// time to change the stack limit
#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)
#define JSONCPP_DEPRECATED_STACK_LIMIT 1000
#endif

static size_t const stackLimit_g =
    JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()

namespace Json {

using CharReaderPtr = std::unique_ptr<CharReader>;

// Implementation of class Features
// 

Features::Features() = default;

Features Features::all() { return {}; }

Features Features::strictMode() {
  Features features;
  features.allowComments_ = false;
  features.strictRoot_ = true;
  features.allowDroppedNullPlaceholders_ = false;
  features.allowNumericKeys_ = false;
  return features;
}

// Implementation of class Reader
// 

/*内部使用了lambda表达式*/
bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) {
  return std::any_of(begin, end, [](char b) { return b == '\n' || b == '\r'; });
}

// Class Reader
// //

Reader::Reader() : features_(Features::all()) {}

Reader::Reader(const Features& features) : features_(features) {}

/*parse函数重载*/
bool Reader::parse(const std::string& document, Value& root,
                   bool collectComments) {
  document_.assign(document.begin(), document.end());
  const char* begin = document_.c_str();
  const char* end = begin + document_.length();
  return parse(begin, end, root, collectComments);
}

bool Reader::parse(std::istream& is, Value& root, bool collectComments) {
  // std::istream_iterator<char> begin(is);
  // std::istream_iterator<char> end;
  // Those would allow streamed input from a file, if parse() were a
  // template function.

  // Since String is reference-counted, this at least does not
  // create an extra copy.
  String doc(std::istreambuf_iterator<char>(is), {});
  return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
}

/*JSON数据解析*/
bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root,
                   bool collectComments) {
  if (!features_.allowComments_) {
    collectComments = false;
  }

  begin_ = beginDoc;
  end_ = endDoc;
  collectComments_ = collectComments;
  current_ = begin_;
  lastValueEnd_ = nullptr;
  lastValue_ = nullptr;
  commentsBefore_.clear();
  errors_.clear();
  while (!nodes_.empty()) /*nodes不为空,这将nodes中数据pop()出去*/
    nodes_.pop();
  nodes_.push(&root);     /*将root入栈*/

  /*readValue中进行递归的解析*/
  bool successful = readValue();
  Token token;
  readTokenSkippingComments(token);
  if (collectComments_ && !commentsBefore_.empty())
    root.setComment(commentsBefore_, commentAfter);
  if (features_.strictRoot_) {
    /*有效的JSON数据必须是对象或者数字值*/
    if (!root.isArray() && !root.isObject()) {
      // Set error location to start of doc, ideally should be first token found
      // in doc
      token.type_ = tokenError;
      token.start_ = beginDoc;
      token.end_ = endDoc;
      addError(
          "A valid JSON document must be either an array or an object value.",
          token);
      return false;
    }
  }
  return successful;
}

bool Reader::readValue() {
  // readValue() may call itself only if it calls readObject() or ReadArray().
  // These methods execute nodes_.push() just before and nodes_.pop)() just
  // after calling readValue(). parse() executes one nodes_.push(), so > instead
  // of >=.
  if (nodes_.size() > stackLimit_g)
    throwRuntimeError("Exceeded stackLimit in readValue().");

  Token token;
  /*读取JSON数据中的token,跳过其中的注释内容,即不获取注释内容*/
  readTokenSkippingComments(token);
  bool successful = true;

  if (collectComments_ && !commentsBefore_.empty()) {
    currentValue().setComment(commentsBefore_, commentBefore);
    commentsBefore_.clear();
  }

  /*识别出JSON token类型*/
  switch (token.type_) {
  case tokenObjectBegin: /*{*/
    successful = readObject(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenArrayBegin: /*[*/
    successful = readArray(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenNumber:    /*数值*/
    successful = decodeNumber(token);
    break;
  case tokenString:   /*字符串*/
    successful = decodeString(token);
    break;
  case tokenTrue: {   /*bool类型*/
    Value v(true); /*直接使用true初始化*/
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenFalse: {
    Value v(false); /*直接使用false初始化*/
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenNull: {
    Value v;
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenArraySeparator: /*,*/
  case tokenObjectEnd:      /*}*/
  case tokenArrayEnd:       /*]*/
    if (features_.allowDroppedNullPlaceholders_) {
      // "Un-read" the current token and mark the current value as a null
      // token.
      current_--;
      Value v;
      currentValue().swapPayload(v);
      currentValue().setOffsetStart(current_ - begin_ - 1);
      currentValue().setOffsetLimit(current_ - begin_);
      break;
    } // Else, fall through...
  default:
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    return addError("Syntax error: value, object or array expected.", token);
  }

  if (collectComments_) {
    lastValueEnd_ = current_;
    lastValue_ = &currentValue();
  }

  return successful;
}

/*读取JSON数据中的token,跳过其中的注释内容,即不获取注释内容*/
bool Reader::readTokenSkippingComments(Token& token) {
  /*JSON token读取,token内容存放在参数token中*/
  bool success = readToken(token);
  if (features_.allowComments_) {
    /*判断读到的token是否为注释内容,如果为注释内容的话继续读token直到不为注释内容*/
    while (success && token.type_ == tokenComment) {
      success = readToken(token);
    }
  }
  return success;
}

/*将JSON数据每个单元数据解析出来*/
bool Reader::readToken(Token& token) {
  /*跳过开头的空白符*/
  skipSpaces();
  token.start_ = current_;
  Char c = getNextChar(); /*获取下一个字符内容*/
  bool ok = true;
  switch (c) {
  case '{':
    token.type_ = tokenObjectBegin;
    break;
  case '}':
    token.type_ = tokenObjectEnd;
    break;
  case '[':
    token.type_ = tokenArrayBegin;
    break;
  case ']':
    token.type_ = tokenArrayEnd;
    break;
  case '"':
    token.type_ = tokenString;
    ok = readString(); /*直到遇到"符号才退出*/
    break;
  case '/':
    token.type_ = tokenComment;
    ok = readComment();
    break;
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
  case '-':
    token.type_ = tokenNumber;
    /*解析整数,小数,指数形式的数据*/
    readNumber();
    break;
  case 't':
    token.type_ = tokenTrue;
    ok = match("rue", 3);
    break;
  case 'f':
    token.type_ = tokenFalse;
    ok = match("alse", 4);
    break;
  case 'n':
    token.type_ = tokenNull;
    ok = match("ull", 3);
    break;
  case ',':
    token.type_ = tokenArraySeparator; /*分割符*/
    break;
  case ':':
    token.type_ = tokenMemberSeparator; /*age": 30,*/
    break;
  case 0:
    token.type_ = tokenEndOfStream;
    break;
  default:
    ok = false;
    break;
  }
  if (!ok)
    token.type_ = tokenError;
  token.end_ = current_;
  return ok;
}

/*跳过开头的空白符*/
void Reader::skipSpaces() {
  while (current_ != end_) {
    Char c = *current_;
    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
      ++current_;
    else
      break;
  }
}

/*匹配比较*/
bool Reader::match(const Char* pattern, int patternLength) {
  if (end_ - current_ < patternLength)
    return false;
  int index = patternLength;
  while (index--)
    if (current_[index] != pattern[index])
      return false;
  current_ += patternLength;
  return true;
}

/*读取注释内容*/
bool Reader::readComment() {
  Location commentBegin = current_ - 1; /*commentBegin指向/*/
  Char c = getNextChar();
  bool successful = false;
  if (c == '*')  // /**/风格的注释内容
    successful = readCStyleComment();
  else if (c == '/') /* //风格的注释内容 */
    successful = readCppStyleComment();
  if (!successful)
    return false;

  if (collectComments_) {
    CommentPlacement placement = commentBefore;
    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
      if (c != '*' || !containsNewLine(commentBegin, current_))
        placement = commentAfterOnSameLine;
    }
    /*记录注释部分的内容*/
    addComment(commentBegin, current_, placement);
  }
  return true;
}

/*这里体现了C++ string操作的便捷*/
String Reader::normalizeEOL(Reader::Location begin, Reader::Location end) {
  String normalized;
  normalized.reserve(static_cast<size_t>(end - begin));
  Reader::Location current = begin;
  while (current != end) {
    char c = *current++;
    if (c == '\r') {
      if (current != end && *current == '\n')
        // convert dos EOL
        ++current;
      // convert Mac EOL
      normalized += '\n';
    } else {
      normalized += c;
    }
  }
  return normalized;
}

void Reader::addComment(Location begin, Location end,
                        CommentPlacement placement) {
  assert(collectComments_);
  /*将注释内容存放到normalized string中*/
  const String& normalized = normalizeEOL(begin, end);
  if (placement == commentAfterOnSameLine) {
    assert(lastValue_ != nullptr);
    lastValue_->setComment(normalized, placement);
  } else {
    commentsBefore_ += normalized;
  }
}

// /**/风格的注释内容
bool Reader::readCStyleComment() {
  while ((current_ + 1) < end_) { /*这里判断current_+1 < end是因为最后的判断是判断的两个字符*和/ */
    Char c = getNextChar();
    if (c == '*' && *current_ == '/') //直到遇到注释的后半部分 */ 才退出
      break;
  }
  return getNextChar() == '/';
}

/* //风格的注释内容 */
bool Reader::readCppStyleComment() {
  while (current_ != end_) {
    Char c = getNextChar(); /*以回车换行作为结束判断依据*/
    if (c == '\n')
      break;
    if (c == '\r') {
      // Consume DOS EOL. It will be normalized in addComment.
      if (current_ != end_ && *current_ == '\n') /*\r\n*/
        getNextChar();
      // Break on Moc OS 9 EOL.
      break;
    }
  }
  return true;
}

/*解析整数,小数,指数形式的数据*/
void Reader::readNumber() {
  Location p = current_;
  char c = '0'; // stopgap for already consumed character
  // integral part
  /*整数部分*/
  while (c >= '0' && c <= '9')
    c = (current_ = p) < end_ ? *p++ : '\0';
  // fractional part
  /*小数部分*/
  if (c == '.') {
    c = (current_ = p) < end_ ? *p++ : '\0';
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : '\0';
  }
  // exponential part
  /*指数部分*/
  if (c == 'e' || c == 'E') {
    c = (current_ = p) < end_ ? *p++ : '\0';
    if (c == '+' || c == '-')
      c = (current_ = p) < end_ ? *p++ : '\0';
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : '\0';
  }
}

/*获取"..."中的数据*/
bool Reader::readString() {
  Char c = '\0';
  while (current_ != end_) {
    c = getNextChar();
    if (c == '\\')    /*\符号后面一般情况下后面接转义字符*/
      getNextChar();  /*没有获取字符数据,说明转义字符不处理*/
    else if (c == '"')
      break;          /*直到"才退出*/
  }
  return c == '"';
}

/*读对象数据*/
bool Reader::readObject(Token& token) {
  Token tokenName;
  String name;

  Value init(objectValue);
  currentValue().swapPayload(init);
  /*token起始位置相对于begin_的偏移量*/
  currentValue().setOffsetStart(token.start_ - begin_);

  /*读取JSON中的token 键值对集合(对象)数据,跳过注释内容*/
  while (readTokenSkippingComments(tokenName)) {
    if (tokenName.type_ == tokenObjectEnd && name.empty()) // { } 空obj
      return true;
    name.clear();

    if (tokenName.type_ == tokenString) {
      if (!decodeString(tokenName, name)) /*对string中的数据进行解码,注意:需要对其中的转义字符进行处理*/
        return recoverFromError(tokenObjectEnd);
    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
      Value numberName;
      if (!decodeNumber(tokenName, numberName)) /*解码数据*/
        return recoverFromError(tokenObjectEnd);
      name = numberName.asString();
    } else {
      break; /*退出循环*/
    }

    Token colon; /*colon 冒号 :*/
    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
      return addErrorAndRecover("Missing ':' after object member name", colon,
                                tokenObjectEnd);
    }

    /*
      Value类的下标运算符,如果[]中的数据不存在则默认初始化插入数据到map中,并返回插入的数据的引用,便于修改操作
      上面部分将json中键值对集合(对象){"key":value}中键值数据name解析出来,其作为Value的下标[name]插入到map中
      name数据其实已经保存到的map中,下面需要解析value的值并将其存入map中即可
    */
    Value& value = currentValue()[name];
    nodes_.push(&value);    /*需要设置哪个Value的内容就需要先将其放入到nodes_栈中*/
    bool ok = readValue();  /*获取其数据,递归获取JSON中的数据*/
    nodes_.pop();           /*弹出nodes_栈*/
    if (!ok) // error already set
      return recoverFromError(tokenObjectEnd);

    Token comma; /*comma 逗号 ,*/
    if (!readTokenSkippingComments(comma) ||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) {
      return addErrorAndRecover("Missing ',' or '}' in object declaration",
                                comma, tokenObjectEnd);
    }
    if (comma.type_ == tokenObjectEnd)
      return true;
  }
  return addErrorAndRecover("Missing '}' or object member name", tokenName,
                            tokenObjectEnd);
}

/*读数组数据*/
bool Reader::readArray(Token& token) {
  Value init(arrayValue);  /*变量init初始化*/
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(token.start_ - begin_);
  skipSpaces();
  if (current_ != end_ && *current_ == ']') // empty array
  {
    Token endArray;
    readToken(endArray);
    return true;
  }
  int index = 0;
  for (;;) {
    Value& value = currentValue()[index++]; /*Value类的下标运算符[]*/
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenArrayEnd);

    Token currentToken;
    // Accept Comment after last item in the array.
    ok = readTokenSkippingComments(currentToken);
    bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
                         currentToken.type_ != tokenArrayEnd);
    if (!ok || badTokenType) {
      return addErrorAndRecover("Missing ',' or ']' in array declaration",
                                currentToken, tokenArrayEnd);
    }
    if (currentToken.type_ == tokenArrayEnd)
      break;
  }
  return true;
}

bool Reader::decodeNumber(Token& token) {
  Value decoded;
  if (!decodeNumber(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_); /*Value开始相对于JSON数据开始位置的偏移*/
  currentValue().setOffsetLimit(token.end_ - begin_);   /*Value结束相对于JSON数据结束位置的偏移*/
  return true;
}

bool Reader::decodeNumber(Token& token, Value& decoded) {
  // Attempts to parse the number as an integer. If the number is
  // larger than the maximum supported value of an integer then
  // we decode the number as a double.
  /*尝试将解析数据为整数,如果数据比整数的最大值还大则解码为浮点数,此时存在精度的丢失但是总比溢出好*/
  Location current = token.start_;
  bool isNegative = *current == '-';
  if (isNegative)
    ++current;
  // TODO: Help the compiler do the div and mod at compile time or get rid of
  // them.
  Value::LargestUInt maxIntegerValue =
      isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 /*有符号数的最大值*/
                 : Value::maxLargestUInt; /*无符号数的最大值*/
  /*设置一个门限值,超过门限值*/
  Value::LargestUInt threshold = maxIntegerValue / 10; /*丢弃个数上的数值*/
  Value::LargestUInt value = 0;
  while (current < token.end_) {
    Char c = *current++;
    /*JSON整数或浮点数,不支持八进制或十六进制前缀(如 0x)*/
    if (c < '0' || c > '9') /*视为浮点数处理*/
      return decodeDouble(token, decoded);
    auto digit(static_cast<Value::UInt>(c - '0')); /*这是一个变量的定义,C++ 非常让人无解的地方*/
    if (value >= threshold) { /*累积的value超过门限值*/
      // 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
      // c) it's small enough to fit in that rounding delta, we're okay.
      // Otherwise treat this number as a double to avoid overflow.
      if (value > threshold || current != token.end_ ||
          digit > maxIntegerValue % 10 /*digit比最大值个位上数据还大,必然溢出*/) {
        return decodeDouble(token, decoded); /*视为浮点数处理,会丢失精度*/
      }
    }
    value = value * 10 + digit;
  }
  if (isNegative && value == maxIntegerValue)
    decoded = Value::minLargestInt;
  else if (isNegative)
    decoded = -Value::LargestInt(value);
  else if (value <= Value::LargestUInt(Value::maxInt))
    decoded = Value::LargestInt(value);
  else
    decoded = value;
  return true;
}

bool Reader::decodeDouble(Token& token) {
  Value decoded;
  if (!decodeDouble(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool Reader::decodeDouble(Token& token, Value& decoded) {
  double value = 0;

  IStringStream is(String(token.start_, token.end_));
  if (!(is >> value)) { /*double时出错*/
    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)) /*std::isinf 是 C++ 标准库 <cmath> 中提供的函数,用于检测一个浮点数是否为无穷大(Infinity)​。*/
      return addError(
          "'" + String(token.start_, token.end_) + "' is not a number.", token);
  }
  decoded = value; /*隐式类型转换*/
  return true;
}

bool Reader::decodeString(Token& token) {
  String decoded_string;
  if (!decodeString(token, decoded_string))
    return false;
  Value decoded(decoded_string);
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

/*注意:需要对其中的转义字符进行处理*/
bool Reader::decodeString(Token& token, String& decoded) {
  /*-2,"..."去除开始和结束的两个"符号*/
  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
  Location current = token.start_ + 1; // skip '"'
  Location end = token.end_ - 1;       // do not include '"'
  while (current != end) {
    Char c = *current++;
    if (c == '"')
      break;
    if (c == '\\') { /*转义字符的处理*/
      if (current == end)
        return addError("Empty escape sequence in string", token, current);
      Char escape = *current++;
      switch (escape) { /*解析字符串中的转义字符*/
      case '"': // \"
        decoded += '"';
        break;
      case '/': // \/
        decoded += '/';
        break;
      case '\\': // \\
        decoded += '\\';
        break;
      case 'b': 
        decoded += '\b';
        break;
      case 'f':
        decoded += '\f';
        break;
      case 'n':
        decoded += '\n';
        break;
      case 'r':
        decoded += '\r';
        break;
      case 't':
        decoded += '\t';
        break;
/*
在JSON(JavaScript Object Notation)中,\u是一种转义序列,用于表示​Unicode字符。
它的作用是将Unicode码点(以十六进制表示)转换为对应的字符,
确保JSON数据可以包含各种语言的字符(如中文、表情符号等),同时保持纯文本格式的兼容性。
*/
      case 'u': {  // \u:unicode编码
        unsigned int unicode;
        /*解码JSON中的unicode码*/
        if (!decodeUnicodeCodePoint(token, current, end, unicode))
          return false;
        decoded += codePointToUTF8(unicode); /*unicode码点转换为UTF-8*/
      } break;
      default:
        return addError("Bad escape sequence in string", token, current);
      }
    } else {
      decoded += c;
    }
  }
  return true;
}

/*解码JSON中的unicode码*/
bool Reader::decodeUnicodeCodePoint(Token& token, Location& current,
                                    Location end, unsigned int& unicode) {
  if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) /*解码4位16进制 unicode码*/
    return false;
  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
    // surrogate pairs  代理对
    if (end - current < 6)
      return addError(
          "additional six characters expected to parse unicode surrogate pair.",
          token, current);
    if (*(current++) == '\\' && *(current++) == 'u') {
      unsigned int surrogatePair;
      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
      } else
        return false;
    } else
      return addError("expecting another \\u token to begin the second half of "
                      "a unicode surrogate pair",
                      token, current);
  }
  return true;
}

/*解码16进制 unicode码*/
bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current,
                                         Location end,
                                         unsigned int& ret_unicode) {
  if (end - current < 4) /*非4位16进制则报错*/
    return addError(
        "Bad unicode escape sequence in string: four digits expected.", token,
        current);
  int unicode = 0;
  for (int index = 0; index < 4; ++index) {
    Char c = *current++;
    unicode *= 16;
    if (c >= '0' && c <= '9')
      unicode += c - '0';
    else if (c >= 'a' && c <= 'f')
      unicode += c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
      unicode += c - 'A' + 10;
    else
      return addError(
          "Bad unicode escape sequence in string: hexadecimal digit expected.",
          token, current);
  }
  ret_unicode = static_cast<unsigned int>(unicode);
  return true;
}

bool Reader::addError(const String& message, Token& token, Location extra) {
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = extra;
  errors_.push_back(info);
  return false;
}

bool Reader::recoverFromError(TokenType skipUntilToken) {
  size_t const errorCount = errors_.size();
  Token skip;
  for (;;) {
    if (!readToken(skip))
      errors_.resize(errorCount); // discard errors caused by recovery
    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
      break;
  }
  errors_.resize(errorCount);
  return false;
}

bool Reader::addErrorAndRecover(const String& message, Token& token,
                                TokenType skipUntilToken) {
  addError(message, token);
  return recoverFromError(skipUntilToken);
}

Value& Reader::currentValue() { return *(nodes_.top()); }

Reader::Char Reader::getNextChar() {
  if (current_ == end_)
    return 0;
  return *current_++;
}

void Reader::getLocationLineAndColumn(Location location, int& line,
                                      int& column) const {
  Location current = begin_;
  Location lastLineStart = current;
  line = 0;
  while (current < location && current != end_) {
    Char c = *current++;
    if (c == '\r') {
      if (current != end_ && *current == '\n')
        ++current;
      lastLineStart = current;
      ++line;
    } else if (c == '\n') {
      lastLineStart = current;
      ++line;
    }
  }
  // column & line start at 1
  column = int(location - lastLineStart) + 1;
  ++line;
}

String Reader::getLocationLineAndColumn(Location location) const {
  int line, column;
  getLocationLineAndColumn(location, line, column);
  char buffer[18 + 16 + 16 + 1];
  jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
  return buffer;
}

// Deprecated. Preserved for backward compatibility
String Reader::getFormatedErrorMessages() const {
  return getFormattedErrorMessages();
}

String Reader::getFormattedErrorMessages() const {
  String formattedMessage;
  for (const auto& error : errors_) {
    formattedMessage +=
        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
    formattedMessage += "  " + error.message_ + "\n";
    if (error.extra_)
      formattedMessage +=
          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
  }
  return formattedMessage;
}

std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
  std::vector<Reader::StructuredError> allErrors;
  for (const auto& error : errors_) {
    Reader::StructuredError structured;
    structured.offset_start = error.token_.start_ - begin_;
    structured.offset_limit = error.token_.end_ - begin_;
    structured.message = error.message_;
    allErrors.push_back(structured);
  }
  return allErrors;
}

bool Reader::pushError(const Value& value, const String& message) {
  ptrdiff_t const length = end_ - begin_;
  if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
    return false;
  Token token;
  token.type_ = tokenError;
  token.start_ = begin_ + value.getOffsetStart();
  token.end_ = begin_ + value.getOffsetLimit();
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = nullptr;
  errors_.push_back(info);
  return true;
}

bool Reader::pushError(const Value& value, const String& message,
                       const Value& extra) {
  ptrdiff_t const length = end_ - begin_;
  if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
      extra.getOffsetLimit() > length)
    return false;
  Token token;
  token.type_ = tokenError;
  token.start_ = begin_ + value.getOffsetStart();
  token.end_ = begin_ + value.getOffsetLimit();
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = begin_ + extra.getOffsetStart();
  errors_.push_back(info);
  return true;
}

bool Reader::good() const { return errors_.empty(); }

// Originally copied from the Features class (now deprecated), used internally
// for features implementation.
class OurFeatures {
public:
  static OurFeatures all();
  bool allowComments_;
  bool allowTrailingCommas_;
  bool strictRoot_;
  bool allowDroppedNullPlaceholders_;
  bool allowNumericKeys_;
  bool allowSingleQuotes_;
  bool failIfExtra_;
  bool rejectDupKeys_;
  bool allowSpecialFloats_;
  bool skipBom_;
  size_t stackLimit_;
}; // OurFeatures

OurFeatures OurFeatures::all() { return {}; }

// Implementation of class Reader
// 

// Originally copied from the Reader class (now deprecated), used internally
// for implementing JSON reading.
/*最初是从Reader类(现已弃用)复制的,目前仅用于内部实现JSON读取功能。*/
class OurReader {
public:
  using Char = char;
  using Location = const Char*;

  explicit OurReader(OurFeatures const& features);
  bool parse(const char* beginDoc, const char* endDoc, Value& root,
             bool collectComments = true);
  String getFormattedErrorMessages() const;
  std::vector<CharReader::StructuredError> getStructuredErrors() const;

private:
  OurReader(OurReader const&);      // no impl
  void operator=(OurReader const&); // no impl

  enum TokenType {
    tokenEndOfStream = 0,
    tokenObjectBegin,
    tokenObjectEnd,
    tokenArrayBegin,
    tokenArrayEnd,
    tokenString,
    tokenNumber,
    tokenTrue,
    tokenFalse,
    tokenNull,
    tokenNaN,
    tokenPosInf,
    tokenNegInf,
    tokenArraySeparator,
    tokenMemberSeparator,
    tokenComment,
    tokenError
  };

  class Token {
  public:
    TokenType type_;
    Location start_;
    Location end_;
  };

  class ErrorInfo {
  public:
    Token token_;
    String message_;
    Location extra_;
  };

  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);
  bool readComment();
  bool readCStyleComment(bool* containsNewLineResult);
  bool readCppStyleComment();
  bool readString();
  bool readStringSingleQuote();
  bool readNumber(bool checkInf);
  bool readValue();
  bool readObject(Token& token);
  bool readArray(Token& token);
  bool decodeNumber(Token& token);
  bool decodeNumber(Token& token, Value& decoded);
  bool decodeString(Token& token);
  bool decodeString(Token& token, String& decoded);
  bool decodeDouble(Token& token);
  bool decodeDouble(Token& token, Value& decoded);
  bool decodeUnicodeCodePoint(Token& token, Location& current, Location end,
                              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 recoverFromError(TokenType skipUntilToken);
  bool addErrorAndRecover(const String& message, Token& token,
                          TokenType skipUntilToken);
  void skipUntilSpace();
  Value& currentValue();
  Char getNextChar();
  void getLocationLineAndColumn(Location location, int& line,
                                int& column) const;
  String getLocationLineAndColumn(Location location) const;
  void addComment(Location begin, Location end, CommentPlacement placement);

  static String normalizeEOL(Location begin, Location end);
  static bool containsNewLine(Location begin, Location end);

  using Nodes = std::stack<Value*>;

  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_{};

  OurFeatures const features_;
  bool collectComments_ = false;
}; // OurReader

// complete copy of Read impl, for OurReader

bool OurReader::containsNewLine(OurReader::Location begin,
                                OurReader::Location end) {
  return std::any_of(begin, end, [](char b) { return b == '\n' || b == '\r'; });
}

OurReader::OurReader(OurFeatures const& features) : features_(features) {}

bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root,
                      bool collectComments) {
  if (!features_.allowComments_) {
    collectComments = false;
  }

  begin_ = beginDoc;
  end_ = endDoc;
  collectComments_ = collectComments;
  current_ = begin_;
  lastValueEnd_ = nullptr;
  lastValue_ = nullptr;
  commentsBefore_.clear();
  errors_.clear();
  while (!nodes_.empty())
    nodes_.pop();
  nodes_.push(&root);

  // skip byte order mark if it exists at the beginning of the UTF-8 text.
  skipBom(features_.skipBom_);
  bool successful = readValue();
  nodes_.pop();
  Token token;
  readTokenSkippingComments(token);
  if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) {
    addError("Extra non-whitespace after JSON value.", token);
    return false;
  }
  if (collectComments_ && !commentsBefore_.empty())
    root.setComment(commentsBefore_, commentAfter);
  if (features_.strictRoot_) {
    if (!root.isArray() && !root.isObject()) {
      // Set error location to start of doc, ideally should be first token found
      // in doc
      token.type_ = tokenError;
      token.start_ = beginDoc;
      token.end_ = endDoc;
      addError(
          "A valid JSON document must be either an array or an object value.",
          token);
      return false;
    }
  }
  return successful;
}

bool OurReader::readValue() {
  //  To preserve the old behaviour we cast size_t to int.
  if (nodes_.size() > features_.stackLimit_)
    throwRuntimeError("Exceeded stackLimit in readValue().");
  Token token;
  readTokenSkippingComments(token);
  bool successful = true;

  if (collectComments_ && !commentsBefore_.empty()) {
    currentValue().setComment(commentsBefore_, commentBefore);
    commentsBefore_.clear();
  }

  switch (token.type_) {
  case tokenObjectBegin:
    successful = readObject(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenArrayBegin:
    successful = readArray(token);
    currentValue().setOffsetLimit(current_ - begin_);
    break;
  case tokenNumber:
    successful = decodeNumber(token);
    break;
  case tokenString:
    successful = decodeString(token);
    break;
  case tokenTrue: {
    Value v(true);
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenFalse: {
    Value v(false);
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenNull: {
    Value v;
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenNaN: {
    Value v(std::numeric_limits<double>::quiet_NaN());
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenPosInf: {
    Value v(std::numeric_limits<double>::infinity());
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenNegInf: {
    Value v(-std::numeric_limits<double>::infinity());
    currentValue().swapPayload(v);
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
  } break;
  case tokenArraySeparator:
  case tokenObjectEnd:
  case tokenArrayEnd:
    if (features_.allowDroppedNullPlaceholders_) {
      // "Un-read" the current token and mark the current value as a null
      // token.
      current_--;
      Value v;
      currentValue().swapPayload(v);
      currentValue().setOffsetStart(current_ - begin_ - 1);
      currentValue().setOffsetLimit(current_ - begin_);
      break;
    } // else, fall through ...
  default:
    currentValue().setOffsetStart(token.start_ - begin_);
    currentValue().setOffsetLimit(token.end_ - begin_);
    return addError("Syntax error: value, object or array expected.", token);
  }

  if (collectComments_) {
    lastValueEnd_ = current_;
    lastValueHasAComment_ = false;
    lastValue_ = &currentValue();
  }

  return successful;
}

bool OurReader::readTokenSkippingComments(Token& token) {
  bool success = readToken(token);
  if (features_.allowComments_) {
    while (success && token.type_ == tokenComment) {
      success = readToken(token);
    }
  }
  return success;
}

bool OurReader::readToken(Token& token) {
  skipSpaces();
  token.start_ = current_;
  Char c = getNextChar();
  bool ok = true;
  switch (c) {
  case '{':
    token.type_ = tokenObjectBegin;
    break;
  case '}':
    token.type_ = tokenObjectEnd;
    break;
  case '[':
    token.type_ = tokenArrayBegin;
    break;
  case ']':
    token.type_ = tokenArrayEnd;
    break;
  case '"':
    token.type_ = tokenString;
    ok = readString();
    break;
  case '\'':
    if (features_.allowSingleQuotes_) {
      token.type_ = tokenString;
      ok = readStringSingleQuote();
    } else {
      // If we don't allow single quotes, this is a failure case.
      ok = false;
    }
    break;
  case '/':
    token.type_ = tokenComment;
    ok = readComment();
    break;
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    token.type_ = tokenNumber;
    readNumber(false);
    break;
  case '-':
    if (readNumber(true)) {
      token.type_ = tokenNumber;
    } else {
      token.type_ = tokenNegInf;
      ok = features_.allowSpecialFloats_ && match("nfinity", 7);
    }
    break;
  case '+':
    if (readNumber(true)) {
      token.type_ = tokenNumber;
    } else {
      token.type_ = tokenPosInf;
      ok = features_.allowSpecialFloats_ && match("nfinity", 7);
    }
    break;
  case 't':
    token.type_ = tokenTrue;
    ok = match("rue", 3);
    break;
  case 'f':
    token.type_ = tokenFalse;
    ok = match("alse", 4);
    break;
  case 'n':
    token.type_ = tokenNull;
    ok = match("ull", 3);
    break;
  case 'N':
    if (features_.allowSpecialFloats_) {
      token.type_ = tokenNaN;
      ok = match("aN", 2);
    } else {
      ok = false;
    }
    break;
  case 'I':
    if (features_.allowSpecialFloats_) {
      token.type_ = tokenPosInf;
      ok = match("nfinity", 7);
    } else {
      ok = false;
    }
    break;
  case ',':
    token.type_ = tokenArraySeparator;
    break;
  case ':':
    token.type_ = tokenMemberSeparator;
    break;
  case 0:
    token.type_ = tokenEndOfStream;
    break;
  default:
    ok = false;
    break;
  }
  if (!ok)
    token.type_ = tokenError;
  token.end_ = current_;
  return ok;
}

void OurReader::skipSpaces() {
  while (current_ != end_) {
    Char c = *current_;
    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
      ++current_;
    else
      break;
  }
}

void OurReader::skipBom(bool skipBom) {
  // The default behavior is to skip BOM.
  if (skipBom) {
    if ((end_ - begin_) >= 3 && strncmp(begin_, "\xEF\xBB\xBF", 3) == 0) {
      begin_ += 3;
      current_ = begin_;
    }
  }
}

bool OurReader::match(const Char* pattern, int patternLength) {
  if (end_ - current_ < patternLength)
    return false;
  int index = patternLength;
  while (index--)
    if (current_[index] != pattern[index])
      return false;
  current_ += patternLength;
  return true;
}

bool OurReader::readComment() {
  const Location commentBegin = current_ - 1;
  const Char c = getNextChar();
  bool successful = false;
  bool cStyleWithEmbeddedNewline = false;

  const bool isCStyleComment = (c == '*');
  const bool isCppStyleComment = (c == '/');
  if (isCStyleComment) {
    successful = readCStyleComment(&cStyleWithEmbeddedNewline);
  } else if (isCppStyleComment) {
    successful = readCppStyleComment();
  }

  if (!successful)
    return false;

  if (collectComments_) {
    CommentPlacement placement = commentBefore;

    if (!lastValueHasAComment_) {
      if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
        if (isCppStyleComment || !cStyleWithEmbeddedNewline) {
          placement = commentAfterOnSameLine;
          lastValueHasAComment_ = true;
        }
      }
    }

    addComment(commentBegin, current_, placement);
  }
  return true;
}

String OurReader::normalizeEOL(OurReader::Location begin,
                               OurReader::Location end) {
  String normalized;
  normalized.reserve(static_cast<size_t>(end - begin));
  OurReader::Location current = begin;
  while (current != end) {
    char c = *current++;
    if (c == '\r') {
      if (current != end && *current == '\n')
        // convert dos EOL
        ++current;
      // convert Mac EOL
      normalized += '\n';
    } else {
      normalized += c;
    }
  }
  return normalized;
}

void OurReader::addComment(Location begin, Location end,
                           CommentPlacement placement) {
  assert(collectComments_);
  const String& normalized = normalizeEOL(begin, end);
  if (placement == commentAfterOnSameLine) {
    assert(lastValue_ != nullptr);
    lastValue_->setComment(normalized, placement);
  } else {
    commentsBefore_ += normalized;
  }
}

bool OurReader::readCStyleComment(bool* containsNewLineResult) {
  *containsNewLineResult = false;

  while ((current_ + 1) < end_) {
    Char c = getNextChar();
    if (c == '*' && *current_ == '/')
      break;
    if (c == '\n')
      *containsNewLineResult = true;
  }

  return getNextChar() == '/';
}

bool OurReader::readCppStyleComment() {
  while (current_ != end_) {
    Char c = getNextChar();
    if (c == '\n')
      break;
    if (c == '\r') {
      // Consume DOS EOL. It will be normalized in addComment.
      if (current_ != end_ && *current_ == '\n')
        getNextChar();
      // Break on Moc OS 9 EOL.
      break;
    }
  }
  return true;
}

bool OurReader::readNumber(bool checkInf) {
  Location p = current_;
  if (checkInf && p != end_ && *p == 'I') {
    current_ = ++p;
    return false;
  }
  char c = '0'; // stopgap for already consumed character
  // integral part
  while (c >= '0' && c <= '9')
    c = (current_ = p) < end_ ? *p++ : '\0';
  // fractional part
  if (c == '.') {
    c = (current_ = p) < end_ ? *p++ : '\0';
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : '\0';
  }
  // exponential part
  if (c == 'e' || c == 'E') {
    c = (current_ = p) < end_ ? *p++ : '\0';
    if (c == '+' || c == '-')
      c = (current_ = p) < end_ ? *p++ : '\0';
    while (c >= '0' && c <= '9')
      c = (current_ = p) < end_ ? *p++ : '\0';
  }
  return true;
}
bool OurReader::readString() {
  Char c = 0;
  while (current_ != end_) {
    c = getNextChar();
    if (c == '\\')
      getNextChar();
    else if (c == '"')
      break;
  }
  return c == '"';
}

bool OurReader::readStringSingleQuote() {
  Char c = 0;
  while (current_ != end_) {
    c = getNextChar();
    if (c == '\\')
      getNextChar();
    else if (c == '\'')
      break;
  }
  return c == '\'';
}

bool OurReader::readObject(Token& token) {
  Token tokenName;
  String name;
  Value init(objectValue);
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(token.start_ - begin_);
  while (readTokenSkippingComments(tokenName)) {
    if (tokenName.type_ == tokenObjectEnd &&
        (name.empty() ||
         features_.allowTrailingCommas_)) // empty object or trailing comma
      return true;
    name.clear();
    if (tokenName.type_ == tokenString) {
      if (!decodeString(tokenName, name))
        return recoverFromError(tokenObjectEnd);
    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
      Value numberName;
      if (!decodeNumber(tokenName, numberName))
        return recoverFromError(tokenObjectEnd);
      name = numberName.asString();
    } else {
      break;
    }
    if (name.length() >= (1U << 30))
      throwRuntimeError("keylength >= 2^30");
    if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
      String msg = "Duplicate key: '" + name + "'";
      return addErrorAndRecover(msg, tokenName, tokenObjectEnd);
    }

    Token colon;
    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
      return addErrorAndRecover("Missing ':' after object member name", colon,
                                tokenObjectEnd);
    }
    Value& value = currentValue()[name];
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenObjectEnd);

    Token comma;
    if (!readTokenSkippingComments(comma) ||
        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) {
      return addErrorAndRecover("Missing ',' or '}' in object declaration",
                                comma, tokenObjectEnd);
    }
    if (comma.type_ == tokenObjectEnd)
      return true;
  }
  return addErrorAndRecover("Missing '}' or object member name", tokenName,
                            tokenObjectEnd);
}

bool OurReader::readArray(Token& token) {
  Value init(arrayValue);
  currentValue().swapPayload(init);
  currentValue().setOffsetStart(token.start_ - begin_);
  int index = 0;
  for (;;) {
    skipSpaces();
    if (current_ != end_ && *current_ == ']' &&
        (index == 0 ||
         (features_.allowTrailingCommas_ &&
          !features_.allowDroppedNullPlaceholders_))) // empty array or trailing
                                                      // comma
    {
      Token endArray;
      readToken(endArray);
      return true;
    }
    Value& value = currentValue()[index++];
    nodes_.push(&value);
    bool ok = readValue();
    nodes_.pop();
    if (!ok) // error already set
      return recoverFromError(tokenArrayEnd);

    Token currentToken;
    // Accept Comment after last item in the array.
    ok = readTokenSkippingComments(currentToken);
    bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
                         currentToken.type_ != tokenArrayEnd);
    if (!ok || badTokenType) {
      return addErrorAndRecover("Missing ',' or ']' in array declaration",
                                currentToken, tokenArrayEnd);
    }
    if (currentToken.type_ == tokenArrayEnd)
      break;
  }
  return true;
}

bool OurReader::decodeNumber(Token& token) {
  Value decoded;
  if (!decodeNumber(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool OurReader::decodeNumber(Token& token, Value& decoded) {
  // Attempts to parse the number as an integer. If the number is
  // larger than the maximum supported value of an integer then
  // we decode the number as a double.
  Location current = token.start_;
  const bool isNegative = *current == '-';
  if (isNegative) {
    ++current;
  }

  // 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");

  // 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");

  static constexpr Value::LargestUInt positive_threshold =
      Value::maxLargestUInt / 10;
  static constexpr 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 =
      Value::LargestUInt(-(Value::minLargestInt / 10));
  static constexpr auto negative_last_digit =
      Value::UInt(-(Value::minLargestInt % 10));

  const Value::LargestUInt threshold =
      isNegative ? negative_threshold : positive_threshold;
  const Value::UInt max_last_digit =
      isNegative ? negative_last_digit : positive_last_digit;

  Value::LargestUInt value = 0;
  while (current < token.end_) {
    Char c = *current++;
    if (c < '0' || c > '9')
      return decodeDouble(token, 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, 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.
      if (value > threshold || current != token.end_ ||
          digit > max_last_digit) {
        return decodeDouble(token, decoded);
      }
    }
    value = value * 10 + digit;
  }

  if (isNegative) {
    // We use the same magnitude assumption here, just in case.
    const auto last_digit = static_cast<Value::UInt>(value % 10);
    decoded = -Value::LargestInt(value / 10) * 10 - last_digit;
  } else if (value <= Value::LargestUInt(Value::maxLargestInt)) {
    decoded = Value::LargestInt(value);
  } else {
    decoded = value;
  }

  return true;
}

bool OurReader::decodeDouble(Token& token) {
  Value decoded;
  if (!decodeDouble(token, decoded))
    return false;
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool OurReader::decodeDouble(Token& token, Value& decoded) {
  double value = 0;
  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;
}

bool OurReader::decodeString(Token& token) {
  String decoded_string;
  if (!decodeString(token, decoded_string))
    return false;
  Value decoded(decoded_string);
  currentValue().swapPayload(decoded);
  currentValue().setOffsetStart(token.start_ - begin_);
  currentValue().setOffsetLimit(token.end_ - begin_);
  return true;
}

bool OurReader::decodeString(Token& token, String& decoded) {
  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
  Location current = token.start_ + 1; // skip '"'
  Location end = token.end_ - 1;       // do not include '"'
  while (current != end) {
    Char c = *current++;
    if (c == '"')
      break;
    if (c == '\\') {
      if (current == end)
        return addError("Empty escape sequence in string", token, current);
      Char escape = *current++;
      switch (escape) {
      case '"':
        decoded += '"';
        break;
      case '/':
        decoded += '/';
        break;
      case '\\':
        decoded += '\\';
        break;
      case 'b':
        decoded += '\b';
        break;
      case 'f':
        decoded += '\f';
        break;
      case 'n':
        decoded += '\n';
        break;
      case 'r':
        decoded += '\r';
        break;
      case 't':
        decoded += '\t';
        break;
      case 'u': {
        unsigned int unicode;
        if (!decodeUnicodeCodePoint(token, current, end, unicode))
          return false;
        decoded += codePointToUTF8(unicode);
      } break;
      default:
        return addError("Bad escape sequence in string", token, current);
      }
    } else {
      decoded += c;
    }
  }
  return true;
}

bool OurReader::decodeUnicodeCodePoint(Token& token, Location& current,
                                       Location end, unsigned int& unicode) {

  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
    return false;
  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
    // surrogate pairs
    if (end - current < 6)
      return addError(
          "additional six characters expected to parse unicode surrogate pair.",
          token, current);
    if (*(current++) == '\\' && *(current++) == 'u') {
      unsigned int surrogatePair;
      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
      } else
        return false;
    } else
      return addError("expecting another \\u token to begin the second half of "
                      "a unicode surrogate pair",
                      token, current);
  }
  return true;
}

bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current,
                                            Location end,
                                            unsigned int& ret_unicode) {
  if (end - current < 4)
    return addError(
        "Bad unicode escape sequence in string: four digits expected.", token,
        current);
  int unicode = 0;
  for (int index = 0; index < 4; ++index) {
    Char c = *current++;
    unicode *= 16;
    if (c >= '0' && c <= '9')
      unicode += c - '0';
    else if (c >= 'a' && c <= 'f')
      unicode += c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
      unicode += c - 'A' + 10;
    else
      return addError(
          "Bad unicode escape sequence in string: hexadecimal digit expected.",
          token, current);
  }
  ret_unicode = static_cast<unsigned int>(unicode);
  return true;
}

bool OurReader::addError(const String& message, Token& token, Location extra) {
  ErrorInfo info;
  info.token_ = token;
  info.message_ = message;
  info.extra_ = extra;
  errors_.push_back(info);
  return false;
}

bool OurReader::recoverFromError(TokenType skipUntilToken) {
  size_t errorCount = errors_.size();
  Token skip;
  for (;;) {
    if (!readToken(skip))
      errors_.resize(errorCount); // discard errors caused by recovery
    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
      break;
  }
  errors_.resize(errorCount);
  return false;
}

bool OurReader::addErrorAndRecover(const String& message, Token& token,
                                   TokenType skipUntilToken) {
  addError(message, token);
  return recoverFromError(skipUntilToken);
}

Value& OurReader::currentValue() { return *(nodes_.top()); }

OurReader::Char OurReader::getNextChar() {
  if (current_ == end_)
    return 0;
  return *current_++;
}

void OurReader::getLocationLineAndColumn(Location location, int& line,
                                         int& column) const {
  Location current = begin_;
  Location lastLineStart = current;
  line = 0;
  while (current < location && current != end_) {
    Char c = *current++;
    if (c == '\r') {
      if (current != end_ && *current == '\n')
        ++current;
      lastLineStart = current;
      ++line;
    } else if (c == '\n') {
      lastLineStart = current;
      ++line;
    }
  }
  // column & line start at 1
  column = int(location - lastLineStart) + 1;
  ++line;
}

String OurReader::getLocationLineAndColumn(Location location) const {
  int line, column;
  getLocationLineAndColumn(location, line, column);
  char buffer[18 + 16 + 16 + 1];
  jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
  return buffer;
}

String OurReader::getFormattedErrorMessages() const {
  String formattedMessage;
  for (const auto& error : errors_) {
    formattedMessage +=
        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
    formattedMessage += "  " + error.message_ + "\n";
    if (error.extra_)
      formattedMessage +=
          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
  }
  return formattedMessage;
}

std::vector<CharReader::StructuredError>
OurReader::getStructuredErrors() const {
  std::vector<CharReader::StructuredError> allErrors;
  for (const auto& error : errors_) {
    CharReader::StructuredError structured;
    structured.offset_start = error.token_.start_ - begin_;
    structured.offset_limit = error.token_.end_ - begin_;
    structured.message = error.message_;
    allErrors.push_back(structured);
  }
  return allErrors;
}

/*OurCharReader公开继承CharReader*/
class OurCharReader : public CharReader {

public:
  OurCharReader(bool collectComments, OurFeatures const& features)
      : CharReader( /*使用派生类OurImpl*/
            std::unique_ptr<OurImpl>(new OurImpl(collectComments, features))) {}

protected:
  /*OurImpl类公开继承于Impl类*/
  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 {
      /*内部调用OurReader的parse*/
      bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
      if (errs) {
        *errs = reader_.getFormattedErrorMessages();
      }
      return ok;
    }

    std::vector<CharReader::StructuredError>
    getStructuredErrors() const override {
      return reader_.getStructuredErrors();
    }

  private:
    bool const collectComments_;
    /*OurReader拷贝自Reader,其是实现JSON解析的关键*/
    OurReader reader_;
  };
};

CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }
CharReaderBuilder::~CharReaderBuilder() = default;

/*返回的是CharReader类型的地址*/
CharReader* CharReaderBuilder::newCharReader() const {
  /*通过settings_来对features进行赋值*/
  bool collectComments = settings_["collectComments"].asBool();
  OurFeatures features = OurFeatures::all();
  features.allowComments_ = settings_["allowComments"].asBool();
  features.allowTrailingCommas_ = settings_["allowTrailingCommas"].asBool();
  features.strictRoot_ = settings_["strictRoot"].asBool();
  features.allowDroppedNullPlaceholders_ =
      settings_["allowDroppedNullPlaceholders"].asBool();
  features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
  features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();

  // Stack limit is always a size_t, so we get this as an unsigned int
  // regardless of it we have 64-bit integer support enabled.
  features.stackLimit_ = static_cast<size_t>(settings_["stackLimit"].asUInt());
  features.failIfExtra_ = settings_["failIfExtra"].asBool();
  features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
  features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
  features.skipBom_ = settings_["skipBom"].asBool();

  /*返回派生类OurCharReader*/
  return new OurCharReader(collectComments, features);
}

bool CharReaderBuilder::validate(Json::Value* invalid) const {
  static const auto& valid_keys = *new std::set<String>{
      "collectComments",
      "allowComments",
      "allowTrailingCommas",
      "strictRoot",
      "allowDroppedNullPlaceholders",
      "allowNumericKeys",
      "allowSingleQuotes",
      "stackLimit",
      "failIfExtra",
      "rejectDupKeys",
      "allowSpecialFloats",
      "skipBom",
  };
  for (auto si = settings_.begin(); si != settings_.end(); ++si) {
    auto key = si.name();
    if (valid_keys.count(key))
      continue;
    if (invalid)
      (*invalid)[key] = *si;
    else
      return false;
  }
  return invalid ? invalid->empty() : true;
}

Value& CharReaderBuilder::operator[](const String& key) {
  return settings_[key];
}
// static
void CharReaderBuilder::strictMode(Json::Value* settings) {
  //! [CharReaderBuilderStrictMode]
  (*settings)["allowComments"] = false;
  (*settings)["allowTrailingCommas"] = false;
  (*settings)["strictRoot"] = true;
  (*settings)["allowDroppedNullPlaceholders"] = false;
  (*settings)["allowNumericKeys"] = false;
  (*settings)["allowSingleQuotes"] = false;
  (*settings)["stackLimit"] = 1000;
  (*settings)["failIfExtra"] = true;
  (*settings)["rejectDupKeys"] = true;
  (*settings)["allowSpecialFloats"] = false;
  (*settings)["skipBom"] = true;
  //! [CharReaderBuilderStrictMode]
}
// static
void CharReaderBuilder::setDefaults(Json::Value* settings) {
  //! [CharReaderBuilderDefaults]
  (*settings)["collectComments"] = true;
  (*settings)["allowComments"] = true;
  (*settings)["allowTrailingCommas"] = true;
  (*settings)["strictRoot"] = false;
  (*settings)["allowDroppedNullPlaceholders"] = false;
  (*settings)["allowNumericKeys"] = false;
  (*settings)["allowSingleQuotes"] = false;
  (*settings)["stackLimit"] = 1000;
  (*settings)["failIfExtra"] = false;
  (*settings)["rejectDupKeys"] = false;
  (*settings)["allowSpecialFloats"] = false;
  (*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();
}

/*CharReader的解析函数*/
bool CharReader::parse(char const* beginDoc, char const* endDoc, Value* root,
                       String* errs) {
  /*调用内部Impl类的parse*/                      
  return _impl->parse(beginDoc, endDoc, root, errs);
}

//
// global functions

bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root,
                     String* errs) {
  OStringStream ssin;
  ssin << sin.rdbuf();
  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.
  CharReaderPtr const reader(fact.newCharReader());
  return reader->parse(begin, end, root, errs);
}

IStream& operator>>(IStream& sin, Value& root) {
  CharReaderBuilder b;
  String errs;
  bool ok = parseFromStream(b, sin, &root, &errs);
  if (!ok) {
    throwRuntimeError(errs);
  }
  return sin;
}

} // namespace Json


网站公告

今日签到

点亮在社区的每一天
去签到