新增子JSON支持

This commit is contained in:
Letter 2019-09-30 07:59:51 +08:00
parent 4e4fe8e7ea
commit ba65233636
4 changed files with 73 additions and 30 deletions

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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);