From 41bb36a038d63912fa540ea1bbab3e98e8283e94 Mon Sep 17 00:00:00 2001 From: sunchb <448573057@qq.com> Date: Wed, 6 May 2020 02:42:33 -0700 Subject: [PATCH 1/8] multi array support --- demo/main.c | 2 +- demo/test.c | 46 ++++++------- demo/test2.c | 24 +++---- inc/cson.h | 48 +++++++------ src/cson.c | 187 ++++++++++++++++++++++++++++++++++++++------------- 5 files changed, 204 insertions(+), 103 deletions(-) diff --git a/demo/main.c b/demo/main.c index f48bc19..2912a3d 100644 --- a/demo/main.c +++ b/demo/main.c @@ -7,6 +7,6 @@ extern void test2(); int main() { test1(); - test2(); + //test2(); return 0; } diff --git a/demo/test.c b/demo/test.c index e753eeb..444475e 100644 --- a/demo/test.c +++ b/demo/test.c @@ -113,7 +113,7 @@ typedef struct { size_t lyricNum; Lyric* lyric; size_t keyNum; - int* key; + int** key; size_t strNum; char** strList; } SongInfo; @@ -149,11 +149,11 @@ reflect_item_t song_ref_tbl[] = { _property_bool(SongInfo, paid), _property_real(SongInfo, price), _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, 1), _property_int_ex(SongInfo, keyNum, _ex_args_all), - _property_array_int(SongInfo, key, int, keyNum), + _property_array_int(SongInfo, key, int, keyNum, 2), _property_int_ex(SongInfo, strNum, _ex_args_all), - _property_array_string(SongInfo, strList, char*, strNum), + _property_array_string(SongInfo, strList, char*, strNum, 1), _property_end() }; @@ -167,7 +167,7 @@ reflect_item_t play_list_ref_tbl[] = { _property_string(PlayList, name), _property_string(PlayList, creater), _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, 1), _property_obj(PlayList, extData, ext_data_ref_tbl), _property_end() }; @@ -175,7 +175,7 @@ reflect_item_t play_list_ref_tbl[] = { static void printPlayList(PlayList* list); 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],[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], [4321,9876,5432]],\"strList\":[\"abcd\",\"efgh\",\"ijkl\"]}],\"extData\":{\"a\":999,\"b\":1}}"; static void checkResult(PlayList* playList, char* jstrOutput); /* @@ -197,14 +197,14 @@ void test1() //csonPrintProperty(&playList, play_list_ref_tbl); char* jstrOutput; - ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); - CHECK_NUMBER(ret, 0); - printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); + // ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); + // 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); printf("Successed %s.\n", __FUNCTION__); @@ -217,7 +217,7 @@ void checkResult(PlayList* playList, char* jstrOutput){ /* assert test */ CHECK_STRING(playList->name, "jay zhou"); CHECK_STRING(playList->creater, "dahuaxia"); - CHECK_NUMBER(playList->songNum, 2); + //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"); @@ -225,16 +225,16 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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].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_NUMBER(playList->songList[0].keyNum, 3); + CHECK_NUMBER(playList->songList[0].key[0][0], 1111); + CHECK_NUMBER(playList->songList[0].key[0][1], 2222); + CHECK_NUMBER(playList->songList[0].key[0][2], 3333); + //CHECK_NUMBER(playList->songList[0].strNum, 0); CHECK_STRING(playList->songList[1].songName, "dongfengpo"); CHECK_STRING(playList->songList[1].signerName, "jay zhou"); @@ -243,16 +243,16 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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].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_NUMBER(playList->songList[1].keyNum, 3); + CHECK_NUMBER(playList->songList[1].key[0][0], 1234); + CHECK_NUMBER(playList->songList[1].key[0][1], 5678); + CHECK_NUMBER(playList->songList[1].key[0][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"); diff --git a/demo/test2.c b/demo/test2.c index 224d1b2..28a4e31 100644 --- a/demo/test2.c +++ b/demo/test2.c @@ -49,14 +49,14 @@ reflect_item_t ClassInfoTbl[] = { _property_int(ClassInfo, id), _property_string(ClassInfo, name), _property_int_ex(ClassInfo, childrenNum, _ex_args_all), - _property_array_object(ClassInfo, children, ClassInfoChildTbl, ClassInfoChild, childrenNum), + _property_array_object(ClassInfo, children, ClassInfoChildTbl, ClassInfoChild, childrenNum, 1), _property_end() }; reflect_item_t DataTbl[] = { _property_int(Data, timestamp), _property_int_ex(Data, infoNum, _ex_args_all), - _property_array_object(Data, info, ClassInfoTbl, ClassInfo, infoNum), + _property_array_object(Data, info, ClassInfoTbl, ClassInfo, infoNum, 1), _property_end() }; @@ -108,13 +108,13 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_NUMBER(resp->status, 1); CHECK_NUMBER(resp->data.timestamp, 1579069151); - CHECK_NUMBER(resp->data.infoNum, 9); + //CHECK_NUMBER(resp->data.infoNum, 9); CHECK_NUMBER(resp->data.info[0].has_child, 1); CHECK_STRING(resp->data.info[0].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172444711866.png"); CHECK_NUMBER(resp->data.info[0].id, 153); CHECK_STRING(resp->data.info[0].name, "专区"); - CHECK_NUMBER(resp->data.info[0].childrenNum, 16); + //CHECK_NUMBER(resp->data.info[0].childrenNum, 16); CHECK_STRING(resp->data.info[0].children[0].name, "DJ专区"); CHECK_STRING(resp->data.info[0].children[0].jump_url, "https://miniapp.kugou.com/node/v2?type=1&id=74&path=%2Findex.html%23%2Fmobile%2Fhome%2F1"); CHECK_STRING(resp->data.info[0].children[1].name, "抖音专区"); @@ -153,7 +153,7 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_STRING(resp->data.info[1].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104103209217784.png"); CHECK_NUMBER(resp->data.info[1].id, 2005); CHECK_STRING(resp->data.info[1].name, "心情"); - CHECK_NUMBER(resp->data.info[1].childrenNum, 9); + //CHECK_NUMBER(resp->data.info[1].childrenNum, 9); CHECK_STRING(resp->data.info[1].children[0].name, "伤感专区"); CHECK_STRING(resp->data.info[1].children[1].name, "安静专区"); CHECK_STRING(resp->data.info[1].children[2].name, "对抗抑郁专区"); @@ -169,7 +169,7 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_STRING(resp->data.info[2].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172455112096.png"); CHECK_NUMBER(resp->data.info[2].id, 1263); CHECK_STRING(resp->data.info[2].name, "特色"); - CHECK_NUMBER(resp->data.info[2].childrenNum, 16); + //CHECK_NUMBER(resp->data.info[2].childrenNum, 16); CHECK_STRING(resp->data.info[2].children[0].name, "官方歌单"); CHECK_STRING(resp->data.info[2].children[1].name, "重返2010专区"); CHECK_STRING(resp->data.info[2].children[2].name, "佛乐专区"); @@ -201,37 +201,37 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_STRING(resp->data.info[3].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104103220446249.png"); CHECK_NUMBER(resp->data.info[3].id, 2003); CHECK_STRING(resp->data.info[3].name, "场景"); - CHECK_NUMBER(resp->data.info[3].childrenNum, 9); + //CHECK_NUMBER(resp->data.info[3].childrenNum, 9); CHECK_NUMBER(resp->data.info[4].has_child, 1); CHECK_STRING(resp->data.info[4].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104103232420148.png"); CHECK_NUMBER(resp->data.info[4].id, 2007); CHECK_STRING(resp->data.info[4].name, "主题"); - CHECK_NUMBER(resp->data.info[4].childrenNum, 14); + //CHECK_NUMBER(resp->data.info[4].childrenNum, 14); CHECK_NUMBER(resp->data.info[5].has_child, 0); CHECK_STRING(resp->data.info[5].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172345416784.png"); CHECK_NUMBER(resp->data.info[5].id, 32); CHECK_STRING(resp->data.info[5].name, "年代"); - CHECK_NUMBER(resp->data.info[5].childrenNum, 4); + //CHECK_NUMBER(resp->data.info[5].childrenNum, 4); CHECK_NUMBER(resp->data.info[6].has_child, 1); CHECK_STRING(resp->data.info[6].icon, "http://imge.kugou.com/mcommon/{size}/20191202/20191202161746384633.png"); CHECK_NUMBER(resp->data.info[6].id, 2009); CHECK_STRING(resp->data.info[6].name, "语言"); - CHECK_NUMBER(resp->data.info[6].childrenNum, 9); + //CHECK_NUMBER(resp->data.info[6].childrenNum, 9); CHECK_NUMBER(resp->data.info[7].has_child, 1); CHECK_STRING(resp->data.info[7].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104102344527371.png"); CHECK_NUMBER(resp->data.info[7].id, 1599); CHECK_STRING(resp->data.info[7].name, "风格"); - CHECK_NUMBER(resp->data.info[7].childrenNum, 21); + //CHECK_NUMBER(resp->data.info[7].childrenNum, 21); CHECK_NUMBER(resp->data.info[8].has_child, 0); CHECK_STRING(resp->data.info[8].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172408696210.png"); CHECK_NUMBER(resp->data.info[8].id, 58); CHECK_STRING(resp->data.info[8].name, "乐器"); - CHECK_NUMBER(resp->data.info[8].childrenNum, 10); + //CHECK_NUMBER(resp->data.info[8].childrenNum, 10); CHECK_STRING(jstrOutput, encodeTest); } \ No newline at end of file diff --git a/inc/cson.h b/inc/cson.h index e2d0687..7a16454 100644 --- a/inc/cson.h +++ b/inc/cson.h @@ -97,6 +97,7 @@ typedef struct reflect_item_t { 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 */ const char* arrayCountField; /**< field saving array size */ + int arrayDimensional; int exArgs; /**< paser return failure when the field is not found and nullable equals to 0 */ } reflect_item_t; @@ -112,8 +113,8 @@ extern const reflect_item_t realReflectTbl[]; #define _offset(type, field) (size_t)(&(((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_end() {NULL, 0, 0, CSON_NULL, NULL, 0, NULL, 1} +#define _property(type, field, jtype, tbl, nullable) {#field, _offset(type, field), _size(type, field), jtype, tbl, 0, NULL, 0, nullable} +#define _property_end() {NULL, 0, 0, CSON_NULL, NULL, 0, NULL, 0, 1} /** * @brief Declaring integer properties. @@ -171,12 +172,12 @@ extern const reflect_item_t realReflectTbl[]; * @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, _ex_args_nullable} -#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_string(type, field, subType, count) _property_array(type, field, stringReflectTbl, subType, count) -#define _property_array_real(type, field, subType, count) _property_array(type, field, realReflectTbl, subType, count) -#define _property_array_bool(type, field, subType, count) _property_array(type, field, boolReflectTbl, subType, count) +#define _property_array(type, field, tbl, subType, count, dimen) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, dimen, _ex_args_nullable} +#define _property_array_object(type, field, tbl, subType, count, dimen) _property_array(type, field, tbl, subType, count, dimen) +#define _property_array_int(type, field, subType, count, dimen) _property_array(type, field, integerReflectTbl, subType, count, dimen) +#define _property_array_string(type, field, subType, count, dimen) _property_array(type, field, stringReflectTbl, subType, count, dimen) +#define _property_array_real(type, field, subType, count, dimen) _property_array(type, field, realReflectTbl, subType, count, dimen) +#define _property_array_bool(type, field, subType, count, dimen) _property_array(type, field, boolReflectTbl, subType, count, dimen) /** * @brief nonull definitions. parser will stop and return error code when field not found which declared whit it. @@ -188,12 +189,12 @@ extern const reflect_item_t realReflectTbl[]; #define _property_bool_nonull(type, field) _property(type, field, CSON_TRUE, NULL, 0) #define _property_string_nonull(type, field) _property(type, field, CSON_STRING, NULL, 0) #define _property_obj_nonull(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, 0) -#define _property_array_nonull(type, field, tbl, subType, count) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, 0} -#define _property_array_object_nonull(type, field, tbl, subType, count) _property_array_nonull(type, field, tbl, subType, count) -#define _property_array_int_nonull(type, field, subType, count) _property_array_nonull(type, field, integerReflectTbl, subType, count) -#define _property_array_string_nonull(type, field, subType, count) _property_array_nonull(type, field, stringReflectTbl, 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_nonull(type, field, tbl, subType, count, dimen) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, dimen, 0} +#define _property_array_object_nonull(type, field, tbl, subType, count, dimen) _property_array_nonull(type, field, tbl, subType, count, dimen) +#define _property_array_int_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, integerReflectTbl, subType, count, dimen) +#define _property_array_string_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, stringReflectTbl, subType, count, dimen) +#define _property_array_real_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, realReflectTbl, subType, count, dimen) +#define _property_array_bool_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, boolReflectTbl, subType, count, dimen) /** * @brief nonull definitions. parser will stop and return error code when field not found which declared whit it. @@ -206,12 +207,12 @@ extern const reflect_item_t realReflectTbl[]; #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) +#define _property_array_ex(type, field, tbl, subType, count, dimen, args) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, dimen, args} +#define _property_array_object_ex(type, field, tbl, subType, count, dimen, args) _property_array_ex(type, field, tbl, subType, count, dimen) +#define _property_array_int_ex(type, field, subType, count, dimen, args) _property_array_ex(type, field, integerReflectTbl, subType, count, dimen) +#define _property_array_string_ex(type, field, subType, count, dimen, args) _property_array_ex(type, field, stringReflectTbl, subType, count, dimen) +#define _property_array_real_ex(type, field, subType, count, dimen, args) _property_array_ex(type, field, realReflectTbl, subType, count, dimen) +#define _property_array_bool_ex(type, field, subType, count, dimen, args) _property_array_ex(type, field, boolReflectTbl, subType, count, dimen) /** * @brief function type of csonLoopProperty. @@ -276,4 +277,11 @@ void csonPrintProperty(void* pData, const reflect_item_t* tbl); */ void csonFreePointer(void* list, const reflect_item_t* tbl); +#define _CSON_SUPPORT_MULTI_ARRAY_ +#ifdef _CSON_SUPPORT_MULTI_ARRAY_ +typedef size_t cson_array_size_t; +cson_array_size_t csonArrayGetSize(void* ptr); +cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl); +#endif + #endif \ No newline at end of file diff --git a/src/cson.c b/src/cson.c index 41e5a0e..2b1f4bf 100644 --- a/src/cson.c +++ b/src/cson.c @@ -144,6 +144,28 @@ json_obj_proc jsonObjDefaultTbl[] = { static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl); +typedef struct { + cson_array_size_t size; + cson_array_size_t sizePerItem; + int dimen; +} cson_array_header_t; + +typedef struct { + cson_array_header_t header; + void* ptr; +} cson_array_t; + +void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem); +void csonArrayFree(void* ptr); +cson_array_size_t csonArrayGetSize(void* ptr); +void csonArraySetSize(void* ptr, cson_array_size_t size); +cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl); +cson_array_size_t csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size); +void* parseJsonArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); +void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); +void csonArraySetDimen(void* ptr, int dimen); +int csonArrayGetDimen(void* ptr); + int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl) { cson_t jsonPack = cson_object(); @@ -253,18 +275,13 @@ int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) if (pSrc == NULL) return ERR_MISSING_FIELD; - void* ptr = csonGetProperty(input, tbl[index].arrayCountField, tbl, &countIndex); - - if (ptr == NULL || countIndex == -1) { - return ERR_MISSING_FIELD; - } - long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + cson_array_size_t size = csonArrayGetSize(pSrc); cson_t joArray = cson_array(); - long long successCount = 0; + cson_array_size_t successCount = 0; - for (long long i = 0; i < size; i++) { + for (cson_array_size_t i = 0; i < size; i++) { cson_t jotmp; if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ @@ -425,29 +442,61 @@ int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int return csonJsonObj2Struct(jo_tmp, (char*)output + tbl[index].offset, tbl[index].reflect_tbl); } -int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) -{ +int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ + //检查维度 + printf("arrayDimensional:%d\n", tbl[index].arrayDimensional); + void* pRet = parseJsonArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); + csonSetPropertyFast(output, &pRet, tbl + index); + return ERR_NONE; +} + +void* parseJsonArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen){ + if(dimen == 1){ + return parseJsonArrayTail(jo_tmp, tbl, index); + }else{ + cson_array_size_t arraySize = cson_array_size(jo_tmp); + if(arraySize == 0) return NULL; + + void** pMem = (void**)csonArrayAlloc(arraySize, sizeof(void*)); + csonArraySetDimen(pMem, dimen); + + cson_array_size_t successCount = 0; + + for(cson_array_size_t i = 0; i < arraySize; i++){ + cson_t item = cson_array_get(jo_tmp, i); + if(cson_typeof(item) != CSON_ARRAY) continue; + void* p = parseJsonArraySub(item, tbl, index, dimen - 1); + if(p != NULL){ + pMem[successCount++] = p; + } + } + + if(successCount == 0){ + csonArrayFree(pMem); + return NULL; + }else{ + csonArraySetSize(pMem, successCount); + return (void*)pMem; + } + } +} + +void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index){ size_t arraySize = cson_array_size(jo_tmp); - if (arraySize == 0) { - csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl); - return ERR_NONE; + return NULL; } - int countIndex = -1; - csonGetProperty(output, tbl[index].arrayCountField, tbl, &countIndex); - - if (countIndex == -1) { - return ERR_MISSING_FIELD; - } - - char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize); - if (pMem == NULL) return ERR_MEMORY; - + char* pMem = (char*)csonArrayAlloc(arraySize, tbl[index].arrayItemSize); + if (pMem == NULL) return NULL; + memset(pMem, 0, arraySize * tbl[index].arrayItemSize); + + csonArraySetDimen(pMem, 1); + + cson_array_size_t successCount = 0; - long long successCount = 0; - for (size_t j = 0; j < arraySize; j++) { + for (cson_array_size_t j = 0; j < arraySize; j++) { cson_t item = cson_array_get(jo_tmp, j); if (item != NULL) { int ret; @@ -464,22 +513,14 @@ int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int i } } - integer_val_t val; - if (convertInteger(successCount, tbl[countIndex].size, &val) != ERR_NONE) { - successCount = 0; + if (successCount == 0) { + csonArrayFree(pMem); + pMem = NULL; + }else{ + csonArraySetSize(pMem, successCount); } - if (successCount == 0) { - csonSetPropertyFast(output, &successCount, tbl + countIndex); - free(pMem); - pMem = NULL; - csonSetPropertyFast(output, &pMem, tbl + index); - return ERR_MISSING_FIELD; - } else { - csonSetPropertyFast(output, &val, tbl + countIndex); - csonSetPropertyFast(output, &pMem, tbl + index); - return ERR_NONE; - } + return pMem; } int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) @@ -725,15 +766,13 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) char* pProperty = (char*)pData + tbl[i].offset; if (tbl[i].type == CSON_ARRAY) { - int countIndex = -1; - void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); - - if (ptr == NULL || countIndex == -1) { + if(*((void**)pProperty) == NULL){ + i++; continue; } - long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + cson_array_size_t size = csonArrayGetSize(*((void**)pProperty)); - for (long long j = 0; j < size; j++) { + for (cson_array_size_t j = 0; j < size; j++) { csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); } } else if (tbl[i].type == CSON_OBJECT) { @@ -761,10 +800,15 @@ static void* printPropertySub(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_STRING) { //printf("free field %s.\n", tbl->field); free(*(void**)pData); *(void**)pData = NULL; + }else if(tbl->type == CSON_ARRAY){ + //printf("free field %s.\n", tbl->field); + csonArrayFree(*(void**)pData); + }else{ + } return NULL; } @@ -779,4 +823,53 @@ void csonFreePointer(void* list, const reflect_item_t* tbl) { /* 调用loopProperty迭代结构体中的属性,释放字符串和数组申请的内存空间 */ csonLoopProperty(list, tbl, freePointerSub); -} \ No newline at end of file +} + +void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem){ + char* pMem = (char*)malloc(count * sizePerItem + sizeof(cson_array_header_t)); + + if(!pMem) return NULL; + + return pMem + sizeof(cson_array_header_t); +} + +void csonArrayFree(void* ptr){ + if(!ptr) return; + char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); + free(pArrayHeader); +} + +cson_array_size_t csonArrayGetSize(void* ptr){ + if(!ptr) return 0; + char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); + return ((cson_array_header_t*)pArrayHeader)->size; +} + +void csonArraySetSize(void* ptr, cson_array_size_t size){ + if(!ptr) return; + char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); + ((cson_array_header_t*)pArrayHeader)->size = size; +} + +int csonArrayGetDimen(void* ptr){ + if(!ptr) return 0; + char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); + return ((cson_array_header_t*)pArrayHeader)->dimen; +} + +void csonArraySetDimen(void* ptr, int dimen){ + if(!ptr) return; + char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); + ((cson_array_header_t*)pArrayHeader)->dimen = dimen; +} + +cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl){ + void* pArray = csonGetProperty(pData, field, tbl, NULL); + return csonArrayGetSize(*((void**)pArray)); +} + +cson_array_size_t csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size){ + void* pArray = csonGetProperty(pData, field, tbl, NULL); + csonArraySetSize(*((void**)pArray), size); +} + From 6775d176078cdf236c3f3fd964ecb1dcdd91f9c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E4=BC=A0=E5=AE=9D?= Date: Wed, 6 May 2020 23:39:18 +0800 Subject: [PATCH 2/8] encode multi array --- demo/test.c | 8 +++---- src/cson.c | 68 +++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/demo/test.c b/demo/test.c index 444475e..f659590 100644 --- a/demo/test.c +++ b/demo/test.c @@ -197,14 +197,14 @@ void test1() //csonPrintProperty(&playList, play_list_ref_tbl); char* jstrOutput; - // ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); - // CHECK_NUMBER(ret, 0); - // printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); + ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); + 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); printf("Successed %s.\n", __FUNCTION__); diff --git a/src/cson.c b/src/cson.c index 2b1f4bf..15c515b 100644 --- a/src/cson.c +++ b/src/cson.c @@ -160,12 +160,15 @@ void csonArrayFree(void* ptr); cson_array_size_t csonArrayGetSize(void* ptr); void csonArraySetSize(void* ptr, cson_array_size_t size); cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl); -cson_array_size_t csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size); +void csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size); void* parseJsonArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); void csonArraySetDimen(void* ptr, int dimen); int csonArrayGetDimen(void* ptr); +cson_t getJsonArrayTail(void* ptr, const reflect_item_t* tbl, int index); +cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index); + int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl) { cson_t jsonPack = cson_object(); @@ -267,16 +270,40 @@ int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj return ret; } -int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) -{ - int ret = ERR_NONE; - int countIndex = -1; - char* pSrc = (*(char**)((char*)input + tbl[index].offset)); +cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index){ + int dimen = csonArrayGetDimen(ptr); + printf("filed:%s,dimen=%d\n", tbl[index].field, dimen); + if(csonArrayGetDimen(ptr) == 1){ + return getJsonArrayTail(ptr, tbl, index); + }else{ + cson_t joArray = cson_array(); - if (pSrc == NULL) return ERR_MISSING_FIELD; + cson_array_size_t size = csonArrayGetSize(ptr); + printf("filed:%s,size=%zu\n", tbl[index].field, size); - cson_array_size_t size = csonArrayGetSize(pSrc); + cson_array_size_t successCount = 0; + for(cson_array_size_t i = 0; i < size; i++){ + void** p = (void**)ptr; + cson_t jotmp = getJsonArraySub(p[i], tbl, index); + + if(jotmp != NULL){ + successCount++; + cson_array_add(joArray, jotmp); + } + } + + if (successCount == 0) { + cson_decref(joArray); + joArray = NULL; + } + + return joArray; + } +} + +cson_t getJsonArrayTail(void* ptr, const reflect_item_t* tbl, int index){ + cson_array_size_t size = csonArrayGetSize(ptr); cson_t joArray = cson_array(); cson_array_size_t successCount = 0; @@ -284,11 +311,12 @@ int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) for (cson_array_size_t i = 0; i < size; i++) { cson_t jotmp; + int ret = ERR_NONE; if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ - ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); + ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](ptr + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); } else { jotmp = cson_object(); - ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + ret = csonStruct2JsonObj(jotmp, ptr + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); } if (ret == ERR_NONE) { @@ -302,12 +330,22 @@ int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) if (successCount == 0) { cson_decref(joArray); - return ERR_MISSING_FIELD; - } else { - *obj = joArray; - return ERR_NONE; + joArray = NULL; } + return joArray; +} + +int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +{ + int ret = ERR_NONE; + int countIndex = -1; + char* pSrc = (*(char**)((char*)input + tbl[index].offset)); + + if (pSrc == NULL) return ERR_MISSING_FIELD; + + *obj = getJsonArraySub(pSrc, tbl, index); + if(*obj == NULL) return ERR_MISSING_FIELD; return ret; } @@ -868,7 +906,7 @@ cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const return csonArrayGetSize(*((void**)pArray)); } -cson_array_size_t csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size){ +void csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size){ void* pArray = csonGetProperty(pData, field, tbl, NULL); csonArraySetSize(*((void**)pArray), size); } From a7dcdb435463a1f0f98252c5a7c0915faab45cf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E4=BC=A0=E5=AE=9D?= Date: Thu, 7 May 2020 07:22:18 +0800 Subject: [PATCH 3/8] multi array --- demo/test.c | 2 +- src/cson.c | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/demo/test.c b/demo/test.c index f659590..0fe3970 100644 --- a/demo/test.c +++ b/demo/test.c @@ -194,7 +194,7 @@ void test1() CHECK_NUMBER(ret, 0); printf("decode ret=%d\n", ret); /* test print */ - //csonPrintProperty(&playList, play_list_ref_tbl); + csonPrintProperty(&playList, play_list_ref_tbl); char* jstrOutput; ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); diff --git a/src/cson.c b/src/cson.c index 15c515b..20d887a 100644 --- a/src/cson.c +++ b/src/cson.c @@ -796,6 +796,29 @@ void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl) return; } +void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func){ + if(pProperty == NULL){ + return; + } + + void* ptr = *((void**)pProperty); + + cson_array_size_t size = csonArrayGetSize(ptr); + + if(dimen == 1){ + for (cson_array_size_t j = 0; j < size; j++) { + csonLoopProperty(((char*)ptr) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); + } + }else{ + for (cson_array_size_t j = 0; j < size; j++) { + void** p = (void**)ptr; + csonLoopPropertyArraySub(p + j, tbl, i, dimen - 1, func); + } + } + + func(pProperty, tbl + i); +} + void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) { int i = 0; @@ -804,25 +827,26 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) char* pProperty = (char*)pData + tbl[i].offset; if (tbl[i].type == CSON_ARRAY) { - if(*((void**)pProperty) == NULL){ + if(pProperty == NULL){ i++; continue; } - cson_array_size_t size = csonArrayGetSize(*((void**)pProperty)); - - for (cson_array_size_t j = 0; j < size; j++) { - csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); - } + csonLoopPropertyArraySub(pProperty, tbl, i, tbl[i].arrayDimensional, func); } else if (tbl[i].type == CSON_OBJECT) { csonLoopProperty(pProperty, tbl[i].reflect_tbl, func); + func(pProperty, tbl + i); + }else{ + func(pProperty, tbl + i); } - func(pProperty, tbl + i); - i++; } } +void csonLoopPropertyArrayTail(void* ptr, const reflect_item_t* tbl, loop_func_t func, int dimen){ + +} + static void* printPropertySub(void* pData, const reflect_item_t* tbl) { if (tbl->type == CSON_ARRAY || tbl->type == CSON_OBJECT) return NULL; From 97a549f799ce1b531356c8520b6155f9c54818f9 Mon Sep 17 00:00:00 2001 From: sunchb <448573057@qq.com> Date: Thu, 7 May 2020 15:21:56 +0800 Subject: [PATCH 4/8] add init/deinit multi-array function --- demo/Makefile | 65 +++++++++++++++++++++++++++++--- demo/main.c | 6 ++- demo/test.c | 37 ++++++++++--------- demo/test5.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ inc/cson.h | 85 ++++++++++++++++++++++++++++++++++++++++-- src/cson.c | 57 ++++++++++++++++++---------- 6 files changed, 303 insertions(+), 47 deletions(-) create mode 100644 demo/test5.c diff --git a/demo/Makefile b/demo/Makefile index 9dc20d7..5682fad 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -1,9 +1,62 @@ -INC += -I../3rd/inc -INC += -I../inc -LIB_PATH += -L../3rd/lib +MD := @mkdir -p +RM := @rm -rf LIB_PATH += -L../output CC=gcc -test:test.c main.c - @$(CC) $(INC) $(LIB_PATH) -g -o test test.c test2.c main.c -Wno-int-conversion -lcson -ljansson +INC += -I../inc + +OUT_DIR := ./output +TARGET := $(OUT_DIR)/test + +## source files +SRC_DIR = ../src +SRC_FILES += $(wildcard $(SRC_DIR)/*.c) + +## adapter files +ADAP_DIR = ../adapter/cjson +ADAP_FILES += $(wildcard $(ADAP_DIR)/*.c) + +## test source files +TEST_SRC_DIR = . +TEST_SRC_FILES += $(wildcard $(TEST_SRC_DIR)/*.c) +# TEST_SRC_FILES += ./test.c +# TEST_SRC_FILES += ./test5.c +# TEST_SRC_FILES += ./main.c + +## *.o +OBJS += $(patsubst $(SRC_DIR)/%.c, $(OUT_DIR)/%.o, $(SRC_FILES)) +OBJS += $(patsubst $(TEST_SRC_DIR)/%.c, $(OUT_DIR)/%.o, $(TEST_SRC_FILES)) +OBJS += $(patsubst $(ADAP_DIR)/%.c, $(OUT_DIR)/%.o, $(ADAP_FILES)) + + +$(TARGET):$(OBJS) + @$(CC) $(LIB_PATH) -g -Wl,--whole-archive -Wl,-O1 -Wl,-Map,$(OUT_DIR)/test.map -Wl,--no-whole-archive -fPIC $(OBJS) -o $(TARGET) -lgcov + +## rule for source file +$(OUT_DIR)/%.o:$(SRC_DIR)/%.c + @$(MD) $(OUT_DIR) + $(CC) $(INC) -Wno-int-conversion -fprofile-arcs -ftest-coverage -c -g $< -o $@ + +$(OUT_DIR)/%.o:$(ADAP_DIR)/%.c + @$(MD) $(OUT_DIR) + $(CC) $(INC) -Wno-int-conversion -fprofile-arcs -ftest-coverage -c -g $< -o $@ + +## rule for test source file +$(OUT_DIR)/%.o:$(TEST_SRC_DIR)/%.c + @$(MD) $(OUT_DIR) + $(CC) $(INC) -Wno-int-conversion -c -g $< -o $@ + +.PHONY:report run clean memchk + +run:$(TARGET) + $(TARGET) + +report:run + lcov -d . -t test -o $(OUT_DIR)/test.info -b . -c --rc lcov_branch_coverage=1 + lcov --extract $(OUT_DIR)/test.info '*.c' -o $(OUT_DIR)/finalresult.info --rc lcov_branch_coverage=1 + genhtml -o $(OUT_DIR)/result $(OUT_DIR)/finalresult.info --branch-coverage + +memchk:$(TARGET) + valgrind --tool=memcheck --leak-check=full $(TARGET) + clean: - @rm -rf test + @rm -rf ./output diff --git a/demo/main.c b/demo/main.c index 2912a3d..de95ae9 100644 --- a/demo/main.c +++ b/demo/main.c @@ -1,5 +1,7 @@ extern void test1(); extern void test2(); +extern void test5(); +extern void test6(); #include "cson.h" #include "stdio.h" @@ -7,6 +9,8 @@ extern void test2(); int main() { test1(); - //test2(); + test2(); + test5(); + test6(); return 0; } diff --git a/demo/test.c b/demo/test.c index 0fe3970..9c99e52 100644 --- a/demo/test.c +++ b/demo/test.c @@ -111,11 +111,11 @@ typedef struct { int paid; double price; size_t lyricNum; - Lyric* lyric; + Lyric** lyric; size_t keyNum; int** key; size_t strNum; - char** strList; + char*** strList; } SongInfo; typedef struct { @@ -149,11 +149,11 @@ reflect_item_t song_ref_tbl[] = { _property_bool(SongInfo, paid), _property_real(SongInfo, price), _property_int_ex(SongInfo, lyricNum, _ex_args_all), - _property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum, 1), + _property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum, 2), _property_int_ex(SongInfo, keyNum, _ex_args_all), _property_array_int(SongInfo, key, int, keyNum, 2), _property_int_ex(SongInfo, strNum, _ex_args_all), - _property_array_string(SongInfo, strList, char*, strNum, 1), + _property_array_string(SongInfo, strList, char*, strNum, 2), _property_end() }; @@ -175,7 +175,7 @@ reflect_item_t play_list_ref_tbl[] = { static void printPlayList(PlayList* list); 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],[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], [4321,9876,5432]],\"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\"}],[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}],[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}]],\"key\":[ [1111,2222,3333],[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], [4321,9876,5432]],\"strList\":[[\"abcd\",\"efgh\",\"ijkl\"],[\"abcd\",\"efgh\",\"ijkl\"]]}],\"extData\":{\"a\":999,\"b\":1}}"; static void checkResult(PlayList* playList, char* jstrOutput); /* @@ -212,7 +212,7 @@ void test1() 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}}"; + 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],[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],[4321,9876,5432]],\"strList\":[\"abcd\",\"efgh\",\"ijkl\"]}],\"extData\":{\"a\":999,\"b\":1}}"; /* assert test */ CHECK_STRING(playList->name, "jay zhou"); @@ -226,10 +226,10 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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].lyric[0][0].time, 1); + CHECK_STRING(playList->songList[0].lyric[0][0].text, "Sparrow outside the window"); + CHECK_NUMBER(playList->songList[0].lyric[0][1].time, 10); + CHECK_STRING(playList->songList[0].lyric[0][1].text, "Multi mouth on the pole"); //CHECK_NUMBER(playList->songList[0].keyNum, 3); CHECK_NUMBER(playList->songList[0].key[0][0], 1111); CHECK_NUMBER(playList->songList[0].key[0][1], 2222); @@ -244,18 +244,21 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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].lyric[0][0].time, 10); + CHECK_STRING(playList->songList[1].lyric[0][0].text, "A sad parting, standing alone in the window"); + CHECK_NUMBER(playList->songList[1].lyric[0][1].time, 20); + CHECK_STRING(playList->songList[1].lyric[0][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][0], 1234); CHECK_NUMBER(playList->songList[1].key[0][1], 5678); CHECK_NUMBER(playList->songList[1].key[0][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_STRING(playList->songList[1].strList[0][0], "abcd"); + CHECK_STRING(playList->songList[1].strList[0][1], "efgh"); + CHECK_STRING(playList->songList[1].strList[0][2], "ijkl"); + CHECK_STRING(playList->songList[1].strList[1][0], "abcd"); + CHECK_STRING(playList->songList[1].strList[1][1], "efgh"); + CHECK_STRING(playList->songList[1].strList[1][2], "ijkl"); CHECK_NUMBER(playList->extData.a, 999); CHECK_REAL(playList->extData.b, 1); diff --git a/demo/test5.c b/demo/test5.c new file mode 100644 index 0000000..6172f48 --- /dev/null +++ b/demo/test5.c @@ -0,0 +1,100 @@ +#include "cson.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.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) + +typedef struct { + int*** array; + char**** strArray; +} MultiArrayTest; + +reflect_item_t multi_array_ref_tbl[] = { + _property_array_int(MultiArrayTest, array, int, NULL, 3), + _property_array_string(MultiArrayTest, strArray, char*, NULL, 3), + _property_end() +}; + +void* freePointerOfArray(void* pData, const reflect_item_t* tbl) +{ + if(tbl->type == CSON_ARRAY){ + //printf("free field %s.\n", tbl->field); + csonArrayFree(*(void**)pData); + *(void**)pData = NULL; + } + + return NULL; +} + +void test5(){ + cson_array_size_t dimenSize[3] = {10, 10, 10}; + + MultiArrayTest testObj; + + testObj.array = (int***)csonAllocMultiDimenArray(3, dimenSize, sizeof(int)); + testObj.strArray = (char****)csonAllocMultiDimenArray(3, dimenSize, sizeof(char*)); + char* testStr = "str"; + + int num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + testObj.array[i][j][k] = num++; + testObj.strArray[i][j][k] = testStr; + + } + } + } + + num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + CHECK_NUMBER(testObj.array[i][j][k], num++); + } + } + } + + char* jstrOutput; + int ret = csonStruct2JsonStr(&jstrOutput, &testObj, multi_array_ref_tbl); + printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); + + free(jstrOutput); + csonLoopProperty(&testObj, multi_array_ref_tbl, freePointerOfArray); +} + +void test6(){ + cson_array_size_t dimenSize[4] = {10, 10, 10, 100}; + int**** pArray3D = (int****)csonAllocMultiDimenArray(4, dimenSize, sizeof(int)); + + int num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + for(int m = 0; m < dimenSize[3]; m++){ + pArray3D[i][j][k][m] = num++; + } + } + } + } + + num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + for(int m = 0; m < dimenSize[3]; m++){ + CHECK_NUMBER(pArray3D[i][j][k][m], num++); + } + } + } + } + + csonFreeMultiDimenArray(pArray3D); +} \ No newline at end of file diff --git a/inc/cson.h b/inc/cson.h index 7a16454..8e8fe62 100644 --- a/inc/cson.h +++ b/inc/cson.h @@ -277,11 +277,88 @@ void csonPrintProperty(void* pData, const reflect_item_t* tbl); */ void csonFreePointer(void* list, const reflect_item_t* tbl); -#define _CSON_SUPPORT_MULTI_ARRAY_ -#ifdef _CSON_SUPPORT_MULTI_ARRAY_ +/* + for Multidimensional array support +*/ typedef size_t cson_array_size_t; + +/** + * @brief get array memory. + * + * @param count: count of array item + * @param sizePerItem: bytes per array time + * + * @return void*. + * @attention Array header information is implied, so don't use malloc directly. + */ +void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem); + +/** + * @brief free array memory. + * + * @param ptr: array memory to be free. + * + * @return void. + * @attention Array header information is implied, so don't use free directly. + */ +void csonArrayFree(void* ptr); + +/** + * @brief get size(item count) of array + * + * @param ptr: array + * + * @return cson_array_size_t. + */ cson_array_size_t csonArrayGetSize(void* ptr); -cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl); -#endif + +/** + * @brief set size(item count) of array + * + * @param ptr: array + * @param size: size + * + * @return cson_array_size_t. + */ +void csonArraySetSize(void* ptr, cson_array_size_t size); + +/** + * @brief set dimension of array + * + * @param ptr: array + * @param dimen: dimension + * + * @return cson_array_size_t. + */ +void csonArraySetDimen(void* ptr, int dimen); + +/** + * @brief get dimension of array + * + * @param ptr: array + * + * @return cson_array_size_t. + */ +int csonArrayGetDimen(void* ptr); + +/** + * @brief fast alloc multi-dimen array + * + * @param dimen: dimen of array. + * @param sizePerDimen: size of per dimen. + * @param sizeOfItem: size of item. + * + * @return void*. + */ +void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_t sizeOfItem); + +/** + * @brief fast free multi-dimen array + * + * @param p: pointer of array. + * + * @return void*. + */ +void csonFreeMultiDimenArray(void* p); #endif \ No newline at end of file diff --git a/src/cson.c b/src/cson.c index 20d887a..6c703c3 100644 --- a/src/cson.c +++ b/src/cson.c @@ -146,7 +146,6 @@ static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl typedef struct { cson_array_size_t size; - cson_array_size_t sizePerItem; int dimen; } cson_array_header_t; @@ -155,19 +154,11 @@ typedef struct { void* ptr; } cson_array_t; -void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem); -void csonArrayFree(void* ptr); -cson_array_size_t csonArrayGetSize(void* ptr); -void csonArraySetSize(void* ptr, cson_array_size_t size); -cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl); -void csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size); void* parseJsonArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); -void csonArraySetDimen(void* ptr, int dimen); -int csonArrayGetDimen(void* ptr); - cson_t getJsonArrayTail(void* ptr, const reflect_item_t* tbl, int index); cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index); +void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func); int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl) { @@ -272,15 +263,12 @@ int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index){ int dimen = csonArrayGetDimen(ptr); - printf("filed:%s,dimen=%d\n", tbl[index].field, dimen); if(csonArrayGetDimen(ptr) == 1){ return getJsonArrayTail(ptr, tbl, index); }else{ cson_t joArray = cson_array(); cson_array_size_t size = csonArrayGetSize(ptr); - printf("filed:%s,size=%zu\n", tbl[index].field, size); - cson_array_size_t successCount = 0; for(cson_array_size_t i = 0; i < size; i++){ @@ -481,8 +469,6 @@ int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int } int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ - //检查维度 - printf("arrayDimensional:%d\n", tbl[index].arrayDimensional); void* pRet = parseJsonArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); csonSetPropertyFast(output, &pRet, tbl + index); return ERR_NONE; @@ -843,10 +829,6 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) } } -void csonLoopPropertyArrayTail(void* ptr, const reflect_item_t* tbl, loop_func_t func, int dimen){ - -} - static void* printPropertySub(void* pData, const reflect_item_t* tbl) { if (tbl->type == CSON_ARRAY || tbl->type == CSON_OBJECT) return NULL; @@ -869,6 +851,7 @@ static void* freePointerSub(void* pData, const reflect_item_t* tbl) }else if(tbl->type == CSON_ARRAY){ //printf("free field %s.\n", tbl->field); csonArrayFree(*(void**)pData); + *(void**)pData = NULL; }else{ } @@ -935,3 +918,39 @@ void csonArraySetSizeByField(void* pData, const char* field, const reflect_item_ csonArraySetSize(*((void**)pArray), size); } +void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_t sizeOfItem){ + if(dimen <= 0 || !sizePerDimen || sizeOfItem == 0) return NULL; + + if(dimen == 1){ + void* p = csonArrayAlloc(sizePerDimen[0], sizeOfItem); + csonArraySetSize(p, sizePerDimen[0]); + csonArraySetDimen(p, dimen); + return p; + }else{ + void** p = (void**)csonArrayAlloc(sizePerDimen[0], sizeof(void*)); + + for(int i = 0; i < sizePerDimen[0]; i++){ + p[i] = csonAllocMultiDimenArray(dimen - 1, sizePerDimen + 1, sizeOfItem); + } + csonArraySetSize(p, sizePerDimen[0]); + csonArraySetDimen(p, dimen); + return (void*)p; + } +} + +void csonFreeMultiDimenArray(void* p){ + if(!p) return; + + int dimen = csonArrayGetDimen(p); + + if(dimen == 1){ + csonArrayFree(p); + }else{ + cson_array_size_t size = csonArrayGetSize(p); + void** ptr = (void**)p; + for(int i = 0; i < size; i++){ + csonFreeMultiDimenArray(ptr[i]); + } + csonArrayFree(p); + } +} \ No newline at end of file From 4a3053e6930b6285a80dd4a49a91678a66b60703 Mon Sep 17 00:00:00 2001 From: sunchb <448573057@qq.com> Date: Thu, 7 May 2020 15:48:37 +0800 Subject: [PATCH 5/8] add test case of multi-array object --- demo/test5.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/demo/test5.c b/demo/test5.c index 6172f48..d6d5bba 100644 --- a/demo/test5.c +++ b/demo/test5.c @@ -11,21 +11,33 @@ #define CHECK_NUMBER(a, b) assert(a == b) #define CHECK_REAL(a, b) assert(fabs(a-b) <= 1e-6) +typedef struct { + char* name; + int num; +} Data; + typedef struct { int*** array; char**** strArray; + Data*** objArray; } MultiArrayTest; +reflect_item_t data_ref_tbl[] = { + _property_string(Data, name), + _property_int(Data, num), + _property_end() +}; + reflect_item_t multi_array_ref_tbl[] = { _property_array_int(MultiArrayTest, array, int, NULL, 3), _property_array_string(MultiArrayTest, strArray, char*, NULL, 3), + _property_array_object(MultiArrayTest, objArray, data_ref_tbl, Data, NULL, 3), _property_end() }; void* freePointerOfArray(void* pData, const reflect_item_t* tbl) { if(tbl->type == CSON_ARRAY){ - //printf("free field %s.\n", tbl->field); csonArrayFree(*(void**)pData); *(void**)pData = NULL; } @@ -40,6 +52,7 @@ void test5(){ testObj.array = (int***)csonAllocMultiDimenArray(3, dimenSize, sizeof(int)); testObj.strArray = (char****)csonAllocMultiDimenArray(3, dimenSize, sizeof(char*)); + testObj.objArray = (Data***)csonAllocMultiDimenArray(3, dimenSize, sizeof(Data)); char* testStr = "str"; int num = 1; @@ -48,7 +61,8 @@ void test5(){ for(int k = 0; k < dimenSize[2]; k++){ testObj.array[i][j][k] = num++; testObj.strArray[i][j][k] = testStr; - + testObj.objArray[i][j][k].num = num++; + testObj.objArray[i][j][k].name = testStr; } } } @@ -58,6 +72,7 @@ void test5(){ for(int j = 0; j < dimenSize[1]; j++){ for(int k = 0; k < dimenSize[2]; k++){ CHECK_NUMBER(testObj.array[i][j][k], num++); + CHECK_NUMBER(testObj.objArray[i][j][k].num, num++); } } } From 59c922d1eec20ea323f1e4f6b1e16782ce687c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E4=BC=A0=E5=AE=9D?= Date: Mon, 8 Jun 2020 23:37:23 +0800 Subject: [PATCH 6/8] merge --- demo/Makefile | 2 +- demo/main.c | 8 +-- demo/test.c | 69 ++++++++++---------- demo/test2.c | 20 +++--- demo/test5.c | 115 ---------------------------------- inc/cson.h | 2 + src/cson.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++---- 7 files changed, 209 insertions(+), 177 deletions(-) diff --git a/demo/Makefile b/demo/Makefile index 5682fad..1507c4f 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -29,7 +29,7 @@ OBJS += $(patsubst $(ADAP_DIR)/%.c, $(OUT_DIR)/%.o, $(ADAP_FILES)) $(TARGET):$(OBJS) - @$(CC) $(LIB_PATH) -g -Wl,--whole-archive -Wl,-O1 -Wl,-Map,$(OUT_DIR)/test.map -Wl,--no-whole-archive -fPIC $(OBJS) -o $(TARGET) -lgcov + @$(CC) $(LIB_PATH) -g $(OBJS) -o $(TARGET) -fprofile-arcs -ftest-coverage ## rule for source file $(OUT_DIR)/%.o:$(SRC_DIR)/%.c diff --git a/demo/main.c b/demo/main.c index de95ae9..54d8153 100644 --- a/demo/main.c +++ b/demo/main.c @@ -1,7 +1,7 @@ extern void test1(); extern void test2(); -extern void test5(); -extern void test6(); +//extern void test5(); +//extern void test6(); #include "cson.h" #include "stdio.h" @@ -10,7 +10,7 @@ int main() { test1(); test2(); - test5(); - test6(); + //test5(); + //test6(); return 0; } diff --git a/demo/test.c b/demo/test.c index 9c99e52..75c0652 100644 --- a/demo/test.c +++ b/demo/test.c @@ -111,11 +111,11 @@ typedef struct { int paid; double price; size_t lyricNum; - Lyric** lyric; + Lyric* lyric; size_t keyNum; - int** key; + int* key; size_t strNum; - char*** strList; + char** strList; } SongInfo; typedef struct { @@ -149,11 +149,11 @@ reflect_item_t song_ref_tbl[] = { _property_bool(SongInfo, paid), _property_real(SongInfo, price), _property_int_ex(SongInfo, lyricNum, _ex_args_all), - _property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum, 2), + _property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum, 1), _property_int_ex(SongInfo, keyNum, _ex_args_all), - _property_array_int(SongInfo, key, int, keyNum, 2), + _property_array_int(SongInfo, key, int, keyNum, 1), _property_int_ex(SongInfo, strNum, _ex_args_all), - _property_array_string(SongInfo, strList, char*, strNum, 2), + _property_array_string(SongInfo, strList, char*, strNum, 1), _property_end() }; @@ -175,7 +175,7 @@ reflect_item_t play_list_ref_tbl[] = { static void printPlayList(PlayList* list); 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\"}],[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}],[{\"time\":1,\"text\":\"Sparrow outside the window\"},{\"time\":10,\"text\":\"Multi mouth on the pole\"}]],\"key\":[ [1111,2222,3333],[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], [4321,9876,5432]],\"strList\":[[\"abcd\",\"efgh\",\"ijkl\"],[\"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); /* @@ -194,7 +194,7 @@ void test1() CHECK_NUMBER(ret, 0); printf("decode ret=%d\n", ret); /* test print */ - csonPrintProperty(&playList, play_list_ref_tbl); + //csonPrintProperty(&playList, play_list_ref_tbl); char* jstrOutput; ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); @@ -212,12 +212,12 @@ void test1() 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],[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],[4321,9876,5432]],\"strList\":[\"abcd\",\"efgh\",\"ijkl\"]}],\"extData\":{\"a\":999,\"b\":1}}"; + 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_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"); @@ -225,16 +225,16 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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][0].time, 1); - CHECK_STRING(playList->songList[0].lyric[0][0].text, "Sparrow outside the window"); - CHECK_NUMBER(playList->songList[0].lyric[0][1].time, 10); - CHECK_STRING(playList->songList[0].lyric[0][1].text, "Multi mouth on the pole"); - //CHECK_NUMBER(playList->songList[0].keyNum, 3); - CHECK_NUMBER(playList->songList[0].key[0][0], 1111); - CHECK_NUMBER(playList->songList[0].key[0][1], 2222); - CHECK_NUMBER(playList->songList[0].key[0][2], 3333); - //CHECK_NUMBER(playList->songList[0].strNum, 0); + 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"); @@ -243,22 +243,19 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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][0].time, 10); - CHECK_STRING(playList->songList[1].lyric[0][0].text, "A sad parting, standing alone in the window"); - CHECK_NUMBER(playList->songList[1].lyric[0][1].time, 20); - CHECK_STRING(playList->songList[1].lyric[0][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][0], 1234); - CHECK_NUMBER(playList->songList[1].key[0][1], 5678); - CHECK_NUMBER(playList->songList[1].key[0][2], 9876); - //CHECK_NUMBER(playList->songList[1].strNum, 3); - CHECK_STRING(playList->songList[1].strList[0][0], "abcd"); - CHECK_STRING(playList->songList[1].strList[0][1], "efgh"); - CHECK_STRING(playList->songList[1].strList[0][2], "ijkl"); - CHECK_STRING(playList->songList[1].strList[1][0], "abcd"); - CHECK_STRING(playList->songList[1].strList[1][1], "efgh"); - CHECK_STRING(playList->songList[1].strList[1][2], "ijkl"); + 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); diff --git a/demo/test2.c b/demo/test2.c index 28a4e31..4a496db 100644 --- a/demo/test2.c +++ b/demo/test2.c @@ -108,13 +108,13 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_NUMBER(resp->status, 1); CHECK_NUMBER(resp->data.timestamp, 1579069151); - //CHECK_NUMBER(resp->data.infoNum, 9); + CHECK_NUMBER(resp->data.infoNum, 9); CHECK_NUMBER(resp->data.info[0].has_child, 1); CHECK_STRING(resp->data.info[0].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172444711866.png"); CHECK_NUMBER(resp->data.info[0].id, 153); CHECK_STRING(resp->data.info[0].name, "专区"); - //CHECK_NUMBER(resp->data.info[0].childrenNum, 16); + CHECK_NUMBER(resp->data.info[0].childrenNum, 16); CHECK_STRING(resp->data.info[0].children[0].name, "DJ专区"); CHECK_STRING(resp->data.info[0].children[0].jump_url, "https://miniapp.kugou.com/node/v2?type=1&id=74&path=%2Findex.html%23%2Fmobile%2Fhome%2F1"); CHECK_STRING(resp->data.info[0].children[1].name, "抖音专区"); @@ -153,7 +153,7 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_STRING(resp->data.info[1].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104103209217784.png"); CHECK_NUMBER(resp->data.info[1].id, 2005); CHECK_STRING(resp->data.info[1].name, "心情"); - //CHECK_NUMBER(resp->data.info[1].childrenNum, 9); + CHECK_NUMBER(resp->data.info[1].childrenNum, 9); CHECK_STRING(resp->data.info[1].children[0].name, "伤感专区"); CHECK_STRING(resp->data.info[1].children[1].name, "安静专区"); CHECK_STRING(resp->data.info[1].children[2].name, "对抗抑郁专区"); @@ -169,7 +169,7 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_STRING(resp->data.info[2].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172455112096.png"); CHECK_NUMBER(resp->data.info[2].id, 1263); CHECK_STRING(resp->data.info[2].name, "特色"); - //CHECK_NUMBER(resp->data.info[2].childrenNum, 16); + CHECK_NUMBER(resp->data.info[2].childrenNum, 16); CHECK_STRING(resp->data.info[2].children[0].name, "官方歌单"); CHECK_STRING(resp->data.info[2].children[1].name, "重返2010专区"); CHECK_STRING(resp->data.info[2].children[2].name, "佛乐专区"); @@ -201,37 +201,37 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_STRING(resp->data.info[3].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104103220446249.png"); CHECK_NUMBER(resp->data.info[3].id, 2003); CHECK_STRING(resp->data.info[3].name, "场景"); - //CHECK_NUMBER(resp->data.info[3].childrenNum, 9); + CHECK_NUMBER(resp->data.info[3].childrenNum, 9); CHECK_NUMBER(resp->data.info[4].has_child, 1); CHECK_STRING(resp->data.info[4].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104103232420148.png"); CHECK_NUMBER(resp->data.info[4].id, 2007); CHECK_STRING(resp->data.info[4].name, "主题"); - //CHECK_NUMBER(resp->data.info[4].childrenNum, 14); + CHECK_NUMBER(resp->data.info[4].childrenNum, 14); CHECK_NUMBER(resp->data.info[5].has_child, 0); CHECK_STRING(resp->data.info[5].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172345416784.png"); CHECK_NUMBER(resp->data.info[5].id, 32); CHECK_STRING(resp->data.info[5].name, "年代"); - //CHECK_NUMBER(resp->data.info[5].childrenNum, 4); + CHECK_NUMBER(resp->data.info[5].childrenNum, 4); CHECK_NUMBER(resp->data.info[6].has_child, 1); CHECK_STRING(resp->data.info[6].icon, "http://imge.kugou.com/mcommon/{size}/20191202/20191202161746384633.png"); CHECK_NUMBER(resp->data.info[6].id, 2009); CHECK_STRING(resp->data.info[6].name, "语言"); - //CHECK_NUMBER(resp->data.info[6].childrenNum, 9); + CHECK_NUMBER(resp->data.info[6].childrenNum, 9); CHECK_NUMBER(resp->data.info[7].has_child, 1); CHECK_STRING(resp->data.info[7].icon, "http://imge.kugou.com/mcommon/{size}/20191104/20191104102344527371.png"); CHECK_NUMBER(resp->data.info[7].id, 1599); CHECK_STRING(resp->data.info[7].name, "风格"); - //CHECK_NUMBER(resp->data.info[7].childrenNum, 21); + CHECK_NUMBER(resp->data.info[7].childrenNum, 21); CHECK_NUMBER(resp->data.info[8].has_child, 0); CHECK_STRING(resp->data.info[8].icon, "http://imge.kugou.com/mcommon/{size}/20181130/20181130172408696210.png"); CHECK_NUMBER(resp->data.info[8].id, 58); CHECK_STRING(resp->data.info[8].name, "乐器"); - //CHECK_NUMBER(resp->data.info[8].childrenNum, 10); + CHECK_NUMBER(resp->data.info[8].childrenNum, 10); CHECK_STRING(jstrOutput, encodeTest); } \ No newline at end of file diff --git a/demo/test5.c b/demo/test5.c index d6d5bba..e69de29 100644 --- a/demo/test5.c +++ b/demo/test5.c @@ -1,115 +0,0 @@ -#include "cson.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.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) - -typedef struct { - char* name; - int num; -} Data; - -typedef struct { - int*** array; - char**** strArray; - Data*** objArray; -} MultiArrayTest; - -reflect_item_t data_ref_tbl[] = { - _property_string(Data, name), - _property_int(Data, num), - _property_end() -}; - -reflect_item_t multi_array_ref_tbl[] = { - _property_array_int(MultiArrayTest, array, int, NULL, 3), - _property_array_string(MultiArrayTest, strArray, char*, NULL, 3), - _property_array_object(MultiArrayTest, objArray, data_ref_tbl, Data, NULL, 3), - _property_end() -}; - -void* freePointerOfArray(void* pData, const reflect_item_t* tbl) -{ - if(tbl->type == CSON_ARRAY){ - csonArrayFree(*(void**)pData); - *(void**)pData = NULL; - } - - return NULL; -} - -void test5(){ - cson_array_size_t dimenSize[3] = {10, 10, 10}; - - MultiArrayTest testObj; - - testObj.array = (int***)csonAllocMultiDimenArray(3, dimenSize, sizeof(int)); - testObj.strArray = (char****)csonAllocMultiDimenArray(3, dimenSize, sizeof(char*)); - testObj.objArray = (Data***)csonAllocMultiDimenArray(3, dimenSize, sizeof(Data)); - char* testStr = "str"; - - int num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - testObj.array[i][j][k] = num++; - testObj.strArray[i][j][k] = testStr; - testObj.objArray[i][j][k].num = num++; - testObj.objArray[i][j][k].name = testStr; - } - } - } - - num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - CHECK_NUMBER(testObj.array[i][j][k], num++); - CHECK_NUMBER(testObj.objArray[i][j][k].num, num++); - } - } - } - - char* jstrOutput; - int ret = csonStruct2JsonStr(&jstrOutput, &testObj, multi_array_ref_tbl); - printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); - - free(jstrOutput); - csonLoopProperty(&testObj, multi_array_ref_tbl, freePointerOfArray); -} - -void test6(){ - cson_array_size_t dimenSize[4] = {10, 10, 10, 100}; - int**** pArray3D = (int****)csonAllocMultiDimenArray(4, dimenSize, sizeof(int)); - - int num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - for(int m = 0; m < dimenSize[3]; m++){ - pArray3D[i][j][k][m] = num++; - } - } - } - } - - num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - for(int m = 0; m < dimenSize[3]; m++){ - CHECK_NUMBER(pArray3D[i][j][k][m], num++); - } - } - } - } - - csonFreeMultiDimenArray(pArray3D); -} \ No newline at end of file diff --git a/inc/cson.h b/inc/cson.h index 8e8fe62..7bcc358 100644 --- a/inc/cson.h +++ b/inc/cson.h @@ -277,6 +277,7 @@ void csonPrintProperty(void* pData, const reflect_item_t* tbl); */ void csonFreePointer(void* list, const reflect_item_t* tbl); +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ /* for Multidimensional array support */ @@ -360,5 +361,6 @@ void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_ * @return void*. */ void csonFreeMultiDimenArray(void* p); +#endif #endif \ No newline at end of file diff --git a/src/cson.c b/src/cson.c index 6c703c3..50012a7 100644 --- a/src/cson.c +++ b/src/cson.c @@ -144,6 +144,7 @@ json_obj_proc jsonObjDefaultTbl[] = { static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl); +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ typedef struct { cson_array_size_t size; int dimen; @@ -159,6 +160,7 @@ void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); cson_t getJsonArrayTail(void* ptr, const reflect_item_t* tbl, int index); cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index); void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func); +#endif int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl) { @@ -261,6 +263,7 @@ int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj return ret; } +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index){ int dimen = csonArrayGetDimen(ptr); if(csonArrayGetDimen(ptr) == 1){ @@ -336,6 +339,56 @@ int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) if(*obj == NULL) return ERR_MISSING_FIELD; return ret; } +#else +int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +{ + int ret = ERR_NONE; + int countIndex = -1; + char* pSrc = (*(char**)((char*)input + tbl[index].offset)); + + if (pSrc == NULL) return ERR_MISSING_FIELD; + + void* ptr = csonGetProperty(input, tbl[index].arrayCountField, tbl, &countIndex); + + if (ptr == NULL || countIndex == -1) { + return ERR_MISSING_FIELD; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + + cson_t joArray = cson_array(); + + long long successCount = 0; + + for (long long i = 0; i < size; i++) { + cson_t jotmp; + + if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ + ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); + } else { + jotmp = cson_object(); + ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + } + + if (ret == ERR_NONE) { + successCount++; + cson_array_add(joArray, jotmp); + } else { + printf("create array item faild.\n"); + cson_decref(jotmp); + } + } + + if (successCount == 0) { + cson_decref(joArray); + return ERR_MISSING_FIELD; + } else { + *obj = joArray; + return ERR_NONE; + } + + return ret; +} +#endif int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj) { @@ -468,6 +521,7 @@ int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int return csonJsonObj2Struct(jo_tmp, (char*)output + tbl[index].offset, tbl[index].reflect_tbl); } +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ void* pRet = parseJsonArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); csonSetPropertyFast(output, &pRet, tbl + index); @@ -546,6 +600,64 @@ void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index){ return pMem; } +#else +int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) +{ + size_t arraySize = cson_array_size(jo_tmp); + + if (arraySize == 0) { + csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl); + return ERR_NONE; + } + + int countIndex = -1; + csonGetProperty(output, tbl[index].arrayCountField, tbl, &countIndex); + + if (countIndex == -1) { + return ERR_MISSING_FIELD; + } + + char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize); + if (pMem == NULL) return ERR_MEMORY; + + memset(pMem, 0, arraySize * tbl[index].arrayItemSize); + + long long successCount = 0; + for (size_t j = 0; j < arraySize; j++) { + cson_t item = cson_array_get(jo_tmp, j); + if (item != NULL) { + int ret; + + if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ + ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0); + } else { + ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + } + + if (ret == ERR_NONE) { + successCount++; + } + } + } + + integer_val_t val; + if (convertInteger(successCount, tbl[countIndex].size, &val) != ERR_NONE) { + successCount = 0; + } + + if (successCount == 0) { + csonSetPropertyFast(output, &successCount, tbl + countIndex); + free(pMem); + pMem = NULL; + csonSetPropertyFast(output, &pMem, tbl + index); + return ERR_MISSING_FIELD; + } else { + csonSetPropertyFast(output, &val, tbl + countIndex); + csonSetPropertyFast(output, &pMem, tbl + index); + return ERR_NONE; + } +} +#endif int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { @@ -782,6 +894,8 @@ void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl) return; } + +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func){ if(pProperty == NULL){ return; @@ -828,6 +942,36 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) i++; } } +#else +void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) +{ + int i = 0; + while (1) { + if (!tbl[i].field) break; + + char* pProperty = (char*)pData + tbl[i].offset; + if (tbl[i].type == CSON_ARRAY) { + int countIndex = -1; + void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); + + if (ptr == NULL || countIndex == -1) { + continue; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + + for (long long j = 0; j < size; j++) { + csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); + } + } else if (tbl[i].type == CSON_OBJECT) { + csonLoopProperty(pProperty, tbl[i].reflect_tbl, func); + } + + func(pProperty, tbl + i); + + i++; + } +} +#endif static void* printPropertySub(void* pData, const reflect_item_t* tbl) { @@ -842,6 +986,7 @@ static void* printPropertySub(void* pData, const reflect_item_t* tbl) return NULL; } +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ static void* freePointerSub(void* pData, const reflect_item_t* tbl) { if (tbl->type == CSON_STRING) { @@ -857,6 +1002,17 @@ static void* freePointerSub(void* pData, const reflect_item_t* tbl) } return NULL; } +#else +static void* freePointerSub(void* pData, const reflect_item_t* tbl) +{ + if (tbl->type == CSON_ARRAY || tbl->type == CSON_STRING) { + //printf("free field %s.\n", tbl->field); + free(*(void**)pData); + *(void**)pData = NULL; + } + return NULL; +} +#endif void csonPrintProperty(void* pData, const reflect_item_t* tbl) { @@ -870,6 +1026,7 @@ void csonFreePointer(void* list, const reflect_item_t* tbl) csonLoopProperty(list, tbl, freePointerSub); } +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem){ char* pMem = (char*)malloc(count * sizePerItem + sizeof(cson_array_header_t)); @@ -908,16 +1065,6 @@ void csonArraySetDimen(void* ptr, int dimen){ ((cson_array_header_t*)pArrayHeader)->dimen = dimen; } -cson_array_size_t csonArrayGetSizeByField(void* pData, const char* field, const reflect_item_t* tbl){ - void* pArray = csonGetProperty(pData, field, tbl, NULL); - return csonArrayGetSize(*((void**)pArray)); -} - -void csonArraySetSizeByField(void* pData, const char* field, const reflect_item_t* tbl, cson_array_size_t size){ - void* pArray = csonGetProperty(pData, field, tbl, NULL); - csonArraySetSize(*((void**)pArray), size); -} - void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_t sizeOfItem){ if(dimen <= 0 || !sizePerDimen || sizeOfItem == 0) return NULL; @@ -953,4 +1100,5 @@ void csonFreeMultiDimenArray(void* p){ } csonArrayFree(p); } -} \ No newline at end of file +} +#endif \ No newline at end of file From dd889242e851af2d44dfe1372b1c9d6feba11bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E4=BC=A0=E5=AE=9D?= Date: Tue, 9 Jun 2020 00:18:16 +0800 Subject: [PATCH 7/8] merge --- demo/Makefile | 7 +- demo/main.c | 17 +- demo/test.c | 4 +- demo/test2.c | 4 +- demo/test5.c | 117 ++++++++ inc/cson.h | 3 - src/cson.c | 737 +++++++++++++++++++++++++------------------------- 7 files changed, 502 insertions(+), 387 deletions(-) diff --git a/demo/Makefile b/demo/Makefile index 1507c4f..3ffdae1 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -27,6 +27,7 @@ OBJS += $(patsubst $(SRC_DIR)/%.c, $(OUT_DIR)/%.o, $(SRC_FILES)) OBJS += $(patsubst $(TEST_SRC_DIR)/%.c, $(OUT_DIR)/%.o, $(TEST_SRC_FILES)) OBJS += $(patsubst $(ADAP_DIR)/%.c, $(OUT_DIR)/%.o, $(ADAP_FILES)) +#CFLAGS += -D_CSON_MULTI_ARRAY_SUPPORT_ $(TARGET):$(OBJS) @$(CC) $(LIB_PATH) -g $(OBJS) -o $(TARGET) -fprofile-arcs -ftest-coverage @@ -34,16 +35,16 @@ $(TARGET):$(OBJS) ## rule for source file $(OUT_DIR)/%.o:$(SRC_DIR)/%.c @$(MD) $(OUT_DIR) - $(CC) $(INC) -Wno-int-conversion -fprofile-arcs -ftest-coverage -c -g $< -o $@ + $(CC) $(INC) $(CFLAGS) -Wno-int-conversion -fprofile-arcs -ftest-coverage -c -g $< -o $@ $(OUT_DIR)/%.o:$(ADAP_DIR)/%.c @$(MD) $(OUT_DIR) - $(CC) $(INC) -Wno-int-conversion -fprofile-arcs -ftest-coverage -c -g $< -o $@ + $(CC) $(INC) $(CFLAGS) -Wno-int-conversion -fprofile-arcs -ftest-coverage -c -g $< -o $@ ## rule for test source file $(OUT_DIR)/%.o:$(TEST_SRC_DIR)/%.c @$(MD) $(OUT_DIR) - $(CC) $(INC) -Wno-int-conversion -c -g $< -o $@ + $(CC) $(INC) $(CFLAGS) -Wno-int-conversion -c -g $< -o $@ .PHONY:report run clean memchk diff --git a/demo/main.c b/demo/main.c index 54d8153..00a3014 100644 --- a/demo/main.c +++ b/demo/main.c @@ -1,16 +1,25 @@ + +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ +extern void test3(); +extern void test5(); +extern void test6(); +#else extern void test1(); extern void test2(); -//extern void test5(); -//extern void test6(); +#endif #include "cson.h" #include "stdio.h" int main() { +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ + test3(); + test5(); + test6(); +#else test1(); test2(); - //test5(); - //test6(); +#endif return 0; } diff --git a/demo/test.c b/demo/test.c index 75c0652..c64b75d 100644 --- a/demo/test.c +++ b/demo/test.c @@ -1,3 +1,4 @@ +#ifndef _CSON_MULTI_ARRAY_SUPPORT_ #include "cson.h" #include "stdio.h" #include "string.h" @@ -261,4 +262,5 @@ void checkResult(PlayList* playList, char* jstrOutput){ //It is difficult to predict the output due to the accuracy problem. //CHECK_STRING(jstrOutput, encodeTest); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/demo/test2.c b/demo/test2.c index 4a496db..8c0ae79 100644 --- a/demo/test2.c +++ b/demo/test2.c @@ -1,3 +1,4 @@ +#ifndef _CSON_MULTI_ARRAY_SUPPORT_ #include "cson.h" #include "stdio.h" #include "stdlib.h" @@ -234,4 +235,5 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_NUMBER(resp->data.info[8].childrenNum, 10); CHECK_STRING(jstrOutput, encodeTest); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/demo/test5.c b/demo/test5.c index e69de29..039f8af 100644 --- a/demo/test5.c +++ b/demo/test5.c @@ -0,0 +1,117 @@ +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ +#include "cson.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.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) + +typedef struct { + char* name; + int num; +} Data; + +typedef struct { + int*** array; + char**** strArray; + Data*** objArray; +} MultiArrayTest; + +reflect_item_t data_ref_tbl[] = { + _property_string(Data, name), + _property_int(Data, num), + _property_end() +}; + +reflect_item_t multi_array_ref_tbl[] = { + _property_array_int(MultiArrayTest, array, int, NULL, 3), + _property_array_string(MultiArrayTest, strArray, char*, NULL, 3), + _property_array_object(MultiArrayTest, objArray, data_ref_tbl, Data, NULL, 3), + _property_end() +}; + +void* freePointerOfArray(void* pData, const reflect_item_t* tbl) +{ + if(tbl->type == CSON_ARRAY){ + csonArrayFree(*(void**)pData); + *(void**)pData = NULL; + } + + return NULL; +} + +void test5(){ + cson_array_size_t dimenSize[3] = {10, 10, 10}; + + MultiArrayTest testObj; + + testObj.array = (int***)csonAllocMultiDimenArray(3, dimenSize, sizeof(int)); + testObj.strArray = (char****)csonAllocMultiDimenArray(3, dimenSize, sizeof(char*)); + testObj.objArray = (Data***)csonAllocMultiDimenArray(3, dimenSize, sizeof(Data)); + char* testStr = "str"; + + int num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + testObj.array[i][j][k] = num++; + testObj.strArray[i][j][k] = testStr; + testObj.objArray[i][j][k].num = num++; + testObj.objArray[i][j][k].name = testStr; + } + } + } + + num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + CHECK_NUMBER(testObj.array[i][j][k], num++); + CHECK_NUMBER(testObj.objArray[i][j][k].num, num++); + } + } + } + + char* jstrOutput; + int ret = csonStruct2JsonStr(&jstrOutput, &testObj, multi_array_ref_tbl); + printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); + + free(jstrOutput); + csonLoopProperty(&testObj, multi_array_ref_tbl, freePointerOfArray); +} + +void test6(){ + cson_array_size_t dimenSize[4] = {10, 10, 10, 100}; + int**** pArray3D = (int****)csonAllocMultiDimenArray(4, dimenSize, sizeof(int)); + + int num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + for(int m = 0; m < dimenSize[3]; m++){ + pArray3D[i][j][k][m] = num++; + } + } + } + } + + num = 1; + for(int i = 0; i < dimenSize[0]; i++){ + for(int j = 0; j < dimenSize[1]; j++){ + for(int k = 0; k < dimenSize[2]; k++){ + for(int m = 0; m < dimenSize[3]; m++){ + CHECK_NUMBER(pArray3D[i][j][k][m], num++); + } + } + } + } + + csonFreeMultiDimenArray(pArray3D); +} +#endif \ No newline at end of file diff --git a/inc/cson.h b/inc/cson.h index 7bcc358..d61ca3d 100644 --- a/inc/cson.h +++ b/inc/cson.h @@ -277,7 +277,6 @@ void csonPrintProperty(void* pData, const reflect_item_t* tbl); */ void csonFreePointer(void* list, const reflect_item_t* tbl); -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ /* for Multidimensional array support */ @@ -361,6 +360,4 @@ void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_ * @return void*. */ void csonFreeMultiDimenArray(void* p); -#endif - #endif \ No newline at end of file diff --git a/src/cson.c b/src/cson.c index 50012a7..0623881 100644 --- a/src/cson.c +++ b/src/cson.c @@ -144,7 +144,6 @@ json_obj_proc jsonObjDefaultTbl[] = { static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl); -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ typedef struct { cson_array_size_t size; int dimen; @@ -155,12 +154,15 @@ typedef struct { void* ptr; } cson_array_t; -void* parseJsonArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); -void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); -cson_t getJsonArrayTail(void* ptr, const reflect_item_t* tbl, int index); -cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index); -void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func); -#endif +static int getJsonSingleArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj); +static int parseJsonSingleArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index); +static cson_t getJsonMultiArraySub(void* ptr, const reflect_item_t* tbl, int index); +static cson_t getJsonMultiArrayTail(void* ptr, const reflect_item_t* tbl, int index); +static int getJsonMultiArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj); +static int parseJsonMultiArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index); +static void* parseJsonMultiArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); +static void* parseJsonMultiArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); +static void csonLoopPropertyMultiArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func); int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl) { @@ -263,133 +265,16 @@ int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj return ret; } +int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +{ #ifdef _CSON_MULTI_ARRAY_SUPPORT_ -cson_t getJsonArraySub(void* ptr, const reflect_item_t* tbl, int index){ - int dimen = csonArrayGetDimen(ptr); - if(csonArrayGetDimen(ptr) == 1){ - return getJsonArrayTail(ptr, tbl, index); - }else{ - cson_t joArray = cson_array(); - - cson_array_size_t size = csonArrayGetSize(ptr); - cson_array_size_t successCount = 0; - - for(cson_array_size_t i = 0; i < size; i++){ - void** p = (void**)ptr; - cson_t jotmp = getJsonArraySub(p[i], tbl, index); - - if(jotmp != NULL){ - successCount++; - cson_array_add(joArray, jotmp); - } - } - - if (successCount == 0) { - cson_decref(joArray); - joArray = NULL; - } - - return joArray; - } -} - -cson_t getJsonArrayTail(void* ptr, const reflect_item_t* tbl, int index){ - cson_array_size_t size = csonArrayGetSize(ptr); - cson_t joArray = cson_array(); - - cson_array_size_t successCount = 0; - - for (cson_array_size_t i = 0; i < size; i++) { - cson_t jotmp; - - int ret = ERR_NONE; - if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ - ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](ptr + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); - } else { - jotmp = cson_object(); - ret = csonStruct2JsonObj(jotmp, ptr + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); - } - - if (ret == ERR_NONE) { - successCount++; - cson_array_add(joArray, jotmp); - } else { - printf("create array item faild.\n"); - cson_decref(jotmp); - } - } - - if (successCount == 0) { - cson_decref(joArray); - joArray = NULL; - } - - return joArray; -} - -int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) -{ - int ret = ERR_NONE; - int countIndex = -1; - char* pSrc = (*(char**)((char*)input + tbl[index].offset)); - - if (pSrc == NULL) return ERR_MISSING_FIELD; - - *obj = getJsonArraySub(pSrc, tbl, index); - if(*obj == NULL) return ERR_MISSING_FIELD; - return ret; -} + return getJsonMultiArray(input, tbl, index, obj); #else -int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) -{ - int ret = ERR_NONE; - int countIndex = -1; - char* pSrc = (*(char**)((char*)input + tbl[index].offset)); - - if (pSrc == NULL) return ERR_MISSING_FIELD; - - void* ptr = csonGetProperty(input, tbl[index].arrayCountField, tbl, &countIndex); - - if (ptr == NULL || countIndex == -1) { - return ERR_MISSING_FIELD; - } - long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); - - cson_t joArray = cson_array(); - - long long successCount = 0; - - for (long long i = 0; i < size; i++) { - cson_t jotmp; - - if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ - ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); - } else { - jotmp = cson_object(); - ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); - } - - if (ret == ERR_NONE) { - successCount++; - cson_array_add(joArray, jotmp); - } else { - printf("create array item faild.\n"); - cson_decref(jotmp); - } - } - - if (successCount == 0) { - cson_decref(joArray); - return ERR_MISSING_FIELD; - } else { - *obj = joArray; - return ERR_NONE; - } - - return ret; -} + return getJsonSingleArray(input, tbl, index, obj); #endif +} + int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj) { if (tbl[index].size != sizeof(double)) { @@ -521,143 +406,14 @@ int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int return csonJsonObj2Struct(jo_tmp, (char*)output + tbl[index].offset, tbl[index].reflect_tbl); } -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ -int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ - void* pRet = parseJsonArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); - csonSetPropertyFast(output, &pRet, tbl + index); - return ERR_NONE; -} - -void* parseJsonArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen){ - if(dimen == 1){ - return parseJsonArrayTail(jo_tmp, tbl, index); - }else{ - cson_array_size_t arraySize = cson_array_size(jo_tmp); - if(arraySize == 0) return NULL; - - void** pMem = (void**)csonArrayAlloc(arraySize, sizeof(void*)); - csonArraySetDimen(pMem, dimen); - - cson_array_size_t successCount = 0; - - for(cson_array_size_t i = 0; i < arraySize; i++){ - cson_t item = cson_array_get(jo_tmp, i); - if(cson_typeof(item) != CSON_ARRAY) continue; - void* p = parseJsonArraySub(item, tbl, index, dimen - 1); - if(p != NULL){ - pMem[successCount++] = p; - } - } - - if(successCount == 0){ - csonArrayFree(pMem); - return NULL; - }else{ - csonArraySetSize(pMem, successCount); - return (void*)pMem; - } - } -} - -void* parseJsonArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index){ - size_t arraySize = cson_array_size(jo_tmp); - if (arraySize == 0) { - return NULL; - } - - char* pMem = (char*)csonArrayAlloc(arraySize, tbl[index].arrayItemSize); - if (pMem == NULL) return NULL; - - memset(pMem, 0, arraySize * tbl[index].arrayItemSize); - - csonArraySetDimen(pMem, 1); - - cson_array_size_t successCount = 0; - - for (cson_array_size_t j = 0; j < arraySize; j++) { - cson_t item = cson_array_get(jo_tmp, j); - if (item != NULL) { - int ret; - - if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ - ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0); - } else { - ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl); - } - - if (ret == ERR_NONE) { - successCount++; - } - } - } - - if (successCount == 0) { - csonArrayFree(pMem); - pMem = NULL; - }else{ - csonArraySetSize(pMem, successCount); - } - - return pMem; -} -#else int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { - size_t arraySize = cson_array_size(jo_tmp); - - if (arraySize == 0) { - csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl); - return ERR_NONE; - } - - int countIndex = -1; - csonGetProperty(output, tbl[index].arrayCountField, tbl, &countIndex); - - if (countIndex == -1) { - return ERR_MISSING_FIELD; - } - - char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize); - if (pMem == NULL) return ERR_MEMORY; - - memset(pMem, 0, arraySize * tbl[index].arrayItemSize); - - long long successCount = 0; - for (size_t j = 0; j < arraySize; j++) { - cson_t item = cson_array_get(jo_tmp, j); - if (item != NULL) { - int ret; - - if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ - ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0); - } else { - ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl); - } - - if (ret == ERR_NONE) { - successCount++; - } - } - } - - integer_val_t val; - if (convertInteger(successCount, tbl[countIndex].size, &val) != ERR_NONE) { - successCount = 0; - } - - if (successCount == 0) { - csonSetPropertyFast(output, &successCount, tbl + countIndex); - free(pMem); - pMem = NULL; - csonSetPropertyFast(output, &pMem, tbl + index); - return ERR_MISSING_FIELD; - } else { - csonSetPropertyFast(output, &val, tbl + countIndex); - csonSetPropertyFast(output, &pMem, tbl + index); - return ERR_NONE; - } -} +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ + return parseJsonMultiArray(jo_tmp, output, tbl, index); +#else + return parseJsonSingleArray(jo_tmp, output, tbl, index); #endif +} int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { @@ -894,9 +650,243 @@ void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl) return; } +void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) +{ + int i = 0; + while (1) { + if (!tbl[i].field) break; + char* pProperty = (char*)pData + tbl[i].offset; + if (tbl[i].type == CSON_ARRAY) { #ifdef _CSON_MULTI_ARRAY_SUPPORT_ -void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func){ + if(pProperty == NULL){ + i++; + continue; + } + csonLoopPropertyMultiArraySub(pProperty, tbl, i, tbl[i].arrayDimensional, func); +#else + int countIndex = -1; + void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); + + if (ptr == NULL || countIndex == -1) { + continue; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + + for (long long j = 0; j < size; j++) { + csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); + } +#endif + } else if (tbl[i].type == CSON_OBJECT) { + csonLoopProperty(pProperty, tbl[i].reflect_tbl, func); + } + + func(pProperty, tbl + i); + + i++; + } +} + +static void* printPropertySub(void* pData, const reflect_item_t* tbl) +{ + if (tbl->type == CSON_ARRAY || tbl->type == CSON_OBJECT) return NULL; + + if (tbl->type == CSON_INTEGER || tbl->type == CSON_TRUE || tbl->type == CSON_FALSE) printf("%s:%d\n", tbl->field, *(int*)pData); + + if (tbl->type == CSON_REAL) printf("%s:%f\n", tbl->field, *(double*)pData); + + if (tbl->type == CSON_STRING) printf("%s:%s\n", tbl->field, *((char**)pData)); + + return NULL; +} + +static void* freePointerSub(void* pData, const reflect_item_t* tbl) +{ + if (tbl->type == CSON_STRING) { + //printf("free field %s.\n", tbl->field); + free(*(void**)pData); + *(void**)pData = NULL; + }else if(tbl->type == CSON_ARRAY){ +#ifdef _CSON_MULTI_ARRAY_SUPPORT_ + //printf("free field %s.\n", tbl->field); + csonArrayFree(*(void**)pData); + *(void**)pData = NULL; +#else + free(*(void**)pData); + *(void**)pData = NULL; +#endif + }else{ + + } + return NULL; +} + +void csonPrintProperty(void* pData, const reflect_item_t* tbl) +{ + /* 调用loopProperty迭代结构体中的属性,完成迭代输出属性值 */ + csonLoopProperty(pData, tbl, printPropertySub); +} + +void csonFreePointer(void* list, const reflect_item_t* tbl) +{ + /* 调用loopProperty迭代结构体中的属性,释放字符串和数组申请的内存空间 */ + csonLoopProperty(list, tbl, freePointerSub); +} + +cson_t getJsonMultiArraySub(void* ptr, const reflect_item_t* tbl, int index){ + int dimen = csonArrayGetDimen(ptr); + if(csonArrayGetDimen(ptr) == 1){ + return getJsonMultiArrayTail(ptr, tbl, index); + }else{ + cson_t joArray = cson_array(); + + cson_array_size_t size = csonArrayGetSize(ptr); + cson_array_size_t successCount = 0; + + for(cson_array_size_t i = 0; i < size; i++){ + void** p = (void**)ptr; + cson_t jotmp = getJsonMultiArraySub(p[i], tbl, index); + + if(jotmp != NULL){ + successCount++; + cson_array_add(joArray, jotmp); + } + } + + if (successCount == 0) { + cson_decref(joArray); + joArray = NULL; + } + + return joArray; + } +} + +cson_t getJsonMultiArrayTail(void* ptr, const reflect_item_t* tbl, int index){ + cson_array_size_t size = csonArrayGetSize(ptr); + cson_t joArray = cson_array(); + + cson_array_size_t successCount = 0; + + for (cson_array_size_t i = 0; i < size; i++) { + cson_t jotmp; + + int ret = ERR_NONE; + if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ + ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](ptr + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); + } else { + jotmp = cson_object(); + ret = csonStruct2JsonObj(jotmp, ptr + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + } + + if (ret == ERR_NONE) { + successCount++; + cson_array_add(joArray, jotmp); + } else { + printf("create array item faild.\n"); + cson_decref(jotmp); + } + } + + if (successCount == 0) { + cson_decref(joArray); + joArray = NULL; + } + + return joArray; +} + +int getJsonMultiArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +{ + int ret = ERR_NONE; + int countIndex = -1; + char* pSrc = (*(char**)((char*)input + tbl[index].offset)); + + if (pSrc == NULL) return ERR_MISSING_FIELD; + + *obj = getJsonMultiArraySub(pSrc, tbl, index); + if(*obj == NULL) return ERR_MISSING_FIELD; + return ret; +} +int parseJsonMultiArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ + void* pRet = parseJsonMultiArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); + csonSetPropertyFast(output, &pRet, tbl + index); + return ERR_NONE; +} + +void* parseJsonMultiArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen){ + if(dimen == 1){ + return parseJsonMultiArrayTail(jo_tmp, tbl, index); + }else{ + cson_array_size_t arraySize = cson_array_size(jo_tmp); + if(arraySize == 0) return NULL; + + void** pMem = (void**)csonArrayAlloc(arraySize, sizeof(void*)); + csonArraySetDimen(pMem, dimen); + + cson_array_size_t successCount = 0; + + for(cson_array_size_t i = 0; i < arraySize; i++){ + cson_t item = cson_array_get(jo_tmp, i); + if(cson_typeof(item) != CSON_ARRAY) continue; + void* p = parseJsonMultiArraySub(item, tbl, index, dimen - 1); + if(p != NULL){ + pMem[successCount++] = p; + } + } + + if(successCount == 0){ + csonArrayFree(pMem); + return NULL; + }else{ + csonArraySetSize(pMem, successCount); + return (void*)pMem; + } + } +} + +void* parseJsonMultiArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index){ + size_t arraySize = cson_array_size(jo_tmp); + if (arraySize == 0) { + return NULL; + } + + char* pMem = (char*)csonArrayAlloc(arraySize, tbl[index].arrayItemSize); + if (pMem == NULL) return NULL; + + memset(pMem, 0, arraySize * tbl[index].arrayItemSize); + + csonArraySetDimen(pMem, 1); + + cson_array_size_t successCount = 0; + + for (cson_array_size_t j = 0; j < arraySize; j++) { + cson_t item = cson_array_get(jo_tmp, j); + if (item != NULL) { + int ret; + + if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ + ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0); + } else { + ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + } + + if (ret == ERR_NONE) { + successCount++; + } + } + } + + if (successCount == 0) { + csonArrayFree(pMem); + pMem = NULL; + }else{ + csonArraySetSize(pMem, successCount); + } + + return pMem; +} +void csonLoopPropertyMultiArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func){ if(pProperty == NULL){ return; } @@ -912,121 +902,13 @@ void csonLoopPropertyArraySub(void* pProperty, const reflect_item_t* tbl, int i, }else{ for (cson_array_size_t j = 0; j < size; j++) { void** p = (void**)ptr; - csonLoopPropertyArraySub(p + j, tbl, i, dimen - 1, func); + csonLoopPropertyMultiArraySub(p + j, tbl, i, dimen - 1, func); } } func(pProperty, tbl + i); } -void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) -{ - int i = 0; - while (1) { - if (!tbl[i].field) break; - - char* pProperty = (char*)pData + tbl[i].offset; - if (tbl[i].type == CSON_ARRAY) { - if(pProperty == NULL){ - i++; - continue; - } - csonLoopPropertyArraySub(pProperty, tbl, i, tbl[i].arrayDimensional, func); - } else if (tbl[i].type == CSON_OBJECT) { - csonLoopProperty(pProperty, tbl[i].reflect_tbl, func); - func(pProperty, tbl + i); - }else{ - func(pProperty, tbl + i); - } - - i++; - } -} -#else -void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) -{ - int i = 0; - while (1) { - if (!tbl[i].field) break; - - char* pProperty = (char*)pData + tbl[i].offset; - if (tbl[i].type == CSON_ARRAY) { - int countIndex = -1; - void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); - - if (ptr == NULL || countIndex == -1) { - continue; - } - long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); - - for (long long j = 0; j < size; j++) { - csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); - } - } else if (tbl[i].type == CSON_OBJECT) { - csonLoopProperty(pProperty, tbl[i].reflect_tbl, func); - } - - func(pProperty, tbl + i); - - i++; - } -} -#endif - -static void* printPropertySub(void* pData, const reflect_item_t* tbl) -{ - if (tbl->type == CSON_ARRAY || tbl->type == CSON_OBJECT) return NULL; - - if (tbl->type == CSON_INTEGER || tbl->type == CSON_TRUE || tbl->type == CSON_FALSE) printf("%s:%d\n", tbl->field, *(int*)pData); - - if (tbl->type == CSON_REAL) printf("%s:%f\n", tbl->field, *(double*)pData); - - if (tbl->type == CSON_STRING) printf("%s:%s\n", tbl->field, *((char**)pData)); - - return NULL; -} - -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ -static void* freePointerSub(void* pData, const reflect_item_t* tbl) -{ - if (tbl->type == CSON_STRING) { - //printf("free field %s.\n", tbl->field); - free(*(void**)pData); - *(void**)pData = NULL; - }else if(tbl->type == CSON_ARRAY){ - //printf("free field %s.\n", tbl->field); - csonArrayFree(*(void**)pData); - *(void**)pData = NULL; - }else{ - - } - return NULL; -} -#else -static void* freePointerSub(void* pData, const reflect_item_t* tbl) -{ - if (tbl->type == CSON_ARRAY || tbl->type == CSON_STRING) { - //printf("free field %s.\n", tbl->field); - free(*(void**)pData); - *(void**)pData = NULL; - } - return NULL; -} -#endif - -void csonPrintProperty(void* pData, const reflect_item_t* tbl) -{ - /* 调用loopProperty迭代结构体中的属性,完成迭代输出属性值 */ - csonLoopProperty(pData, tbl, printPropertySub); -} - -void csonFreePointer(void* list, const reflect_item_t* tbl) -{ - /* 调用loopProperty迭代结构体中的属性,释放字符串和数组申请的内存空间 */ - csonLoopProperty(list, tbl, freePointerSub); -} - -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem){ char* pMem = (char*)malloc(count * sizePerItem + sizeof(cson_array_header_t)); @@ -1101,4 +983,109 @@ void csonFreeMultiDimenArray(void* p){ csonArrayFree(p); } } -#endif \ No newline at end of file + +int getJsonSingleArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +{ + int ret = ERR_NONE; + int countIndex = -1; + char* pSrc = (*(char**)((char*)input + tbl[index].offset)); + + if (pSrc == NULL) return ERR_MISSING_FIELD; + + void* ptr = csonGetProperty(input, tbl[index].arrayCountField, tbl, &countIndex); + + if (ptr == NULL || countIndex == -1) { + return ERR_MISSING_FIELD; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + + cson_t joArray = cson_array(); + + long long successCount = 0; + + for (long long i = 0; i < size; i++) { + cson_t jotmp; + + if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ + ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp); + } else { + jotmp = cson_object(); + ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + } + + if (ret == ERR_NONE) { + successCount++; + cson_array_add(joArray, jotmp); + } else { + printf("create array item faild.\n"); + cson_decref(jotmp); + } + } + + if (successCount == 0) { + cson_decref(joArray); + return ERR_MISSING_FIELD; + } else { + *obj = joArray; + return ERR_NONE; + } + + return ret; +} + +int parseJsonSingleArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) +{ + size_t arraySize = cson_array_size(jo_tmp); + + if (arraySize == 0) { + csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl); + return ERR_NONE; + } + + int countIndex = -1; + csonGetProperty(output, tbl[index].arrayCountField, tbl, &countIndex); + + if (countIndex == -1) { + return ERR_MISSING_FIELD; + } + + char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize); + if (pMem == NULL) return ERR_MEMORY; + + memset(pMem, 0, arraySize * tbl[index].arrayItemSize); + + long long successCount = 0; + for (size_t j = 0; j < arraySize; j++) { + cson_t item = cson_array_get(jo_tmp, j); + if (item != NULL) { + int ret; + + if (tbl[index].reflect_tbl[0].field[0] == '0') { /* field start with '0' mean basic types. */ + ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0); + } else { + ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl); + } + + if (ret == ERR_NONE) { + successCount++; + } + } + } + + integer_val_t val; + if (convertInteger(successCount, tbl[countIndex].size, &val) != ERR_NONE) { + successCount = 0; + } + + if (successCount == 0) { + csonSetPropertyFast(output, &successCount, tbl + countIndex); + free(pMem); + pMem = NULL; + csonSetPropertyFast(output, &pMem, tbl + index); + return ERR_MISSING_FIELD; + } else { + csonSetPropertyFast(output, &val, tbl + countIndex); + csonSetPropertyFast(output, &pMem, tbl + index); + return ERR_NONE; + } +} \ No newline at end of file From edf1c1090afb391a4b91ad3e8617529e958abea7 Mon Sep 17 00:00:00 2001 From: sunchb <448573057@qq.com> Date: Tue, 9 Jun 2020 10:37:17 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/Makefile | 2 - demo/main.c | 14 +-- demo/test.c | 11 +- demo/test2.c | 11 +- demo/test5.c | 126 ++++++++++------------ inc/cson.h | 100 ++++++++--------- src/cson.c | 289 ++++++++++++++++++++++++-------------------------- 7 files changed, 249 insertions(+), 304 deletions(-) diff --git a/demo/Makefile b/demo/Makefile index 3ffdae1..d16b4a6 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -27,8 +27,6 @@ OBJS += $(patsubst $(SRC_DIR)/%.c, $(OUT_DIR)/%.o, $(SRC_FILES)) OBJS += $(patsubst $(TEST_SRC_DIR)/%.c, $(OUT_DIR)/%.o, $(TEST_SRC_FILES)) OBJS += $(patsubst $(ADAP_DIR)/%.c, $(OUT_DIR)/%.o, $(ADAP_FILES)) -#CFLAGS += -D_CSON_MULTI_ARRAY_SUPPORT_ - $(TARGET):$(OBJS) @$(CC) $(LIB_PATH) -g $(OBJS) -o $(TARGET) -fprofile-arcs -ftest-coverage diff --git a/demo/main.c b/demo/main.c index 00a3014..bee1964 100644 --- a/demo/main.c +++ b/demo/main.c @@ -1,25 +1,15 @@ -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ -extern void test3(); -extern void test5(); -extern void test6(); -#else extern void test1(); extern void test2(); -#endif +extern void test5(); #include "cson.h" #include "stdio.h" int main() { -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ - test3(); - test5(); - test6(); -#else test1(); test2(); -#endif + test5(); return 0; } diff --git a/demo/test.c b/demo/test.c index c64b75d..11793fb 100644 --- a/demo/test.c +++ b/demo/test.c @@ -1,4 +1,3 @@ -#ifndef _CSON_MULTI_ARRAY_SUPPORT_ #include "cson.h" #include "stdio.h" #include "string.h" @@ -200,19 +199,20 @@ void test1() char* jstrOutput; ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl); CHECK_NUMBER(ret, 0); - printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); + //printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); /*assert check*/ checkResult(&playList, jstrOutput); free(jstrOutput); csonFreePointer(&playList, play_list_ref_tbl); - + printf("Successed %s.\n", __FUNCTION__); } -void checkResult(PlayList* playList, char* jstrOutput){ +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 */ @@ -259,8 +259,7 @@ void checkResult(PlayList* playList, char* jstrOutput){ 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); } -#endif \ No newline at end of file diff --git a/demo/test2.c b/demo/test2.c index 8c0ae79..22865a0 100644 --- a/demo/test2.c +++ b/demo/test2.c @@ -1,4 +1,3 @@ -#ifndef _CSON_MULTI_ARRAY_SUPPORT_ #include "cson.h" #include "stdio.h" #include "stdlib.h" @@ -94,7 +93,7 @@ void test2() char* jstrOutput; ret = csonStruct2JsonStr(&jstrOutput, &resp, ResponseTbl); CHECK_NUMBER(ret, 0); - printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); + //printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); /*assert check*/ checkResult(&resp, jstrOutput); @@ -105,8 +104,9 @@ void test2() printf("Successed %s.\n", __FUNCTION__); } -void checkResult(Response* resp, char* jstrOutput){ - +void checkResult(Response* resp, char* jstrOutput) +{ + CHECK_NUMBER(resp->status, 1); CHECK_NUMBER(resp->data.timestamp, 1579069151); CHECK_NUMBER(resp->data.infoNum, 9); @@ -235,5 +235,4 @@ void checkResult(Response* resp, char* jstrOutput){ CHECK_NUMBER(resp->data.info[8].childrenNum, 10); CHECK_STRING(jstrOutput, encodeTest); -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/demo/test5.c b/demo/test5.c index 039f8af..ad9a02b 100644 --- a/demo/test5.c +++ b/demo/test5.c @@ -1,10 +1,8 @@ -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ #include "cson.h" #include "stdio.h" #include "stdlib.h" #include "string.h" - #include "assert.h" #include "math.h" @@ -30,88 +28,76 @@ reflect_item_t data_ref_tbl[] = { }; reflect_item_t multi_array_ref_tbl[] = { - _property_array_int(MultiArrayTest, array, int, NULL, 3), - _property_array_string(MultiArrayTest, strArray, char*, NULL, 3), - _property_array_object(MultiArrayTest, objArray, data_ref_tbl, Data, NULL, 3), + _property_array_int(MultiArrayTest, array, int, NULL, 3), //3D array + _property_array_string(MultiArrayTest, strArray, char*, NULL, 3), //3D array + _property_array_object(MultiArrayTest, objArray, data_ref_tbl, Data, NULL, 3), //3D array _property_end() }; -void* freePointerOfArray(void* pData, const reflect_item_t* tbl) +static void checkResult(MultiArrayTest* testObj); + +const static char* testStr = "{\"array\":[[[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24],[25,26,27,28,29,30]],[[31,32,33,34,35,36],[37,38,39,40,41,42],[43,44,45,46,47,48],[49,50,51,52,53,54],[55,56,57,58,59,60]],[[61,62,63,64,65,66],[67,68,69,70,71,72],[73,74,75,76,77,78],[79,80,81,82,83,84],[85,86,87,88,89,90]],[[91,92,93,94,95,96],[97,98,99,100,101,102],[103,104,105,106,107,108],[109,110,111,112,113,114],[115,116,117,118,119,120]],[[121,122,123,124,125,126],[127,128,129,130,131,132],[133,134,135,136,137,138],[139,140,141,142,143,144],[145,146,147,148,149,150]]],\"strArray\":[[[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"]],[[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"]],[[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"]],[[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"]],[[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"],[\"str\",\"str\",\"str\",\"str\",\"str\",\"str\"]]],\"objArray\":[[[{\"name\":\"str\",\"num\":1000},{\"name\":\"str\",\"num\":1001},{\"name\":\"str\",\"num\":1002},{\"name\":\"str\",\"num\":1003},{\"name\":\"str\",\"num\":1004},{\"name\":\"str\",\"num\":1005}],[{\"name\":\"str\",\"num\":1006},{\"name\":\"str\",\"num\":1007},{\"name\":\"str\",\"num\":1008},{\"name\":\"str\",\"num\":1009},{\"name\":\"str\",\"num\":1010},{\"name\":\"str\",\"num\":1011}],[{\"name\":\"str\",\"num\":1012},{\"name\":\"str\",\"num\":1013},{\"name\":\"str\",\"num\":1014},{\"name\":\"str\",\"num\":1015},{\"name\":\"str\",\"num\":1016},{\"name\":\"str\",\"num\":1017}],[{\"name\":\"str\",\"num\":1018},{\"name\":\"str\",\"num\":1019},{\"name\":\"str\",\"num\":1020},{\"name\":\"str\",\"num\":1021},{\"name\":\"str\",\"num\":1022},{\"name\":\"str\",\"num\":1023}],[{\"name\":\"str\",\"num\":1024},{\"name\":\"str\",\"num\":1025},{\"name\":\"str\",\"num\":1026},{\"name\":\"str\",\"num\":1027},{\"name\":\"str\",\"num\":1028},{\"name\":\"str\",\"num\":1029}]],[[{\"name\":\"str\",\"num\":1030},{\"name\":\"str\",\"num\":1031},{\"name\":\"str\",\"num\":1032},{\"name\":\"str\",\"num\":1033},{\"name\":\"str\",\"num\":1034},{\"name\":\"str\",\"num\":1035}],[{\"name\":\"str\",\"num\":1036},{\"name\":\"str\",\"num\":1037},{\"name\":\"str\",\"num\":1038},{\"name\":\"str\",\"num\":1039},{\"name\":\"str\",\"num\":1040},{\"name\":\"str\",\"num\":1041}],[{\"name\":\"str\",\"num\":1042},{\"name\":\"str\",\"num\":1043},{\"name\":\"str\",\"num\":1044},{\"name\":\"str\",\"num\":1045},{\"name\":\"str\",\"num\":1046},{\"name\":\"str\",\"num\":1047}],[{\"name\":\"str\",\"num\":1048},{\"name\":\"str\",\"num\":1049},{\"name\":\"str\",\"num\":1050},{\"name\":\"str\",\"num\":1051},{\"name\":\"str\",\"num\":1052},{\"name\":\"str\",\"num\":1053}],[{\"name\":\"str\",\"num\":1054},{\"name\":\"str\",\"num\":1055},{\"name\":\"str\",\"num\":1056},{\"name\":\"str\",\"num\":1057},{\"name\":\"str\",\"num\":1058},{\"name\":\"str\",\"num\":1059}]],[[{\"name\":\"str\",\"num\":1060},{\"name\":\"str\",\"num\":1061},{\"name\":\"str\",\"num\":1062},{\"name\":\"str\",\"num\":1063},{\"name\":\"str\",\"num\":1064},{\"name\":\"str\",\"num\":1065}],[{\"name\":\"str\",\"num\":1066},{\"name\":\"str\",\"num\":1067},{\"name\":\"str\",\"num\":1068},{\"name\":\"str\",\"num\":1069},{\"name\":\"str\",\"num\":1070},{\"name\":\"str\",\"num\":1071}],[{\"name\":\"str\",\"num\":1072},{\"name\":\"str\",\"num\":1073},{\"name\":\"str\",\"num\":1074},{\"name\":\"str\",\"num\":1075},{\"name\":\"str\",\"num\":1076},{\"name\":\"str\",\"num\":1077}],[{\"name\":\"str\",\"num\":1078},{\"name\":\"str\",\"num\":1079},{\"name\":\"str\",\"num\":1080},{\"name\":\"str\",\"num\":1081},{\"name\":\"str\",\"num\":1082},{\"name\":\"str\",\"num\":1083}],[{\"name\":\"str\",\"num\":1084},{\"name\":\"str\",\"num\":1085},{\"name\":\"str\",\"num\":1086},{\"name\":\"str\",\"num\":1087},{\"name\":\"str\",\"num\":1088},{\"name\":\"str\",\"num\":1089}]],[[{\"name\":\"str\",\"num\":1090},{\"name\":\"str\",\"num\":1091},{\"name\":\"str\",\"num\":1092},{\"name\":\"str\",\"num\":1093},{\"name\":\"str\",\"num\":1094},{\"name\":\"str\",\"num\":1095}],[{\"name\":\"str\",\"num\":1096},{\"name\":\"str\",\"num\":1097},{\"name\":\"str\",\"num\":1098},{\"name\":\"str\",\"num\":1099},{\"name\":\"str\",\"num\":1100},{\"name\":\"str\",\"num\":1101}],[{\"name\":\"str\",\"num\":1102},{\"name\":\"str\",\"num\":1103},{\"name\":\"str\",\"num\":1104},{\"name\":\"str\",\"num\":1105},{\"name\":\"str\",\"num\":1106},{\"name\":\"str\",\"num\":1107}],[{\"name\":\"str\",\"num\":1108},{\"name\":\"str\",\"num\":1109},{\"name\":\"str\",\"num\":1110},{\"name\":\"str\",\"num\":1111},{\"name\":\"str\",\"num\":1112},{\"name\":\"str\",\"num\":1113}],[{\"name\":\"str\",\"num\":1114},{\"name\":\"str\",\"num\":1115},{\"name\":\"str\",\"num\":1116},{\"name\":\"str\",\"num\":1117},{\"name\":\"str\",\"num\":1118},{\"name\":\"str\",\"num\":1119}]],[[{\"name\":\"str\",\"num\":1120},{\"name\":\"str\",\"num\":1121},{\"name\":\"str\",\"num\":1122},{\"name\":\"str\",\"num\":1123},{\"name\":\"str\",\"num\":1124},{\"name\":\"str\",\"num\":1125}],[{\"name\":\"str\",\"num\":1126},{\"name\":\"str\",\"num\":1127},{\"name\":\"str\",\"num\":1128},{\"name\":\"str\",\"num\":1129},{\"name\":\"str\",\"num\":1130},{\"name\":\"str\",\"num\":1131}],[{\"name\":\"str\",\"num\":1132},{\"name\":\"str\",\"num\":1133},{\"name\":\"str\",\"num\":1134},{\"name\":\"str\",\"num\":1135},{\"name\":\"str\",\"num\":1136},{\"name\":\"str\",\"num\":1137}],[{\"name\":\"str\",\"num\":1138},{\"name\":\"str\",\"num\":1139},{\"name\":\"str\",\"num\":1140},{\"name\":\"str\",\"num\":1141},{\"name\":\"str\",\"num\":1142},{\"name\":\"str\",\"num\":1143}],[{\"name\":\"str\",\"num\":1144},{\"name\":\"str\",\"num\":1145},{\"name\":\"str\",\"num\":1146},{\"name\":\"str\",\"num\":1147},{\"name\":\"str\",\"num\":1148},{\"name\":\"str\",\"num\":1149}]]]}"; + +void test5() { - if(tbl->type == CSON_ARRAY){ - csonArrayFree(*(void**)pData); - *(void**)pData = NULL; - } - - return NULL; -} - -void test5(){ - cson_array_size_t dimenSize[3] = {10, 10, 10}; - + printf("=========================================\n"); + printf("\t\tRunning %s\n", __FUNCTION__); + printf("=========================================\n"); MultiArrayTest testObj; - testObj.array = (int***)csonAllocMultiDimenArray(3, dimenSize, sizeof(int)); - testObj.strArray = (char****)csonAllocMultiDimenArray(3, dimenSize, sizeof(char*)); - testObj.objArray = (Data***)csonAllocMultiDimenArray(3, dimenSize, sizeof(Data)); - char* testStr = "str"; - - int num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - testObj.array[i][j][k] = num++; - testObj.strArray[i][j][k] = testStr; - testObj.objArray[i][j][k].num = num++; - testObj.objArray[i][j][k].name = testStr; - } - } - } - - num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - CHECK_NUMBER(testObj.array[i][j][k], num++); - CHECK_NUMBER(testObj.objArray[i][j][k].num, num++); - } - } - } - - char* jstrOutput; - int ret = csonStruct2JsonStr(&jstrOutput, &testObj, multi_array_ref_tbl); - printf("encode ret=%d\nJson:%s\n", ret, jstrOutput); - - free(jstrOutput); - csonLoopProperty(&testObj, multi_array_ref_tbl, freePointerOfArray); + int ret = csonJsonStr2Struct(testStr, &testObj, multi_array_ref_tbl); + CHECK_NUMBER(ret, 0); + checkResult(&testObj); + csonFreePointer(&testObj, multi_array_ref_tbl); + printf("Successed %s.\n", __FUNCTION__); } -void test6(){ - cson_array_size_t dimenSize[4] = {10, 10, 10, 100}; - int**** pArray3D = (int****)csonAllocMultiDimenArray(4, dimenSize, sizeof(int)); - int num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - for(int m = 0; m < dimenSize[3]; m++){ - pArray3D[i][j][k][m] = num++; - } +void checkResult(MultiArrayTest* testObj) +{ + CHECK_NUMBER(array_size(testObj->array), 5); + CHECK_NUMBER(array_size(testObj->strArray), 5); + CHECK_NUMBER(array_size(testObj->objArray), 5); + CHECK_NUMBER(array_dimen(testObj->array), 3); + CHECK_NUMBER(array_dimen(testObj->strArray), 3); + CHECK_NUMBER(array_dimen(testObj->objArray), 3); + + int temp = 1; + for (int i = 0; i < array_size(testObj->array); i++) { + CHECK_NUMBER(array_size(testObj->array[i]), 5); + CHECK_NUMBER(array_dimen(testObj->array[i]), 2); + for (int j = 0; j < array_size(testObj->array[i]); j++) { + CHECK_NUMBER(array_size(testObj->array[i][j]), 6); + CHECK_NUMBER(array_dimen(testObj->array[i][j]), 1); + for (int k = 0; k < array_size(testObj->array[i][j]); k++) { + CHECK_NUMBER(testObj->array[i][j][k], temp++); } } } - num = 1; - for(int i = 0; i < dimenSize[0]; i++){ - for(int j = 0; j < dimenSize[1]; j++){ - for(int k = 0; k < dimenSize[2]; k++){ - for(int m = 0; m < dimenSize[3]; m++){ - CHECK_NUMBER(pArray3D[i][j][k][m], num++); - } + for (int i = 0; i < array_size(testObj->strArray); i++) { + CHECK_NUMBER(array_size(testObj->strArray[i]), 5); + CHECK_NUMBER(array_dimen(testObj->strArray[i]), 2); + for (int j = 0; j < array_size(testObj->strArray[i]); j++) { + CHECK_NUMBER(array_size(testObj->strArray[i][j]), 6); + CHECK_NUMBER(array_dimen(testObj->strArray[i][j]), 1); + for (int k = 0; k < array_size(testObj->strArray[i][j]); k++) { + CHECK_STRING(testObj->strArray[i][j][k], "str"); } } } - csonFreeMultiDimenArray(pArray3D); -} -#endif \ No newline at end of file + temp = 1000; + for (int i = 0; i < array_size(testObj->objArray); i++) { + CHECK_NUMBER(array_size(testObj->objArray[i]), 5); + CHECK_NUMBER(array_dimen(testObj->objArray[i]), 2); + for (int j = 0; j < array_size(testObj->objArray[i]); j++) { + CHECK_NUMBER(array_size(testObj->objArray[i][j]), 6); + CHECK_NUMBER(array_dimen(testObj->objArray[i][j]), 1); + for (int k = 0; k < array_size(testObj->objArray[i][j]); k++) { + CHECK_STRING(testObj->objArray[i][j][k].name, "str"); + CHECK_NUMBER(testObj->objArray[i][j][k].num, temp++); + } + } + } +} \ No newline at end of file diff --git a/inc/cson.h b/inc/cson.h index d61ca3d..70d186f 100644 --- a/inc/cson.h +++ b/inc/cson.h @@ -39,7 +39,7 @@ typedef void* cson_t; */ typedef cson_t (*func_cson_object_get)(const cson_t object, const char* key); typedef cson_type (*func_cson_typeof)(cson_t object); -typedef cson_t (*func_cson_loadb)(const char *buffer, size_t buflen); +typedef cson_t (*func_cson_loadb)(const char* buffer, size_t buflen); typedef void (*func_cson_decref)(cson_t object); typedef const char* (*func_cson_string_value)(const cson_t object); typedef size_t (*func_cson_string_length)(const cson_t object); @@ -96,8 +96,8 @@ typedef struct reflect_item_t { cson_type type; /**< corresponding json type */ 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 */ - const char* arrayCountField; /**< field saving array size */ - int arrayDimensional; + const char* arrayCountField; /**< field saving array size. Valid only for one-dimensional arrays, because the size of a multidimensional array cannot be saved in one number. */ + int arrayDimensional; /**< dimension of array */ int exArgs; /**< paser return failure when the field is not found and nullable equals to 0 */ } reflect_item_t; @@ -170,6 +170,7 @@ extern const reflect_item_t realReflectTbl[]; * @param tbl: property description table of type of array * @param subType: type of array * @param count: property to save the array size + * @param dimen: dimension of array * */ #define _property_array(type, field, tbl, subType, count, dimen) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, dimen, _ex_args_nullable} @@ -184,17 +185,17 @@ extern const reflect_item_t realReflectTbl[]; * * @param refer to comment of nullable definition */ -#define _property_int_nonull(type, field) _property(type, field, CSON_INTEGER, NULL, 0) -#define _property_real_nonull(type, field) _property(type, field, CSON_REAL, NULL, 0) -#define _property_bool_nonull(type, field) _property(type, field, CSON_TRUE, NULL, 0) -#define _property_string_nonull(type, field) _property(type, field, CSON_STRING, NULL, 0) -#define _property_obj_nonull(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, 0) -#define _property_array_nonull(type, field, tbl, subType, count, dimen) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, dimen, 0} -#define _property_array_object_nonull(type, field, tbl, subType, count, dimen) _property_array_nonull(type, field, tbl, subType, count, dimen) -#define _property_array_int_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, integerReflectTbl, subType, count, dimen) -#define _property_array_string_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, stringReflectTbl, subType, count, dimen) -#define _property_array_real_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, realReflectTbl, subType, count, dimen) -#define _property_array_bool_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, boolReflectTbl, subType, count, dimen) +// #define _property_int_nonull(type, field) _property(type, field, CSON_INTEGER, NULL, 0) +// #define _property_real_nonull(type, field) _property(type, field, CSON_REAL, NULL, 0) +// #define _property_bool_nonull(type, field) _property(type, field, CSON_TRUE, NULL, 0) +// #define _property_string_nonull(type, field) _property(type, field, CSON_STRING, NULL, 0) +// #define _property_obj_nonull(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, 0) +// #define _property_array_nonull(type, field, tbl, subType, count, dimen) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, dimen, 0} +// #define _property_array_object_nonull(type, field, tbl, subType, count, dimen) _property_array_nonull(type, field, tbl, subType, count, dimen) +// #define _property_array_int_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, integerReflectTbl, subType, count, dimen) +// #define _property_array_string_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, stringReflectTbl, subType, count, dimen) +// #define _property_array_real_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, realReflectTbl, subType, count, dimen) +// #define _property_array_bool_nonull(type, field, subType, count, dimen) _property_array_nonull(type, field, boolReflectTbl, subType, count, dimen) /** * @brief nonull definitions. parser will stop and return error code when field not found which declared whit it. @@ -303,44 +304,6 @@ void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem); */ void csonArrayFree(void* ptr); -/** - * @brief get size(item count) of array - * - * @param ptr: array - * - * @return cson_array_size_t. - */ -cson_array_size_t csonArrayGetSize(void* ptr); - -/** - * @brief set size(item count) of array - * - * @param ptr: array - * @param size: size - * - * @return cson_array_size_t. - */ -void csonArraySetSize(void* ptr, cson_array_size_t size); - -/** - * @brief set dimension of array - * - * @param ptr: array - * @param dimen: dimension - * - * @return cson_array_size_t. - */ -void csonArraySetDimen(void* ptr, int dimen); - -/** - * @brief get dimension of array - * - * @param ptr: array - * - * @return cson_array_size_t. - */ -int csonArrayGetDimen(void* ptr); - /** * @brief fast alloc multi-dimen array * @@ -353,11 +316,34 @@ int csonArrayGetDimen(void* ptr); void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_t sizeOfItem); /** - * @brief fast free multi-dimen array - * - * @param p: pointer of array. - * - * @return void*. + * @brief the description of multidimensional array. */ void csonFreeMultiDimenArray(void* p); +typedef struct { + cson_array_size_t size; + cson_array_size_t cap; + int dimen; +} cson_array_header_t; + +/** + * @brief get/set size of array + * + * @param p: pointer of array. + */ +#define array_size(p) ((((cson_array_header_t*)p) - 1)->size) + +/** + * @brief get/set dimen of array + * + * @param p: pointer of array. + */ +#define array_dimen(p) ((((cson_array_header_t*)p) - 1)->dimen) + +/** + * @brief get/set capability of array + * + * @param p: pointer of array. + */ +#define array_cap(p) ((((cson_array_header_t*)p) - 1)->cap) + #endif \ No newline at end of file diff --git a/src/cson.c b/src/cson.c index 0623881..6671c8b 100644 --- a/src/cson.c +++ b/src/cson.c @@ -144,25 +144,21 @@ json_obj_proc jsonObjDefaultTbl[] = { static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl); -typedef struct { - cson_array_size_t size; - int dimen; -} cson_array_header_t; - typedef struct { cson_array_header_t header; void* ptr; } cson_array_t; -static int getJsonSingleArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj); -static int parseJsonSingleArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index); -static cson_t getJsonMultiArraySub(void* ptr, const reflect_item_t* tbl, int index); -static cson_t getJsonMultiArrayTail(void* ptr, const reflect_item_t* tbl, int index); -static int getJsonMultiArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj); -static int parseJsonMultiArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index); -static void* parseJsonMultiArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); -static void* parseJsonMultiArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); -static void csonLoopPropertyMultiArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func); +static int getJson1DArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj); +static int parseJson1DArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index); +static cson_t getJsonMDArraySub(void* ptr, const reflect_item_t* tbl, int index); +static cson_t getJsonMDArrayTail(void* ptr, const reflect_item_t* tbl, int index); +static int getJsonMDArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj); +static int parseJsonMDArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index); +static void* parseJsonMDArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen); +static void* parseJsonMDArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index); +static void csonLoopPropertyMDArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func); +static int invalidCountField(const reflect_item_t* tbl); int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl) { @@ -195,7 +191,7 @@ int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl) while (1) { if (tbl[i].field == NULL) break; - if(tbl[i].exArgs & _ex_args_exclude_encode){ + if (tbl[i].exArgs & _ex_args_exclude_encode) { i++; continue; } @@ -267,12 +263,11 @@ int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) { -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ - return getJsonMultiArray(input, tbl, index, obj); -#else - return getJsonSingleArray(input, tbl, index, obj); -#endif - + if (invalidCountField(tbl + index)) { + return getJsonMDArray(input, tbl, index, obj); + } else { + return getJson1DArray(input, tbl, index, obj); + } } int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj) @@ -335,8 +330,8 @@ int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl) for (int i = 0;; i++) { int ret = ERR_NONE; if (tbl[i].field == NULL) break; - - if(tbl[i].exArgs & _ex_args_exclude_decode){ + + if (tbl[i].exArgs & _ex_args_exclude_decode) { continue; } @@ -408,11 +403,11 @@ int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ - return parseJsonMultiArray(jo_tmp, output, tbl, index); -#else - return parseJsonSingleArray(jo_tmp, output, tbl, index); -#endif + if (invalidCountField(tbl + index)) { + return parseJsonMDArray(jo_tmp, output, tbl, index); + } else { + return parseJson1DArray(jo_tmp, output, tbl, index); + } } int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) @@ -452,8 +447,8 @@ int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tb int i = 0; while (1) { if (tbl[i].reflect_tbl[i].field == NULL) break; - - if(tbl[i].exArgs & _ex_args_exclude_decode){ + + if (tbl[i].exArgs & _ex_args_exclude_decode) { i++; continue; } @@ -658,25 +653,25 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func) char* pProperty = (char*)pData + tbl[i].offset; if (tbl[i].type == CSON_ARRAY) { -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ - if(pProperty == NULL){ - i++; - continue; - } - csonLoopPropertyMultiArraySub(pProperty, tbl, i, tbl[i].arrayDimensional, func); -#else - int countIndex = -1; - void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); + if (invalidCountField(tbl + i)) { + if (pProperty == NULL) { + i++; + continue; + } + csonLoopPropertyMDArraySub(pProperty, tbl, i, tbl[i].arrayDimensional, func); + } else { + int countIndex = -1; + void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex); - if (ptr == NULL || countIndex == -1) { - continue; - } - long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); + if (ptr == NULL || countIndex == -1) { + continue; + } + long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size); - for (long long j = 0; j < size; j++) { - csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); + for (long long j = 0; j < size; j++) { + csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); + } } -#endif } else if (tbl[i].type == CSON_OBJECT) { csonLoopProperty(pProperty, tbl[i].reflect_tbl, func); } @@ -706,16 +701,16 @@ static void* freePointerSub(void* pData, const reflect_item_t* tbl) //printf("free field %s.\n", tbl->field); free(*(void**)pData); *(void**)pData = NULL; - }else if(tbl->type == CSON_ARRAY){ -#ifdef _CSON_MULTI_ARRAY_SUPPORT_ + } else if (tbl->type == CSON_ARRAY) { //printf("free field %s.\n", tbl->field); - csonArrayFree(*(void**)pData); - *(void**)pData = NULL; -#else - free(*(void**)pData); - *(void**)pData = NULL; -#endif - }else{ + if (invalidCountField(tbl)) { + csonArrayFree(*(void**)pData); + *(void**)pData = NULL; + } else { + free(*(void**)pData); + *(void**)pData = NULL; + } + } else { } return NULL; @@ -723,31 +718,35 @@ static void* freePointerSub(void* pData, const reflect_item_t* tbl) void csonPrintProperty(void* pData, const reflect_item_t* tbl) { - /* 调用loopProperty迭代结构体中的属性,完成迭代输出属性值 */ csonLoopProperty(pData, tbl, printPropertySub); } void csonFreePointer(void* list, const reflect_item_t* tbl) { - /* 调用loopProperty迭代结构体中的属性,释放字符串和数组申请的内存空间 */ csonLoopProperty(list, tbl, freePointerSub); } -cson_t getJsonMultiArraySub(void* ptr, const reflect_item_t* tbl, int index){ - int dimen = csonArrayGetDimen(ptr); - if(csonArrayGetDimen(ptr) == 1){ - return getJsonMultiArrayTail(ptr, tbl, index); - }else{ +int invalidCountField(const reflect_item_t* tbl) +{ + return tbl->arrayDimensional > 1 || tbl->arrayCountField == NULL; +} + +/* Multidimensional array functions */ +cson_t getJsonMDArraySub(void* ptr, const reflect_item_t* tbl, int index) +{ + if (array_dimen(ptr) == 1) { + return getJsonMDArrayTail(ptr, tbl, index); + } else { cson_t joArray = cson_array(); - cson_array_size_t size = csonArrayGetSize(ptr); + cson_array_size_t size = array_size(ptr); cson_array_size_t successCount = 0; - for(cson_array_size_t i = 0; i < size; i++){ + for (cson_array_size_t i = 0; i < size; i++) { void** p = (void**)ptr; - cson_t jotmp = getJsonMultiArraySub(p[i], tbl, index); + cson_t jotmp = getJsonMDArraySub(p[i], tbl, index); - if(jotmp != NULL){ + if (jotmp != NULL) { successCount++; cson_array_add(joArray, jotmp); } @@ -762,8 +761,9 @@ cson_t getJsonMultiArraySub(void* ptr, const reflect_item_t* tbl, int index){ } } -cson_t getJsonMultiArrayTail(void* ptr, const reflect_item_t* tbl, int index){ - cson_array_size_t size = csonArrayGetSize(ptr); +cson_t getJsonMDArrayTail(void* ptr, const reflect_item_t* tbl, int index) +{ + cson_array_size_t size = array_size(ptr); cson_t joArray = cson_array(); cson_array_size_t successCount = 0; @@ -796,7 +796,7 @@ cson_t getJsonMultiArrayTail(void* ptr, const reflect_item_t* tbl, int index){ return joArray; } -int getJsonMultiArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +int getJsonMDArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) { int ret = ERR_NONE; int countIndex = -1; @@ -804,48 +804,52 @@ int getJsonMultiArray(void* input, const reflect_item_t* tbl, int index, cson_t* if (pSrc == NULL) return ERR_MISSING_FIELD; - *obj = getJsonMultiArraySub(pSrc, tbl, index); - if(*obj == NULL) return ERR_MISSING_FIELD; + *obj = getJsonMDArraySub(pSrc, tbl, index); + if (*obj == NULL) return ERR_MISSING_FIELD; return ret; } -int parseJsonMultiArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ - void* pRet = parseJsonMultiArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); + +int parseJsonMDArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) +{ + void* pRet = parseJsonMDArraySub(jo_tmp, tbl, index, tbl[index].arrayDimensional); csonSetPropertyFast(output, &pRet, tbl + index); return ERR_NONE; } -void* parseJsonMultiArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen){ - if(dimen == 1){ - return parseJsonMultiArrayTail(jo_tmp, tbl, index); - }else{ +void* parseJsonMDArraySub(cson_t jo_tmp, const reflect_item_t* tbl, int index, int dimen) +{ + if (dimen == 1) { + return parseJsonMDArrayTail(jo_tmp, tbl, index); + } else { cson_array_size_t arraySize = cson_array_size(jo_tmp); - if(arraySize == 0) return NULL; + if (arraySize == 0) return NULL; void** pMem = (void**)csonArrayAlloc(arraySize, sizeof(void*)); - csonArraySetDimen(pMem, dimen); - + array_dimen(pMem) = dimen; + cson_array_size_t successCount = 0; - for(cson_array_size_t i = 0; i < arraySize; i++){ + for (cson_array_size_t i = 0; i < arraySize; i++) { cson_t item = cson_array_get(jo_tmp, i); - if(cson_typeof(item) != CSON_ARRAY) continue; - void* p = parseJsonMultiArraySub(item, tbl, index, dimen - 1); - if(p != NULL){ + if (cson_typeof(item) != CSON_ARRAY) continue; + void* p = parseJsonMDArraySub(item, tbl, index, dimen - 1); + if (p != NULL) { pMem[successCount++] = p; } } - if(successCount == 0){ + if (successCount == 0) { csonArrayFree(pMem); return NULL; - }else{ - csonArraySetSize(pMem, successCount); + } else { + array_size(pMem) = successCount; return (void*)pMem; } } } -void* parseJsonMultiArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index){ +void* parseJsonMDArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int index) +{ size_t arraySize = cson_array_size(jo_tmp); if (arraySize == 0) { return NULL; @@ -853,11 +857,11 @@ void* parseJsonMultiArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int inde char* pMem = (char*)csonArrayAlloc(arraySize, tbl[index].arrayItemSize); if (pMem == NULL) return NULL; - + memset(pMem, 0, arraySize * tbl[index].arrayItemSize); - - csonArraySetDimen(pMem, 1); - + + array_dimen(pMem) = 1; + cson_array_size_t successCount = 0; for (cson_array_size_t j = 0; j < arraySize; j++) { @@ -880,111 +884,94 @@ void* parseJsonMultiArrayTail(cson_t jo_tmp, const reflect_item_t* tbl, int inde if (successCount == 0) { csonArrayFree(pMem); pMem = NULL; - }else{ - csonArraySetSize(pMem, successCount); + } else { + array_size(pMem) = successCount; } return pMem; } -void csonLoopPropertyMultiArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func){ - if(pProperty == NULL){ + +void csonLoopPropertyMDArraySub(void* pProperty, const reflect_item_t* tbl, int i, int dimen, loop_func_t func) +{ + if (pProperty == NULL) { return; } void* ptr = *((void**)pProperty); - cson_array_size_t size = csonArrayGetSize(ptr); + cson_array_size_t size = array_size(ptr); - if(dimen == 1){ + if (dimen == 1) { for (cson_array_size_t j = 0; j < size; j++) { csonLoopProperty(((char*)ptr) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func); } - }else{ + } else { for (cson_array_size_t j = 0; j < size; j++) { void** p = (void**)ptr; - csonLoopPropertyMultiArraySub(p + j, tbl, i, dimen - 1, func); + csonLoopPropertyMDArraySub(p + j, tbl, i, dimen - 1, func); } } func(pProperty, tbl + i); } -void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem){ - char* pMem = (char*)malloc(count * sizePerItem + sizeof(cson_array_header_t)); +void* csonArrayAlloc(cson_array_size_t count, cson_array_size_t sizePerItem) +{ + cson_array_header_t* pMem = (cson_array_header_t*)malloc(count * sizePerItem + sizeof(cson_array_header_t)); - if(!pMem) return NULL; + if (!pMem) return NULL; - return pMem + sizeof(cson_array_header_t); + pMem->cap = count; + pMem->size = 0; + + return pMem + 1; } -void csonArrayFree(void* ptr){ - if(!ptr) return; - char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); - free(pArrayHeader); +void csonArrayFree(void* ptr) +{ + if (!ptr) return; + free(((cson_array_header_t*)ptr) - 1); } -cson_array_size_t csonArrayGetSize(void* ptr){ - if(!ptr) return 0; - char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); - return ((cson_array_header_t*)pArrayHeader)->size; -} +void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_t sizeOfItem) +{ + if (dimen <= 0 || !sizePerDimen || sizeOfItem == 0) return NULL; -void csonArraySetSize(void* ptr, cson_array_size_t size){ - if(!ptr) return; - char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); - ((cson_array_header_t*)pArrayHeader)->size = size; -} - -int csonArrayGetDimen(void* ptr){ - if(!ptr) return 0; - char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); - return ((cson_array_header_t*)pArrayHeader)->dimen; -} - -void csonArraySetDimen(void* ptr, int dimen){ - if(!ptr) return; - char* pArrayHeader = ((char*)ptr) - sizeof(cson_array_header_t); - ((cson_array_header_t*)pArrayHeader)->dimen = dimen; -} - -void* csonAllocMultiDimenArray(int dimen, cson_array_size_t* sizePerDimen, size_t sizeOfItem){ - if(dimen <= 0 || !sizePerDimen || sizeOfItem == 0) return NULL; - - if(dimen == 1){ + if (dimen == 1) { void* p = csonArrayAlloc(sizePerDimen[0], sizeOfItem); - csonArraySetSize(p, sizePerDimen[0]); - csonArraySetDimen(p, dimen); + array_dimen(p) = dimen; + array_size(p) = sizePerDimen[0]; return p; - }else{ + } else { void** p = (void**)csonArrayAlloc(sizePerDimen[0], sizeof(void*)); - for(int i = 0; i < sizePerDimen[0]; i++){ + for (int i = 0; i < sizePerDimen[0]; i++) { p[i] = csonAllocMultiDimenArray(dimen - 1, sizePerDimen + 1, sizeOfItem); } - csonArraySetSize(p, sizePerDimen[0]); - csonArraySetDimen(p, dimen); + array_dimen(p) = dimen; + array_size(p) = sizePerDimen[0]; return (void*)p; } } -void csonFreeMultiDimenArray(void* p){ - if(!p) return; +void csonFreeMultiDimenArray(void* p) +{ + if (!p) return; - int dimen = csonArrayGetDimen(p); - - if(dimen == 1){ + if (array_dimen(p) == 1) { csonArrayFree(p); - }else{ - cson_array_size_t size = csonArrayGetSize(p); + } else { + cson_array_size_t size = array_size(p); void** ptr = (void**)p; - for(int i = 0; i < size; i++){ + for (int i = 0; i < size; i++) { csonFreeMultiDimenArray(ptr[i]); } csonArrayFree(p); } } -int getJsonSingleArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) +/* one dimensional array functions */ +int getJson1DArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj) { int ret = ERR_NONE; int countIndex = -1; @@ -1033,7 +1020,7 @@ int getJsonSingleArray(void* input, const reflect_item_t* tbl, int index, cson_t return ret; } -int parseJsonSingleArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) +int parseJson1DArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) { size_t arraySize = cson_array_size(jo_tmp);