Browse Source

添加一些示例

ryancw 2 years ago
parent
commit
8ea376a609

+ 2 - 1
.vscode/settings.json

@@ -17,7 +17,8 @@
         "cjson.h": "c",
         "unity.h": "c",
         "unity_config.h": "c",
-        "common.h": "c"
+        "common.h": "c",
+        "stdio.h": "c"
     },
     "commentTranslate.source": "Google"
 }

+ 3 - 1
.vscode/tasks.json

@@ -11,9 +11,11 @@
                 "-std=c99",
                 "-g",
                 "-O0",
+                "-Werror",
+                // "-Wextra",
+                // "-Wall",
                 "${cwd}\\**.c",
                 // "${cwd}\\**.h",
-                // "${cwd}\\jsonGetByStructDemo.c",
                 "${cwd}\\RyanJson\\**.c",
                 "${cwd}\\RyanJson\\**.h",
                 "${cwd}\\cJSON\\**.c",

+ 45 - 1
README.md

@@ -1,2 +1,46 @@
 # RyanJson
-一个针对资源受限的嵌入式设备优化的Json库,简介高效!
+***一个针对资源受限的嵌入式设备优化的Json库,内存占用极小的通用json库,简洁高效!***
+
+*初衷:项目进行重构json结构变复杂了很多,cJSON内存占用太高,已经满足不了需求。*
+
+## 1、介绍
+
+RyanJson是一个小巧的c语言json解析器,包含json文本文件解析 / 生成,**专门针对内存占用进行优化**。
+
+在内存占用减少40% - 60%的前提下,实现了大部分cJSON接口。
+
+运行速度和cJSON差不多,在json文本数据小于80k / 嵌套深度3000以下的json数据,RyanJson和cJSON因为小巧的设计速度要比别的json库快得多。
+
+- **低内存占用**:使用动态扩展技术,在32位系统下,一个基础json节点仅占用8字节。
+- **开发人员友好**:仅有一个c文件和头文件轻松集成,hook函数方便自定义内存钩子。类cJSON的api,迁移成本低。
+- **严格但不严苛**:符合 RFC 8295 大部分JSON标准,支持无限的json嵌套级别(需注意堆栈空间)、灵活的配置修改项
+- **可扩展性**:允许注释(需调用mini函数清除注释后再解析)、尾随逗号等无效字符(parse时可配置是否允许)等
+
+## 2、局限性
+
+- 使用int / double表示json中的number类型,精度有所丢失。建议64位的number类型最好用string字符串表示。
+- 对象中允许有重复的key,RyanJson库采用单向链表,会访问到第一个对象。
+
+## 3、测试
+
+测试代码可在本项目根目录查看。
+
+#### RFC 8295 标准测试,大部分嵌入式场景不会出现复杂的特殊json结构
+
+***RyanJson和cJSON都不适合处理复杂的UTF-16字符集,如果项目需要兼容Unicode字符集,可以考虑yyjson / json-c***
+
+![image-20230822112554099](docs/assert/README.assert/image-20230822112554099.png)
+
+#### 内存占用测试
+
+![image-20230822112757872](docs/assert/README.assert/image-20230822112757872.png)
+
+## 4、文档
+
+文档可在 [Ryan组件库](http://localhost:8000/ryan-json)获取
+
+## 5、联系
+
+Email:1831931681@qq.com
+
+wx:17513216936

+ 3 - 6
RFC8259JsonTest.c

@@ -14,7 +14,7 @@
 #include "./yyjson/yyjson.h"
 #include "./valloc/valloc.h"
 
-#define PrintfStrCmpEnable
+// #define PrintfStrCmpEnable
 
 typedef int (*jsonParseData)(char *file_name, char *data, uint32_t len);
 
@@ -266,7 +266,6 @@ next:
 // https://github.com/nst/JSONTestSuite
 int RFC8259JsonTest(void)
 {
-    printf("开始 RFC 8259 JSON 测试\r\n");
     RyanJsonInitHooks(v_malloc, v_free, v_realloc);
 
     cJSON_Hooks hooks = {
@@ -274,10 +273,8 @@ int RFC8259JsonTest(void)
         .free_fn = v_free};
     cJSON_InitHooks(&hooks);
 
-    /**
-     * @brief 其余常用功能测试
-     *
-     */
+    printf("开始 RFC 8259 JSON 测试");
+
     printf("\r\n--------------------------- RFC8259  RyanJson --------------------------\r\n");
     testFile("./RFC8259JsonData", RyanJsonParseData);
 

+ 18 - 45
RyanJson/RyanJson.c

@@ -14,7 +14,7 @@
     }
 
 // 是否还有可读的待解析文本
-#define parseCanRead(buf, num) ((buf)->size >= (num))
+#define parseCanRead(buf, num) ((buf)->size >= (uint32_t)(num))
 
 // 偏移几个字节
 #define parseBufAddOffset(buf, num) \
@@ -71,7 +71,7 @@ static free_t jsonFree = free;
 static realloc_t jsonRealloc = realloc;
 
 static RyanJsonBool RyanJsonParseValue(parseBuffer *buf, char *key, RyanJson_t *out);
-static RyanJsonBool RyanJsonPrintValue(RyanJson_t pJson, printBuffer *buf, int32_t depth, RyanJsonBool format);
+static RyanJsonBool RyanJsonPrintValue(RyanJson_t pJson, printBuffer *buf, uint32_t depth, RyanJsonBool format);
 
 static void *temp_realloc(void *block, size_t size)
 {
@@ -201,7 +201,7 @@ static char *RyanJsonStrdup(const char *str)
  * @param key 带key的对象将动态添加key子项, 没有的传null,由调用者保证key的时间有效性
  * @return RyanJson_t 新json节点句柄
  */
-static RyanJson_t RyanJsonNewNode(int32_t info, char *key)
+RyanJson_t RyanJsonNewNode(int32_t info, char *key)
 {
 
     RyanJson_t pJson = NULL;
@@ -290,7 +290,7 @@ void RyanJsonDelete(RyanJson_t pJson)
  *
  * @param block
  */
-void inline RyanJsonFree(void *block)
+inline void RyanJsonFree(void *block)
 {
     jsonFree(block);
 }
@@ -1014,7 +1014,7 @@ static inline RyanJsonBool RyanJsonPrintString(RyanJson_t pJson, printBuffer *bu
  * @param format
  * @return RyanJsonBool
  */
-static RyanJsonBool RyanJsonPrintArray(RyanJson_t pJson, printBuffer *buf, int32_t depth, RyanJsonBool format)
+static RyanJsonBool RyanJsonPrintArray(RyanJson_t pJson, printBuffer *buf, uint32_t depth, RyanJsonBool format)
 {
     int32_t count = 0;
     RyanJson_t child = RyanJsonGetObjectValue(pJson);
@@ -1106,7 +1106,7 @@ static RyanJsonBool RyanJsonPrintArray(RyanJson_t pJson, printBuffer *buf, int32
  * @param format
  * @return RyanJsonBool
  */
-static RyanJsonBool RyanJsonPrintObject(RyanJson_t pJson, printBuffer *buf, int32_t depth, RyanJsonBool format)
+static RyanJsonBool RyanJsonPrintObject(RyanJson_t pJson, printBuffer *buf, uint32_t depth, RyanJsonBool format)
 {
     RyanJson_t child = RyanJsonGetObjectValue(pJson);
 
@@ -1173,7 +1173,7 @@ static RyanJsonBool RyanJsonPrintObject(RyanJson_t pJson, printBuffer *buf, int3
     return RyanJsonTrue;
 }
 
-static RyanJsonBool RyanJsonPrintValue(RyanJson_t pJson, printBuffer *buf, int32_t depth, RyanJsonBool format)
+static RyanJsonBool RyanJsonPrintValue(RyanJson_t pJson, printBuffer *buf, uint32_t depth, RyanJsonBool format)
 {
     if (NULL == pJson)
         return RyanJsonFalse;
@@ -1340,7 +1340,7 @@ char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, uint32_t length,
 }
 
 /**
- * @brief 获取json的大小,json对象必须为obj / arr
+ * @brief 获取 json 的子项个数
  *
  * @param pJson
  * @return uint32_t
@@ -1354,7 +1354,7 @@ uint32_t RyanJsonGetSize(RyanJson_t pJson)
         return RyanJsonFalse;
 
     if (!_checkType(pJson->info, RyanJsonTypeArray) && !_checkType(pJson->info, RyanJsonTypeObject))
-        return RyanJsonFalse;
+        return 1;
 
     nextItem = RyanJsonGetObjectValue(pJson);
 
@@ -1381,8 +1381,8 @@ RyanJsonBool RyanJsonReapplyString(char **dst, const char *src)
     if (NULL == dst || NULL == src)
         return RyanJsonFalse;
 
-    if (NULL != *dst && 0 == strcmp(*dst, src))
-        return RyanJsonTrue;
+    // if (0 == strcmp(*dst, src))
+    //     return RyanJsonTrue;
 
     k = RyanJsonStrdup(src);
     if (NULL == k)
@@ -1983,7 +1983,7 @@ RyanJson_t RyanJsonCreateObject()
  * @param item
  * @return RyanJson_t
  */
-RyanJson_t RyanJsonCreateItem(char *key, RyanJson_t item)
+RyanJson_t RyanJsonCreateItem(const char *key, RyanJson_t item)
 {
     RyanJson_t newItem = NULL;
     char *k = NULL;
@@ -2307,7 +2307,7 @@ RyanJsonBool RyanJsonCompare(RyanJson_t a, RyanJson_t b)
         if (RyanJsonGetSize(a) != RyanJsonGetSize(b))
             return RyanJsonFalse;
 
-        for (int32_t count = 0; count < RyanJsonGetSize(a); count++)
+        for (uint32_t count = 0; count < RyanJsonGetSize(a); count++)
         {
             if (RyanJsonTrue != RyanJsonCompare(RyanJsonGetObjectToIndex(a, count), RyanJsonGetObjectToIndex(b, count)))
                 return RyanJsonFalse;
@@ -2363,7 +2363,7 @@ RyanJsonBool RyanJsonCompare(RyanJson_t a, RyanJson_t b)
  * @param b
  * @return RyanJsonBool
  */
-RyanJsonBool RyanJsonCompare2(RyanJson_t a, RyanJson_t b)
+RyanJsonBool RyanJsonCompareOnlyKey(RyanJson_t a, RyanJson_t b)
 {
     if (NULL == a || NULL == b)
         return RyanJsonFalse;
@@ -2391,9 +2391,9 @@ RyanJsonBool RyanJsonCompare2(RyanJson_t a, RyanJson_t b)
         if (RyanJsonGetSize(a) != RyanJsonGetSize(b))
             return RyanJsonFalse;
 
-        for (int32_t count = 0; count < RyanJsonGetSize(a); count++)
+        for (uint32_t count = 0; count < RyanJsonGetSize(a); count++)
         {
-            if (RyanJsonTrue != RyanJsonCompare2(RyanJsonGetObjectToIndex(a, count), RyanJsonGetObjectToIndex(b, count)))
+            if (RyanJsonTrue != RyanJsonCompareOnlyKey(RyanJsonGetObjectToIndex(a, count), RyanJsonGetObjectToIndex(b, count)))
                 return RyanJsonFalse;
         }
         return RyanJsonTrue;
@@ -2414,7 +2414,7 @@ RyanJsonBool RyanJsonCompare2(RyanJson_t a, RyanJson_t b)
             if (NULL == b_element)
                 return RyanJsonFalse;
 
-            if (RyanJsonTrue != RyanJsonCompare2(a_element, b_element))
+            if (RyanJsonTrue != RyanJsonCompareOnlyKey(a_element, b_element))
                 return RyanJsonFalse;
         }
 
@@ -2425,7 +2425,7 @@ RyanJsonBool RyanJsonCompare2(RyanJson_t a, RyanJson_t b)
             if (NULL == a_element)
                 return RyanJsonFalse;
 
-            if (RyanJsonTrue != RyanJsonCompare2(b_element, a_element))
+            if (RyanJsonTrue != RyanJsonCompareOnlyKey(b_element, a_element))
                 return RyanJsonFalse;
         }
         return RyanJsonTrue;
@@ -2438,30 +2438,3 @@ RyanJsonBool RyanJsonCompare2(RyanJson_t a, RyanJson_t b)
 
     return RyanJsonTrue;
 }
-
-RyanJson_t RyanJsonCreateItem2(char *key, RyanJson_t item)
-{
-    RyanJson_t newItem = NULL;
-    char *k = NULL;
-
-    if (NULL == item)
-        return NULL;
-
-    if (NULL != key)
-    {
-        k = strdup(key);
-        if (NULL == k)
-            return RyanJsonFalse;
-    }
-
-    newItem = RyanJsonNewNode(_checkType(item->info, RyanJsonTypeArray) ? RyanJsonTypeArray : RyanJsonTypeObject, k);
-    if (NULL == newItem)
-    {
-        jsonFree(k);
-        return NULL;
-    }
-
-    RyanJsonGetObjectValue(newItem) = RyanJsonGetObjectValue(item);
-
-    return newItem;
-}

+ 15 - 7
RyanJson/RyanJson.h

@@ -16,7 +16,7 @@ extern "C"
 #include <float.h>
 #include <math.h>
 
-    enum
+    typedef enum
     {
         // 类型标志 占用8字节,剩余一个备用
         RyanJsonTypeUnknow = 1 << 0,
@@ -26,12 +26,15 @@ extern "C"
         RyanJsonTypeString = 1 << 4,
         RyanJsonTypeArray = 1 << 5,
         RyanJsonTypeObject = 1 << 6,
+    } RyanjsonType_e;
 
+    typedef enum
+    {
         // flag标志
         RyanJsonValueBoolTrueFlag = 1 << 8,
         RyanJsonValueNumberIntFlag = 1 << 9,
         RyanJsonWithKeyFlag = 1 << 10
-    };
+    } RyanJsonInfoFlag_e;
 
     typedef enum
     {
@@ -61,7 +64,7 @@ extern "C"
 // RyanJson使用递归 序列化/反序列化 json
 // 请根据单片机资源合理设置以防止堆栈溢出。
 #ifndef RyanJsonNestingLimit
-#define RyanJsonNestingLimit 30000000
+#define RyanJsonNestingLimit 30000
 #endif
 
 /**
@@ -74,14 +77,17 @@ extern "C"
     RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, int32_t index, ...);
     RyanJson_t RyanJsonGetObjectByKeys(RyanJson_t pJson, char *key, ...);
     RyanJsonBool RyanJsonReapplyString(char **dst, const char *src);
-    RyanJson_t RyanJsonCreateItem(char *key, RyanJson_t item);
+    RyanJson_t RyanJsonCreateItem(const char *key, RyanJson_t item);
 
     /**
      * @brief json对象函数
      */
     RyanJsonBool RyanJsonInitHooks(malloc_t _malloc, free_t _free, realloc_t _realloc);
     RyanJson_t RyanJsonParseOptions(const char *text, uint32_t size, RyanJsonBool require_null_terminated, const char **return_parse_end); // 需用户释放内存
-#define RyanJsonParse(text) RyanJsonParseOptions(text, strlen(text), RyanJsonFalse, NULL)                                                  // 需用户释放内存                                               // 需用户释放内存
+    static inline RyanJson_t RyanJsonParse(char *text)                                                                                     // 需用户释放内存
+    {
+        return RyanJsonParseOptions(text, strlen(text), RyanJsonFalse, NULL);
+    }
 
     char *RyanJsonPrint(RyanJson_t pJson, uint32_t preset, RyanJsonBool format, uint32_t *len); // 需用户释放内存
     char *RyanJsonPrintPreallocated(RyanJson_t pJson, char *buffer, uint32_t length, RyanJsonBool format, uint32_t *len);
@@ -89,10 +95,13 @@ extern "C"
     RyanJson_t RyanJsonDuplicate(RyanJson_t pJson); // 需用户释放内存
     uint32_t RyanJsonGetSize(RyanJson_t pJson);
     void RyanJsonMinify(char *text);
+
     void RyanJsonDelete(RyanJson_t pJson);
-    RyanJsonBool RyanJsonCompare(RyanJson_t a, RyanJson_t b);
     void RyanJsonFree(void *block);
 
+    RyanJsonBool RyanJsonCompare(RyanJson_t a, RyanJson_t b);
+    RyanJsonBool RyanJsonCompareOnlyKey(RyanJson_t a, RyanJson_t b);
+
     /**
      * @brief 添加 / 删除相关函数
      */
@@ -179,7 +188,6 @@ extern "C"
     RyanJsonBool RyanJsonReplaceByKey(RyanJson_t pJson, const char *key, RyanJson_t item);
     RyanJsonBool RyanJsonReplaceByIndex(RyanJson_t pJson, int32_t index, RyanJson_t item); // object对象也可以使用,但是不推荐
 
-    RyanJsonBool RyanJsonCompare2(RyanJson_t a, RyanJson_t b);
 #ifdef __cplusplus
 }
 #endif

+ 142 - 0
RyanJsonExample.c

@@ -0,0 +1,142 @@
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "./RyanJson/RyanJson.h"
+
+/**
+ * @brief 生成json示例
+ *
+ * @return int
+ */
+int createJsonExample()
+{
+    char *str = NULL;
+    RyanJson_t jsonRoot, item;
+
+    // 对象生成测试
+    jsonRoot = RyanJsonCreateObject();
+    RyanJsonAddIntToObject(jsonRoot, "inter", 16);
+    RyanJsonAddDoubleToObject(jsonRoot, "double", 16.89);
+    RyanJsonAddStringToObject(jsonRoot, "string", "hello");
+    RyanJsonAddBoolToObject(jsonRoot, "boolTrue", RyanJsonTrue);
+    RyanJsonAddBoolToObject(jsonRoot, "boolFalse", RyanJsonFalse);
+    RyanJsonAddNullToObject(jsonRoot, "null");
+
+    // 添加子对象
+    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");
+    RyanJsonAddItemToObject(jsonRoot, "item", item); // 将上面创建的item子对象添加到root父对象
+
+    // 添加子数组
+    int arrayInt[] = {16, 16, 16, 16, 16};
+    RyanJsonAddItemToObject(jsonRoot, "arrayInt",
+                            RyanJsonCreateIntArray(arrayInt, sizeof(arrayInt) / sizeof(arrayInt[0])));
+
+    double arrayDouble[] = {16.89, 16.89, 16.89, 16.89, 16.89};
+    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])));
+
+    RyanJson_t array = RyanJsonCreateArray();
+    RyanJsonAddIntToArray(array, 16);
+    RyanJsonAddDoubleToArray(array, 16.89);
+    RyanJsonAddStringToArray(array, "hello");
+    RyanJsonAddBoolToArray(array, RyanJsonTrue);
+    RyanJsonAddBoolToArray(array, RyanJsonFalse);
+    RyanJsonAddNullToArray(array);
+    RyanJsonAddItemToObject(jsonRoot, "array", array); // 将上面创建的item子对象数组添加到root父对象
+
+    // 添加对象数组
+    RyanJson_t arrayItem = RyanJsonCreateArray();
+    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");
+    RyanJsonAddItemToObject(arrayItem, "item", item); // 将item对象添加到arrayItem数组里面
+
+    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");
+    RyanJsonAddItemToObject(arrayItem, "item", item); // 将item对象添加到arrayItem数组里面
+
+    RyanJsonAddItemToObject(jsonRoot, "arrayItem", arrayItem); // 将arrayItem数组添加到root父对象
+
+    uint32_t len = 0;
+    str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, &len); // 以带格式方式将数据打印出来
+    printf("strLen: %d, data: %s\r\n", len, str);
+    RyanJsonFree(str);
+
+    RyanJsonDelete(jsonRoot);
+
+    return 1;
+}
+
+/**
+ * @brief 序列化json文本示例
+ *
+ * @return int
+ */
+int loadJsonExample()
+{
+    char *str = NULL;
+    RyanJson_t jsonRoot;
+    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);
+    if (jsonRoot == NULL)
+    {
+        printf("%s:%d 序列化失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // 将序列化的数据以无格式样式打印出来,并和原始数据进行对比
+    str = RyanJsonPrint(jsonRoot, 250, RyanJsonFalse, NULL);
+    if (strcmp(str, jsonstr) != 0)
+    {
+        printf("%s:%d 序列化与反序列化后的数据不对应\r\n", __FILE__, __LINE__);
+        RyanJsonFree(str);
+        return 0;
+    }
+
+    // 将序列化的数据以有格式样式打印出来
+    uint32_t len = 0;
+    str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, &len);
+    printf("strLen: %d, data: %s\r\n", len, str);
+    RyanJsonFree(str);
+
+    // 删除json对象
+    RyanJsonDelete(jsonRoot);
+
+    return 1;
+}
+
+int RyanJsonExample(void)
+{
+    printf("\r\n--------------------------- RyanJson 生成示例 --------------------------\r\n");
+    createJsonExample();
+
+    printf("\r\n--------------------------- RyanJson 序列化json文本示例 --------------------------\r\n");
+    loadJsonExample();
+
+    return 0;
+}

File diff suppressed because it is too large
+ 56 - 0
RyanJsonMemoryFootprintTest.c


+ 920 - 0
RyanJsonTest.c

@@ -0,0 +1,920 @@
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <intrin.h>
+
+#include "./RyanJson/RyanJson.h"
+#include "./cJSON/cJSON.h"
+#include "./valloc/valloc.h"
+
+/* --------------------------------------- jsonTest ------------------------------------------- */
+// !(fabs(RyanJsonGetDoubleValue(RyanJsonGetObjectToKey(json, "double")) - 16.89) < 1e-6)
+static RyanJsonBool compare_double(double a, double b)
+{
+    double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
+    return (fabs(a - b) <= maxVal * DBL_EPSILON);
+}
+
+static uint64_t start;
+uint64_t getClock()
+{
+    return clock();
+}
+
+static int rootNodeCheckTest(RyanJson_t json)
+{
+    if (!RyanJsonIsInt(RyanJsonGetObjectToKey(json, "inter")) || 16 != RyanJsonGetIntValue(RyanJsonGetObjectToKey(json, "inter")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsDouble(RyanJsonGetObjectToKey(json, "double")) || !compare_double(RyanJsonGetDoubleValue(RyanJsonGetObjectToKey(json, "double")), 16.89))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsString(RyanJsonGetObjectToKey(json, "string")) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToKey(json, "string")), "hello"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolTrue")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolTrue")) != RyanJsonTrue)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolFalse")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolFalse")) != RyanJsonFalse)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsNull(RyanJsonGetObjectToKey(json, "null")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+    return 1;
+}
+
+int itemNodeCheckTest(RyanJson_t json)
+{
+    RyanJson_t item = RyanJsonGetObjectToKey(json, "item");
+    if (0 == rootNodeCheckTest(item))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+    return 1;
+}
+
+int arrayNodeCheckTest(RyanJson_t json)
+{
+    RyanJson_t item = NULL;
+
+    // 判断是不是数组类型
+    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayInt")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayDouble")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayString")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "array")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    /**
+     * @brief 检查弱类型数组
+     *
+     */
+    //   array: [16, 16.89, "hello", true, false, null],
+    if (!RyanJsonIsInt(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 0)) || 16 != RyanJsonGetIntValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 0)))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsDouble(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 1)) || !compare_double(RyanJsonGetDoubleValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 1)), 16.89))
+    {
+        printf("%s:%d 解析失败 %f\r\n", __FILE__, __LINE__, RyanJsonGetDoubleValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 1)));
+        return 0;
+    }
+
+    if (!RyanJsonIsString(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 2)) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 2)), "hello"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsBool(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 3)) || RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 3)) != RyanJsonTrue)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsBool(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 4)) || RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 4)) != RyanJsonFalse)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (!RyanJsonIsNull(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 5)))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    /**
+     * @brief 检查强类型数组
+     *
+     */
+    for (uint8_t count = 0; count < RyanJsonGetSize(RyanJsonGetObjectToKey(json, "arrayInt")); count++)
+    {
+        item = RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "arrayInt"), count);
+        if (!RyanJsonIsInt(item) || 16 != RyanJsonGetIntValue(item))
+        {
+            printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+            return 0;
+        }
+    }
+
+    for (uint8_t count = 0; count < RyanJsonGetSize(RyanJsonGetObjectToKey(json, "arrayDouble")); count++)
+    {
+        item = RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "arrayDouble"), count);
+        if (!RyanJsonIsDouble(item) || fabs(RyanJsonGetDoubleValue(item) - 16.8) < 0.001)
+        {
+            printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+            return 0;
+        }
+    }
+
+    for (uint8_t count = 0; count < RyanJsonGetSize(RyanJsonGetObjectToKey(json, "arrayString")); count++)
+    {
+        item = RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "arrayString"), count);
+        if (!RyanJsonIsString(item) || strcmp(RyanJsonGetStringValue(item), "hello"))
+        {
+            printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+            return 0;
+        }
+    }
+
+    if (6 != RyanJsonGetSize(RyanJsonGetObjectToKey(json, "array")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    return 1;
+}
+
+int arrayItemNodeCheckTest(RyanJson_t json)
+{
+    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayItem")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (0 == rootNodeCheckTest(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0)))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    if (0 == rootNodeCheckTest(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 1)))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+    return 1;
+}
+
+/* --------------------------------------------------------------------- */
+
+int loadJsonTest()
+{
+    char *str = NULL;
+    RyanJson_t json;
+    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 = RyanJsonParse(jsonstr);
+    if (json == NULL)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    str = RyanJsonPrint(json, 250, RyanJsonFalse, NULL);
+    if (strcmp(str, jsonstr) != 0)
+    {
+        printf("%s:%d 序列化与反序列化后的数据不对应\r\n", __FILE__, __LINE__);
+        RyanJsonFree(str);
+        RyanJsonDelete(json);
+        return 0;
+    }
+
+    RyanJsonFree(str);
+
+    rootNodeCheckTest(json);
+    itemNodeCheckTest(json);
+    arrayNodeCheckTest(json);
+    arrayItemNodeCheckTest(json);
+    RyanJsonDelete(json);
+
+    // 测试序列化错误json结构
+
+    // \"inter\":16poi,  无效数字
+    json = RyanJsonParse("{\"inter\":16poi,\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"double\":16.8yu9,,  无效浮点数
+    json = RyanJsonParse("{\"inter\":16,\"double\":16.8yu9,\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // boolTrue 设置为 tru
+    json = RyanJsonParse("{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":tru,\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // null 设置为 nul
+    json = RyanJsonParse("{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":nul,\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // null 设置为 NULL
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"inter\":16后面少个,
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // array数组项少一个,
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // boolFalse 设置为 fale
+    json = RyanJsonParse("{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":fale,\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"item:{\"inter\":16,\"  少一个"
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"item\":{\"inter\":16,double\"  少一个"
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"item\":{\"inter\":16,\"\"double\"  多一个"
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"item\":{\"inter\":16\",\"double\"  多一个"
+    json = RyanJsonParse("{\"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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // \"arrayInt\":[16,16,16m,16,16]  无效数组数字
+    json = RyanJsonParse("{\"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,16m,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}]}");
+    if (json != NULL)
+    {
+        RyanJsonDelete(json);
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+    return 1;
+}
+
+int createJsonTest()
+{
+
+    char *str = NULL;
+    RyanJson_t jsonRoot, item;
+
+    // 对象生成测试
+    jsonRoot = RyanJsonCreateObject();
+    RyanJsonAddIntToObject(jsonRoot, "inter", 16);
+    RyanJsonAddDoubleToObject(jsonRoot, "double", 16.89);
+    RyanJsonAddStringToObject(jsonRoot, "string", "hello");
+    RyanJsonAddBoolToObject(jsonRoot, "boolTrue", RyanJsonTrue);
+    RyanJsonAddBoolToObject(jsonRoot, "boolFalse", RyanJsonFalse);
+    RyanJsonAddNullToObject(jsonRoot, "null");
+
+    /**
+     * @brief 对象添加测试
+     *
+     */
+    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");
+    RyanJsonAddItemToObject(jsonRoot, "item", item);
+
+    /**
+     * @brief 数组添加测试
+     *
+     */
+    int arrayInt[] = {16, 16, 16, 16, 16};
+    RyanJsonAddItemToObject(jsonRoot, "arrayInt",
+                            RyanJsonCreateIntArray(arrayInt, sizeof(arrayInt) / sizeof(arrayInt[0])));
+
+    double arrayDouble[] = {16.89, 16.89, 16.89, 16.89, 16.89};
+    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])));
+
+    RyanJson_t array = RyanJsonCreateArray();
+    RyanJsonAddIntToArray(array, 16);
+    RyanJsonAddDoubleToArray(array, 16.89);
+    RyanJsonAddStringToArray(array, "hello");
+    RyanJsonAddBoolToArray(array, RyanJsonTrue);
+    RyanJsonAddBoolToArray(array, RyanJsonFalse);
+    RyanJsonAddNullToArray(array);
+    RyanJsonAddItemToObject(jsonRoot, "array", array);
+
+    /**
+     * @brief 对象数组测试
+     *
+     */
+    RyanJson_t arrayItem = RyanJsonCreateArray();
+    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");
+    RyanJsonAddItemToObject(arrayItem, "item", item);
+
+    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");
+    RyanJsonAddItemToObject(arrayItem, "item", item);
+
+    RyanJsonAddItemToObject(jsonRoot, "arrayItem", arrayItem);
+
+    // str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, NULL);
+    // printf("aa %s\r\n", str);
+    // RyanJsonFree(str);
+
+    rootNodeCheckTest(jsonRoot);
+    itemNodeCheckTest(jsonRoot);
+    arrayNodeCheckTest(jsonRoot);
+    arrayItemNodeCheckTest(jsonRoot);
+
+    RyanJsonDelete(jsonRoot);
+    return 1;
+}
+
+int changeJsonTest()
+{
+
+    char *str = NULL;
+    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}]}";
+
+    RyanJson_t json = RyanJsonParse(jsonstr);
+    if (json == NULL)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    /**
+     * @brief 修改对应类型
+     *
+     */
+    RyanJsonChangeIntValue(RyanJsonGetObjectToKey(json, "inter"), 20);
+    if (!RyanJsonIsInt(RyanJsonGetObjectToKey(json, "inter")) || 20 != RyanJsonGetIntValue(RyanJsonGetObjectToKey(json, "inter")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonChangeDoubleValue(RyanJsonGetObjectToKey(json, "double"), 20.89);
+    if (!RyanJsonIsDouble(RyanJsonGetObjectToKey(json, "double")) || !compare_double(RyanJsonGetDoubleValue(RyanJsonGetObjectToKey(json, "double")), 20.89))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonChangeStringValue(RyanJsonGetObjectToKey(json, "string"), "world");
+    if (!RyanJsonIsString(RyanJsonGetObjectToKey(json, "string")) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToKey(json, "string")), "world"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json, "boolTrue"), RyanJsonFalse);
+    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolTrue")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolTrue")) != RyanJsonFalse)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json, "boolFalse"), RyanJsonTrue);
+    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolFalse")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolFalse")) != RyanJsonTrue)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    /* ---------------------------------- replace使用 -------------------------------------*/
+    // 数组没有key, replace的子项不能有key, 函数内部没有做逻辑判断,会造成内存泄漏
+    RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0, RyanJsonCreateString(NULL, "arrayInt"));
+    if (!RyanJsonIsString(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0)) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0)), "arrayInt"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0, RyanJsonCreateString(NULL, "arrayItem"));
+    if (!RyanJsonIsString(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0)) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0)), "arrayItem"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    // 对象必须包含key, 如果创建的对象key为null会引起内存错误
+    RyanJsonReplaceByKey(json, "arrayString", RyanJsonCreateString("", "arrayString"));
+    if (!RyanJsonIsString(RyanJsonGetObjectToKey(json, "arrayString")) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToKey(json, "arrayString")), "arrayString"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    // 修改数组节点为对象节点
+    RyanJsonReplaceByKey(json, "arrayDouble", RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item")));
+    if (!RyanJsonIsObject(RyanJsonGetObjectToKey(json, "arrayDouble")) || !rootNodeCheckTest(RyanJsonGetObjectToKey(json, "arrayDouble")))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+
+        goto err;
+    }
+
+    /**
+     * @brief 对象子项删除测试
+     *
+     */
+    RyanJsonDeleteByIndex(json, 0);
+    if (RyanJsonGetObjectToKey(json, "inter"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    RyanJsonDeleteByKey(json, "double");
+    if (RyanJsonGetObjectToKey(json, "double"))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    /**
+     * @brief 数组对象子项删除测试
+     *
+     */
+    RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json, "array"), 0);
+    if (RyanJsonGetSize(RyanJsonGetObjectToKey(json, "array")) != 5)
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        return 0;
+    }
+
+    // str = RyanJsonPrint(json, 1024, RyanJsonTrue, NULL);
+    // printf("aa %s\r\n", str);
+    // RyanJsonFree(str);
+    RyanJsonDelete(json);
+    return 1;
+
+err:
+    RyanJsonDelete(json);
+    return 0;
+}
+
+void compareJsonTest()
+{
+
+    char *str = NULL;
+    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}]}";
+    // char jsonstr[] = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}";
+
+    RyanJson_t json = RyanJsonParse(jsonstr);
+    RyanJson_t json2 = RyanJsonParse(jsonstr);
+
+    // 比较函数
+    if (RyanJsonTrue != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeKey(RyanJsonGetObjectToKey(json2, "inter"), "int2");
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeIntValue(RyanJsonGetObjectToKey(json2, "inter"), 17);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeDoubleValue(RyanJsonGetObjectToKey(json2, "double"), 20.89);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeStringValue(RyanJsonGetObjectToKey(json2, "string"), "49");
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json2, "boolTrue"), RyanJsonFalse);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json2, "item", "boolTrue"), RyanJsonFalse);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeIntValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayInt"), 0), 17);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeDoubleValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayDouble"), 0), 20.89);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayString"), 0), "20.89");
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeIntValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "array"), 0), 17);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonChangeIntValue(RyanJsonGetObjectToKey(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayItem"), 0), "inter"), 17);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonDeleteByKey(json2, "arrayItem");
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json2, "arrayInt"), 2);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+    RyanJsonDelete(json2);
+    json2 = RyanJsonParse(jsonstr);
+    RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json2, "arrayItem"), 0);
+    if (RyanJsonFalse != RyanJsonCompare(json, json2))
+    {
+        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
+        goto err;
+    }
+
+err:
+    RyanJsonDelete(json);
+    RyanJsonDelete(json2);
+}
+
+void duplicateTest()
+{
+
+    char *str = NULL;
+    RyanJson_t json, item, dupItem;
+    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}]}";
+
+    // 内存泄漏测试
+
+    /**
+     * @brief 普通类型
+     *
+     */
+    json = RyanJsonParse(jsonstr);
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
+    RyanJsonDelete(dupItem);
+
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    RyanJsonDelete(RyanJsonGetObjectByKey(json, "test"));
+
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    RyanJsonDelete(json);
+
+    json = RyanJsonParse(jsonstr);
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    item = RyanJsonDetachByKey(json, "test");
+    RyanJsonDelete(item);
+    RyanJsonDelete(json);
+
+    /**
+     * @brief 对象类型
+     *
+     */
+    json = RyanJsonParse(jsonstr);
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
+    RyanJsonDelete(dupItem);
+
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    RyanJsonDelete(RyanJsonGetObjectByKey(json, "test"));
+
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    RyanJsonDelete(json);
+
+    json = RyanJsonParse(jsonstr);
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    item = RyanJsonDetachByKey(json, "test");
+    RyanJsonDelete(item);
+    RyanJsonDelete(json);
+
+    /**
+     * @brief 数组类型
+     *
+     */
+    json = RyanJsonParse(jsonstr);
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
+    RyanJsonDelete(dupItem);
+
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    RyanJsonDelete(RyanJsonGetObjectByKey(json, "test"));
+
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    RyanJsonDelete(json);
+
+    json = RyanJsonParse(jsonstr);
+    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
+    RyanJsonAddItemToObject(json, "test", dupItem);
+    item = RyanJsonDetachByKey(json, "test");
+    RyanJsonDelete(item);
+    RyanJsonDelete(json);
+
+    json = RyanJsonParse(jsonstr);
+    RyanJson_t jsonRoot = RyanJsonCreateObject();
+    RyanJsonAddBoolToObject(jsonRoot, "arrayItem", RyanJsonTrue);
+    int use = 0;
+    for (uint8_t i = 0; i < 10; i++)
+    {
+        dupItem = RyanJsonParse(jsonstr);
+        RyanJsonReplaceByKey(jsonRoot, "arrayItem", RyanJsonDuplicate(dupItem));
+        RyanJsonReplaceByKey(json, "arrayItem", RyanJsonDuplicate(RyanJsonGetObjectByKey(dupItem, "item")));
+        RyanJsonDelete(dupItem);
+
+        int newuse = 0;
+        v_mcheck(NULL, &newuse);
+        if (i != 0 && newuse != use)
+        {
+            printf("%s:%d 内存泄漏\r\n", __FILE__, __LINE__);
+            break;
+        }
+        use = newuse;
+        // displayMem();
+        // _sleep(1000)
+    }
+
+    RyanJsonDelete(json);
+    RyanJsonDelete(jsonRoot);
+}
+
+void likeReferenceTest()
+{
+
+    // char *str = NULL;
+    // 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}]}";
+    // RyanJson_t json = RyanJsonParse(jsonstr);
+    // RyanJson_t item = NULL;
+
+    // // RyanJson_t adfasdf = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
+
+    // // RyanJsonAddItemToObject(json, "test", adfasdf);
+
+    // // 这里做你想做的事,这里我选择打印出来
+    // // str = RyanJsonPrint(json, 50, RyanJsonTrue, NULL);
+    // // printf("item %s \r\n", str);
+    // // RyanJsonFree(str);
+
+    // for (int i = 0; i < 1; i++)
+    // {
+    //     // 分离test对象
+    //     item = RyanJsonDetachByKey(json, "item");
+
+    //     // if (RyanJsonIsKey(item))
+    //     //     RyanJsonFree(RyanJsonGetKey(item));
+
+    //     // RyanJsonFree(item);
+    // }
+
+    // RyanJsonAddItemToObject(json, "item", item);
+
+    // str = RyanJsonPrint(json, 50, RyanJsonTrue, NULL);
+    // printf("item %s \r\n", str);
+    // RyanJsonFree(str);
+
+    // RyanJsonDelete(json);
+}
+
+void forEachTest()
+{
+    char *str = NULL;
+    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}]}";
+
+    RyanJson_t json = RyanJsonParse(jsonstr);
+    RyanJson_t item = NULL;
+    printf("arrayDouble: ");
+    RyanJsonArrayForEach(RyanJsonGetObjectToKey(json, "arrayDouble"), item)
+    {
+        printf("%lf ", RyanJsonGetDoubleValue(item));
+    }
+    printf("\r\n");
+
+    int strLen;
+    RyanJsonObjectForEach(RyanJsonGetObjectToKey(json, "item"), item)
+    {
+        str = RyanJsonPrint(item, 50, RyanJsonTrue, &strLen);
+        printf("item { %s : %s }  %d\r\n", RyanJsonGetKey(item), str, strLen);
+        RyanJsonFree(str);
+    }
+    RyanJsonDelete(json);
+}
+
+int RyanJsonTest(void)
+{
+
+    RyanJsonInitHooks(v_malloc, v_free, v_realloc);
+
+    loadJsonTest(); // 从文本解析json测试
+
+    createJsonTest(); // 生成json节点树测试
+
+    changeJsonTest(); // 修改json节点测试,包含删除、分离
+
+    compareJsonTest(); // 比较json节点树测试
+
+    duplicateTest(); // 复制测试
+
+    forEachTest();
+
+    likeReferenceTest(); // 模仿 引用类型实现 示例
+
+    displayMem();
+
+    return 0;
+}

