Skip to content

Commit ff48b21

Browse files
authored
Merge pull request #5 from Ryan-CW-Code/next
Next
2 parents a7ce791 + 8a2226a commit ff48b21

24 files changed

+1381
-774
lines changed

README.md

Lines changed: 166 additions & 136 deletions
Large diffs are not rendered by default.

RyanJson/RyanJson.c

Lines changed: 180 additions & 132 deletions
Large diffs are not rendered by default.

RyanJson/RyanJson.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ extern "C" {
1515
if (!(EX)) \
1616
{ \
1717
jsonLog("\r\n%s:%d Check failed: %s\n", __FILE__, __LINE__, #EX); \
18-
{code}; \
18+
code \
1919
}
2020

21-
#define RyanJsonCheckCode(EX, code) RyanJsonCheckCodeNoReturn(EX, { {code}; });
21+
#define RyanJsonCheckCode(EX, code) RyanJsonCheckCodeNoReturn(EX, code)
2222

23-
#define RyanJsonCheckReturnFlase(EX) RyanJsonCheckCode(EX, { return RyanJsonFalse; })
24-
#define RyanJsonCheckReturnNull(EX) RyanJsonCheckCode(EX, { return NULL; })
25-
#define RyanJsonCheckAssert(EX) RyanJsonCheckCode(EX, { RyanJsonAssert(NULL && "RyanJsonCheckAssert"); })
23+
#define RyanJsonCheckReturnFalse(EX) RyanJsonCheckCode(EX, return RyanJsonFalse;)
24+
#define RyanJsonCheckReturnNull(EX) RyanJsonCheckCode(EX, return NULL;)
25+
#ifdef RyanJsonEnableAssert
26+
#define RyanJsonCheckAssert(EX) RyanJsonCheckCode(EX, RyanJsonAssert(NULL && "RyanJsonCheckAssert");)
27+
#else
28+
#define RyanJsonCheckAssert(EX) (void)(EX)
29+
#endif
2630

2731
// Json 的最基础节点,所有 Json 元素都由该节点表示。
2832
// 结构体中仅包含固定的 next 指针,用于单向链表串联。
@@ -89,7 +93,7 @@ struct RyanJsonNode
8993
/*
9094
* 设计特点:
9195
* - 一个 Json 节点最多 malloc 两次(一次节点本身,一次可选的 key/stringValue),
92-
* 对嵌入式系统非常友好,减少 malloc 头部开销。
96+
* 对嵌入式系统非常友好,减少 malloc 头部开销, 尽可能的减少内存碎片
9397
*
9498
* - key 和 stringValue 必须通过指针管理:
9599
* * 如果直接放在节点里,虽然只需一次 malloc,
@@ -225,21 +229,21 @@ extern RyanJson_t RyanJsonGetObjectByIndex(RyanJson_t pJson, uint32_t index);
225229
#define RyanJsonHasObjectByIndex(pJson, index) RyanJsonMakeBool(RyanJsonGetObjectByIndex(pJson, index))
226230

227231
/**
228-
* @brief 类型判断宏
232+
* @brief RyanJson 类型判断接口
229233
*/
230-
#define RyanJsonIsKey(pJson) RyanJsonMakeBool(RyanJsonGetPayloadWhiteKeyByFlag(pJson))
231-
#define RyanJsonIsNull(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeNull)
232-
#define RyanJsonIsBool(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeBool)
233-
#define RyanJsonIsNumber(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeNumber)
234-
#define RyanJsonIsInt(pJson) RyanJsonMakeBool(RyanJsonIsNumber(pJson) && (RyanJsonFalse == RyanJsonGetPayloadNumberIsDoubleByFlag(pJson)))
235-
#define RyanJsonIsDouble(pJson) RyanJsonMakeBool(RyanJsonIsNumber(pJson) && (RyanJsonTrue == RyanJsonGetPayloadNumberIsDoubleByFlag(pJson)))
236-
#define RyanJsonIsString(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeString)
237-
#define RyanJsonIsArray(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeArray)
238-
#define RyanJsonIsObject(pJson) RyanJsonMakeBool(RyanJsonGetType(pJson) == RyanJsonTypeObject)
234+
extern RyanJsonBool_e RyanJsonIsKey(RyanJson_t pJson);
235+
extern RyanJsonBool_e RyanJsonIsNull(RyanJson_t pJson);
236+
extern RyanJsonBool_e RyanJsonIsBool(RyanJson_t pJson);
237+
extern RyanJsonBool_e RyanJsonIsNumber(RyanJson_t pJson);
238+
extern RyanJsonBool_e RyanJsonIsString(RyanJson_t pJson);
239+
extern RyanJsonBool_e RyanJsonIsArray(RyanJson_t pJson);
240+
extern RyanJsonBool_e RyanJsonIsObject(RyanJson_t pJson);
241+
extern RyanJsonBool_e RyanJsonIsInt(RyanJson_t pJson);
242+
extern RyanJsonBool_e RyanJsonIsDouble(RyanJson_t pJson);
239243

240244
/**
241245
* @brief 取值宏
242-
* !取值宏使用前一定要RyanJsonIsXXXX类型判断宏做好判断,否则会内存访问越界
246+
* !取值宏使用前一定要RyanJsonIsXXXX类型判断函数做好判断,否则会内存访问越界
243247
*/
244248
extern char *RyanJsonGetKey(RyanJson_t pJson);
245249
extern char *RyanJsonGetStringValue(RyanJson_t pJson);
@@ -259,7 +263,7 @@ extern char *RyanJsonGetStringValue(RyanJson_t pJson);
259263
#define RyanJsonAddIntToObject(pJson, key, number) RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateInt(key, number))
260264
#define RyanJsonAddDoubleToObject(pJson, key, number) RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateDouble(key, number))
261265
#define RyanJsonAddStringToObject(pJson, key, string) RyanJsonInsert(pJson, UINT32_MAX, RyanJsonCreateString(key, string))
262-
extern RyanJsonBool_e RyanJsonAddItemToObject(RyanJson_t pJson, char *key, RyanJson_t item);
266+
extern RyanJsonBool_e RyanJsonAddItemToObject(RyanJson_t pJson, const char *key, RyanJson_t item);
263267

264268
#define RyanJsonAddNullToArray(pJson) RyanJsonAddNullToObject(pJson, NULL)
265269
#define RyanJsonAddBoolToArray(pJson, boolean) RyanJsonAddBoolToObject(pJson, NULL, boolean)

RyanJson/RyanJsonConfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extern "C" {
4747
// RyanJson使用递归 序列化/反序列化 json
4848
// 请根据单片机资源合理设置以防止堆栈溢出。
4949
#ifndef RyanJsonNestingLimit
50-
#define RyanJsonNestingLimit 9000000
50+
#define RyanJsonNestingLimit 3000
5151
#endif
5252

5353
// 当 RyanJsonPrint 剩余缓冲空间不足时申请的空间大小

RyanJson/RyanJsonUtils.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ RyanJson_t RyanJsonGetObjectByKeys(RyanJson_t pJson, const char *key, ...)
3939
*/
4040
RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, uint32_t index, ...)
4141
{
42-
RyanJsonCheckReturnNull(NULL != pJson && index >= 0);
42+
RyanJsonCheckReturnNull(NULL != pJson);
4343

4444
uint32_t nextIndex = index;
4545
RyanJson_t nextItem = RyanJsonGetObjectByIndex(pJson, nextIndex);
@@ -48,7 +48,7 @@ RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, uint32_t index, ...)
4848
va_list args;
4949
va_start(args, index);
5050
nextIndex = va_arg(args, uint32_t);
51-
while (nextItem && nextIndex > 0)
51+
while (nextItem && UINT32_MAX != nextIndex)
5252
{
5353
nextItem = RyanJsonGetObjectByIndex(nextItem, nextIndex);
5454
nextIndex = va_arg(args, uint32_t);
@@ -67,7 +67,7 @@ RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, uint32_t index, ...)
6767
*/
6868
RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, uint32_t count)
6969
{
70-
RyanJsonCheckReturnNull(NULL != numbers && count > 0);
70+
RyanJsonCheckReturnNull(NULL != numbers);
7171

7272
RyanJson_t pJson = RyanJsonCreateArray();
7373
for (uint32_t i = 0; pJson && i < count; i++) { RyanJsonAddIntToArray(pJson, numbers[i]); }
@@ -83,7 +83,7 @@ RyanJson_t RyanJsonCreateIntArray(const int32_t *numbers, uint32_t count)
8383
*/
8484
RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, uint32_t count)
8585
{
86-
RyanJsonCheckReturnNull(NULL != numbers && count > 0);
86+
RyanJsonCheckReturnNull(NULL != numbers);
8787

8888
RyanJson_t pJson = RyanJsonCreateArray();
8989
for (uint32_t i = 0; pJson && i < count; i++) { RyanJsonAddDoubleToArray(pJson, numbers[i]); }
@@ -99,7 +99,7 @@ RyanJson_t RyanJsonCreateDoubleArray(const double *numbers, uint32_t count)
9999
*/
100100
RyanJson_t RyanJsonCreateStringArray(const char **strings, uint32_t count)
101101
{
102-
RyanJsonCheckReturnNull(NULL != strings && count > 0);
102+
RyanJsonCheckReturnNull(NULL != strings);
103103

104104
RyanJson_t pJson = RyanJsonCreateArray();
105105
for (uint32_t i = 0; pJson && i < count; i++) { RyanJsonAddStringToArray(pJson, strings[i]); }

RyanJson/RyanJsonUtils.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,25 @@ extern RyanJson_t RyanJsonCreateStringArray(const char **strings, uint32_t count
1818
extern RyanJsonBool_e RyanJsonCompareOnlyKey(RyanJson_t leftJson, RyanJson_t rightJson);
1919

2020
/**
21-
* @brief 查询函数
21+
* @brief 查询函数,此接口较为底层,请使用下发的宏定义调用
2222
*/
2323
extern RyanJson_t RyanJsonGetObjectByIndexs(RyanJson_t pJson, uint32_t index, ...);
2424
extern RyanJson_t RyanJsonGetObjectByKeys(RyanJson_t pJson, const char *key, ...);
25+
26+
/**
27+
* @brief 可使用此宏进行嵌套式查找,例如 RyanJsonGetObjectToKey(json, "test", "inter")
28+
*
29+
*/
2530
#define RyanJsonGetObjectToKey(pJson, key, ...) RyanJsonGetObjectByKeys(pJson, (key), ##__VA_ARGS__, NULL)
26-
#define RyanJsonGetObjectToIndex(pJson, index, ...) RyanJsonGetObjectByIndexs(pJson, (index), ##__VA_ARGS__, 0)
31+
32+
/**
33+
* @brief 可使用此宏进行嵌套式查找,例如 RyanJsonGetObjectToIndex(json, 0, 2)
34+
*
35+
*/
36+
#define RyanJsonGetObjectToIndex(pJson, index, ...) RyanJsonGetObjectByIndexs(pJson, (index), ##__VA_ARGS__, UINT32_MAX)
2737

2838
#define RyanJsonHasObjectToKey(pJson, key, ...) RyanJsonMakeBool(RyanJsonGetObjectByKeys(pJson, key, ##__VA_ARGS__, NULL))
29-
#define RyanJsonHasObjectToIndex(pJson, index, ...) RyanJsonMakeBool(RyanJsonGetObjectByIndexs(pJson, index, ##__VA_ARGS__, 0))
39+
#define RyanJsonHasObjectToIndex(pJson, index, ...) RyanJsonMakeBool(RyanJsonGetObjectByIndexs(pJson, index, ##__VA_ARGS__, UINT32_MAX))
3040

3141
#ifdef __cplusplus
3242
}

externalModule/yyjson/yyjson.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,7 +1997,7 @@ yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num);
19971997
/** Set the value to int.
19981998
Returns false if input is NULL or `val` is object or array.
19991999
@warning This will modify the `immutable` value, use with caution. */
2000-
yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int num);
2000+
yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int64_t num);
20012001

