From ba65233636d2b6afc202eda29f2425a137c3b68c Mon Sep 17 00:00:00 2001 From: Letter Date: Mon, 30 Sep 2019 07:59:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AD=90JSON=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/cson_test.c | 26 +++++++++++++++++--------- readme.md | 35 +++++++++++++++++++---------------- src/cson.c | 24 ++++++++++++++++++++++-- src/cson.h | 18 +++++++++++++++--- 4 files changed, 73 insertions(+), 30 deletions(-) diff --git a/demo/cson_test.c b/demo/cson_test.c index c13f05f..5a0e0ce 100644 --- a/demo/cson_test.c +++ b/demo/cson_test.c @@ -10,7 +10,7 @@ */ #include "shell.h" -#include "ulog.h" +#include "log.h" #include "cson.h" @@ -32,6 +32,7 @@ struct test char *str[2]; CsonList *charList; CsonList *strList; + char *subjson; }; CsonModel subModel[] = @@ -54,7 +55,8 @@ CsonModel model[] = CSON_MODEL_LIST(struct test, list, subModel, sizeof(subModel)/sizeof(CsonModel)), CSON_MODEL_ARRAY(struct test, str, CSON_TYPE_STRING, 2), CSON_MODEL_LIST(struct test, charList, CSON_MODEL_INT_LIST, CSON_BASIC_LIST_MODEL_SIZE), - CSON_MODEL_LIST(struct test, strList, CSON_MODEL_STRING_LIST, CSON_BASIC_LIST_MODEL_SIZE) + CSON_MODEL_LIST(struct test, strList, CSON_MODEL_STRING_LIST, CSON_BASIC_LIST_MODEL_SIZE), + CSON_MODEL_JSON(struct test, subjson) }; @@ -67,19 +69,24 @@ void csonTest(void) " \"list\": [{\"id\": 21, \"test\": \"hello cson\"}, {\"id\": 22, \"test\": \"hello letter\"}]," "\"str\": [\"array1\", \"array2\"]," "\"charList\": [1, 12, 52], " - "\"strList\": [\"str1\", \"str2\"]}"; + "\"strList\": [\"str1\", \"str2\"]," + "\"subjson\":{\"test\": \"hello\"}}"; struct test *st = csonDecode(jsonStr, model, sizeof(model)/sizeof(CsonModel)); - ulogDebug("josn 0x%08x, id: %d, num: %d, max: %d, value: %lf, name: %s\r\nsub: id: %d, test: %s", - st, st->id, st->num, st->max, st->value, st->name, st->sub->id, st->sub->test); - ulogDebug("str: %s %s", st->str[0], st->str[1]); + logDebug("json 0x%08x, id: %d, num: %d, max: %d, value: %lf, name: %s\r\nsub: id: %d, test: %s", + st, st->id, st->num, st->max, st->value, st->name, st->sub ? st->sub->id : 0, st->sub ? st->sub->test : "null"); + logDebug("str: %s %s", st->str[0], st->str[1]); CsonList *p = st->list; while (p) { struct subtest *sst = p->obj; if (p->obj) { - ulogDebug("list: id: %d, test: %s", sst->id, sst->test); + logDebug("list: id: %d, test: %s", sst->id, sst->test); + } + else + { + logDebug("list: null"); } p = p->next; } @@ -89,7 +96,7 @@ void csonTest(void) int *sst = p->obj; if (p->obj) { - ulogDebug("list: id: %d", *sst); + logDebug("list: id: %d", *sst); } p = p->next; } @@ -99,10 +106,11 @@ void csonTest(void) char **sst = p->obj; if (p->obj) { - ulogDebug("list: id: %s", *sst); + logDebug("list: id: %s", *sst); } p = p->next; } + logDebug("subjson: %s", st->subjson); char *root = csonEncode(st, model, sizeof(model)/sizeof(CsonModel), 512, 0); printf("encode: %s", root); diff --git a/readme.md b/readme.md index 6e73c71..ac6f951 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,8 @@ # CSON -![version](https://img.shields.io/badge/version-1.0.1-brightgreen.svg) -![build](https://img.shields.io/badge/build-2019.9.4-brightgreen.svg) +![version](https://img.shields.io/badge/version-1.0.2-brightgreen.svg) +![build](https://img.shields.io/badge/build-2019.9.29-brightgreen.svg) +![license](https://img.shields.io/badge/license-MIT-brightgreen.svg) 基于[cJSON](https://github.com/kbranigan/cJSON),运行于C语言平台的json-struct模型解析工具 @@ -126,6 +127,7 @@ CSON采用数据模型对结构体进行解析,在方便json操作的同时, 4. 基本类型数组(char[], short[], int[], long[], float[], double[], *char[]) 5. 子结构体(指针形式) 6. 链表(CsonList) +7. 子json(char *) 其中,为了方便解析,CSON定义了一个专用的链表(CsonList),用于对json中复杂结构的数组映射 @@ -167,20 +169,21 @@ typedef struct cson_model 一般情况下,你只需要使用CSON提供的宏进行数据模型条目的定义,数据模型宏与对应的数据类型对应如下: -| 数据模型宏 | 数据类型 | 备注 | -| -------------------------------------------------- | -------- | -------------------------------------------------- | -| CSON_MODEL_OBJ(type) | 结构体 | 用于描述整个结构体,每一个数据模型都需要包含此条目 | -| CSON_MODEL_CHAR(type, key) | char | | -| CSON_MODEL_SHORT(type, key) | short | | -| CSON_MODEL_INT(type, key) | int | | -| CSON_MODEL_LONG(type, key) | long | | -| CSON_MODEL_FLOAT(type, key) | float | | -| CSON_MODEL_DOUBLE(type, key) | double | | -| CSON_MODEL_BOOL(type, key) | bool | C没有bool,对应为char | -| CSON_MODEL_STRING(type, key) | char * | | -| CSON_MODEL_STRUCT(type, key, submodel, subsize) | 子结构体 | 子结构体必须是结构体指针的形式 | -| CSON_MODEL_LIST(type, key, submodel, subsize) | CsonList | CSON定义的链表 | -| CSON_MODEL_ARRAY(type, key, elementType, arraySize | 数组 | 支持基本数据类型, 数组的每一个元素必须合法 | +| 数据模型宏 | 数据类型 | 备注 | +| --------------------------------------------------- | -------- | ------------------------------------------------------ | +| CSON_MODEL_OBJ(type) | 结构体 | 用于描述整个结构体,每一个数据模型都需要包含此条目 | +| CSON_MODEL_CHAR(type, key) | char | | +| CSON_MODEL_SHORT(type, key) | short | | +| CSON_MODEL_INT(type, key) | int | | +| CSON_MODEL_LONG(type, key) | long | | +| CSON_MODEL_FLOAT(type, key) | float | | +| CSON_MODEL_DOUBLE(type, key) | double | | +| CSON_MODEL_BOOL(type, key) | bool | C没有bool,对应为char | +| CSON_MODEL_STRING(type, key) | char * | | +| CSON_MODEL_STRUCT(type, key, submodel, subsize) | 子结构体 | 子结构体必须是结构体指针的形式 | +| CSON_MODEL_LIST(type, key, submodel, subsize) | CsonList | CSON定义的链表 | +| CSON_MODEL_ARRAY(type, key, elementType, arraySize) | 数组 | 支持基本数据类型, 数组的每一个元素必须合法 | +| CSON_MODEL_JSON(type, key) | 子json | 将子json直接以字符串解析,或者将json字符串转化为子json | ## API diff --git a/src/cson.c b/src/cson.c index 9399334..d1ac31c 100644 --- a/src/cson.c +++ b/src/cson.c @@ -186,6 +186,15 @@ void *csonDecodeList(cJSON *json, char *key, CsonModel *model, int modelSize) } +/** + * @brief 解析数组 + * + * @param json json对象 + * @param key key + * @param base 数组基址 + * @param elementType 数组元素类型 + * @param arraySize 数组大小 + */ void csonDecodeArray(cJSON *json, char *key, void * base, CsonType elementType, short arraySize) { cJSON *array = cJSON_GetObjectItem(json, key); @@ -301,6 +310,10 @@ void *csonDecodeObject(cJSON *json, CsonModel *model, int modelSize) csonDecodeArray(json, model[i].key, (void *)((int)obj + model[i].offset), model[i].param.array.eleType, model[i].param.array.size); break; + case CSON_TYPE_JSON: + *(int *)((int)obj + model[i].offset) = (int)cJSON_PrintUnformatted( + cJSON_GetObjectItem(json, model[i].key)); + break; default: break; } @@ -452,7 +465,7 @@ cJSON* csonEncodeArray(void *base, CsonType elementType, short arraySize) * @param obj 对象 * @param model 数据模型 * @param modelSize 数据模型数量 - * @return cJSON* 编码得到的JOSN对象 + * @return cJSON* 编码得到的json对象 */ cJSON* csonEncodeObject(void *obj, CsonModel *model, int modelSize) { @@ -504,6 +517,10 @@ cJSON* csonEncodeObject(void *obj, CsonModel *model, int modelSize) (void *)((int)obj + model[i].offset), model[i].param.array.eleType, model[i].param.array.size)); break; + case CSON_TYPE_JSON: + cJSON_AddItemToObject(root, model[i].key, + cJSON_Parse((char *)(*(int *)((int)obj + model[i].offset)))); + break; default: break; } @@ -518,7 +535,9 @@ cJSON* csonEncodeObject(void *obj, CsonModel *model, int modelSize) * @param obj 对象 * @param model 数据模型 * @param modelSize 数据模型数量 - * @return char* 编码得到的josn字符串 + * @param bufferSize 分配给json字符串的空间大小 + * @param fmt 是否格式化json字符串 + * @return char* 编码得到的json字符串 */ char* csonEncode(void *obj, CsonModel *model, int modelSize, int bufferSize, int fmt) { @@ -553,6 +572,7 @@ void csonFree(void *obj, CsonModel *model, int modelSize) case CSON_TYPE_DOUBLE: break; case CSON_TYPE_STRING: + case CSON_TYPE_JSON: cson.free((char *)(*(int *)((int)obj + model[i].offset))); break; case CSON_TYPE_LIST: diff --git a/src/cson.h b/src/cson.h index 79cfdd6..c39439c 100644 --- a/src/cson.h +++ b/src/cson.h @@ -16,7 +16,7 @@ #include "cJSON.h" -#define CSON_VERSION "1.0.1" /**< CSON版本 */ +#define CSON_VERSION "1.0.2" /**< CSON版本 */ /** * @defgroup CSON cson @@ -44,6 +44,7 @@ typedef enum CSON_TYPE_STRUCT, CSON_TYPE_LIST, CSON_TYPE_ARRAY, + CSON_TYPE_JSON, } CsonType; @@ -209,6 +210,15 @@ extern CsonModel csonBasicListModel[]; /**< 基础类型链表数据模型 */ */ #define CSON_MODEL_ARRAY(type, key, elementType, arraySize) \ {CSON_TYPE_ARRAY, #key, offsetof(type, key), .param.array.eleType=elementType, .param.array.size=arraySize} + +/** + * @brief 子json数据模型 + * + * @param type 对象模型 + * @param key 数据键值 + */ +#define CSON_MODEL_JSON(type, key) \ + {CSON_TYPE_JSON, #key, offsetof(type, key)} /** * @brief CSON断言 @@ -280,7 +290,7 @@ void *csonDecode(const char *jsonStr, CsonModel *model, int modelSize); * @param obj 对象 * @param model 数据模型 * @param modelSize 数据模型数量 - * @return char* 编码得到的josn字符串 + * @return char* 编码得到的json字符串 */ cJSON* csonEncodeObject(void *obj, CsonModel *model, int modelSize); @@ -290,7 +300,9 @@ cJSON* csonEncodeObject(void *obj, CsonModel *model, int modelSize); * @param obj 对象 * @param model 数据模型 * @param modelSize 数据模型数量 - * @return char* 编码得到的josn字符串 + * @param bufferSize 分配给json字符串的空间大小 + * @param fmt 是否格式化json字符串 + * @return char* 编码得到的json字符串 */ char* csonEncode(void *obj, CsonModel *model, int modelSize, int bufferSize, int fmt);