BIN
docs/assert/README.assert/image-20230822112554099.png


BIN
docs/assert/README.assert/image-20230822112757872.png


+ 18 - 892
main.c

@@ -1,909 +1,35 @@
-
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <math.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <intrin.h>
-
 #include "./RyanJson/RyanJson.h"
-#include "./cJSON/cJSON.h"
-#include "./valloc/valloc.h"
-
-/* --------------------------------------- jsonTest ------------------------------------------- */
-// !(fabs(RyanJsonGetDoubleValue(RyanJsonGetObjectToKey(json, "double")) - 16.89) < 1e-6)
-static RyanJsonBool compare_double(double a, double b)
-{
-    double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
-    return (fabs(a - b) <= maxVal * DBL_EPSILON);
-}
-
-static uint64_t start;
-uint64_t getClock()
-{
-    return clock();
-}
-
-void displayMem()
-{
-    int area = 0, use = 0;
-    v_mcheck(&area, &use);
-    printf("|||----------->>> area = %d, size = %d\r\n", area, use);
-}
-
-static int rootNodeCheckTest(RyanJson_t json)
-{
-    if (!RyanJsonIsInt(RyanJsonGetObjectToKey(json, "inter")) || 16 != RyanJsonGetIntValue(RyanJsonGetObjectToKey(json, "inter")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsDouble(RyanJsonGetObjectToKey(json, "double")) || !compare_double(RyanJsonGetDoubleValue(RyanJsonGetObjectToKey(json, "double")), 16.89))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsString(RyanJsonGetObjectToKey(json, "string")) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToKey(json, "string")), "hello"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolTrue")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolTrue")) != RyanJsonTrue)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolFalse")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolFalse")) != RyanJsonFalse)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsNull(RyanJsonGetObjectToKey(json, "null")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-}
-
-int itemNodeCheckTest(RyanJson_t json)
-{
-    RyanJson_t item = RyanJsonGetObjectToKey(json, "item");
-    if (0 == rootNodeCheckTest(item))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-}
-
-int arrayNodeCheckTest(RyanJson_t json)
-{
-    RyanJson_t item = NULL;
-
-    // 判断是不是数组类型
-    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayInt")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayDouble")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayString")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "array")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    /**
-     * @brief 检查弱类型数组
-     *
-     */
-    //   array: [16, 16.89, "hello", true, false, null],
-    if (!RyanJsonIsInt(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 0)) || 16 != RyanJsonGetIntValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 0)))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsDouble(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 1)) || !compare_double(RyanJsonGetDoubleValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 1)), 16.89))
-    {
-        printf("%s:%d 解析失败 %f\r\n", __FILE__, __LINE__, RyanJsonGetDoubleValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 1)));
-        return 0;
-    }
-
-    if (!RyanJsonIsString(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 2)) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 2)), "hello"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsBool(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 3)) || RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 3)) != RyanJsonTrue)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsBool(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 4)) || RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 4)) != RyanJsonFalse)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (!RyanJsonIsNull(RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "array"), 5)))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    /**
-     * @brief 检查强类型数组
-     *
-     */
-    for (uint8_t count = 0; count < RyanJsonGetSize(RyanJsonGetObjectToKey(json, "arrayInt")); count++)
-    {
-        item = RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "arrayInt"), count);
-        if (!RyanJsonIsInt(item) || 16 != RyanJsonGetIntValue(item))
-        {
-            printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-            return 0;
-        }
-    }
-
-    for (uint8_t count = 0; count < RyanJsonGetSize(RyanJsonGetObjectToKey(json, "arrayDouble")); count++)
-    {
-        item = RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "arrayDouble"), count);
-        if (!RyanJsonIsDouble(item) || fabs(RyanJsonGetDoubleValue(item) - 16.8) < 0.001)
-        {
-            printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-            return 0;
-        }
-    }
-
-    for (uint8_t count = 0; count < RyanJsonGetSize(RyanJsonGetObjectToKey(json, "arrayString")); count++)
-    {
-        item = RyanJsonGetObjectByIndex(RyanJsonGetObjectToKey(json, "arrayString"), count);
-        if (!RyanJsonIsString(item) || strcmp(RyanJsonGetStringValue(item), "hello"))
-        {
-            printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-            return 0;
-        }
-    }
-
-    if (6 != RyanJsonGetSize(RyanJsonGetObjectToKey(json, "array")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-}
-
-int arrayItemNodeCheckTest(RyanJson_t json)
-{
-    if (!RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayItem")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (0 == rootNodeCheckTest(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0)))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    if (0 == rootNodeCheckTest(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 1)))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-}
-
-/* --------------------------------------------------------------------- */
-
-int loadJsonTest()
-{
-    char *str = NULL;
-    RyanJson_t json;
-    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 = RyanJsonParse(jsonstr);
-    if (json == NULL)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    rootNodeCheckTest(json);
-    itemNodeCheckTest(json);
-    arrayNodeCheckTest(json);
-    arrayItemNodeCheckTest(json);
-    RyanJsonDelete(json);
-
-    // 测试序列化错误json结构
-
-    // \"inter\":16poi,  无效数字
-    json = RyanJsonParse("{\"inter\":16poi,\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"double\":16.8yu9,,  无效浮点数
-    json = RyanJsonParse("{\"inter\":16,\"double\":16.8yu9,\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // boolTrue 设置为 tru
-    json = RyanJsonParse("{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":tru,\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // null 设置为 nul
-    json = RyanJsonParse("{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":nul,\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // null 设置为 NULL
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"inter\":16后面少个,
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // array数组项少一个,
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // boolFalse 设置为 fale
-    json = RyanJsonParse("{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":fale,\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"item:{\"inter\":16,\"  少一个"
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"item\":{\"inter\":16,double\"  少一个"
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"item\":{\"inter\":16,\"\"double\"  多一个"
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"item\":{\"inter\":16\",\"double\"  多一个"
-    json = RyanJsonParse("{\"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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // \"arrayInt\":[16,16,16m,16,16]  无效数组数字
-    json = RyanJsonParse("{\"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,16m,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}]}");
-    if (json != NULL)
-    {
-        RyanJsonDelete(json);
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-}
-
-int createJsonTest()
-{
-
-    char *str = NULL;
-    RyanJson_t jsonRoot, item;
-
-    // 对象生成测试
-    jsonRoot = RyanJsonCreateObject();
-    RyanJsonAddIntToObject(jsonRoot, "inter", 16);
-    RyanJsonAddDoubleToObject(jsonRoot, "double", 16.89);
-    RyanJsonAddStringToObject(jsonRoot, "string", "hello");
-    RyanJsonAddBoolToObject(jsonRoot, "boolTrue", RyanJsonTrue);
-    RyanJsonAddBoolToObject(jsonRoot, "boolFalse", RyanJsonFalse);
-    RyanJsonAddNullToObject(jsonRoot, "null");
-
-    /**
-     * @brief 对象添加测试
-     *
-     */
-    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");
-    RyanJsonAddItemToObject(jsonRoot, "item", item);
-
-    /**
-     * @brief 数组添加测试
-     *
-     */
-    int arrayInt[] = {16, 16, 16, 16, 16};
-    RyanJsonAddItemToObject(jsonRoot, "arrayInt",
-                            RyanJsonCreateIntArray(arrayInt, sizeof(arrayInt) / sizeof(arrayInt[0])));
-
-    double arrayDouble[] = {16.89, 16.89, 16.89, 16.89, 16.89};
-    RyanJsonAddItemToObject(jsonRoot, "arrayDouble",
-                            RyanJsonCreateDoubleArray(arrayDouble, sizeof(arrayDouble) / sizeof(arrayDouble[0])));
-
-    char *arrayString[] = {"hello", "hello", "hello", "hello", "hello"};
-    RyanJsonAddItemToObject(jsonRoot, "arrayString",
-                            RyanJsonCreateStringArray(arrayString, sizeof(arrayString) / sizeof(arrayString[0])));
-
-    RyanJson_t array = RyanJsonCreateArray();
-    RyanJsonAddIntToArray(array, 16);
-    RyanJsonAddDoubleToArray(array, 16.89);
-    RyanJsonAddStringToArray(array, "hello");
-    RyanJsonAddBoolToArray(array, RyanJsonTrue);
-    RyanJsonAddBoolToArray(array, RyanJsonFalse);
-    RyanJsonAddNullToArray(array);
-    RyanJsonAddItemToObject(jsonRoot, "array", array);
-
-    /**
-     * @brief 对象数组测试
-     *
-     */
-    RyanJson_t arrayItem = RyanJsonCreateArray();
-    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");
-    RyanJsonAddItemToObject(arrayItem, "item", item);
-
-    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");
-    RyanJsonAddItemToObject(arrayItem, "item", item);
-
-    RyanJsonAddItemToObject(jsonRoot, "arrayItem", arrayItem);
-
-    // str = RyanJsonPrint(jsonRoot, 250, RyanJsonTrue, NULL);
-    // printf("aa %s\r\n", str);
-    // RyanJsonFree(str);
-
-    rootNodeCheckTest(jsonRoot);
-    itemNodeCheckTest(jsonRoot);
-    arrayNodeCheckTest(jsonRoot);
-    arrayItemNodeCheckTest(jsonRoot);
-
-    RyanJsonDelete(jsonRoot);
-}
-
-int changeJsonTest()
-{
-
-    char *str = NULL;
-    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}]}";
 
-    RyanJson_t json = RyanJsonParse(jsonstr);
-    if (json == NULL)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    /**
-     * @brief 修改对应类型
-     *
-     */
-    RyanJsonChangeIntValue(RyanJsonGetObjectToKey(json, "inter"), 20);
-    if (!RyanJsonIsInt(RyanJsonGetObjectToKey(json, "inter")) || 20 != RyanJsonGetIntValue(RyanJsonGetObjectToKey(json, "inter")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonChangeDoubleValue(RyanJsonGetObjectToKey(json, "double"), 20.89);
-    if (!RyanJsonIsDouble(RyanJsonGetObjectToKey(json, "double")) || !compare_double(RyanJsonGetDoubleValue(RyanJsonGetObjectToKey(json, "double")), 20.89))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonChangeStringValue(RyanJsonGetObjectToKey(json, "string"), "world");
-    if (!RyanJsonIsString(RyanJsonGetObjectToKey(json, "string")) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToKey(json, "string")), "world"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json, "boolTrue"), RyanJsonFalse);
-    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolTrue")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolTrue")) != RyanJsonFalse)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json, "boolFalse"), RyanJsonTrue);
-    if (!RyanJsonIsBool(RyanJsonGetObjectToKey(json, "boolFalse")) || RyanJsonGetBoolValue(RyanJsonGetObjectToKey(json, "boolFalse")) != RyanJsonTrue)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    /* ---------------------------------- replace使用 -------------------------------------*/
-    // 数组没有key, replace的子项不能有key, 函数内部没有做逻辑判断,会造成内存泄漏
-    RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0, RyanJsonCreateString(NULL, "arrayInt"));
-    if (!RyanJsonIsString(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0)) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0)), "arrayInt"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0, RyanJsonCreateString(NULL, "arrayItem"));
-    if (!RyanJsonIsString(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0)) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0)), "arrayItem"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    // 对象必须包含key, 如果创建的对象key为null会引起内存错误
-    RyanJsonReplaceByKey(json, "arrayString", RyanJsonCreateString("", "arrayString"));
-    if (!RyanJsonIsString(RyanJsonGetObjectToKey(json, "arrayString")) || strcmp(RyanJsonGetStringValue(RyanJsonGetObjectToKey(json, "arrayString")), "arrayString"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    // 修改数组节点为对象节点
-    RyanJsonReplaceByKey(json, "arrayDouble", RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item")));
-    if (!RyanJsonIsObject(RyanJsonGetObjectToKey(json, "arrayDouble")) || !rootNodeCheckTest(RyanJsonGetObjectToKey(json, "arrayDouble")))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    /**
-     * @brief 对象子项删除测试
-     *
-     */
-    RyanJsonDeleteByIndex(json, 0);
-    if (RyanJsonGetObjectToKey(json, "inter"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    RyanJsonDeleteByKey(json, "double");
-    if (RyanJsonGetObjectToKey(json, "double"))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    /**
-     * @brief 数组对象子项删除测试
-     *
-     */
-    RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json, "array"), 0);
-    if (RyanJsonGetSize(RyanJsonGetObjectToKey(json, "array")) != 5)
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        return 0;
-    }
-
-    // str = RyanJsonPrint(json, 1024, RyanJsonTrue, NULL);
-    // printf("aa %s\r\n", str);
-    // RyanJsonFree(str);
-
-err:
-    RyanJsonDelete(json);
-}
-
-void compareJsonTest()
-{
-
-    char *str = NULL;
-    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}]}";
-    // char jsonstr[] = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}";
-
-    RyanJson_t json = RyanJsonParse(jsonstr);
-    RyanJson_t json2 = RyanJsonParse(jsonstr);
-
-    // 比较函数
-    if (RyanJsonTrue != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeKey(RyanJsonGetObjectToKey(json2, "inter"), "int2");
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeIntValue(RyanJsonGetObjectToKey(json2, "inter"), 17);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeDoubleValue(RyanJsonGetObjectToKey(json2, "double"), 20.89);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeStringValue(RyanJsonGetObjectToKey(json2, "string"), "49");
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json2, "boolTrue"), RyanJsonFalse);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json2, "item", "boolTrue"), RyanJsonFalse);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeIntValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayInt"), 0), 17);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeDoubleValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayDouble"), 0), 20.89);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayString"), 0), "20.89");
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeIntValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "array"), 0), 17);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonChangeIntValue(RyanJsonGetObjectToKey(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayItem"), 0), "inter"), 17);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonDeleteByKey(json2, "arrayItem");
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json2, "arrayInt"), 2);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-    RyanJsonDelete(json2);
-    json2 = RyanJsonParse(jsonstr);
-    RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json2, "arrayItem"), 0);
-    if (RyanJsonFalse != RyanJsonCompare(json, json2))
-    {
-        printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
-        goto err;
-    }
-
-err:
-    RyanJsonDelete(json);
-    RyanJsonDelete(json2);
-}
-
-void duplicateTest()
+void printfTitle(char *title)
 {
-
-    char *str = NULL;
-    RyanJson_t json, item, dupItem;
-    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}]}";
-
-    // 内存泄漏测试
-
-    /**
-     * @brief 普通类型
-     *
-     */
-    json = RyanJsonParse(jsonstr);
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
-    RyanJsonDelete(dupItem);
-
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    RyanJsonDelete(RyanJsonGetObjectByKey(json, "test"));
-
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    RyanJsonDelete(json);
-
-    json = RyanJsonParse(jsonstr);
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    item = RyanJsonDetachByKey(json, "test");
-    RyanJsonDelete(item);
-    RyanJsonDelete(json);
-
-    /**
-     * @brief 对象类型
-     *
-     */
-    json = RyanJsonParse(jsonstr);
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
-    RyanJsonDelete(dupItem);
-
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    RyanJsonDelete(RyanJsonGetObjectByKey(json, "test"));
-
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    RyanJsonDelete(json);
-
-    json = RyanJsonParse(jsonstr);
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    item = RyanJsonDetachByKey(json, "test");
-    RyanJsonDelete(item);
-    RyanJsonDelete(json);
-
-    /**
-     * @brief 数组类型
-     *
-     */
-    json = RyanJsonParse(jsonstr);
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
-    RyanJsonDelete(dupItem);
-
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    RyanJsonDelete(RyanJsonGetObjectByKey(json, "test"));
-
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    RyanJsonDelete(json);
-
-    json = RyanJsonParse(jsonstr);
-    dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
-    RyanJsonAddItemToObject(json, "test", dupItem);
-    item = RyanJsonDetachByKey(json, "test");
-    RyanJsonDelete(item);
-    RyanJsonDelete(json);
-
-    json = RyanJsonParse(jsonstr);
-    RyanJson_t jsonRoot = RyanJsonCreateObject();
-    RyanJsonAddBoolToObject(jsonRoot, "arrayItem", RyanJsonTrue);
-    int use = 0;
-    for (uint8_t i = 0; i < 10; i++)
-    {
-        dupItem = RyanJsonParse(jsonstr);
-        RyanJsonReplaceByKey(jsonRoot, "arrayItem", RyanJsonDuplicate(dupItem));
-        RyanJsonReplaceByKey(json, "arrayItem", RyanJsonDuplicate(RyanJsonGetObjectByKey(dupItem, "item")));
-        RyanJsonDelete(dupItem);
-
-        int newuse = 0;
-        v_mcheck(NULL, &newuse);
-        if (i != 0 && newuse != use)
-        {
-            printf("%s:%d 内存泄漏\r\n", __FILE__, __LINE__);
-            break;
-        }
-        use = newuse;
-        // displayMem();
-        // _sleep(1000)
-    }
-
-    RyanJsonDelete(json);
-    RyanJsonDelete(jsonRoot);
-}
-
-void likeReferenceTest()
-{
-
-    // char *str = NULL;
-    // 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}]}";
-    // RyanJson_t json = RyanJsonParse(jsonstr);
-    // RyanJson_t item = NULL;
-
-    // // RyanJson_t adfasdf = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
-
-    // // RyanJsonAddItemToObject(json, "test", adfasdf);
-
-    // // 这里做你想做的事,这里我选择打印出来
-    // // str = RyanJsonPrint(json, 50, RyanJsonTrue, NULL);
-    // // printf("item %s \r\n", str);
-    // // RyanJsonFree(str);
-
-    // for (int i = 0; i < 1; i++)
-    // {
-    //     // 分离test对象
-    //     item = RyanJsonDetachByKey(json, "item");
-
-    //     // if (RyanJsonIsKey(item))
-    //     //     RyanJsonFree(RyanJsonGetKey(item));
-
-    //     // RyanJsonFree(item);
-    // }
-
-    // RyanJsonAddItemToObject(json, "item", item);
-
-    // str = RyanJsonPrint(json, 50, RyanJsonTrue, NULL);
-    // printf("item %s \r\n", str);
-    // RyanJsonFree(str);
-
-    // RyanJsonDelete(json);
-}
-
-void forEachTest()
-{
-    char *str = NULL;
-    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}]}";
-
-    RyanJson_t json = RyanJsonParse(jsonstr);
-    RyanJson_t item = NULL;
-    printf("arrayDouble: ");
-    RyanJsonArrayForEach(RyanJsonGetObjectToKey(json, "arrayDouble"), item)
-    {
-        printf("%lf ", RyanJsonGetDoubleValue(item));
-    }
     printf("\r\n");