20022002
/** Set the value to float.
20032003
Returns false if input is NULL or `val` is object or array.
@@ -2600,7 +2600,7 @@ yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val *val, int64_t num);
26002600
/** Set the value to int.
26012601
Returns false if input is NULL.
26022602
@warning This function should not be used on an existing object or array. */
2603-
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int num);
2603+
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int64_t num);
26042604

26052605
/** Set the value to float.
26062606
Returns false if input is NULL.
@@ -5426,9 +5426,9 @@ yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num) {
54265426
return true;
54275427
}
54285428

5429-
yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int num) {
5429+
yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int64_t num) {
54305430
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5431-
unsafe_yyjson_set_sint(val, (int64_t)num);
5431+
unsafe_yyjson_set_sint(val, num);
54325432
return true;
54335433
}
54345434

@@ -5979,9 +5979,9 @@ yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val *val, int64_t num) {
59795979
return true;
59805980
}
59815981

5982-
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int num) {
5982+
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int64_t num) {
59835983
if (yyjson_unlikely(!val)) return false;
5984-
unsafe_yyjson_set_sint(val, (int64_t)num);
5984+
unsafe_yyjson_set_sint(val, num);
59855985
return true;
59865986
}
59875987

run_coverage.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ set -e # 遇到错误立即退出
88
./test/fuzzer/corpus \
99
-dict=./test/fuzzer/RyanJsonFuzzer.dict \
1010
-timeout=2 \
11-
-runs=99999 \
11+
-runs=999999 \
1212
-verbosity=0 \
1313
-max_len=16384
1414

@@ -27,6 +27,7 @@ llvm-cov report ./build/linux/x86/release/RyanJson \
2727
-instr-profile=default.profdata \
2828
-show-mcdc-summary \
2929
-show-functions \
30+
-show-region-summary \
3031
-sources ./test/fuzzer ./RyanJson
3132

3233
# ================================
@@ -36,4 +37,8 @@ llvm-cov show ./build/linux/x86/release/RyanJson \
3637
-instr-profile=default.profdata \
3738
-format=html \
3839
-output-dir=docs \
39-
-show-mcdc-summary
40+
-show-mcdc-summary \
41+
-show-expansions \
42+
-show-regions \
43+
-show-line-counts-or-regions \
44+
-sources ./test/fuzzer ./RyanJson

test/RyanJsonMemoryFootprintTest.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,36 +42,40 @@ static int cJSONMemoryFootprint(char *jsonstr)
4242

4343
static int yyjsonMemoryFootprint(char *jsonstr)
4444
{
45-
// static yyjson_alc yyalc = {yy_malloc, yy_realloc, yy_free, NULL};
46-
// // 先解析成只读文档(可用自定义分配器 yyalc)
47-
// yyjson_doc *doc = yyjson_read_opts(jsonstr, strlen(jsonstr), YYJSON_READ_NOFLAG, &yyalc, NULL);
48-
// if (doc == NULL) { return -1; }
45+
static yyjson_alc yyalc = {yy_malloc, yy_realloc, yy_free, NULL};
46+
// 先解析成只读文档(可用自定义分配器 yyalc)
47+
yyjson_doc *doc = yyjson_read_opts(jsonstr, strlen(jsonstr), YYJSON_READ_NOFLAG, &yyalc, NULL);
48+
if (doc == NULL) { return -1; }
4949

50-
// // 从只读文档拷贝为可变文档(用于后续读写修改)
51-
// yyjson_mut_doc *mdoc = yyjson_doc_mut_copy(doc, &yyalc);
52-
// yyjson_doc_free(doc);
53-
// if (mdoc == NULL) { return -1; }
50+
// 从只读文档拷贝为可变文档(用于后续读写修改)
51+
yyjson_mut_doc *mdoc = yyjson_doc_mut_copy(doc, &yyalc);
52+
yyjson_doc_free(doc);
53+
if (mdoc == NULL) { return -1; }
5454

5555
// 统计当前分配器的占用
5656
int area = 0, use = 0;
5757
v_mcheck(&area, &use);
5858

59-
// // 用完释放可变文档
60-
// yyjson_mut_doc_free(mdoc);
59+
// 用完释放可变文档
60+
yyjson_mut_doc_free(mdoc);
6161
return use;
6262
}
6363

6464
static void printfJsonCompera(char *jsonstr)
6565
{
6666
int RyanJsonCount = 0;
6767
int cJSONCount = 0;
68+
int yyjsonCount = 0;
6869
RyanJsonCount = RyanJsonMemoryFootprint(jsonstr);
6970
cJSONCount = cJSONMemoryFootprint(jsonstr);
70-
71-
printf("json原始文本长度为 %ld, 序列化后RyanJson内存占用: %d, cJSON内存占用: %d\r\n", strlen(jsonstr), RyanJsonCount, cJSONCount);
71+
yyjsonCount = yyjsonMemoryFootprint(jsonstr);
72+
printf("json原始文本长度为 %ld, 序列化后RyanJson内存占用: %d, cJSON内存占用: %d, yyjson内存占用: %d\r\n", strlen(jsonstr),
73+
RyanJsonCount, cJSONCount, yyjsonCount);
7274

7375
double save_vs_cjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)cJSONCount;
74-
printf("比cJSON节省: %.2f%% 内存占用\r\n", save_vs_cjson);
76+
double save_vs_yyjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)yyjsonCount;
77+
78+
printf("比cJSON节省: %.2f%% 内存占用, 比yyjson节省: %.2f%% 内存占用\r\n", save_vs_cjson, save_vs_yyjson);
7579
}
7680

7781
RyanJsonBool_e RyanJsonMemoryFootprintTest(void)

0 commit comments

Comments
 (0)