瀏覽代碼

chore: 各类细节优化

RyanCW 2 周之前
父節點
當前提交
9354d74652

+ 2 - 0
.gitignore

@@ -13,8 +13,10 @@ null
 core
 build
 .xmake
+.dump
 .vscode-ctags
 
 default.profdata
 default.profraw
 test/fuzzer/corpus
+docs

+ 14 - 1
.vscode/settings.json

@@ -30,6 +30,19 @@
         "stdint.h": "c",
         "ryanjsontest.h": "c",
         "dirent.h": "c",
-        "valloc.h": "c"
+        "valloc.h": "c",
+        "initializer_list": "c",
+        "array": "c",
+        "string_view": "c",
+        "utility": "c",
+        "math.h": "c",
+        "compare": "c",
+        "type_traits": "c",
+        "cjson.h": "c",
+        "ryanjson.h": "c",
+        "string.h": "c",
+        "stdarg.h": "c",
+        "cstdlib": "c",
+        "ryanjsonconfig.h": "c"
     },
 }

+ 243 - 67
README.md

@@ -1,24 +1,34 @@
 # RyanJson
 ### *希望有兴趣的大佬多试试,找找bug、提提意见*
 
+📢 **使用过程中遇到问题?欢迎提交 Issue 或在 [RT-Thread 社区](https://club.rt-thread.org/index.html) 提问,感谢支持!**
+
 ***一个针对资源受限的嵌入式设备优化的Json库,内存占用极小的通用Json库,简洁高效!***
 
-*初衷:项目进行重构Json结构变复杂了很多,cJSON内存占用太高,已经满足不了需求。*
+***示例代码请参考`RyanJsonExample`文件夹!***
+
+### 1、介绍
 
-***示例代码请参考`RyanJsonExample`文件夹内!***
+**RyanJson** 是一个小巧的 C 语言 JSON 解析器,支持 JSON 文本解析与生成,专门针对嵌入式平台的 **低内存占用** 进行优化。
 
-## 1、介绍
+*初衷:项目重构后 JSON 结构复杂度提升,cJSON 内存占用过高,无法满足需求。*
 
-RyanJson是一个小巧的C语言Json解析器,包含json文本文件解析 / 生成,**专门针对内存占用进行优化**,相比cJSON内存占用减少30% - 60%,运行速度和cJSON差不多。
+#### ✅ 特性亮点
 
-- **低内存占用**:使用动态扩展技术,在32位系统下,一个基础json节点仅占用8字节。
-- **开发人员友好**:仅有一个c文件和头文件轻松集成,hook函数方便自定义内存钩子。类cJSON的api,迁移成本低。
-- **严格但不严苛**:符合 RFC 8295 大部分JSON标准,支持无限的json嵌套级别(需注意堆栈空间)、灵活的配置修改项
-- **可扩展性**:允许注释(需调用mini函数清除注释后再解析)、尾随逗号等无效字符(parse时可配置是否允许)等
+- 💡 **极致内存优化**:在资源受限设备上实现 **40-70% 内存节省**(对比 cJSON),在 RT-Thread 平台 malloc 头部空间为 12 字节时节省约 40%,无 malloc 头部空间可接近 70%。同时保持工业级健壮性,运行速度与 cJSON 基本持平。
+- ✅ **模糊测试**:LLVM Fuzzer,千万级输入,覆盖率 **99.9%**,稳定性极高,确保在各种非法输入和极端场景下依旧安全。
+- ✅ **运行时安全分析验证**,使用 **[Sanitizer](https://clang.llvm.org/docs/index.html#sanitizers)** 系列工具,捕获内存越界、Use-after-free、数据竞争、未定义行为、内存泄漏等问题,提升代码健壮性与安全性
+- ✅ **高质量代码保障** , 引入 **[clang-tidy](https://clang.llvm.org/extra/clang-tidy/#clang-tidy)** 与 **[Cppcheck](https://cppcheck.sourceforge.io/)** 进行静态分析,实现接近语法级的"**零缺陷**",显著提升可维护性与可读性
+- ✅ **AI 辅助开发与审查**,结合  **[coderabbitai](https://www.coderabbit.ai)** 与 **[Copilot](https://github.com/features/copilot)** ,在编码与代码审查阶段持续优化代码质量,构建多层安全防线
+- ✅ **6 大类专项测试用例**,覆盖广泛场景,全链路内存泄漏检测,强化稳定性与可靠性
+- ✅ **低内存占用**:动态扩展方案,内存空间利用率超高。
+- ✅ **开发人员友好**:轻松集成,类 cJSON API,迁移成本低。
+- **✅ 严格但不严苛**:符合 RFC 8295 绝大部分JSON标准,支持无限的Json嵌套级别(需注意堆栈空间)、灵活的配置修改项
+- ✅ **可扩展性**:允许注释(需调用mini函数清除注释后再解析)、尾随逗号等无效字符(parse时可配置是否允许)等
 
-## 2、设计
+### 2、设计
 
-**RyanJson设计时大量借鉴了 [json](https://api.gitee.com/Lamdonn/json) 和 [cJSON](https://github.com/DaveGamble/cJSON) ! 是从 [json](https://api.gitee.com/Lamdonn/json) 的基础上修改来的**
+**RyanJson设计时大量借鉴了 [json](https://api.gitee.com/Lamdonn/json) 和 [cJSON](https://github.com/DaveGamble/cJSON) ! **
 
 Json语法是**JavaScript**对象语法的子集,可通过下面两个连接学习json语法。
 
@@ -31,68 +41,148 @@ Json语法是**JavaScript**对象语法的子集,可通过下面两个连接
 在RyanJson解析器中,**使用结构体来表示一个键值对,是存储的最小单元**,结构如下:
 
 ```c
+// Json 的最基础节点,所有 Json 元素都由该节点表示。
+// 结构体中仅包含固定的 next 指针,用于单向链表串联。
+// 其余数据(flag、key、stringValue、numberValue、doubleValue 等)均通过动态内存分配管理。
 struct RyanJsonNode
 {
-    uint32_t info;             // 包含类型,key等标志
-    struct RyanJsonNode *next; // 单链表node节点
-
-    // [char *key] 有key的json节点, 会动态申请内存
-
-    // 有value值的节点, 会动态申请内存
-    // [int32_t value / double value / char* value / RyanJson_t item]
+    struct RyanJsonNode *next; // 单链表节点指针
+
+    /*
+     * 在 next 后紧跟一个字节的 flag,用于描述节点的核心信息:
+     *
+     * 位分布如下:
+     * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
+     * -----------------------------------------------------
+     * 保留   KeyLen KeyLen HasKey NumExt Type2 Type1 Type0
+     *
+     * 各位含义:
+     * - bit0-2 : 节点类型
+     *            000=Unknown, 001=Null, 010=Bool, 011=Number,
+     *            100=String, 101=Array, 110=Object, 111=Reserved
+     *
+     * - bit3   : 扩展位
+     *            Bool 类型:0=false, 1=true
+     *            Number 类型:0=int, 1=double
+     *
+     * - bit4   : 是否包含 Key
+     *            0=无 Key(数组元素)
+     *            1=有 Key(对象成员)
+     *
+     * - bit5-6 : Key 长度字段字节数
+     *            00=1字节 (≤255)
+     *            01=2字节 (≤65535)
+     *            10=3字节 (≤16M)
+     *            11=4字节 (≤UINT32_MAX)
+     *
+     * - bit7   : 保留位(未来可用于压缩标记、特殊类型等)
+     */
+
+    /*
+     * flag 后若节点包含 key / strValue,则跟随一个指针,
+     * 指向存储区:[ keyLen | key | stringValue ]
+     * 其中 keyLen 的大小由 flag 中的长度信息决定(最多 4 字节)。
+     *
+     * 在指针之后,根据节点类型存储具体数据:
+     * - null / bool : 由 flag 表示
+     * - string      : 由上述指针指向
+     * - number      : 根据 flag 决定存储 int(4字节) 或 double(8字节)
+     * - object      : 动态分配空间存储子节点,链表结构如下:
+     *
+     *   {
+     *       "name": "RyanJson",
+     *   next (
+     *       "version": "xxx",
+     *   next (
+     *       "repository": "https://github.com/Ryan-CW-Code/RyanJson",
+     *   next (
+     *       "keywords": ["json", "streamlined", "parser"],
+     *   next (
+     *       "others": { ... }
+     *   )))
+     *   }
+     */
+
+    /*
+     * 设计特点:
+     * - 一个 Json 节点最多 malloc 两次(一次节点本身,一次可选的 key/stringValue),
+     *   对嵌入式系统非常友好,减少 malloc 头部开销。
+     *
+     * - key 和 stringValue 必须通过指针管理:
+     *   * 如果直接放在节点里,虽然只需一次 malloc,
+     *     但修改场景会遇到替换/释放困难。
+     *   * 用户可能传递的 Json 对象不是指针,无法直接替换节点,
+     *     要求应用层传递指针会增加侵入性,不符合“应用层无需修改”的目标。
+     *
+     * - 因此采用指针方式,保证灵活性和低侵入性。
+     */
 };
 
+
 typedef struct RyanJsonNode *RyanJson_t;
 ```
 
-**此结构体包含两个固定成员 info 和 next;**
+### 3、测试体系
 
-**info**:为当前节点的配置信息用来表示 节点数据类型 和 flag标志位。
+**LLVM模糊测试**(核心亮点),模糊测试是 RyanJson 的 **核心稳定性保障**,针对嵌入式环境的复杂场景进行了深度设计与验证
 
-```
-bits  low --> high
----------------------------------------------------------------------
-| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | NA | NA | .......
----------------------------------------------------------------------
-\______________________________/  |   |   |
-             low 8bits            |   |   |
-                |                 |   |   |
-                V                 |   |   |
-   RyanJsonTypeUnknow    (bit0)   |   |   |
-   RyanJsonTypeNull      (bit1)   |   |   |
-   RyanJsonTypeBool      (bit2)   |   |   +----> RyanJsonWithKeyFlag            (1 << 10)
-   RyanJsonTypeNumber    (bit3)   |   |
-   RyanJsonTypeString    (bit4)   |   +--------> RyanJsonValueNumberIntFlag     (1 << 9)
-   RyanJsonTypeArray     (bit5)   |
-   RyanJsonTypeObject    (bit6)   +------------> RyanJsonValueBoolTrueFlag      (1 << 8)
-   spare                 (bit7)
-```
+### 📊 特点与优势
 
-**next**:指针指向链表下一个节点
+- **千万级测试样本**:LLVM Fuzzer 自动生成并执行千万级随机与非法 JSON 输入。
+- **覆盖率极高**:
+  - 模糊测试文件行覆盖率 **100%**
+  - 核心 JSON 代码行覆盖率 **99.9%**
+  - 千万级输入并且警告复杂逻辑测试下无崩溃、无泄漏。
+- **异常场景全覆盖**:内存申请失败、扩容失败、非法转义字符、尾随逗号、嵌套过深、随机类型切换。
+- **内存安全验证**:结合 Sanitizer 工具链,确保无泄漏、无悬空指针、无越界。
+- **鲁棒性验证**:弱网、随机内存故障、长时间运行等极端条件下保持稳定。
 
-```
-{
-      "name": "RyanJson",
-next (
-      "version": "xxx",
-next (
-      "repository": "https://github.com/Ryan-CW-Code/RyanJson",
-next (
-      "keywords": ["json", "streamlined", "parser"],
-next (      \__item__/  \__next__/    \__next__/
-      "others": {
-            ...
-      }
-}
-```
+| 测试类别                              | 测试目标                 |
+| ------------------------------------- | ------------------------ |
+| 内存故障测试                          | 验证内存不足时的健壮性   |
+| 解析 Json 节点测试                    | 随机非法/合法输入解析    |
+| 循环遍历删除节点测试                  | 确保链表删除安全性       |
+| 循环遍历分离节点测试                  | 验证节点分离逻辑正确性   |
+| Json 压缩去除转义测试                 | 检查转义字符处理健壮性   |
+| Json 打印和解析测试                   | 序列化与反序列化一致性   |
+| 循环遍历获取 Value 测试               | 确保随机访问稳定性       |
+| 循环遍历随机复制 Json 节点测试        | 验证深拷贝与浅拷贝安全性 |
+| 循环遍历随机修改节点类型/创建节点测试 | 动态扩展与类型切换能力   |
 
-**此结构体还包括两个可能动态创建的成员 key 和 value;**
+#### 📊 手写的专项基础测试用例
 
-**key**:存储JSON键值对的 key 信息,当存在key时会在申请RyanJsonNode内存时动态添加。
+| 测试类别             | 测试目标             |
+| -------------------- | -------------------- |
+| 文本解析 Json 测试   | 基础解析能力         |
+| 创建 Json 节点树测试 | 节点生成与结构正确性 |
+| 修改 Json 节点测试   | 删除、分离、修改     |
+| 比较 Json 节点测试   | 节点比较与一致性     |
+| 复制 Json 节点测试   | 深拷贝与浅拷贝验证   |
+| Json 循环测试        | 遍历与稳定性         |
 
-**value**:存储JSON键值对的 value 信息,会根据不同节点类型创建不同的value值。会在申请RyanJsonNode内存时动态添加。
+### 4、代码质量与规范
 
-## 3、测试
+#### ✅ 工具链全面集成
+
+| 工具                                                         | 用途                                                         |
+| ------------------------------------------------------------ | ------------------------------------------------------------ |
+| **[Sanitizer](https://clang.llvm.org/docs/index.html#sanitizers)** | 运行时捕获内存与线程安全问题                                 |
+| **[clang-tidy](https://clang.llvm.org/extra/clang-tidy/#clang-tidy)** | 静态分析潜在缺陷(空指针、资源泄漏等)                       |
+| **[Cppcheck](https://cppcheck.sourceforge.io/)**             | 深度扫描内存与资源问题                                       |
+| **[ClangFormat](https://clang.llvm.org/docs/ClangFormat.html)** | 统一代码风格                                                 |
+| **编译器警告**                                               | `-Wall -Wextra`(默认)、`-Weffc++`/`-Weverything`(Clang 可选,CI 强化时开启) |
+
+#### ✅ 检查重点覆盖
+
+- 内存安全:杜绝泄漏、越界、悬空指针
+- 性能优化:减少冗余拷贝与低效算法
+- 可读性:命名规范、注释完整、逻辑清晰
+
+> ✅ **成果**:实现接近语法级"**零缺陷**",长期维护成本大幅降低
+
+
+
+### 6、示例
 
 *测试代码和示例代码可在本项目根目录`RyanJsonExample`文件夹查看。*
 
@@ -102,31 +192,117 @@ next (      \__item__/  \__next__/    \__next__/
 
 
 #### 内存占用测试
-*此测试结果为(2023.08.22)时测试,测试代码可在本项目根目录`RyanJsonExample`文件夹查看。新版本内存占用更低!*
-![image-20230822200726742](docs/assert/README.assert/image-20230822200726742.png)
+*(20251222 linux平台,**不考虑malloc头部空间)**测试代码可在本项目根目录`RyanJsonExample`文件夹查看。新版本内存占用更低!*
 
+```
+*****************************************************************************
+*************************** RyanJson / cJSON / yyjson 内存对比程序 **************************
+*****************************************************************************
 
+--------------------------- 混合类型json数据测试 --------------------------
+json原始文本长度为 2265, 序列化后RyanJson内存占用: 3613, cJSON内存占用: 9160
+比cJSON节省: 60.56% 内存占用
 
-#### RFC 8295 标准测试,大部分嵌入式场景不会出现复杂的特殊json结构
+--------------------------- 对象占多json数据测试 --------------------------
+json原始文本长度为 3991, 序列化后RyanJson内存占用: 5436, cJSON内存占用: 11633
+比cJSON节省: 53.27% 内存占用
 
-***RyanJson和cJSON都不适合处理复杂的UTF-16字符集,如果项目需要兼容Unicode字符集,可以考虑yyjson / json-c***
+--------------------------- 数组占多json数据测试 --------------------------
+json原始文本长度为 1205, 序列化后RyanJson内存占用: 2365, cJSON内存占用: 7340
+比cJSON节省: 67.78% 内存占用
 
-![image-20230822200717809](docs/assert/README.assert/image-20230822200717809.png)
+--------------------------- 小对象json 混合类型内存占用测试 --------------------------
+json原始文本长度为 90, 序列化后RyanJson内存占用: 131, cJSON内存占用: 309
+比cJSON节省: 57.61% 内存占用
+
+--------------------------- 小对象json 纯字符串内存占用测试 --------------------------
+json原始文本长度为 100, 序列化后RyanJson内存占用: 144, cJSON内存占用: 339
+比cJSON节省: 57.52% 内存占用
+```
 
-## 4、局限性
+RT-Thread平台考虑**malloc头部空间12字节**情况下
+
+```
+*****************************************************************************
+*************************** RyanJson / cJSON / yyjson 内存对比程序 **************************
+*****************************************************************************
+
+--------------------------- 混合类型json数据测试 --------------------------
+json原始文本长度为 2265, 序列化后RyanJson内存占用: 7993, cJSON内存占用: 13732
+比cJSON节省: 41.79% 内存占用
+
+--------------------------- 对象占多json数据测试 --------------------------
+json原始文本长度为 3991, 序列化后RyanJson内存占用: 10668, cJSON内存占用: 19109
+比cJSON节省: 44.17% 内存占用
+
+--------------------------- 数组占多json数据测试 --------------------------
+json原始文本长度为 1205, 序列化后RyanJson内存占用: 5449, cJSON内存占用: 10424
+比cJSON节省: 47.73% 内存占用
+
+--------------------------- 小对象json 混合类型内存占用测试 --------------------------
+json原始文本长度为 90, 序列化后RyanJson内存占用: 287, cJSON内存占用: 477
+比cJSON节省: 39.83% 内存占用
+
+--------------------------- 小对象json 纯字符串内存占用测试 --------------------------
+json原始文本长度为 100, 序列化后RyanJson内存占用: 300, cJSON内存占用: 567
+比cJSON节省: 47.09% 内存占用
+```
+
+
+
+RFC 8295 标准测试,大部分嵌入式场景不会出现极为特殊的Unicode字符集
+
+***如果项目需要完全兼容Unicode字符集,可以考虑yyjson / json-c***
+
+```
+*****************************************************************************
+*************************** RyanJson / cJSON / yyjson RFC8259标准测试 **************************
+*****************************************************************************
+开始 RFC 8259 JSON 测试
+--------------------------- RFC8259  RyanJson --------------------------
+应该失败,但是成功: [1eE2], len: 6
+应该成功,但是失败: [20e1], len: 6
+应该成功,但是失败: [0e1], len: 5
+RFC 8259 JSON: (319/322)
+
+--------------------------- RFC8259  cJSON --------------------------
+应该失败,但是成功: [1.], len: 4
+应该失败,但是成功: [
+                     ], len: 3
+应该失败,但是成功: ["\uqqqq"], len: 10
+应该失败,但是成功: [2.e-3], len: 7
+应该失败,但是成功: [-2.], len: 5
+应该失败,但是成功: [-.123], len: 7
+应该失败,但是成功: 123, len: 4
+应该失败,但是成功: [2.e+3], len: 7
+应该失败,但是成功: [0.e1], len: 6
+应该失败,但是成功: ["a, len: 7
+应该失败,但是成功: [-012], len: 6
+应该失败,但是成功: [, len: 3
+应该失败,但是成功: [012], len: 5
+应该失败,但是成功: ["new
+line"], len: 12
+应该失败,但是成功: ["  "], len: 5
+应该失败,但是成功: [-01], len: 5
+应该失败,但是成功: [2.e3], len: 6
+RFC 8259 JSON: (305/322)
+|||----------->>> area = 0, size = 0
+```
+
+
+
+### 4、局限性
 
 - 使用int / double表示json中的number类型,**精度有所丢失**。建议64位的number类型最好用string字符串表示。
 - **对象中允许有重复的key**,RyanJson库采用单向链表,会访问到第一个对象。
 
-## 5、文档
+### 5、文档
 
 文档可在 [Ryan文档中心](https://ryan-cw-code.github.io/RyanDocs/)获取
 
-## 6、联系
+### 6、联系
 
 Email:1831931681@qq.com
 
-wx:17513216936
-
 
 

+ 94 - 79
RyanJson/RyanJson.c

@@ -273,14 +273,14 @@ void *RyanJsonGetValue(RyanJson_t pJson)
 {
 	RyanJsonCheckReturnNull(NULL != pJson);
 
-	uint32_t len = 0;
+	uint32_t len = RyanJsonAlign;
 	if (RyanJsonIsKey(pJson) || RyanJsonIsString(pJson))
 	{
 		len += sizeof(void *);
 		// jsonLog(" keyLen: %d, keyLenField: %d, \r\n", RyanJsonGetLenKey(pJson), RyanJsonGetPayloadEncodeKeyLenByFlag(pJson));
 	}
 
-	return RyanJsonGetPayloadPtr(pJson) + RyanJsonAlign + (len);
+	return RyanJsonGetPayloadPtr(pJson) + len;
 }
 
 char *RyanJsonGetKey(RyanJson_t pJson)
@@ -1003,13 +1003,12 @@ static RyanJsonBool_e RyanJsonParseCheckNullTerminator(RyanJsonParseBuffer *pars
 	return RyanJsonTrue;
 }
 
-RyanJson_t RyanJsonParseOptions(const char *text, int32_t size, RyanJsonBool_e requireNullTerminator, const char **parseEndPtr)
+RyanJson_t RyanJsonParseOptions(const char *text, uint32_t size, RyanJsonBool_e requireNullTerminator, const char **parseEndPtr)
 {
 	RyanJson_t pJson;
 	RyanJsonCheckReturnNull(NULL != text);
-	RyanJsonCheckReturnNull(size >= 0);
 
-	RyanJsonParseBuffer parseBuf = {.currentPtr = (const uint8_t *)text, .remainSize = (uint32_t)size};
+	RyanJsonParseBuffer parseBuf = {.currentPtr = (const uint8_t *)text, .remainSize = size};
 	RyanJsonCheckReturnNull(RyanJsonTrue == parseBufSkipWhitespace(&parseBuf));
 
 	RyanJsonCheckReturnNull(RyanJsonTrue == RyanJsonParseValue(&parseBuf, NULL, &pJson));
@@ -1035,7 +1034,7 @@ static RyanJsonBool_e RyanJsonPrintNumber(RyanJson_t pJson, RyanJsonPrintBuffer
 {
 	RyanJsonCheckAssert(NULL != pJson && NULL != printfBuf);
 
-	double f;
+	double numberValue;
 	int32_t len;
 
 	// RyanJsonNumber 类型是一个整数
@@ -1051,26 +1050,26 @@ static RyanJsonBool_e RyanJsonPrintNumber(RyanJson_t pJson, RyanJsonPrintBuffer
 	else // RyanJsonNumber 的类型是浮点型
 	{
 		RyanJsonCheckReturnFlase(printBufAppend(printfBuf, 64)); // 64 位整数最多包含  20 个数字字符、1 符号
-		f = RyanJsonGetDoubleValue(pJson);
+		numberValue = RyanJsonGetDoubleValue(pJson);
 
 		// use full transformation within bounded space
-		if (fabs(floor(f) - f) <= DBL_EPSILON && fabs(f) < 1.0e60)
+		if (fabs(floor(numberValue) - numberValue) <= DBL_EPSILON && fabs(numberValue) < 1.0e60)
 		{
-			len = RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "%.1lf", f);
+			len = RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "%.1lf", numberValue);
 			RyanJsonCheckReturnFlase(len > 0); // snprintf 失败
 		}
 
 		// use exponential form conversion beyond the limited range
-		else if (fabs(f) < 1.0e-6 || fabs(f) > 1.0e9)
+		else if (fabs(numberValue) < 1.0e-6 || fabs(numberValue) > 1.0e9)
 		{
-			len = RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "%e", f);
+			len = RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "%e", numberValue);
 			RyanJsonCheckReturnFlase(len > 0); // snprintf 失败
 		}
 
 		// default conversion
 		else
 		{
-			len = RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "%lf", f);
+			len = RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "%lf", numberValue);
 			RyanJsonCheckReturnFlase(len > 0); // snprintf 失败
 			while (len > 0 && printBufCurrentPtr(printfBuf)[len - 1] == '0' &&
 			       printBufCurrentPtr(printfBuf)[len - 2] != '.') // 删除小数部分中无效的 0
@@ -1087,19 +1086,19 @@ static RyanJsonBool_e RyanJsonPrintNumber(RyanJson_t pJson, RyanJsonPrintBuffer
 /**
  * @brief 反序列化字符串
  *
- * @param str
+ * @param strValue
  * @param buf
  * @return RyanJsonBool_e
  */
-static RyanJsonBool_e RyanJsonPrintStringBuffer(const uint8_t *str, RyanJsonPrintBuffer *printfBuf)
+static RyanJsonBool_e RyanJsonPrintStringBuffer(const uint8_t *strValue, RyanJsonPrintBuffer *printfBuf)
 {
-	RyanJsonCheckAssert(NULL != str && NULL != printfBuf);
+	RyanJsonCheckAssert(NULL != strValue && NULL != printfBuf);
 	// 获取长度
-	const uint8_t *input_pointer = str;
-	uint32_t escape_characters = 0;
-	for (input_pointer = str; *input_pointer; input_pointer++)
+	const uint8_t *strCurrentPtr = strValue;
+	uint32_t escapeCharCount = 0;
+	for (strCurrentPtr = strValue; *strCurrentPtr; strCurrentPtr++)
 	{
-		switch (*input_pointer)
+		switch (*strCurrentPtr)
 		{
 		case '\"':
 		case '\\':
@@ -1108,39 +1107,39 @@ static RyanJsonBool_e RyanJsonPrintStringBuffer(const uint8_t *str, RyanJsonPrin
 		case '\n':
 		case '\r':
 		case '\t':
-		case '/': escape_characters++; break;
+		case '/': escapeCharCount++; break;
 
 		default:
 			// 每个字节都+5肯定满足printf的需求了
-			if (*input_pointer < 32) { escape_characters += 5; }
+			if (*strCurrentPtr < 32) { escapeCharCount += 5; }
 			break;
 		}
 	}
 
-	RyanJsonCheckReturnFlase(printBufAppend(printfBuf, (uint32_t)(input_pointer - str) + escape_characters + 2U)); // 最小是\" \"
+	RyanJsonCheckReturnFlase(printBufAppend(printfBuf, (uint32_t)(strCurrentPtr - strValue) + escapeCharCount + 2U)); // 最小是\" \"
 	printBufPutChar(printfBuf, '\"');
 
 	// 没有转义字符
-	if (0 == escape_characters)
+	if (0 == escapeCharCount)
 	{
-		printBufPutString(printfBuf, str, (input_pointer - str));
+		printBufPutString(printfBuf, strValue, (strCurrentPtr - strValue));
 		printBufPutChar(printfBuf, '\"');
 		return RyanJsonTrue;
 	}
 
-	const uint8_t *p = str;
-	while (*p)
+	strCurrentPtr = strValue;
+	while (*strCurrentPtr)
 	{
-		if ((*p) >= ' ' && *p != '\"' && *p != '\\')
+		if ((*strCurrentPtr) >= ' ' && *strCurrentPtr != '\"' && *strCurrentPtr != '\\')
 		{
-			printBufPutChar(printfBuf, *p++);
+			printBufPutChar(printfBuf, *strCurrentPtr++);
 			continue;
 		}
 
 		// 转义和打印
 		printBufPutChar(printfBuf, '\\');
 
-		switch (*p)
+		switch (*strCurrentPtr)
 		{
 		case '\\': printBufPutChar(printfBuf, '\\'); break;
 		case '\"': printBufPutChar(printfBuf, '\"'); break;
@@ -1154,13 +1153,13 @@ static RyanJsonBool_e RyanJsonPrintStringBuffer(const uint8_t *str, RyanJsonPrin
 		default: {
 			// 可以不加p有效性的判断是因为,这个RyanJson生成的字符串,RyanJson可以确保p一定是有效的
 			// jsonLog("hexasdf:\\u%04X\n", codepoint);
-			RyanJsonCheckReturnFlase(5 ==
-						 RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "u%04X", *p));
+			RyanJsonCheckReturnFlase(
+				5 == RyanJsonSnprintf((char *)printBufCurrentPtr(printfBuf), printfBuf->size, "u%04X", *strCurrentPtr));
 			printfBuf->cursor += 5; // utf
 			break;
 		}
 		}
-		p++;
+		strCurrentPtr++;
 	}
 
 	printBufPutChar(printfBuf, '\"');
@@ -1375,13 +1374,13 @@ static RyanJsonBool_e RyanJsonPrintValue(RyanJson_t pJson, RyanJsonPrintBuffer *
  * @param len 可以通过指针来获取转换后的长度
  * @return char* NULL失败
  */
-char *RyanJsonPrint(RyanJson_t pJson, int32_t preset, RyanJsonBool_e format, int32_t *len)
+char *RyanJsonPrint(RyanJson_t pJson, uint32_t preset, RyanJsonBool_e format, uint32_t *len)
 {
 	RyanJsonCheckReturnNull(NULL != pJson);
 
 	RyanJsonPrintBuffer printfBuf = {
 		.isNoAlloc = RyanJsonFalse,
-		.size = (uint32_t)preset,
+		.size = preset,
 		.cursor = 0,
 	};
 
@@ -1400,7 +1399,7 @@ char *RyanJsonPrint(RyanJson_t pJson, int32_t preset, RyanJsonBool_e format, int
 	});
 
 	printfBuf.bufAddress[printfBuf.cursor] = '\0';
-	if (len) { *len = (int32_t)printfBuf.cursor; }
+	if (len) { *len = printfBuf.cursor; }
 
 	return (char *)printfBuf.bufAddress;
 }
@@ -1415,14 +1414,14 @@ char *RyanJsonPrint(RyanJson_t pJson, int32_t preset, RyanJsonBool_e format, int
  * @param len
  * @return char*
  */
-char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, int32_t length, RyanJsonBool_e format, int32_t *len)
+char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, uint32_t length, RyanJsonBool_e format, uint32_t *len)
 {
 	RyanJsonCheckReturnNull(NULL != pJson && NULL != buffer);
 
 	RyanJsonPrintBuffer printfBuf = {
 		.bufAddress = (uint8_t *)buffer,
 		.isNoAlloc = RyanJsonTrue,
-		.size = (uint32_t)length,
+		.size = length,
 		.cursor = 0,
 	};
 
@@ -1430,7 +1429,7 @@ char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, int32_t length,
 
 	RyanJsonCheckReturnNull(printBufAppend(&printfBuf, 1));
 	printfBuf.bufAddress[printfBuf.cursor] = '\0';
-	if (len) { *len = (int32_t)printfBuf.cursor; }
+	if (len) { *len = printfBuf.cursor; }
 
 	return (char *)printfBuf.bufAddress;
 }
@@ -1439,23 +1438,23 @@ char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, int32_t length,
  * @brief 获取 json 的子项个数
  *
  * @param pJson
- * @return int32_t
+ * @return uint32_t
  */
-int32_t RyanJsonGetSize(RyanJson_t pJson)
+uint32_t RyanJsonGetSize(RyanJson_t pJson)
 {
 	RyanJsonCheckCode(NULL != pJson, { return 0; });
 
 	if (!_checkType(RyanJsonGetType(pJson), RyanJsonTypeArray) && !_checkType(RyanJsonGetType(pJson), RyanJsonTypeObject)) { return 1; }
 
 	RyanJson_t nextItem = RyanJsonGetObjectValue(pJson);
-	int32_t i = 0;
+	uint32_t size = 0;
 	while (NULL != nextItem)
 	{
-		i++;
+		size++;
 		nextItem = nextItem->next;
 	}
 
-	return i;
+	return size;
 }
 
 /**
@@ -1465,7 +1464,7 @@ int32_t RyanJsonGetSize(RyanJson_t pJson)
  * @param index
  * @return RyanJson_t
  */
-RyanJson_t RyanJsonGetObjectByIndex(RyanJson_t pJson, int32_t index)
+RyanJson_t RyanJsonGetObjectByIndex(RyanJson_t pJson, uint32_t index)
 {
 	RyanJsonCheckReturnNull(NULL != pJson && index >= 0);
 
@@ -1514,7 +1513,7 @@ RyanJson_t RyanJsonGetObjectByKey(RyanJson_t pJson, const char *key)
  * @param index
  * @return RyanJson_t 被分离对象的指针
  */
-RyanJson_t RyanJsonDetachByIndex(RyanJson_t pJson, int32_t index)
+RyanJson_t RyanJsonDetachByIndex(RyanJson_t pJson, uint32_t index)
 {
 	RyanJsonCheckReturnNull(NULL != pJson && index >= 0);
 
@@ -1586,7 +1585,7 @@ RyanJson_t RyanJsonDetachByKey(RyanJson_t pJson, const char *key)
  * @param index
  * @return RyanJsonBool_e
  */
-RyanJsonBool_e RyanJsonDeleteByIndex(RyanJson_t pJson, int32_t index)
+RyanJsonBool_e RyanJsonDeleteByIndex(RyanJson_t pJson, uint32_t index)
 {
 	RyanJsonCheckReturnFlase(NULL != pJson && index >= 0);
 
@@ -1623,7 +1622,7 @@ RyanJsonBool_e RyanJsonDeleteByKey(RyanJson_t pJson, const char *key)
  * @param item
  * @return RyanJsonBool_e
  */
-RyanJsonBool_e RyanJsonInsert(RyanJson_t pJson, int32_t index, RyanJson_t item)
+RyanJsonBool_e RyanJsonInsert(RyanJson_t pJson, uint32_t index, RyanJson_t item)
 {
 	RyanJsonCheckReturnFlase(NULL != item);
 	RyanJsonCheckCode(NULL != pJson && index >= 0, { goto __exit; });
@@ -1674,6 +1673,14 @@ RyanJsonBool_e RyanJsonAddItemToObject(RyanJson_t pJson, char *key, RyanJson_t i
 	return RyanJsonInsert(pJson, INT32_MAX, pItem);
 }
 
+/**
+ * @brief 替换json对象节点
+ *
+ * @param prev
+ * @param oldItem
+ * @param newItem
+ * @return RyanJsonBool_e
+ */
 static RyanJsonBool_e RyanJsonReplaceNode(RyanJson_t prev, RyanJson_t oldItem, RyanJson_t newItem)
 {
 	RyanJsonCheckAssert(NULL != oldItem && NULL != newItem);
@@ -1696,7 +1703,7 @@ static RyanJsonBool_e RyanJsonReplaceNode(RyanJson_t prev, RyanJson_t oldItem, R
  * @param item
  * @return RyanJsonBool_e
  */
-RyanJsonBool_e RyanJsonReplaceByIndex(RyanJson_t pJson, int32_t index, RyanJson_t item)
+RyanJsonBool_e RyanJsonReplaceByIndex(RyanJson_t pJson, uint32_t index, RyanJson_t item)
 {
 	RyanJsonCheckReturnFlase(NULL != pJson && index >= 0 && NULL != item);
 
@@ -1757,13 +1764,12 @@ RyanJsonBool_e RyanJsonReplaceByKey(RyanJson_t pJson, const char *key, RyanJson_
 	// 没有key的对象 申请一个带key的对象
 	if (RyanJsonFalse == RyanJsonIsKey(item))
 	{
-		// RyanJsonChangeKey((item), key);
 		item = RyanJsonCreateItem(key, item);
 		RyanJsonCheckReturnFlase(NULL != item);
 	}
 	else
 	{
-		if (0 != RyanJsonStrcmp(RyanJsonGetKey(item), key)) { RyanJsonChangeKey((item), key); }
+		if (0 != RyanJsonStrcmp(RyanJsonGetKey(item), key)) { RyanJsonChangeKey(item, key); }
 	}
 
 	RyanJsonReplaceNode(prev, nextItem, item);
@@ -2002,13 +2008,21 @@ err:
  *
  * @param text 文本指针
  */
-int32_t RyanJsonMinify(char *text, int32_t textLen)
+
+/**
+ * @brief 通过删除无效字符、注释等, 减少json文本大小
+ *
+ * @param text 文本指针
+ * @param textLen 文本长度,使用int32_t是方式用户隐士转换不好发现bug
+ * @return uint32_t
+ */
+uint32_t RyanJsonMinify(char *text, int32_t textLen)
 {
 	RyanJsonCheckCode(NULL != text && textLen > 0, { return 0; });
 
 	char *t = (char *)text;           // 假设 text 指向可写缓冲区
 	const char *end = text + textLen; // 边界
-	int32_t count = 0;                // 压缩后字符数
+	uint32_t count = 0;               // 压缩后字符数
 
 	while (text < end && *text)
 	{
@@ -2057,67 +2071,68 @@ int32_t RyanJsonMinify(char *text, int32_t textLen)
 /**
  * @brief 递归比较两个 pJson 对象key和value是否相等。
  * 此接口效率较低, 谨慎使用
- * @param a
- * @param b
+ * @param leftJson
+ * @param rightJson
  * @return RyanJsonBool_e
  */
-RyanJsonBool_e RyanJsonCompare(RyanJson_t a, RyanJson_t b)
+RyanJsonBool_e RyanJsonCompare(RyanJson_t leftJson, RyanJson_t rightJson)
 {
-	if (NULL == a || NULL == b) { return RyanJsonFalse; }
+	if (NULL == leftJson || NULL == rightJson) { return RyanJsonFalse; }
 
 	// 相同的对象相等
-	if (a == b) { return RyanJsonTrue; }
+	if (leftJson == rightJson) { return RyanJsonTrue; }
 
-	if (RyanJsonGetType(a) != RyanJsonGetType(b)) { return RyanJsonFalse; }
+	if (RyanJsonGetType(leftJson) != RyanJsonGetType(rightJson)) { return RyanJsonFalse; }
 
-	switch (RyanJsonGetType(a))
+	switch (RyanJsonGetType(leftJson))
 	{
 	case RyanJsonTypeNull: return RyanJsonTrue;
 
-	case RyanJsonTypeBool: return RyanJsonGetBoolValue(a) == RyanJsonGetBoolValue(b) ? RyanJsonTrue : RyanJsonFalse;
+	case RyanJsonTypeBool: return RyanJsonGetBoolValue(leftJson) == RyanJsonGetBoolValue(rightJson) ? RyanJsonTrue : RyanJsonFalse;
 
 	case RyanJsonTypeNumber: {
 
-		if (RyanJsonTrue == RyanJsonIsInt(a) && RyanJsonTrue == RyanJsonIsInt(b))
+		if (RyanJsonTrue == RyanJsonIsInt(leftJson) && RyanJsonTrue == RyanJsonIsInt(rightJson))
 		{
-			return (RyanJsonGetIntValue(a) == RyanJsonGetIntValue(b)) ? RyanJsonTrue : RyanJsonFalse;
+			return (RyanJsonGetIntValue(leftJson) == RyanJsonGetIntValue(rightJson)) ? RyanJsonTrue : RyanJsonFalse;
 		}
 
-		if (RyanJsonTrue == RyanJsonIsDouble(a) && RyanJsonTrue == RyanJsonIsDouble(b))
+		if (RyanJsonTrue == RyanJsonIsDouble(leftJson) && RyanJsonTrue == RyanJsonIsDouble(rightJson))
 		{
-			return compare_double(RyanJsonGetDoubleValue(a), RyanJsonGetDoubleValue(b));
+			return compare_double(RyanJsonGetDoubleValue(leftJson), RyanJsonGetDoubleValue(rightJson));
 		}
 
 		return RyanJsonFalse;
 	}
 
 	case RyanJsonTypeString:
-		return (0 == RyanJsonStrcmp(RyanJsonGetStringValue(a), RyanJsonGetStringValue(b))) ? RyanJsonTrue : RyanJsonFalse;
+		return (0 == RyanJsonStrcmp(RyanJsonGetStringValue(leftJson), RyanJsonGetStringValue(rightJson))) ? RyanJsonTrue
+														  : RyanJsonFalse;
 
 	case RyanJsonTypeArray: {
-		if (RyanJsonGetSize(a) != RyanJsonGetSize(b)) { return RyanJsonFalse; }
+		if (RyanJsonGetSize(leftJson) != RyanJsonGetSize(rightJson)) { return RyanJsonFalse; }
 
-		for (int32_t count = 0; count < RyanJsonGetSize(a); count++)
+		RyanJson_t item;
+		uint32_t itemIndex = 0;
+		RyanJsonArrayForEach(leftJson, item)
 		{
-			if (RyanJsonTrue != RyanJsonCompare(RyanJsonGetObjectByIndex(a, count), RyanJsonGetObjectByIndex(b, count)))
-			{
-				return RyanJsonFalse;
-			}
+			if (RyanJsonTrue != RyanJsonCompare(item, RyanJsonGetObjectByIndex(rightJson, itemIndex))) { return RyanJsonFalse; }
+			itemIndex++;
 		}
+
 		return RyanJsonTrue;
 	}
 
 	case RyanJsonTypeObject: {
-		if (RyanJsonGetSize(a) != RyanJsonGetSize(b)) { return RyanJsonFalse; }
+		if (RyanJsonGetSize(leftJson) != RyanJsonGetSize(rightJson)) { return RyanJsonFalse; }
 
-		RyanJson_t a_element, b_element;
-
-		RyanJsonObjectForEach(a, a_element)
+		RyanJson_t item;
+		RyanJsonObjectForEach(leftJson, item)
 		{
-			b_element = RyanJsonGetObjectByKey(b, RyanJsonGetKey(a_element));
-			if (NULL == b_element) { return RyanJsonFalse; }
-
-			if (RyanJsonTrue != RyanJsonCompare(a_element, b_element)) { return RyanJsonFalse; }
+			if (RyanJsonTrue != RyanJsonCompare(item, RyanJsonGetObjectByKey(rightJson, RyanJsonGetKey(item))))
+			{
+				return RyanJsonFalse;
+			}
 		}
 
 		return RyanJsonTrue;

+ 129 - 75
RyanJson/RyanJson.h

@@ -1,4 +1,3 @@
-
 #ifndef __RyanJson__
 #define __RyanJson__
 
@@ -25,40 +24,81 @@ extern "C" {
 #define RyanJsonCheckReturnNull(EX)  RyanJsonCheckCode(EX, { return NULL; })
 #define RyanJsonCheckAssert(EX)      RyanJsonCheckCode(EX, { RyanJsonAssert(NULL && "RyanJsonCheckAssert"); })
 
-// Json的最基础节点,所有Json元素都由该节点表示。
+// Json 的最基础节点,所有 Json 元素都由该节点表示。
 // 结构体中仅包含固定的 next 指针,用于单向链表串联。
 // 其余数据(flag、key、stringValue、numberValue、doubleValue 等)均通过动态内存分配管理。
-//
-// 在 next 后紧跟一个字节的 flag,用于描述节点的核心信息:
-//   - 节点类型(null / bool / number / string / object)
-//   - 是否包含 key
-//   - Bool 类型的取值(true/false)
-//   - Number 类型的类别(整数 / 浮点数)
-//   - Key 的长度(占用 1~4 字节)
-//
-// flag 后若节点包含 key 或字符串值,则跟随一个指针,指向存储区:
-//   [ keyLen | key | stringValue ]
-//   其中 keyLen 的大小由 flag 中的长度信息决定(最多 4 字节)。
-//
-// 在指针之后,根据节点类型存储具体数据:
-//   - null / bool:由 flag 表示
-//   - string:由上述指针指向
-//   - number:根据 flag 决定存储 int 或 double,来申请空间
-//   - object:动态分配空间存储子节点,申请一个指针空间
-//
-// 整个设计通过一个字节的 flag 高度复用信息,保证结构紧凑且灵活。
-// 设计特点:
-//   - 一个 Json 节点最多 malloc 两次(一次节点本身,一次可选的 key/stringValue),
-//     对嵌入式系统非常友好,减少 malloc 头部开销。
-//   - key 和 stringValue 必须通过指针管理:
-//       * 如果直接将key 和 stringValue放在节点里,虽然只需一次 malloc,但部分修改场景会遇到问题
-//       * 如何找到前置节点的问题,需要找到前置节点,替换修改过节点,然后释放当前节点。(这个最开始已经实现了,关键是下面这条)
-//       * 用户可能传递的 Json 对象不是指针,无法直接替换节点。要求应用层传递指针会增加侵入性,改动太大,不符合“应用层无需修改”的更新目标。
-//   - 因此采用指针方式,保证灵活性和低侵入性。
-
 struct RyanJsonNode
 {
-	struct RyanJsonNode *next; // 单链表node节点
+	struct RyanJsonNode *next; // 单链表节点指针
+
+	/*
+	 * 在 next 后紧跟一个字节的 flag,用于描述节点的核心信息:
+	 *
+	 * 位分布如下:
+	 * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
+	 * -----------------------------------------------------
+	 * 保留   KeyLen KeyLen HasKey NumExt Type2 Type1 Type0
+	 *
+	 * 各位含义:
+	 * - bit0-2 : 节点类型
+	 *            000=Unknown, 001=Null, 010=Bool, 011=Number,
+	 *            100=String, 101=Array, 110=Object, 111=Reserved
+	 *
+	 * - bit3   : 扩展位
+	 *            Bool 类型:0=false, 1=true
+	 *            Number 类型:0=int, 1=double
+	 *
+	 * - bit4   : 是否包含 Key
+	 *            0=无 Key(数组元素)
+	 *            1=有 Key(对象成员)
+	 *
+	 * - bit5-6 : Key 长度字段字节数
+	 *            00=1字节 (≤255)
+	 *            01=2字节 (≤65535)
+	 *            10=3字节 (≤16M)
+	 *            11=4字节 (≤UINT32_MAX)
+	 *
+	 * - bit7   : 保留位(未来可用于压缩标记、特殊类型等)
+	 */
+
+	/*
+	 * flag 后若节点包含 key / strValue,则跟随一个指针,
+	 * 指向存储区:[ keyLen | key | stringValue ]
+	 * 其中 keyLen 的大小由 flag 中的长度信息决定(最多 4 字节)。
+	 *
+	 * 在指针之后,根据节点类型存储具体数据:
+	 * - null / bool : 由 flag 表示
+	 * - string      : 由上述指针指向
+	 * - number      : 根据 flag 决定存储 int(4字节) 或 double(8字节)
+	 * - object      : 动态分配空间存储子节点,链表结构如下:
+	 *
+	 *   {
+	 *       "name": "RyanJson",
+	 *   next (
+	 *       "version": "xxx",
+	 *   next (
+	 *       "repository": "https://github.com/Ryan-CW-Code/RyanJson",
+	 *   next (
+	 *       "keywords": ["json", "streamlined", "parser"],
+	 *   next (
+	 *       "others": { ... }
+	 *   )))
+	 *   }
+	 */
+
+	/*
+	 * 设计特点:
+	 * - 一个 Json 节点最多 malloc 两次(一次节点本身,一次可选的 key/stringValue),
+	 *   对嵌入式系统非常友好,减少 malloc 头部开销。
+	 *
+	 * - key 和 stringValue 必须通过指针管理:
+	 *   * 如果直接放在节点里,虽然只需一次 malloc,
+	 *     但修改场景会遇到替换/释放困难。
+	 *   * 用户可能传递的 Json 对象不是指针,无法直接替换节点,
+	 *     要求应用层传递指针会增加侵入性,不符合“应用层无需修改”的目标。
+	 *
+	 * - 因此采用指针方式,保证灵活性和低侵入性。
+	 */
 };
 
 typedef struct RyanJsonNode *RyanJson_t;
@@ -87,8 +127,8 @@ typedef void (*RyanJsonFree_t)(void *block);
 typedef void *(*RyanJsonRealloc_t)(void *block, size_t size);
 
 /**
- * !!!较底层接口, 不推荐用户使用,除非用户知道这些接口意义
- * !!!一定要看这里,这里的接口不推荐使用
+ * !!! 较底层接口, 不推荐用户使用,除非用户知道这些接口意义
+ * !!! 一定要看这里,这里的接口不推荐使用
  */
 #define RyanJsonGetMask(bits)                           (((1U << (bits)) - 1))
 #define RyanJsonGetPayloadPtr(pJson)                    ((uint8_t *)(pJson) + sizeof(struct RyanJsonNode))
@@ -113,9 +153,9 @@ typedef void *(*RyanJsonRealloc_t)(void *block, size_t size);
 // flag空间不够的时候可以把这个字段弃用,用redis的listpack方法将key和keyLen一起表示,内存占用也挺好,但是复杂度高,有空间就保持现在这样
 #define RyanJsonGetPayloadEncodeKeyLenByFlag(pJson)        ((uint8_t)RyanJsonGetPayloadFlagField((pJson), 5, RyanJsonGetMask(2)) + 1)
 #define RyanJsonSetPayloadEncodeKeyLenByFlag(pJson, value) RyanJsonSetPayloadFlagField((pJson), 5, RyanJsonGetMask(2), (value))
-extern RyanJsonBool_e RyanJsonInsert(RyanJson_t pJson, int32_t index, RyanJson_t item);
+extern RyanJsonBool_e RyanJsonInsert(RyanJson_t pJson, uint32_t index, RyanJson_t item);
 extern void *RyanJsonGetValue(RyanJson_t pJson);
-extern RyanJson_t RyanJsonCreateItem(const char *key, RyanJson_t item);
+extern RyanJson_t RyanJsonCreateItem(const char *key, RyanJson_t item); // 需用户释放内存
 /**
  * !!!上面的接口不推荐使用
  *
@@ -125,30 +165,29 @@ extern RyanJson_t RyanJsonCreateItem(const char *key, RyanJson_t item);
  * @brief json对象函数
  */
 extern RyanJsonBool_e RyanJsonInitHooks(RyanJsonMalloc_t _malloc, RyanJsonFree_t _free, RyanJsonRealloc_t _realloc);
-extern RyanJson_t RyanJsonParseOptions(const char *text, int32_t size, RyanJsonBool_e requireNullTerminator,
-				       const char **parseEndPtr);                                            // 需用户释放内存
-#define RyanJsonParse(text) RyanJsonParseOptions((text), (int32_t)RyanJsonStrlen(text), RyanJsonFalse, NULL) // 需用户释放内存
+extern RyanJson_t RyanJsonParseOptions(const char *text, uint32_t size, RyanJsonBool_e requireNullTerminator,
+				       const char **parseEndPtr);                                             // 需用户释放内存
+#define RyanJsonParse(text) RyanJsonParseOptions((text), (uint32_t)RyanJsonStrlen(text), RyanJsonFalse, NULL) // 需用户释放内存
+extern void RyanJsonDelete(RyanJson_t pJson);
+extern void RyanJsonFree(void *block);
 
 /**
  * @brief 打印json对象函数
  */
-extern char *RyanJsonPrint(RyanJson_t pJson, int32_t preset, RyanJsonBool_e format, int32_t *len); // 需用户释放内存
-extern char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, int32_t length, RyanJsonBool_e format, int32_t *len);
+extern char *RyanJsonPrint(RyanJson_t pJson, uint32_t preset, RyanJsonBool_e format, uint32_t *len); // 需用户释放内存
+extern char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, uint32_t length, RyanJsonBool_e format, uint32_t *len);
 
 /**
  * @brief json杂项函数
  */
 extern RyanJson_t RyanJsonDuplicate(RyanJson_t pJson); // 需用户释放内存
-extern int32_t RyanJsonGetSize(RyanJson_t pJson);      // 获取Json中子项个数
-extern int32_t RyanJsonMinify(char *text, int32_t textLen);
-
-extern void RyanJsonDelete(RyanJson_t pJson);
-extern void RyanJsonFree(void *block);
-
-extern RyanJsonBool_e RyanJsonCompare(RyanJson_t a, RyanJson_t b);
+extern uint32_t RyanJsonMinify(char *text, int32_t textLen);
+extern RyanJsonBool_e RyanJsonCompare(RyanJson_t leftJson, RyanJson_t rightJson);
+extern uint32_t RyanJsonGetSize(RyanJson_t pJson);
+#define RyanJsonGetArraySize(pJson) RyanJsonGetSize(pJson)
 
 /**
- * @brief 添加 / 删除相关函数
+ * @brief 添加相关函数
  */
 extern RyanJson_t RyanJsonCreateObject(void);                                  // 如果没有添加到父json, 则需释放内存
 extern RyanJson_t RyanJsonCreateNull(const char *key);                         // 如果没有添加到父json, 则需释放内存
@@ -158,30 +197,36 @@ extern RyanJson_t RyanJsonCreateDouble(const char *key, double number);        /
 extern RyanJson_t RyanJsonCreateString(const char *key, const char *string);   // 如果没有添加到父json, 则需释放内存
 extern RyanJson_t RyanJsonCreateArray(void);                                   // 如果没有添加到父json, 则需释放内存
 
-// 语法糖,根据传入的numbers数组创建一个int类型的数组。如果没有添加到父json, 则需释放内存
-extern RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, int32_t count);
-// 语法糖,根据传入的numbers数组创建一个double类型的数组。如果没有添加到父json, 则需释放内存
-extern RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, int32_t count);
-// 语法糖,根据传入的strings数组创建一个string类型的数组。如果没有添加到父json, 则需释放内存
-extern RyanJson_t RyanJsonCreateStringArray(const char **strings, int32_t count);
+/**
+ * @brief 分离相关函数
+ */
+extern RyanJson_t RyanJsonDetachByIndex(RyanJson_t pJson, uint32_t index); // 需用户释放内存
+extern RyanJson_t RyanJsonDetachByKey(RyanJson_t pJson, const char *key);  // 需用户释放内存
 
-extern RyanJson_t RyanJsonDetachByIndex(RyanJson_t pJson, int32_t index); // 需用户释放内存
-extern RyanJson_t RyanJsonDetachByKey(RyanJson_t pJson, const char *key); // 需用户释放内存
-extern RyanJsonBool_e RyanJsonDeleteByIndex(RyanJson_t pJson, int32_t index);
+/**
+ * @brief 删除相关函数
+ */
+extern RyanJsonBool_e RyanJsonDeleteByIndex(RyanJson_t pJson, uint32_t index);
 extern RyanJsonBool_e RyanJsonDeleteByKey(RyanJson_t pJson, const char *key);
 
+/**
+ * @brief 查询函数
+ */
+extern RyanJson_t RyanJsonGetObjectByKey(RyanJson_t pJson, const char *key);
+extern RyanJson_t RyanJsonGetObjectByIndex(RyanJson_t pJson, uint32_t index);
+
 // 工具宏
 #define RyanJsonMakeBool(ex) ((ex) ? RyanJsonTrue : RyanJsonFalse)
 
 /**
  * @brief 查询函数
  */
-extern RyanJson_t RyanJsonGetObjectByKey(RyanJson_t pJson, const char *key);
-extern RyanJson_t RyanJsonGetObjectByIndex(RyanJson_t pJson, int32_t index);
-
 #define RyanJsonHasObjectByKey(pJson, key)     RyanJsonMakeBool(RyanJsonGetObjectByKey(pJson, key))
 #define RyanJsonHasObjectByIndex(pJson, index) RyanJsonMakeBool(RyanJsonGetObjectByIndex(pJson, index))
 
+/**
+ * @brief 类型判断宏
+ */
 #define RyanJsonIsKey(pJson)    RyanJsonMakeBool(RyanJsonGetPayloadWhiteKeyByFlag(pJson))
 #define RyanJsonIsNull(pJson)   RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeNull)
 #define RyanJsonIsBool(pJson)   RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeBool)
@@ -192,7 +237,10 @@ extern RyanJson_t RyanJsonGetObjectByIndex(RyanJson_t pJson, int32_t index);
 #define RyanJsonIsArray(pJson)  RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeArray)
 #define RyanJsonIsObject(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeObject)
 
-//! get value函数使用前一定要RyanJsonIsXXXX宏做好判断,否则会内存访问越界
+/**
+ * @brief 取值宏
+ * !取值宏使用前一定要RyanJsonIsXXXX类型判断宏做好判断,否则会内存访问越界
+ */
 extern char *RyanJsonGetKey(RyanJson_t pJson);
 extern char *RyanJsonGetStringValue(RyanJson_t pJson);
 #define RyanJsonGetBoolValue(pJson)   RyanJsonGetPayloadBoolValueByFlag(pJson)
@@ -201,16 +249,16 @@ extern char *RyanJsonGetStringValue(RyanJson_t pJson);
 #define RyanJsonGetArrayValue(pJson)  (*(RyanJson_t *)RyanJsonGetValue(pJson))
 #define RyanJsonGetObjectValue(pJson) (*(RyanJson_t *)RyanJsonGetValue(pJson))
 
-#define RyanJsonGetArraySize(pJson) RyanJsonGetSize(pJson)
-
-//! add函数使用前建议RyanJsonIsXXXX宏判断是否是对象 / 数组,否则会内存访问越界
-//! add函数内部会处理失败情况,如果返回false,不需要用户手动释放内存
-#define RyanJsonAddNullToObject(pJson, key)           RyanJsonInsert(pJson, INT32_MAX, RyanJsonCreateNull(key))
-#define RyanJsonAddBoolToObject(pJson, key, boolean)  RyanJsonInsert(pJson, INT32_MAX, RyanJsonCreateBool(key, boolean))
-#define RyanJsonAddIntToObject(pJson, key, number)    RyanJsonInsert(pJson, INT32_MAX, RyanJsonCreateInt(key, number))
-#define RyanJsonAddDoubleToObject(pJson, key, number) RyanJsonInsert(pJson, INT32_MAX, RyanJsonCreateDouble(key, number))
-#define RyanJsonAddStringToObject(pJson, key, string) RyanJsonInsert(pJson, INT32_MAX, RyanJsonCreateString(key, string))
-// #define RyanJsonAddItemToObject(pJson, key, item)     RyanJsonInsert(pJson, INT32_MAX, RyanJsonCreateItem(key, item))
+/**
+ * @brief 添加相关函数
+ * ! add函数使用前建议RyanJsonIsXXXX宏判断是否是对象 / 数组,否则会内存访问越界
+ * ! add函数内部会处理失败情况,如果返回false,不需要用户手动释放内存
+ */
+#define RyanJsonAddNullToObject(pJson, key)           RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateNull(key))
+#define RyanJsonAddBoolToObject(pJson, key, boolean)  RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateBool(key, boolean))
+#define RyanJsonAddIntToObject(pJson, key, number)    RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateInt(key, number))
+#define RyanJsonAddDoubleToObject(pJson, key, number) RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateDouble(key, number))
+#define RyanJsonAddStringToObject(pJson, key, string) RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateString(key, string))
 extern RyanJsonBool_e RyanJsonAddItemToObject(RyanJson_t pJson, char *key, RyanJson_t item);
 
 #define RyanJsonAddNullToArray(pJson)           RyanJsonAddNullToObject(pJson, NULL)
@@ -220,13 +268,15 @@ extern RyanJsonBool_e RyanJsonAddItemToObject(RyanJson_t pJson, char *key, RyanJ
 #define RyanJsonAddStringToArray(pJson, string) RyanJsonAddStringToObject(pJson, NULL, string)
 #define RyanJsonAddItemToArray(pJson, item)     RyanJsonAddItemToObject(pJson, NULL, item)
 
-// 遍历函数
+/**
+ * @brief 遍历函数
+ */
 #define RyanJsonArrayForEach(pJson, item)  for ((item) = RyanJsonGetArrayValue(pJson); NULL != (item); (item) = (item)->next)
 #define RyanJsonObjectForEach(pJson, item) for ((item) = RyanJsonGetObjectValue(pJson); NULL != (item); (item) = (item)->next)
 
 /**
- * @brief change函数
- * !change函数没有对入参做校验,使用前请做使用RyanJsonIsXXXX宏做好判断,否则会内存访问越界
+ * @brief 修改相关函数
+ * !修改函数没有对入参做校验,使用前请做使用RyanJsonIsXXXX类型判断宏做好判断,否则会内存访问越界
  */
 extern RyanJsonBool_e RyanJsonChangeKey(RyanJson_t pJson, const char *key);
 extern RyanJsonBool_e RyanJsonChangeStringValue(RyanJson_t pJson, const char *strValue);
@@ -236,8 +286,12 @@ extern RyanJsonBool_e RyanJsonChangeStringValue(RyanJson_t pJson, const char *st
 
 // 这是change方法的补充,当需要修改value类型时,使用此函数
 // 请参考 changeJsonTest 示例,严格按照规则来使用
+/**
+ * @brief
+ * !这是change方法的补充,当需要修改value类型时,使用此函数,请参考 RyanJsonBaseTestChangeJson 示例,严格按照规则来使用
+ */
 extern RyanJsonBool_e RyanJsonReplaceByKey(RyanJson_t pJson, const char *key, RyanJson_t item);
-extern RyanJsonBool_e RyanJsonReplaceByIndex(RyanJson_t pJson, int32_t index, RyanJson_t item); // object对象也可以使用,但是不推荐
+extern RyanJsonBool_e RyanJsonReplaceByIndex(RyanJson_t pJson, uint32_t index, RyanJson_t item); // object对象也可以使用,但是不推荐
 
 #ifdef __cplusplus
 }

+ 77 - 31
RyanJson/RyanJsonConfig.h

@@ -5,26 +5,26 @@
 extern "C" {
 #endif
 
-#ifdef RT_VER_NUM
-#define RyanJsonMemset             rt_memset
-#define RyanJsonMemcpy             rt_memcpy
-#define RyanJsonStrlen             rt_strlen
-#define RyanJsonStrcmp             rt_strcmp
-#define RyanJsonSnprintf           rt_snprintf
-#define RyanJsonPlatformAssert(EX) RT_ASSERT(EX)
-#else
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
-#include <stdarg.h>
 #include <stdbool.h>
 #include <limits.h>
 #include <float.h>
 #include <math.h>
 #include <inttypes.h>
+
+#ifdef RT_VER_NUM
+#include "rtthread.h"
+#define RyanJsonMemset             rt_memset
+#define RyanJsonMemcpy             rt_memcpy
+#define RyanJsonStrlen             rt_strlen
+#define RyanJsonStrcmp             rt_strcmp
+#define RyanJsonSnprintf           rt_snprintf
+#define RyanJsonPlatformAssert(EX) RT_ASSERT(EX)
+#else
 #include <assert.h>
-#include "valloc.h"
 #define RyanJsonMemset             memset
 #define RyanJsonMemcpy             memcpy
 #define RyanJsonStrlen             strlen
@@ -38,13 +38,16 @@ extern "C" {
 
 // 是否支持未对齐访问,未定义时会根据平台选择,
 // 一般不用管,如果你明白你的需求就自己定义
-// #define RyanJsonAlignUnalignedAccessSupported 0
+// true 表示支持未对齐访问
+// false 表示不支持未对齐访问
+// UINT8_MAX 标识让RyanJson自动判断,但可能会漏掉支持对齐访问的平台
+#define RyanJsonAlignUnalignedAccessSupported UINT8_MAX
 
 // 限制解析数组/对象中嵌套的深度
 // RyanJson使用递归 序列化/反序列化 json
 // 请根据单片机资源合理设置以防止堆栈溢出。
 #ifndef RyanJsonNestingLimit
-#define RyanJsonNestingLimit 900000000
+#define RyanJsonNestingLimit 9000000
 #endif
 
 // 当 RyanJsonPrint 剩余缓冲空间不足时申请的空间大小
@@ -69,30 +72,73 @@ extern "C" {
  * @brief 判断是否支持未对齐访问
  *
  */
-#ifndef RyanJsonAlignUnalignedAccessSupported
-
-#if defined(__ARM_ARCH_6M__) // Cortex-M0/M0+/M1 属于 ARMv6-M
-#define RyanJsonAlignUnalignedAccessSupported 0
-#elif defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) // Cortex-M3/M4/M7 属于 ARMv7-M/EM
-#define RyanJsonAlignUnalignedAccessSupported 1
-#elif defined(__ARM_ARCH_8M_BASE__) || defined(__ARM_ARCH_8M_MAIN__) // Cortex-M23/M33 属于 ARMv8-M
-#define RyanJsonAlignUnalignedAccessSupported 1
-#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) // Cortex-A/R 属于 ARMv7-A/R
-#define RyanJsonAlignUnalignedAccessSupported 1
-#elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) // ARM9/ARM11 等老核
-#define RyanJsonAlignUnalignedAccessSupported 0
-#elif defined(__riscv) // RISC-V MCU 默认不支持未对齐访问
-#define RyanJsonAlignUnalignedAccessSupported 0
-#elif defined(__i386__) || defined(__x86_64__) // x86 / x86-64
-#define RyanJsonAlignUnalignedAccessSupported 1
+#if UINT8_MAX == RyanJsonAlignUnalignedAccessSupported
+#undef RyanJsonAlignUnalignedAccessSupported
+
+// Cortex-M0/M0+/M1 属于 ARMv6-M
+#if defined(__ARM_ARCH_6M__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// Cortex-M3/M4/M7 属于 ARMv7-M/EM
+#elif defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+#define RyanJsonAlignUnalignedAccessSupported true
+
+// Cortex-M23/M33 属于 ARMv8-M
+#elif defined(__ARM_ARCH_8M_BASE__) || defined(__ARM_ARCH_8M_MAIN__)
+#define RyanJsonAlignUnalignedAccessSupported true
+
+// Cortex-A/R 属于 ARMv7-A/R
+#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
+#define RyanJsonAlignUnalignedAccessSupported true
+
+// ARM9/ARM11 等老核
+#elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// ARMv8-A / ARM64
+#elif defined(__aarch64__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_9__)
+#define RyanJsonAlignUnalignedAccessSupported true
+
+// RISC-V MCU 默认不支持未对齐访问
+#elif defined(__riscv)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// x86 / x86-64
+#elif defined(__i386__) || defined(__x86_64__)
+#define RyanJsonAlignUnalignedAccessSupported true
+
+// MIPS
+#elif defined(__mips__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// PowerPC
+#elif defined(__powerpc__) || defined(__ppc__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// SPARC
+#elif defined(__sparc__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// SuperH
+#elif defined(__sh__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
+// Alpha
+#elif defined(__alpha__)
+#define RyanJsonAlignUnalignedAccessSupported true
+
+// Itanium
+#elif defined(__ia64__)
+#define RyanJsonAlignUnalignedAccessSupported false
+
 #else
 // 默认认为不支持未对齐访问
-#define RyanJsonAlignUnalignedAccessSupported 0
+#define RyanJsonAlignUnalignedAccessSupported false
 #endif
 
-#endif // RyanJsonAlignUnalignedAccessSupported
+#endif // UINT8_MAX == RyanJsonAlignUnalignedAccessSupported
 
-#if 0 == RyanJsonAlignUnalignedAccessSupported
+#if true != RyanJsonAlignUnalignedAccessSupported
 #define RyanJsonAlign sizeof(void *)
 #else
 #define RyanJsonAlign sizeof(uint8_t)

+ 39 - 37
RyanJson/RyanJsonUtils.c

@@ -12,17 +12,17 @@ RyanJson_t RyanJsonGetObjectByKeys(RyanJson_t pJson, const char *key, ...)
 {
 	RyanJsonCheckReturnNull(NULL != pJson && NULL != key);
 
-	const char *s = key;
-	RyanJson_t nextItem = RyanJsonGetObjectByKey(pJson, s);
+	const char *nextKey = key;
+	RyanJson_t nextItem = RyanJsonGetObjectByKey(pJson, nextKey);
 	RyanJsonCheckReturnNull(NULL != nextItem && RyanJsonIsKey(nextItem));
 
 	va_list args;
 	va_start(args, key);
-	s = va_arg(args, const char *);
-	while (nextItem && NULL != s)
+	nextKey = va_arg(args, const char *);
+	while (nextItem && NULL != nextKey)
 	{
-		nextItem = RyanJsonGetObjectByKey(nextItem, s);
-		s = va_arg(args, char *);
+		nextItem = RyanJsonGetObjectByKey(nextItem, nextKey);
+		nextKey = va_arg(args, char *);
 	}
 	va_end(args);
 
@@ -37,21 +37,21 @@ RyanJson_t RyanJsonGetObjectByKeys(RyanJson_t pJson, const char *key, ...)
  * @param ... 可变参,连续输入索引,直到INT_MIN结束
  * @return RyanJson_t
  */
-RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, int32_t index, ...)
+RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, uint32_t index, ...)
 {
 	RyanJsonCheckReturnNull(NULL != pJson && index >= 0);
 
-	int32_t i = index;
-	RyanJson_t nextItem = RyanJsonGetObjectByIndex(pJson, i);
+	uint32_t nextIndex = index;
+	RyanJson_t nextItem = RyanJsonGetObjectByIndex(pJson, nextIndex);
 	RyanJsonCheckReturnNull(NULL != nextItem);
 
 	va_list args;
 	va_start(args, index);
-	i = va_arg(args, int32_t);
-	while (nextItem && INT32_MIN != i)
+	nextIndex = va_arg(args, uint32_t);
+	while (nextItem && nextIndex > 0)
 	{
-		nextItem = RyanJsonGetObjectByIndex(nextItem, i);
-		i = va_arg(args, int32_t);
+		nextItem = RyanJsonGetObjectByIndex(nextItem, nextIndex);
+		nextIndex = va_arg(args, uint32_t);
 	}
 	va_end(args);
 
@@ -65,12 +65,12 @@ RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, int32_t index, ...)
  * @param count 数组的长度
  * @return RyanJson_t
  */
-RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, int32_t count)
+RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, uint32_t count)
 {
 	RyanJsonCheckReturnNull(NULL != numbers && count > 0);
 
 	RyanJson_t pJson = RyanJsonCreateArray();
-	for (int32_t i = 0; pJson && i < count; i++) { RyanJsonAddIntToArray(pJson, numbers[i]); }
+	for (uint32_t i = 0; pJson && i < count; i++) { RyanJsonAddIntToArray(pJson, numbers[i]); }
 	return pJson;
 }
 
@@ -81,12 +81,12 @@ RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, int32_t count)
  * @param count
  * @return RyanJson_t
  */
-RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, int32_t count)
+RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, uint32_t count)
 {
 	RyanJsonCheckReturnNull(NULL != numbers && count > 0);
 
 	RyanJson_t pJson = RyanJsonCreateArray();
-	for (int32_t i = 0; pJson && i < count; i++) { RyanJsonAddDoubleToArray(pJson, numbers[i]); }
+	for (uint32_t i = 0; pJson && i < count; i++) { RyanJsonAddDoubleToArray(pJson, numbers[i]); }
 	return pJson;
 }
 
@@ -97,32 +97,32 @@ RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, int32_t count)
  * @param count
  * @return RyanJson_t
  */
-RyanJson_t RyanJsonCreateStringArray(const char **strings, int32_t count)
+RyanJson_t RyanJsonCreateStringArray(const char **strings, uint32_t count)
 {
 	RyanJsonCheckReturnNull(NULL != strings && count > 0);
 
 	RyanJson_t pJson = RyanJsonCreateArray();
-	for (int32_t i = 0; pJson && i < count; i++) { RyanJsonAddStringToArray(pJson, strings[i]); }
+	for (uint32_t i = 0; pJson && i < count; i++) { RyanJsonAddStringToArray(pJson, strings[i]); }
 	return pJson;
 }
 
 /**
  * @brief 递归比较两个 pJson 对象key是否相等。
  * 此接口效率较低, 谨慎使用
- * @param a
- * @param b
+ * @param leftJson
+ * @param rightJson
  * @return RyanJsonBool_e
  */
-RyanJsonBool_e RyanJsonCompareOnlyKey(RyanJson_t a, RyanJson_t b)
+RyanJsonBool_e RyanJsonCompareOnlyKey(RyanJson_t leftJson, RyanJson_t rightJson)
 {
-	if (NULL == a || NULL == b) { return RyanJsonFalse; }
+	if (NULL == leftJson || NULL == rightJson) { return RyanJsonFalse; }
 
 	// 相同的对象相等
-	if (a == b) { return RyanJsonTrue; }
+	if (leftJson == rightJson) { return RyanJsonTrue; }
 
-	if (RyanJsonGetType(a) != RyanJsonGetType(b)) { return RyanJsonFalse; }
+	if (RyanJsonGetType(leftJson) != RyanJsonGetType(rightJson)) { return RyanJsonFalse; }
 
-	switch (RyanJsonGetType(a))
+	switch (RyanJsonGetType(leftJson))
 	{
 	case RyanJsonTypeBool:
 	case RyanJsonTypeNull:
@@ -130,30 +130,32 @@ RyanJsonBool_e RyanJsonCompareOnlyKey(RyanJson_t a, RyanJson_t b)
 	case RyanJsonTypeString: return RyanJsonTrue;
 
 	case RyanJsonTypeArray: {
-		if (RyanJsonGetSize(a) != RyanJsonGetSize(b)) { return RyanJsonFalse; }
+		if (RyanJsonGetSize(leftJson) != RyanJsonGetSize(rightJson)) { return RyanJsonFalse; }
 
-		for (int32_t count = 0; count < RyanJsonGetSize(a); count++)
+		RyanJson_t item;
+		uint32_t itemIndex = 0;
+		RyanJsonArrayForEach(leftJson, item)
 		{
-			if (RyanJsonTrue != RyanJsonCompareOnlyKey(RyanJsonGetObjectByIndex(a, count), RyanJsonGetObjectByIndex(b, count)))
+			if (RyanJsonTrue != RyanJsonCompareOnlyKey(item, RyanJsonGetObjectByIndex(rightJson, itemIndex)))
 			{
 				return RyanJsonFalse;
 			}
+			itemIndex++;
 		}
 		return RyanJsonTrue;
 	}
 
 	case RyanJsonTypeObject: {
-		RyanJson_t a_element, b_element;
-		if (RyanJsonGetSize(a) != RyanJsonGetSize(b)) { return RyanJsonFalse; }
+		if (RyanJsonGetSize(leftJson) != RyanJsonGetSize(rightJson)) { return RyanJsonFalse; }
 
-		RyanJsonObjectForEach(a, a_element)
+		RyanJson_t item;
+		RyanJsonObjectForEach(leftJson, item)
 		{
-			b_element = RyanJsonGetObjectByKey(b, RyanJsonGetKey(a_element));
-			if (NULL == b_element) { return RyanJsonFalse; }
-
-			if (RyanJsonTrue != RyanJsonCompareOnlyKey(a_element, b_element)) { return RyanJsonFalse; }
+			if (RyanJsonTrue != RyanJsonCompareOnlyKey(item, RyanJsonGetObjectByKey(rightJson, RyanJsonGetKey(item))))
+			{
+				return RyanJsonFalse;
+			}
 		}
-
 		return RyanJsonTrue;
 	}
 	}

+ 8 - 8
RyanJson/RyanJsonUtils.h

@@ -1,4 +1,3 @@
-
 #ifndef __RyanJsonUtils__
 #define __RyanJsonUtils__
 
@@ -7,26 +6,27 @@ extern "C" {
 #endif
 
 #include "RyanJson.h"
+#include <stdarg.h>
 
 // 语法糖,根据传入的numbers数组创建一个int类型的数组。如果没有添加到父json, 则需释放内存
-extern RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, int32_t count);
+extern RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, uint32_t count);
 // 语法糖,根据传入的numbers数组创建一个double类型的数组。如果没有添加到父json, 则需释放内存
-extern RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, int32_t count);
+extern RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, uint32_t count);
 // 语法糖,根据传入的strings数组创建一个string类型的数组。如果没有添加到父json, 则需释放内存
-extern RyanJson_t RyanJsonCreateStringArray(const char **strings, int32_t count);
+extern RyanJson_t RyanJsonCreateStringArray(const char **strings, uint32_t count);
 
-extern RyanJsonBool_e RyanJsonCompareOnlyKey(RyanJson_t a, RyanJson_t b);
+extern RyanJsonBool_e RyanJsonCompareOnlyKey(RyanJson_t leftJson, RyanJson_t rightJson);
 
 /**
  * @brief 查询函数
  */
-extern RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, int32_t index, ...);
+extern RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, uint32_t index, ...);
 extern RyanJson_t RyanJsonGetObjectByKeys(RyanJson_t pJson, const char *key, ...);
 #define RyanJsonGetObjectToKey(pJson, key, ...)     RyanJsonGetObjectByKeys(pJson, (key), ##__VA_ARGS__, NULL)
-#define RyanJsonGetObjectToIndex(pJson, index, ...) RyanJsonGetObjectByIndexs(pJson, (index), ##__VA_ARGS__, INT32_MIN)
+#define RyanJsonGetObjectToIndex(pJson, index, ...) RyanJsonGetObjectByIndexs(pJson, (index), ##__VA_ARGS__, 0)
 
 #define RyanJsonHasObjectToKey(pJson, key, ...)     RyanJsonMakeBool(RyanJsonGetObjectByKeys(pJson, key, ##__VA_ARGS__, NULL))
-#define RyanJsonHasObjectToIndex(pJson, index, ...) RyanJsonMakeBool(RyanJsonGetObjectByIndexs(pJson, index, ##__VA_ARGS__, INT32_MIN))
+#define RyanJsonHasObjectToIndex(pJson, index, ...) RyanJsonMakeBool(RyanJsonGetObjectByIndexs(pJson, index, ##__VA_ARGS__, 0))
 
 #ifdef __cplusplus
 }

二進制
docs/assert/README.assert/image-20230822200717809.png


二進制
docs/assert/README.assert/image-20230822200726742.png


+ 16 - 9
example/RyanJsonExample.c

@@ -6,6 +6,7 @@
 #include <time.h>
 
 #include "RyanJson.h"
+#include "RyanJsonUtils.h"
 #include "valloc.h"
 
 /**
@@ -43,11 +44,13 @@ static int createJsonExample(void)
 
 	// 添加浮点数子数组
 	double arrayDouble[] = {16.89, 16.89, 16.89, 16.89, 16.89};
-	RyanJsonAddItemToObject(jsonRoot, "arrayDouble", RyanJsonCreateDoubleArray(arrayDouble, sizeof(arrayDouble) / sizeof(arrayDouble[0])));
+	RyanJsonAddItemToObject(jsonRoot, "arrayDouble",
+				RyanJsonCreateDoubleArray(arrayDouble, sizeof(arrayDouble) / sizeof(arrayDouble[0])));
 
 	// 添加字符串子数组
 	const char *arrayString[] = {"hello", "hello", "hello", "hello", "hello"};
-	RyanJsonAddItemToObject(jsonRoot, "arrayString", RyanJsonCreateStringArray(arrayString, sizeof(arrayString) / sizeof(arrayString[0])));
+	RyanJsonAddItemToObject(jsonRoot, "arrayString",
+				RyanJsonCreateStringArray(arrayString, sizeof(arrayString) / sizeof(arrayString[0])));
 
 	// 添加杂项数组
 	RyanJson_t array = RyanJsonCreateArray();
@@ -83,7 +86,7 @@ static int createJsonExample(void)
 
 	uint32_t len = 0;
 	str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, &len); // 以带格式方式将数据打印出来
-	printf("strLen: %d, data: %s\r\n", len, str);
+	printf("strLen: %" PRIu32 ", data: %s\r\n", len, str);
 	RyanJsonFree(str);
 
 	RyanJsonDelete(jsonRoot);
@@ -100,10 +103,14 @@ static int loadJsonExample(void)
 {
 	char *str = NULL;
 	RyanJson_t jsonRoot;
-	const char jsonstr[] = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":{\"inter\":16,\"double\":16.89,\"string\":\"hello\","
-			       "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89],\"arrayString\":[\"hello\","
-			       "\"hello\",\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null],\"arrayItem\":[{\"inter\":16,\"double\":16.89,\"string\":\"hello\","
-			       "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}]}";
+	const char jsonstr[] = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,"
+			       "\"item\":{\"inter\":16,\"double\":16.89,\"string\":\"hello\","
+			       "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,"
+			       "16.89,16.89,16.89,16.89],\"arrayString\":[\"hello\","
+			       "\"hello\",\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null],\"arrayItem\":[{"
+			       "\"inter\":16,\"double\":16.89,\"string\":\"hello\","
+			       "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":\"hello\","
+			       "\"boolTrue\":true,\"boolFalse\":false,\"null\":null}]}";
 
 	// 解析json数据
 	jsonRoot = RyanJsonParse(jsonstr);
@@ -127,7 +134,7 @@ static int loadJsonExample(void)
 	// 将序列化的数据以有格式样式打印出来
 	uint32_t len = 0;
 	str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, &len);
-	printf("strLen: %d, data: %s\r\n", len, str);
+	printf("strLen: %" PRIu32 ", data: %s\r\n", len, str);
 	RyanJsonFree(str);
 
 	// 删除json对象
@@ -168,7 +175,7 @@ static int changeJsonExample(void)
 	// 将序列化的数据以有格式样式打印出来
 	uint32_t len = 0;
 	str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, &len);
-	printf("strLen: %d, data: %s\r\n", len, str);
+	printf("strLen: %" PRIu32 ", data: %s\r\n", len, str);
 	RyanJsonFree(str);
 
 	// 删除json对象

+ 1 - 1
run_coverage.sh

@@ -35,5 +35,5 @@ llvm-cov report ./build/linux/x86/release/RyanJson \
 llvm-cov show ./build/linux/x86/release/RyanJson \
   -instr-profile=default.profdata \
   -format=html \
-  -output-dir=coverage_report \
+  -output-dir=docs \
   -show-mcdc-summary

+ 3 - 7
test/RyanJsonMemoryFootprintTest.c

@@ -65,17 +65,13 @@ static void printfJsonCompera(char *jsonstr)
 {
 	int RyanJsonCount = 0;
 	int cJSONCount = 0;
-	int yyjsonCount = 0;
 	RyanJsonCount = RyanJsonMemoryFootprint(jsonstr);
 	cJSONCount = cJSONMemoryFootprint(jsonstr);
-	yyjsonCount = yyjsonMemoryFootprint(jsonstr);
-	printf("json原始文本长度为 %ld, 序列化后RyanJson内存占用: %d, cJSON内存占用: %d, yyjson内存占用: %d\r\n", strlen(jsonstr),
-	       RyanJsonCount, cJSONCount, yyjsonCount);
 
-	double save_vs_cjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)cJSONCount;
-	double save_vs_yyjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)yyjsonCount;
+	printf("json原始文本长度为 %ld, 序列化后RyanJson内存占用: %d, cJSON内存占用: %d\r\n", strlen(jsonstr), RyanJsonCount, cJSONCount);
 
-	printf("比cJSON节省: %.2f%% 内存占用, 比yyjson节省: %.2f%% 内存占用\r\n", save_vs_cjson, save_vs_yyjson);
+	double save_vs_cjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)cJSONCount;
+	printf("比cJSON节省: %.2f%% 内存占用\r\n", save_vs_cjson);
 }
 
 RyanJsonBool_e RyanJsonMemoryFootprintTest(void)

+ 9 - 9
test/RyanJsonRFC8259JsonTest.c

@@ -469,7 +469,7 @@ static int RyanJsonParseData(char *fileName, char *data, uint32_t len)
 		{
 			alksdjfCOunt++;
 			// 打印时避免 %s,被 NUL 截断;可以打印十六进制
-			printf("%d %s 数据不一致 -- 原始: %s -- 序列化: %s\n", alksdjfCOunt, fileName, data, str);
+			// printf("%d %s 数据不一致 -- 原始: %s -- 序列化: %s\n", alksdjfCOunt, fileName, data, str);
 			// printf("数据不一致 -- 原始len:%zu -- 序列化len:%zu\n", data_len, str_len);
 		}
 	}
@@ -514,7 +514,7 @@ static int cJSONParseData(char *fileName, char *data, uint32_t len)
 	}
 
 	cJSON_Minify(data);
-	if (0 != strcmp(data, str)) { printf("-- 原始: %s -- 序列化: %s\n", data, str); }
+	// if (0 != strcmp(data, str)) { printf("-- 原始: %s -- 序列化: %s\n", data, str); }
 
 	cJSON_free(str);
 #endif
@@ -588,13 +588,13 @@ RyanJsonBool_e RFC8259JsonTest(void)
 		goto err;
 	}
 
-	// printf("\r\n--------------------------- RFC8259  cJSON --------------------------\r\n");
-	// result = testFile("../../../../test//RFC8259JsonData", cJSONParseData);
-	// if (0 != result)
-	// {
-	// 	printf("%s:%d cJSON RFC8259JsonTest fail\r\n", __FILE__, __LINE__);
-	// 	goto err;
-	// }
+	printf("\r\n--------------------------- RFC8259  cJSON --------------------------\r\n");
+	result = testFile("../../../../test//RFC8259JsonData", cJSONParseData);
+	if (0 != result)
+	{
+		printf("%s:%d cJSON RFC8259JsonTest fail\r\n", __FILE__, __LINE__);
+		goto err;
+	}
 
 	// printf("\r\n--------------------------- RFC8259  yyjson --------------------------\r\n");
 	// result = testFile("../../../../test//RFC8259JsonData", yyjsonParseData);

+ 1 - 10
test/RyanJsonTest.c

@@ -44,16 +44,7 @@ int main(void)
 		// const char *jsonstr = "\012444444444444444";
 		// const char *jsonstr = "\"\"";
 		// const char *jsonstr = "{\"nnnnnnnnnnnnnnnnnnn\012nnlnnnnnn\":0}";
-		const char *jsonstr =
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
-			"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[";
+		const char *jsonstr = "4";
 		// const char jsonstr[] =
 		// 	"{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":{"
 		// 	"\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,"

+ 0 - 10
test/baseTest/RyanJsonBaseTestChangeJson.c

@@ -117,16 +117,6 @@ RyanJsonBool_e RyanJsonBaseTestChangeJson()
 		RyanJson_t duplicateJson = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
 		printfJsonaaaa(duplicateJson);
 
-		// RyanJson_t item = RyanJsonCreateObject2("key");
-		// // RyanJson_t item = RyanJsonCreateObject();
-		// RyanJsonAddIntToObject(item, "inter", 16);
-		// RyanJsonAddDoubleToObject(item, "double", 16.89);
-		// RyanJsonAddStringToObject(item, "string", "hello");
-		// RyanJsonAddBoolToObject(item, "boolTrue", RyanJsonTrue);
-		// RyanJsonAddBoolToObject(item, "boolFalse", RyanJsonFalse);
-		// RyanJsonAddNullToObject(item, "null");
-
-		// RyanJsonReplaceByKey(json, "arrayDouble", item);
 		RyanJsonReplaceByKey(json, "arrayDouble", duplicateJson);
 		if (!RyanJsonIsObject(RyanJsonGetObjectToKey(json, "arrayDouble")) ||
 		    -1 == rootNodeCheckTest(RyanJsonGetObjectToKey(json, "arrayDouble")))

+ 26 - 60
test/fuzzer/RyanJsonFuzzer.c

@@ -31,41 +31,21 @@
 	})
 RyanJsonBool_e isadfa = RyanJsonTrue;
 
-static void RyanPrintJsonToLog22(RyanJson_t pJson)
+static RyanJsonBool_e RyanJsonFuzzerTestByParseAndPrint(RyanJson_t pJson, const char *data, uint32_t size)
 {
-	int32_t strLen = 0;
-	char *jsonStr = RyanJsonPrint(pJson, 512, RyanJsonFalse, &strLen);
-	if (NULL == jsonStr) { return; }
 
-	for (int32_t i = 0; i < strLen; i++)
-	{
-		int32_t aaa = strLen - (i * 100);
-		if (aaa > 100) { printf("%.*s", 100, jsonStr + (i * 100)); }
-		else
-		{
-			if (aaa) { printf("%.*s", aaa, jsonStr + (i * 100)); }
-			printf("\r\n");
-			break;
-		}
-	}
-	RyanJsonFree(jsonStr);
-}
-
-static RyanJsonBool_e RyanJsonFuzzerTestByParseAndPrint(RyanJson_t pJson, const char *data, int32_t size)
-{
-
-	int32_t len = 0;
+	uint32_t len = 0;
 	char *jsonStr = RyanJsonPrint(pJson, 100, size % 2 ? RyanJsonFalse : RyanJsonTrue, &len); // 以带格式方式将数据打印出来
 	// printf("len222222222222222222: %d\r\n", len);
 	RyanJsonCheckReturnFlase(NULL != jsonStr && len > 0);
 	RyanJsonFree(jsonStr);
 
 	{
-		int32_t bufLen = len * 3;
+		uint32_t bufLen = len * 3;
 		if (bufLen < 8192) { bufLen = 8192; }
 		char *buf = malloc((size_t)bufLen);
 
-		int32_t len2 = 0;
+		uint32_t len2 = 0;
 		char *jsonStr2 = RyanJsonPrintPreallocated(pJson, buf, bufLen, size % 2 ? RyanJsonFalse : RyanJsonTrue, &len2);
 		// printf("len: %d, len2: %d, str: %s\r\n", len, len2, NULL == jsonStr2 ? "NULL" : jsonStr2);
 		if (buf)
@@ -80,7 +60,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByParseAndPrint(RyanJson_t pJson, const
 	}
 
 	{
-		int32_t bufLen = size * 3;
+		uint32_t bufLen = size * 3;
 		char *buf = malloc((size_t)bufLen);
 		if (buf)
 		{
@@ -93,7 +73,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByParseAndPrint(RyanJson_t pJson, const
 			});
 			free(buf);
 
-			int32_t len3 = 0;
+			uint32_t len3 = 0;
 			char *jsonStr3 =
 				RyanJsonPrint(jsonRoot, 100, size % 2 ? RyanJsonFalse : RyanJsonTrue, &len3); // 以带格式方式将数据打印出来
 			// printf("len222222222222222222: %d\r\n", len);
@@ -120,7 +100,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByDup(RyanJson_t pJson)
 	RyanJson_t pJsonDup = NULL;
 
 	// 测试打印和复制功能
-	int32_t len = 0;
+	uint32_t len = 0;
 
 	jsonStr = RyanJsonPrint(pJson, 100, RyanJsonFalse, &len); // 以带格式方式将数据打印出来
 	RyanJsonCheckGotoExit(NULL != jsonStr && len > 0);
@@ -151,12 +131,12 @@ static RyanJsonBool_e RyanJsonFuzzerTestByDup(RyanJson_t pJson)
 	RyanJsonCheckGotoExit(RyanJsonFalse == RyanJsonCompareOnlyKey(pJson, NULL));
 	RyanJsonCheckGotoExit(RyanJsonFalse == RyanJsonCompareOnlyKey(NULL, NULL));
 
-	int32_t dupLen = 0;
+	uint32_t dupLen = 0;
 	jsonStrDup = RyanJsonPrint(pJsonDup, 100, RyanJsonFalse, &dupLen); // 以带格式方式将数据打印出来
 	RyanJsonCheckGotoExit(NULL != jsonStrDup && dupLen > 0);
 
 	RyanJsonCheckCode(len == dupLen && 0 == memcmp(jsonStr, jsonStrDup, (size_t)len), {
-		printf("len:%d, dupLen:%d\r\n", len, dupLen);
+		printf("len:%" PRIu32 ", dupLen:%" PRIu32 "\r\n", len, dupLen);
 		printf("jsonStr:%s, jsonStrDup:%s\r\n", jsonStr, jsonStrDup);
 		RyanJsonCheckGotoExit(0);
 	});
@@ -224,7 +204,7 @@ __exit:
 	return result;
 }
 
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachChange(RyanJson_t pJson, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachChange(RyanJson_t pJson, uint32_t size)
 {
 	RyanJsonIsNull(pJson);
 
@@ -248,7 +228,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachChange(RyanJson_t pJson, int32_
 		if (RyanJsonIsInt(pJson))
 		{
 			int32_t value = RyanJsonGetIntValue(pJson);
-			RyanJsonChangeIntValue(pJson, size);
+			RyanJsonChangeIntValue(pJson, (int32_t)size);
 			RyanJsonChangeIntValue(pJson, value);
 		}
 		if (RyanJsonIsDouble(pJson))
@@ -292,7 +272,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachChange(RyanJson_t pJson, int32_
 	return RyanJsonTrue;
 }
 
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachGet2(RyanJson_t lastJson, RyanJson_t pJson, int32_t index, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachGet2(RyanJson_t lastJson, RyanJson_t pJson, uint32_t index, uint32_t size)
 {
 	RyanJsonIsNull(pJson);
 
@@ -311,12 +291,12 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachGet2(RyanJson_t lastJson, RyanJ
 	return RyanJsonTrue;
 }
 
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachGet(RyanJson_t pJson, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachGet(RyanJson_t pJson, uint32_t size)
 {
 	if (RyanJsonIsArray(pJson) || RyanJsonIsObject(pJson))
 	{
 		RyanJson_t item;
-		int32_t index = 0;
+		uint32_t index = 0;
 		RyanJsonObjectForEach(pJson, item)
 		{
 			RyanJsonFuzzerTestByForEachGet2(pJson, item, index, size);
@@ -354,7 +334,7 @@ static RyanJson_t RyanJsonFuzzerTestalkdfjald(RyanJson_t pJson)
 	}
 }
 
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachCreate(RyanJson_t pJson, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachCreate(RyanJson_t pJson, uint32_t size)
 {
 	// RyanJsonInsert的特殊情况
 	RyanJsonCheckReturnFlase(RyanJsonFalse == RyanJsonInsert(NULL, INT32_MAX, RyanJsonCreateString("key", "string")));
@@ -423,7 +403,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachCreate(RyanJson_t pJson, int32_
  * @param isFirst 是否为第一次调用(根节点)
  * @return RyanJsonBool_e
  */
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachReplace(RyanJson_t pJson, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachReplace(RyanJson_t pJson, uint32_t size)
 {
 	// 只处理数组或对象
 	if (!(RyanJsonIsArray(pJson) || RyanJsonIsObject(pJson))) { return RyanJsonTrue; }
@@ -456,7 +436,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachReplace(RyanJson_t pJson, int32
 
 	// 按 index 替换
 	{
-		int32_t idx = RyanJsonGetSize(pJson) % size;
+		uint32_t idx = RyanJsonGetSize(pJson) % size;
 		RyanJson_t newNode = RyanJsonFuzzerTestalkdfjald(pJson);
 		if (RyanJsonFalse == RyanJsonReplaceByIndex(pJson, (size % 25) ? idx : 0, newNode))
 		{
@@ -476,7 +456,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachReplace(RyanJson_t pJson, int32
  * @param isFirst 是否为第一次调用(根节点)
  * @return RyanJsonBool_e
  */
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachDetach(RyanJson_t pJson, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachDetach(RyanJson_t pJson, uint32_t size)
 {
 	if (!(RyanJsonIsArray(pJson) || RyanJsonIsObject(pJson))) { return RyanJsonTrue; }
 
@@ -519,7 +499,7 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachDetach(RyanJson_t pJson, int32_
  * @param isFirst 是否为第一次调用(根节点)
  * @return RyanJsonBool_e
  */
-static RyanJsonBool_e RyanJsonFuzzerTestByForEachDelete(RyanJson_t pJson, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByForEachDelete(RyanJson_t pJson, uint32_t size)
 {
 	if (!(RyanJsonIsArray(pJson) || RyanJsonIsObject(pJson))) { return RyanJsonTrue; }
 
@@ -552,7 +532,6 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachDelete(RyanJson_t pJson, int32_
 	{
 		if (LastItem && RyanJsonIsKey(LastItem))
 		{
-			// RyanPrintJsonToLog22(pJson);
 
 			// printf("key is %d %s\r\n", RyanJsonGetType(LastItem),
 			//        RyanJsonGetKey(LastItem) == NULL ? "NULL" : RyanJsonGetKey(LastItem));
@@ -561,19 +540,19 @@ static RyanJsonBool_e RyanJsonFuzzerTestByForEachDelete(RyanJson_t pJson, int32_
 	}
 
 	// 按 index 删除
-	int32_t idx = RyanJsonGetSize(pJson) % size;
+	uint32_t idx = RyanJsonGetSize(pJson) % size;
 	RyanJsonDeleteByIndex(pJson, (size % 25) ? idx : 0);
 
 	return RyanJsonTrue;
 }
 
-static RyanJsonBool_e RyanJsonFuzzerTestByMinify(const char *data, int32_t size)
+static RyanJsonBool_e RyanJsonFuzzerTestByMinify(const char *data, uint32_t size)
 {
 	char *buf = malloc(size + 100);
 	memset(buf, 0, size + 100);
 	memcpy(buf, data, size);
 
-	int32_t size2 = RyanJsonMinify(buf, size);
+	uint32_t size2 = RyanJsonMinify(buf, size);
 	// 非法情况
 	{
 		RyanJsonCheckReturnFlase(0 == RyanJsonMinify(NULL, 0));
@@ -581,11 +560,12 @@ static RyanJsonBool_e RyanJsonFuzzerTestByMinify(const char *data, int32_t size)
 		RyanJsonCheckReturnFlase(0 == RyanJsonMinify(NULL, -10));
 		RyanJsonCheckReturnFlase(0 == RyanJsonMinify(buf, -10));
 	}
+	// 内存泄漏就是上面出错了
 	RyanJson_t pJson2 = RyanJsonParseOptions(buf, size2, size % 2 ? RyanJsonTrue : RyanJsonFalse, NULL);
 	free(buf);
 	if (NULL != pJson2)
 	{
-		int32_t len = 0;
+		uint32_t len = 0;
 		char *jsonStr = RyanJsonPrint(pJson2, 100, RyanJsonFalse, &len); // 以带格式方式将数据打印出来
 		RyanJsonCheckCode(NULL != jsonStr && len > 0, {
 			RyanJsonDelete(pJson2);
@@ -628,7 +608,7 @@ static void *RyanJsonFuzzerRealloc(void *block, size_t size)
 
 // 需要模拟内存故障
 // tokey需要增加s测试
-int LLVMFuzzerTestOneInput(const char *data, int32_t size)
+int LLVMFuzzerTestOneInput(const char *data, uint32_t size)
 {
 
 	// !检查分支覆盖率的时候要把这个取消掉,否则不知道是这个测试用例还是Fuzzer触发的,期望的是Fuzzer触发
@@ -660,7 +640,7 @@ int LLVMFuzzerTestOneInput(const char *data, int32_t size)
 	RyanJsonInitHooks(RyanJsonFuzzerMalloc, RyanJsonFuzzerFree, size % 2 ? NULL : RyanJsonFuzzerRealloc);
 
 	const char *parseEndPtr = NULL;
-	RyanJson_t pJson = RyanJsonParseOptions(data, size, size % 2 ? RyanJsonTrue : RyanJsonFalse, &parseEndPtr);
+	RyanJson_t pJson = RyanJsonParseOptions(data, size, 0 ? RyanJsonTrue : RyanJsonFalse, &parseEndPtr);
 	if (NULL != pJson)
 	{
 		assert(NULL != parseEndPtr && parseEndPtr - data <= size);
@@ -697,23 +677,9 @@ int LLVMFuzzerTestOneInput(const char *data, int32_t size)
 
 		RyanJsonCheckCode(RyanJsonFuzzerTestByForEachReplace(pJson, size), { goto __exit; });
 
-		// 测试打印和复制功能
 		RyanJsonDelete(pJson);
 	}
 
-	// cJSON_Hooks hooks = {.malloc_fn = v_malloc, .free_fn = v_free};
-	// cJSON_InitHooks(&hooks);
-
-	// cJSON *json = cJSON_ParseWithLength(data, size);
-	// if (json)
-	// {
-
-	// 	char *str2 = cJSON_Print(json);
-	// 	cJSON_free(str2);
-	// 	cJSON_Delete(json);
-	// }
-
-	// RyanJsonMinify(data);
 	return 0;
 
 __exit: