-add options:_ex_args_nullable(0x01) _ex_args_exclude_decode(0x02) _ex_args_exclude_encode(0x04)

-fix compile error on g++
-add log when json decode error.
This commit is contained in:
suncb 2020-04-07 17:32:11 +08:00 committed by sunchb
parent eddf45f4c6
commit b826c74c71
9 changed files with 412 additions and 94 deletions

View File

@ -1,37 +1,35 @@
# [简体中文](./README_zh.md) | English # 简体中文 | [English](./README_EN.md)
# cson # cson
Transformation between json string and struct. 轻松完成C语言结构体和Json的转换。
The transformation between string to JSON objects (e.g. json_t in Jansson) 其中Json字符串与Json对象例如Jansson库中的json_t之间的转换由第三方库实现例如Jansson或者cJSON请参考依赖库
is implemented by a third-party library (Jansson or cJSON. Refer to Dependence). cson真正实现的是Json对象与结构体间的转换。
What cson really implements is the transformation between JSON object and structure.
## Compilation ## 编译
### Compile static library ### 编译静态库
``` shell ``` shell
$ git clone https://github.com/sunchb/cson.git $ git clone https://github.com/sunchb/cson.git
$ cd cson $ cd cson
$ make $ make
``` ```
### Compile demo ### 编译示例
``` shell ``` shell
$ cd demo $ cd demo
$ make $ make
$ ./test $ ./test
``` ```
## How to use ## 如何使用cson
1. Define the data structure for JSON. 1. 定义与Json协议对应的结构体。
2. Define the property description table for data structure. 2. 定义结构体的属性描述表。
3. Call cson api to decode or encode. 3. 调用cson接口完成转换。
## Dependence ## 依赖
https://github.com/akheron/jansson.git https://github.com/akheron/jansson.git
https://github.com/DaveGamble/cJSON.git https://github.com/DaveGamble/cJSON.git
## Demo ## 示例
Here is a JSON with various data types. eg. Interger, String, Real, Boolean, Object, and Array. 下面具有各种数据类型的JSON。例如整数字符串实数布尔值对象和数组。我们将通过cson对其进行解码和编码。
We're going to decode and encode it by cson.
``` json ``` json
{ {
@ -87,13 +85,13 @@ We're going to decode and encode it by cson.
} }
``` ```
### 1. Define the data structure for JSON. ### 1. 定义与Json协议对应的结构体。
Even if you don't use cson, you usually need to do like this. 即使不使用cson通常我们也会这么做。
#### Attention #### 注意事项
- String must be declared as char*. - 字符串必须定义为char*类型。
- Array must be declared as pointer. - 数组必须定义为指针类型。
- Declare additional properties to hold the array size for every array property. - 如果结构体包含数组,需要为每一个数组定义一个额外的属性,用于保存数组大小。
``` c ``` c
typedef struct { typedef struct {
@ -127,8 +125,8 @@ typedef struct {
} PlayList; } PlayList;
``` ```
### 2. Define the property description table for data structure. ### 2. 定义结构体的属性描述表。
Use following definitions to help you describe the structure. 使用以下宏定义描述结构体属性。
- _property_int(type, field) - _property_int(type, field)
- _property_real(type, field) - _property_real(type, field)
- _property_bool(type, field) - _property_bool(type, field)
@ -140,13 +138,32 @@ Use following definitions to help you describe the structure.
- _property_array_real(type, field, arrayType, countfild) - _property_array_real(type, field, arrayType, countfild)
- _property_array_bool(type, field, arrayType, countfild) - _property_array_bool(type, field, arrayType, countfild)
Args notes:
参数说明:
- type: type of data structure - type: type of data structure
- field: property name - field: property name
- tbl: description table of the property type. use when object or object array - tbl: description table of the property type. use when object or object array
- arrayType: type of the array (Used to calculate size when dynamically get array memory) - arrayType: type of the array (Used to calculate size when dynamically get array memory)
- countfild: property to save array size - countfild: property to save array size
也可以使用带有扩展参数的宏定义其中args可以是_ex_args_nullable, _ex_args_exclude_decode, _ex_args_exclude_encode的组合。
- #define _ex_args_nullable (0x01) //不会因为该字段异常而停止后续字段解析, 该选项默认打开。
- #define _ex_args_exclude_decode (0x02) //该字段不参与解析————例如指示数组元素个数的字段Json中可以不包含它
- #define _ex_args_exclude_encode (0x04) //该字段不参与格式化输出
- #define _ex_args_all (_ex_args_nullable | _ex_args_exclude_decode | _ex_args_exclude_encode)
- _property_int_ex(type, field, args)
- _property_real_ex(type, field, args)
- _property_bool_ex(type, field, args)
- _property_string_ex(type, field, args)
- _property_obj_ex(type, field, tbl, args)
- _property_array_ex(type, field, tbl, subType, count, args)
- _property_array_object_ex(type, field, tbl, subType, count, args)
- _property_array_int_ex(type, field, subType, count, args)
- _property_array_string_ex(type, field, subType, count, args)
- _property_array_real_ex(type, field, subType, count, args)
- _property_array_bool_ex(type, field, subType, count, args)
``` c ``` c
/* description for Lyric */ /* description for Lyric */
reflect_item_t lyric_ref_tbl[] = { reflect_item_t lyric_ref_tbl[] = {
@ -164,7 +181,7 @@ reflect_item_t song_ref_tbl[] = {
_property_int(SongInfo, duration), _property_int(SongInfo, duration),
_property_bool(SongInfo, paid), _property_bool(SongInfo, paid),
_property_real(SongInfo, price), _property_real(SongInfo, price),
_property_int(SongInfo, lyricNum), _property_int_ex(SongInfo, lyricNum, _ex_args_all),
_property_array(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum), /* Lyric: type of array; lyricNum: property to save array size */ _property_array(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum), /* Lyric: type of array; lyricNum: property to save array size */
_property_end() _property_end()
}; };
@ -180,14 +197,14 @@ reflect_item_t ext_data_ref_tbl[] = {
reflect_item_t play_list_ref_tbl[] = { reflect_item_t play_list_ref_tbl[] = {
_property_string(PlayList, name), _property_string(PlayList, name),
_property_string(PlayList, creater), _property_string(PlayList, creater),
_property_int(PlayList, songNum), _property_int_ex(PlayList, songNum, _ex_args_all),
_property_array(PlayList, songList, song_ref_tbl, SongInfo, songNum), _property_array(PlayList, songList, song_ref_tbl, SongInfo, songNum),
_property_obj(PlayList, extData, ext_data_ref_tbl), _property_obj(PlayList, extData, ext_data_ref_tbl),
_property_end() _property_end()
}; };
``` ```
### 3. Call cson api to decode or encode. ### 3. 调用cson接口编解码Json。
``` c ``` c
PlayList playList; PlayList playList;
@ -199,6 +216,6 @@ char* jstrOutput;
csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl);
``` ```
## Restrict ## 限制
- Multidimensional arrays are not supported. - 暂不支持多维数组。
- Cjson is used by default. If you want to use jannson or other json lib, please modify $(JSON_LIB) in makefile. - 默认使用Cjson库。如果需要使用jannson请修改Makefile中的$(JSON_LIB)变量。

View File

@ -1,35 +1,37 @@
# 简体中文 | [English](./README.md) # 简体中文 | [English](./README_EN.md)
# cson # cson
轻松完成C语言结构体和Json的转换。 Transformation between json string and struct.
其中Json字符串与Json对象例如Jansson库中的json_t之间的转换由第三方库实现例如Jansson或者cJSON请参考依赖库 The transformation between string to JSON objects (e.g. json_t in Jansson)
cson真正实现的是Json对象与结构体间的转换。 is implemented by a third-party library (Jansson or cJSON. Refer to Dependence).
What cson really implements is the transformation between JSON object and structure.
## 编译 ## Compilation
### 编译静态库 ### Compile static library
``` shell ``` shell
$ git clone https://github.com/sunchb/cson.git $ git clone https://github.com/sunchb/cson.git
$ cd cson $ cd cson
$ make $ make
``` ```
### 编译示例 ### Compile demo
``` shell ``` shell
$ cd demo $ cd demo
$ make $ make
$ ./test $ ./test
``` ```
## 如何使用cson ## How to use
1. 定义与Json协议对应的结构体。 1. Define the data structure for JSON.
2. 定义结构体的属性描述表。 2. Define the property description table for data structure.
3. 调用cson接口完成转换。 3. Call cson api to decode or encode.
## 依赖 ## Dependence
https://github.com/akheron/jansson.git https://github.com/akheron/jansson.git
https://github.com/DaveGamble/cJSON.git https://github.com/DaveGamble/cJSON.git
## 示例 ## Demo
下面具有各种数据类型的JSON。例如整数字符串实数布尔值对象和数组。我们将通过cson对其进行解码和编码。 Here is a JSON with various data types. eg. Interger, String, Real, Boolean, Object, and Array.
We're going to decode and encode it by cson.
``` json ``` json
{ {
@ -85,13 +87,13 @@ https://github.com/DaveGamble/cJSON.git
} }
``` ```
### 1. 定义与Json协议对应的结构体。 ### 1. Define the data structure for JSON.
即使不使用cson通常我们也会这么做。 Even if you don't use cson, you usually need to do like this.
#### 注意事项 #### Attention
- 字符串必须定义为char*类型。 - String must be declared as char*.
- 数组必须定义为指针类型。 - Array must be declared as pointer.
- 如果结构体包含数组,需要为每一个数组定义一个额外的属性,用于保存数组大小。 - Declare additional properties to hold the array size for every array property.
``` c ``` c
typedef struct { typedef struct {
@ -125,8 +127,8 @@ typedef struct {
} PlayList; } PlayList;
``` ```
### 2. 定义结构体的属性描述表。 ### 2. Define the property description table for data structure.
使用以下宏定义描述结构体属性。 Use following definitions to help you describe the structure.
- _property_int(type, field) - _property_int(type, field)
- _property_real(type, field) - _property_real(type, field)
- _property_bool(type, field) - _property_bool(type, field)
@ -138,13 +140,31 @@ typedef struct {
- _property_array_real(type, field, arrayType, countfild) - _property_array_real(type, field, arrayType, countfild)
- _property_array_bool(type, field, arrayType, countfild) - _property_array_bool(type, field, arrayType, countfild)
参数说明: Args notes:
- type: type of data structure - type: type of data structure
- field: property name - field: property name
- tbl: description table of the property type. use when object or object array - tbl: description table of the property type. use when object or object array
- arrayType: type of the array (Used to calculate size when dynamically get array memory) - arrayType: type of the array (Used to calculate size when dynamically get array memory)
- countfild: property to save array size - countfild: property to save array size
You can also use macro definitions with extended parameters, the range of args is _ex_args_nullable, _ex_args_exclude_decode, _ex_args_exclude_encode and thire combinations.
- #define _ex_args_nullable (0x01) //continue parse or encode when the field exception occurred. Default is "ON".
- #define _ex_args_exclude_decode (0x02) //do not parse the field.
- #define _ex_args_exclude_encode (0x04) //do not encode the field.
- #define _ex_args_all (_ex_args_nullable | _ex_args_exclude_decode | _ex_args_exclude_encode)
- _property_int_ex(type, field, args)
- _property_real_ex(type, field, args)
- _property_bool_ex(type, field, args)
- _property_string_ex(type, field, args)
- _property_obj_ex(type, field, tbl, args)
- _property_array_ex(type, field, tbl, subType, count, args)
- _property_array_object_ex(type, field, tbl, subType, count, args)
- _property_array_int_ex(type, field, subType, count, args)
- _property_array_string_ex(type, field, subType, count, args)
- _property_array_real_ex(type, field, subType, count, args)
- _property_array_bool_ex(type, field, subType, count, args)
``` c ``` c
/* description for Lyric */ /* description for Lyric */
reflect_item_t lyric_ref_tbl[] = { reflect_item_t lyric_ref_tbl[] = {
@ -185,7 +205,7 @@ reflect_item_t play_list_ref_tbl[] = {
}; };
``` ```
### 3. 调用cson接口编解码Json。 ### 3. Call cson api to decode or encode.
``` c ``` c
PlayList playList; PlayList playList;
@ -197,6 +217,6 @@ char* jstrOutput;
csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl);
``` ```
## 限制 ## Restrict
- 暂不支持多维数组。 - Multidimensional arrays are not supported.
- 默认使用Cjson库。如果需要使用jannson请修改Makefile中的$(JSON_LIB)变量。 - Cjson is used by default. If you want to use jannson or other json lib, please modify $(JSON_LIB) in makefile.

View File

@ -5,6 +5,7 @@
#include "cJSON.h" #include "cJSON.h"
#include "cson.h" #include "cson.h"
#include "string.h" #include "string.h"
#include "stdio.h"
cson_t cjson_impl_object_get(const cson_t object, const char* key){ cson_t cjson_impl_object_get(const cson_t object, const char* key){
return cJSON_GetObjectItem((cJSON*)object, key); return cJSON_GetObjectItem((cJSON*)object, key);
@ -34,7 +35,12 @@ cson_type cjson_impl_typeof(cson_t object){
} }
cson_t cjson_impl_loadb(const char *buffer, size_t buflen){ cson_t cjson_impl_loadb(const char *buffer, size_t buflen){
return cJSON_Parse(buffer); cson_t ret = NULL;
ret = cJSON_Parse(buffer);
if(!ret){
printf("parse stop with:%s\n", cJSON_GetErrorPtr());
}
return ret;
} }
void cjson_impl_decref(cson_t object){ void cjson_impl_decref(cson_t object){

View File

@ -4,6 +4,7 @@
*/ */
#include "cson.h" #include "cson.h"
#include "jansson.h" #include "jansson.h"
#include "stdio.h"
cson_t jansson_impl_object_get(const cson_t object, const char* key){ cson_t jansson_impl_object_get(const cson_t object, const char* key){
return json_object_get((json_t*)object, key); return json_object_get((json_t*)object, key);
@ -14,8 +15,20 @@ cson_type jansson_impl_typeof(cson_t object){
} }
cson_t jansson_impl_loadb(const char *buffer, size_t buflen){ cson_t jansson_impl_loadb(const char *buffer, size_t buflen){
cson_t ret = NULL;
json_error_t err; json_error_t err;
return json_loadb(buffer, buflen, JSON_DECODE_ANY, &err);
ret = json_loadb(buffer, buflen, JSON_DECODE_ANY, &err);
if(!ret){
printf("line:%d,column:%d,pos:%d,source:%s,text:%s\n",
err.line,
err.column,
err.position,
err.source,
err.text);
}
return ret;
} }
void jansson_impl_decref(cson_t object){ void jansson_impl_decref(cson_t object){

View File

@ -4,9 +4,9 @@ extern void test2();
#include "cson.h" #include "cson.h"
#include "stdio.h" #include "stdio.h"
void main() int main()
{ {
test1(); test1();
test2(); test2();
return; return 0;
} }

View File

@ -3,6 +3,12 @@
#include "string.h" #include "string.h"
#include "stdlib.h" #include "stdlib.h"
#include "assert.h"
#include "math.h"
#define CHECK_STRING(a, b) assert(strcmp(a, b) == 0)
#define CHECK_NUMBER(a, b) assert(a == b)
#define CHECK_REAL(a, b) assert(fabs(a-b) <= 1e-6)
/** /**
* 使cson解析如下所示播放列表 * 使cson解析如下所示播放列表
* *
@ -142,11 +148,11 @@ reflect_item_t song_ref_tbl[] = {
_property_int(SongInfo, duration), _property_int(SongInfo, duration),
_property_bool(SongInfo, paid), _property_bool(SongInfo, paid),
_property_real(SongInfo, price), _property_real(SongInfo, price),
_property_int(SongInfo, lyricNum), _property_int_ex(SongInfo, lyricNum, _ex_args_all),
_property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum), _property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum),
_property_int(SongInfo, keyNum), _property_int_ex(SongInfo, keyNum, _ex_args_all),
_property_array_int(SongInfo, key, int, keyNum), _property_array_int(SongInfo, key, int, keyNum),
_property_int(SongInfo, strNum), _property_int_ex(SongInfo, strNum, _ex_args_all),
_property_array_string(SongInfo, strList, char*, strNum), _property_array_string(SongInfo, strList, char*, strNum),
_property_end() _property_end()
}; };
@ -160,7 +166,7 @@ reflect_item_t ext_data_ref_tbl[] = {
reflect_item_t play_list_ref_tbl[] = { reflect_item_t play_list_ref_tbl[] = {
_property_string(PlayList, name), _property_string(PlayList, name),
_property_string(PlayList, creater), _property_string(PlayList, creater),
_property_int(PlayList, songNum), _property_int_ex(PlayList, songNum, _ex_args_all),
_property_array_object(PlayList, songList, song_ref_tbl, SongInfo, songNum), _property_array_object(PlayList, songList, song_ref_tbl, SongInfo, songNum),
_property_obj(PlayList, extData, ext_data_ref_tbl), _property_obj(PlayList, extData, ext_data_ref_tbl),
_property_end() _property_end()
@ -171,6 +177,7 @@ static void freePlayList(PlayList* list);
const static char* jStr = "{\"name\":\"jay zhou\",\"creater\":\"dahuaxia\",\"songList\":[{\"songName\":\"qilixiang\",\"signerName\":\"jay zhou\",\"albumName\":\"qilixiang\",\"url\":\"www.kugou.com\",\"duration\":20093999939292928292234.1,\"paid\":false,\"price\":6.66,\"lyric\":[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}],\"key\":[1111,2222,3333]},{\"songName\":\"dongfengpo\",\"signerName\":\"jay zhou\",\"albumName\":\"dongfengpo\",\"url\":\"music.qq.com\",\"duration\":180.9,\"paid\":true,\"price\":0.88,\"lyric\":[{\"time\":10,\"text\":\"A sad parting, standing alone in the window\"},{\"time\":20,\"text\":\"I'm behind the door pretending you're not gone\"}],\"key\":[1234,5678,9876],\"strList\":[\"abcd\",\"efgh\",\"ijkl\"]}],\"extData\":{\"a\":999,\"b\":1}}"; const static char* jStr = "{\"name\":\"jay zhou\",\"creater\":\"dahuaxia\",\"songList\":[{\"songName\":\"qilixiang\",\"signerName\":\"jay zhou\",\"albumName\":\"qilixiang\",\"url\":\"www.kugou.com\",\"duration\":20093999939292928292234.1,\"paid\":false,\"price\":6.66,\"lyric\":[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}],\"key\":[1111,2222,3333]},{\"songName\":\"dongfengpo\",\"signerName\":\"jay zhou\",\"albumName\":\"dongfengpo\",\"url\":\"music.qq.com\",\"duration\":180.9,\"paid\":true,\"price\":0.88,\"lyric\":[{\"time\":10,\"text\":\"A sad parting, standing alone in the window\"},{\"time\":20,\"text\":\"I'm behind the door pretending you're not gone\"}],\"key\":[1234,5678,9876],\"strList\":[\"abcd\",\"efgh\",\"ijkl\"]}],\"extData\":{\"a\":999,\"b\":1}}";
static void checkResult(PlayList* playList, char* jstrOutput);
/* /*
Step3:csonJsonStr2Struct/csonStruct2JsonStr实现反序列化和序列化 Step3:csonJsonStr2Struct/csonStruct2JsonStr实现反序列化和序列化
*/ */
@ -180,16 +187,78 @@ void test1()
printf("\t\tRunning %s\n", __FUNCTION__); printf("\t\tRunning %s\n", __FUNCTION__);
printf("=========================================\n"); printf("=========================================\n");
PlayList playList; PlayList playList;
memset(&playList, 0, sizeof(playList));
/* string to struct */ /* string to struct */
int ret = csonJsonStr2Struct(jStr, &playList, play_list_ref_tbl); int ret = csonJsonStr2Struct(jStr, &playList, play_list_ref_tbl);
CHECK_NUMBER(ret, 0);
printf("decode ret=%d\n", ret);
/* test print */ /* test print */
printf("ret=%d\n", ret); //csonPrintProperty(&playList, play_list_ref_tbl);
csonPrintProperty(&playList, play_list_ref_tbl);
char* jstrOutput; char* jstrOutput;
ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl);
printf("ret=%d\nJson:%s\n", ret, jstrOutput); CHECK_NUMBER(ret, 0);
printf("encode ret=%d\nJson:%s\n", ret, jstrOutput);
/*assert check*/
checkResult(&playList, jstrOutput);
free(jstrOutput); free(jstrOutput);
csonFreePointer(&playList, play_list_ref_tbl); csonFreePointer(&playList, play_list_ref_tbl);
printf("Successed %s.\n", __FUNCTION__);
}
void checkResult(PlayList* playList, char* jstrOutput){
const char* encodeTest = "{\"name\":\"jay zhou\",\"creater\":\"dahuaxia\",\"songList\":[{\"songName\":\"qilixiang\",\"signerName\":\"jay zhou\",\"albumName\":\"qilixiang\",\"url\":\"www.kugou.com\",\"duration\":0,\"paid\":false,\"price\":6.66,\"lyric\":[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}],\"key\":[1111,2222,3333]},{\"songName\":\"dongfengpo\",\"signerName\":\"jay zhou\",\"albumName\":\"dongfengpo\",\"url\":\"music.qq.com\",\"duration\":180,\"paid\":true,\"price\":0.88,\"lyric\":[{\"time\":10,\"text\":\"A sad parting, standing alone in the window\"},{\"time\":20,\"text\":\"I'm behind the door pretending you're not gone\"}],\"key\":[1234,5678,9876],\"strList\":[\"abcd\",\"efgh\",\"ijkl\"]}],\"extData\":{\"a\":999,\"b\":1}}";
/* assert test */
CHECK_STRING(playList->name, "jay zhou");
CHECK_STRING(playList->creater, "dahuaxia");
CHECK_NUMBER(playList->songNum, 2);
CHECK_STRING(playList->songList[0].songName, "qilixiang");
CHECK_STRING(playList->songList[0].signerName, "jay zhou");
CHECK_STRING(playList->songList[0].albumName, "qilixiang");
CHECK_STRING(playList->songList[0].url, "www.kugou.com");
CHECK_NUMBER(playList->songList[0].duration, 0);
CHECK_NUMBER(playList->songList[0].paid, 0);
CHECK_REAL(playList->songList[0].price, 6.66);
CHECK_NUMBER(playList->songList[0].lyricNum, 2);
CHECK_NUMBER(playList->songList[0].lyric[0].time, 1);
CHECK_STRING(playList->songList[0].lyric[0].text, "Sparrow outside the window");
CHECK_NUMBER(playList->songList[0].lyric[1].time, 10);
CHECK_STRING(playList->songList[0].lyric[1].text, "Multi mouth on the pole");
CHECK_NUMBER(playList->songList[0].keyNum, 3);
CHECK_NUMBER(playList->songList[0].key[0], 1111);
CHECK_NUMBER(playList->songList[0].key[1], 2222);
CHECK_NUMBER(playList->songList[0].key[2], 3333);
CHECK_NUMBER(playList->songList[0].strNum, 0);
CHECK_STRING(playList->songList[1].songName, "dongfengpo");
CHECK_STRING(playList->songList[1].signerName, "jay zhou");
CHECK_STRING(playList->songList[1].albumName, "dongfengpo");
CHECK_STRING(playList->songList[1].url, "music.qq.com");
CHECK_NUMBER(playList->songList[1].duration, 180);
CHECK_NUMBER(playList->songList[1].paid, 1);
CHECK_REAL(playList->songList[1].price, 0.88);
CHECK_NUMBER(playList->songList[1].lyricNum, 2);
CHECK_NUMBER(playList->songList[1].lyric[0].time, 10);
CHECK_STRING(playList->songList[1].lyric[0].text, "A sad parting, standing alone in the window");
CHECK_NUMBER(playList->songList[1].lyric[1].time, 20);
CHECK_STRING(playList->songList[1].lyric[1].text, "I'm behind the door pretending you're not gone");
CHECK_NUMBER(playList->songList[1].keyNum, 3);
CHECK_NUMBER(playList->songList[1].key[0], 1234);
CHECK_NUMBER(playList->songList[1].key[1], 5678);
CHECK_NUMBER(playList->songList[1].key[2], 9876);
CHECK_NUMBER(playList->songList[1].strNum, 3);
CHECK_STRING(playList->songList[1].strList[0], "abcd");
CHECK_STRING(playList->songList[1].strList[1], "efgh");
CHECK_STRING(playList->songList[1].strList[2], "ijkl");
CHECK_NUMBER(playList->extData.a, 999);
CHECK_REAL(playList->extData.b, 1);
//It is difficult to predict the output due to the accuracy problem.
//CHECK_STRING(jstrOutput, encodeTest);
} }

File diff suppressed because one or more lines are too long

View File

@ -90,14 +90,14 @@ typedef struct {
* @TODO: Try to simplify the struct * @TODO: Try to simplify the struct
*/ */
typedef struct reflect_item_t { typedef struct reflect_item_t {
char* field; /**< field */ const char* field; /**< field */
size_t offset; /**< offset of property */ size_t offset; /**< offset of property */
size_t size; /**< size of property */ size_t size; /**< size of property */
cson_type type; /**< corresponding json type */ cson_type type; /**< corresponding json type */
const struct reflect_item_t* reflect_tbl; /**< must be specified when type is object or array */ const struct reflect_item_t* reflect_tbl; /**< must be specified when type is object or array */
size_t arrayItemSize; /**< size of per array item. must be specified when type is array */ size_t arrayItemSize; /**< size of per array item. must be specified when type is array */
char* arrayCountField; /**< field saving array size */ const char* arrayCountField; /**< field saving array size */
int nullable; /**< paser return failure when the field is not found and nullable equals to 0 */ int exArgs; /**< paser return failure when the field is not found and nullable equals to 0 */
} reflect_item_t; } reflect_item_t;
extern const reflect_item_t integerReflectTbl[]; extern const reflect_item_t integerReflectTbl[];
@ -105,7 +105,12 @@ extern const reflect_item_t stringReflectTbl[];
extern const reflect_item_t boolReflectTbl[]; extern const reflect_item_t boolReflectTbl[];
extern const reflect_item_t realReflectTbl[]; extern const reflect_item_t realReflectTbl[];
#define _offset(type, field) (&(((type*)0)->field)) #define _ex_args_nullable (0x01)
#define _ex_args_exclude_decode (0x02)
#define _ex_args_exclude_encode (0x04)
#define _ex_args_all (_ex_args_nullable | _ex_args_exclude_decode | _ex_args_exclude_encode)
#define _offset(type, field) (size_t)(&(((type*)0)->field))
#define _size(type, field) (sizeof(((type*)0)->field)) #define _size(type, field) (sizeof(((type*)0)->field))
#define _property(type, field, jtype, tbl, nullable) {#field, _offset(type, field), _size(type, field), jtype, tbl, 0, NULL, nullable} #define _property(type, field, jtype, tbl, nullable) {#field, _offset(type, field), _size(type, field), jtype, tbl, 0, NULL, nullable}
#define _property_end() {NULL, 0, 0, CSON_NULL, NULL, 0, NULL, 1} #define _property_end() {NULL, 0, 0, CSON_NULL, NULL, 0, NULL, 1}
@ -117,7 +122,7 @@ extern const reflect_item_t realReflectTbl[];
* @param field: field name of properties * @param field: field name of properties
* *
*/ */
#define _property_int(type, field) _property(type, field, CSON_INTEGER, integerReflectTbl, 1) #define _property_int(type, field) _property(type, field, CSON_INTEGER, integerReflectTbl, _ex_args_nullable)
/** /**
* @brief Declaring real properties. * @brief Declaring real properties.
@ -126,7 +131,7 @@ extern const reflect_item_t realReflectTbl[];
* @param field: field name of properties * @param field: field name of properties
* *
*/ */
#define _property_real(type, field) _property(type, field, CSON_REAL, realReflectTbl, 1) #define _property_real(type, field) _property(type, field, CSON_REAL, realReflectTbl, _ex_args_nullable)
/** /**
* @brief Declaring bool properties. * @brief Declaring bool properties.
@ -135,7 +140,7 @@ extern const reflect_item_t realReflectTbl[];
* @param field: field name of properties * @param field: field name of properties
* *
*/ */
#define _property_bool(type, field) _property(type, field, CSON_TRUE, boolReflectTbl, 1) #define _property_bool(type, field) _property(type, field, CSON_TRUE, boolReflectTbl, _ex_args_nullable)
/** /**
* @brief Declaring string properties. * @brief Declaring string properties.
@ -144,7 +149,7 @@ extern const reflect_item_t realReflectTbl[];
* @param field: field name of properties * @param field: field name of properties
* *
*/ */
#define _property_string(type, field) _property(type, field, CSON_STRING, stringReflectTbl, 1) #define _property_string(type, field) _property(type, field, CSON_STRING, stringReflectTbl, _ex_args_nullable)
/** /**
* @brief Declaring struct properties. * @brief Declaring struct properties.
@ -154,7 +159,7 @@ extern const reflect_item_t realReflectTbl[];
* @param tbl: property description table of sub-struct * @param tbl: property description table of sub-struct
* *
*/ */
#define _property_obj(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, 1) #define _property_obj(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, _ex_args_nullable)
/** /**
* @brief Declaring array properties. * @brief Declaring array properties.
@ -166,7 +171,7 @@ extern const reflect_item_t realReflectTbl[];
* @param count: property to save the array size * @param count: property to save the array size
* *
*/ */
#define _property_array(type, field, tbl, subType, count) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, 1} #define _property_array(type, field, tbl, subType, count) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, _ex_args_nullable}
#define _property_array_object(type, field, tbl, subType, count) _property_array(type, field, tbl, subType, count) #define _property_array_object(type, field, tbl, subType, count) _property_array(type, field, tbl, subType, count)
#define _property_array_int(type, field, subType, count) _property_array(type, field, integerReflectTbl, subType, count) #define _property_array_int(type, field, subType, count) _property_array(type, field, integerReflectTbl, subType, count)
#define _property_array_string(type, field, subType, count) _property_array(type, field, stringReflectTbl, subType, count) #define _property_array_string(type, field, subType, count) _property_array(type, field, stringReflectTbl, subType, count)
@ -190,6 +195,24 @@ extern const reflect_item_t realReflectTbl[];
#define _property_array_real_nonull(type, field, subType, count) _property_array_nonull(type, field, realReflectTbl, subType, count) #define _property_array_real_nonull(type, field, subType, count) _property_array_nonull(type, field, realReflectTbl, subType, count)
#define _property_array_bool_nonull(type, field, subType, count) _property_array_nonull(type, field, boolReflectTbl, subType, count) #define _property_array_bool_nonull(type, field, subType, count) _property_array_nonull(type, field, boolReflectTbl, subType, count)
/**
* @brief nonull definitions. parser will stop and return error code when field not found which declared whit it.
*
* @param refer to comment of nullable definition
* @param args opptional with _ex_args_nullable(0x01) _ex_args_exclude_decode(0x02) _ex_args_exclude_encode(0x04)
*/
#define _property_int_ex(type, field, args) _property(type, field, CSON_INTEGER, NULL, args)
#define _property_real_ex(type, field, args) _property(type, field, CSON_REAL, NULL, args)
#define _property_bool_ex(type, field, args) _property(type, field, CSON_TRUE, NULL, args)
#define _property_string_ex(type, field, args) _property(type, field, CSON_STRING, NULL, args)
#define _property_obj_ex(type, field, tbl, args) _property(type, field, CSON_OBJECT, tbl, args)
#define _property_array_ex(type, field, tbl, subType, count, args) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, args}
#define _property_array_object_ex(type, field, tbl, subType, count, args) _property_array_ex(type, field, tbl, subType, count)
#define _property_array_int_ex(type, field, subType, count, args) _property_array_ex(type, field, integerReflectTbl, subType, count)
#define _property_array_string_ex(type, field, subType, count, args) _property_array_ex(type, field, stringReflectTbl, subType, count)
#define _property_array_real_ex(type, field, subType, count, args) _property_array_ex(type, field, realReflectTbl, subType, count)
#define _property_array_bool_ex(type, field, subType, count, args) _property_array_ex(type, field, boolReflectTbl, subType, count)
/** /**
* @brief function type of csonLoopProperty. * @brief function type of csonLoopProperty.
* *

View File

@ -175,6 +175,11 @@ int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl)
while (1) { while (1) {
if (tbl[i].field == NULL) break; if (tbl[i].field == NULL) break;
if(tbl[i].exArgs & _ex_args_exclude_encode){
i++;
continue;
}
cson_t joTmp = NULL; cson_t joTmp = NULL;
int jsonType = tbl[i].type; int jsonType = tbl[i].type;
@ -184,7 +189,7 @@ int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl)
if (ret != ERR_NONE ) { if (ret != ERR_NONE ) {
printf("!!!!pack error on field:%s, cod=%d!!!!\n", tbl[i].field, ret); printf("!!!!pack error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
if (!tbl[i].nullable) return ret; if (!(tbl[i].exArgs & _ex_args_nullable)) return ret;
} else { } else {
cson_object_set_new(obj, tbl[i].field, joTmp); cson_object_set_new(obj, tbl[i].field, joTmp);
} }
@ -350,6 +355,10 @@ int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl)
int ret = ERR_NONE; int ret = ERR_NONE;
if (tbl[i].field == NULL) break; if (tbl[i].field == NULL) break;
if(tbl[i].exArgs & _ex_args_exclude_decode){
continue;
}
cson_t jo_tmp = cson_object_get(jo, tbl[i].field); cson_t jo_tmp = cson_object_get(jo, tbl[i].field);
if (jo_tmp == NULL) { if (jo_tmp == NULL) {
@ -372,7 +381,7 @@ int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl)
if (ret != ERR_NONE ) { if (ret != ERR_NONE ) {
printf("!!!!parse error on field:%s, cod=%d!!!!\n", tbl[i].field, ret); printf("!!!!parse error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
jsonObjDefaultTbl[tbl[i].type](NULL, output, tbl, i); jsonObjDefaultTbl[tbl[i].type](NULL, output, tbl, i);
if (!tbl[i].nullable) return ret; if (!(tbl[i].exArgs & _ex_args_nullable)) return ret;
} }
} }
@ -383,7 +392,7 @@ int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int
{ {
const char* tempstr = cson_string_value(jo_tmp); const char* tempstr = cson_string_value(jo_tmp);
if (NULL != tempstr) { if (NULL != tempstr) {
char* pDst = malloc(strlen(tempstr) + 1); char* pDst = (char*)malloc(strlen(tempstr) + 1);
if (pDst == NULL) { if (pDst == NULL) {
return ERR_MEMORY; return ERR_MEMORY;
} }
@ -435,6 +444,8 @@ int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int i
char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize); char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize);
if (pMem == NULL) return ERR_MEMORY; if (pMem == NULL) return ERR_MEMORY;
memset(pMem, 0, arraySize * tbl[index].arrayItemSize);
long long successCount = 0; long long successCount = 0;
for (size_t j = 0; j < arraySize; j++) { for (size_t j = 0; j < arraySize; j++) {
cson_t item = cson_array_get(jo_tmp, j); cson_t item = cson_array_get(jo_tmp, j);
@ -507,7 +518,13 @@ int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tb
{ {
int i = 0; int i = 0;
while (1) { while (1) {
if (tbl[index].reflect_tbl[i].field == NULL) break; if (tbl[i].reflect_tbl[i].field == NULL) break;
if(tbl[i].exArgs & _ex_args_exclude_decode){
i++;
continue;
}
jsonObjDefaultTbl[tbl[index].reflect_tbl[i].type](NULL, output, tbl[index].reflect_tbl, i); jsonObjDefaultTbl[tbl[index].reflect_tbl[i].type](NULL, output, tbl[index].reflect_tbl, i);
i++; i++;
}; };
@ -745,8 +762,9 @@ static void* printPropertySub(void* pData, const reflect_item_t* tbl)
static void* freePointerSub(void* pData, const reflect_item_t* tbl) static void* freePointerSub(void* pData, const reflect_item_t* tbl)
{ {
if (tbl->type == CSON_ARRAY || tbl->type == CSON_STRING) { if (tbl->type == CSON_ARRAY || tbl->type == CSON_STRING) {
printf("free field %s.\n", tbl->field); //printf("free field %s.\n", tbl->field);
free(*(void**)pData); free(*(void**)pData);
*(void**)pData = NULL;
} }
return NULL; return NULL;
} }