新增子JSON支持
This commit is contained in:
parent
4e4fe8e7ea
commit
ba65233636
|
@ -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);
|
||||
|
|
35
readme.md
35
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
|
||||
|
||||
|
|
24
src/cson.c
24
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:
|
||||
|
|
18
src/cson.h
18
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue