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] =?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);