-
-    int strLen;
-    RyanJsonObjectForEach(RyanJsonGetObjectToKey(json, "item"), item)
-    {
-        str = RyanJsonPrint(item, 50, RyanJsonTrue, &strLen);
-        printf("item { %s : %s }  %d\r\n", RyanJsonGetKey(item), str, strLen);
-        RyanJsonFree(str);
-    }
-    RyanJsonDelete(json);
+    printf("\r\n");
+    printf("*****************************************************************************\r\n");
+    printf("*************************** %s **************************\r\n", title);
+    printf("*****************************************************************************\r\n");
 }
 
+extern int RyanJsonExample();
+extern int RyanJsonTest();
+extern int RyanJsonMemoryFootprintTest();
+extern int RFC8259JsonTest();
+
 int main(void)
 {
+    printfTitle("RyanJson 示例程序");
+    RyanJsonExample();
 
-    RyanJsonInitHooks(v_malloc, v_free, v_realloc);
-
-    loadJsonTest(); // 从文本解析json测试
-
-    createJsonTest(); // 生成json节点树测试
-
-    changeJsonTest(); // 修改json节点测试,包含删除、分离
-
-    compareJsonTest(); // 比较json节点树测试
+    printfTitle("RyanJson 接口测试程序");
+    RyanJsonTest();
 
-    duplicateTest(); // 复制测试
-
-    forEachTest();
-
-    likeReferenceTest(); // 模仿 引用类型实现 示例
-
-    displayMem();
+    printfTitle("RyanJson / cJSON 内存对比程序");
+    RyanJsonMemoryFootprintTest();
 
+    printfTitle("RyanJson / cJSON RFC8259标准测试");
     RFC8259JsonTest();
 
-    // jsonaddTest();
-
     return 0;
-}
+}

+ 7 - 0
valloc/valloc.c

@@ -71,4 +71,11 @@ int v_mcheck(int *_count, int *_use)
     // }
 
     return 0;
+}
+
+void displayMem()
+{
+    int area = 0, use = 0;
+    v_mcheck(&area, &use);
+    printf("|||----------->>> area = %d, size = %d\r\n", area, use);
 }

+ 1 - 0
valloc/valloc.h

@@ -23,6 +23,7 @@ extern "C"
     void v_free(void *block);
     void *v_realloc(void *block, size_t size);
     int v_mcheck(int *_count, int *_use);
+    void displayMem();
 
 #define malloc v_malloc
 #define calloc v_calloc

Some files were not shown because too many files changed in this diff