fix array size process

This commit is contained in:
孙传宝 2020-03-19 01:09:10 +08:00
parent eddf45f4c6
commit 03abd19fdb
4 changed files with 72 additions and 73 deletions

View File

@ -104,11 +104,9 @@ typedef struct {
int duration;
int paid;
double price;
size_t lyricNum;
Lyric* lyric;
size_t keyNum;
int* key;
size_t strNum;
char** strList;
} SongInfo;
@ -120,7 +118,6 @@ typedef struct {
typedef struct {
char* name;
char* creater;
size_t songNum;
SongInfo* songList;
ExtData extData;
} PlayList;
@ -142,12 +139,10 @@ reflect_item_t song_ref_tbl[] = {
_property_int(SongInfo, duration),
_property_bool(SongInfo, paid),
_property_real(SongInfo, price),
_property_int(SongInfo, lyricNum),
_property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric, lyricNum),
_property_array_object(SongInfo, lyric, lyric_ref_tbl, Lyric),
_property_int(SongInfo, keyNum),
_property_array_int(SongInfo, key, int, keyNum),
_property_int(SongInfo, strNum),
_property_array_string(SongInfo, strList, char*, strNum),
_property_array_int(SongInfo, key, int),
_property_array_string(SongInfo, strList, char*),
_property_end()
};
@ -160,8 +155,7 @@ reflect_item_t ext_data_ref_tbl[] = {
reflect_item_t play_list_ref_tbl[] = {
_property_string(PlayList, name),
_property_string(PlayList, creater),
_property_int(PlayList, songNum),
_property_array_object(PlayList, songList, song_ref_tbl, SongInfo, songNum),
_property_array_object(PlayList, songList, song_ref_tbl, SongInfo),
_property_obj(PlayList, extData, ext_data_ref_tbl),
_property_end()
};
@ -187,6 +181,8 @@ void test1()
printf("ret=%d\n", ret);
csonPrintProperty(&playList, play_list_ref_tbl);
size_t s = csonGetArraySizeByField(&playList, "songList", play_list_ref_tbl);
char* jstrOutput;
ret = csonStruct2JsonStr(&jstrOutput, &playList, play_list_ref_tbl);
printf("ret=%d\nJson:%s\n", ret, jstrOutput);

View File

@ -12,13 +12,11 @@ typedef struct {
char* icon;
int id;
char* name;
char childrenNum;
ClassInfoChild* children;
} ClassInfo;
typedef struct {
long long timestamp;
int infoNum;
ClassInfo* info;
} Data;
@ -39,15 +37,13 @@ reflect_item_t ClassInfoTbl[] = {
_property_string(ClassInfo, icon),
_property_int(ClassInfo, id),
_property_string(ClassInfo, name),
_property_int(ClassInfo, childrenNum),
_property_array_object(ClassInfo, children, ClassInfoChildTbl, ClassInfoChild, childrenNum),
_property_array_object(ClassInfo, children, ClassInfoChildTbl, ClassInfoChild),
_property_end()
};
reflect_item_t DataTbl[] = {
_property_int(Data, timestamp),
_property_int(Data, infoNum),
_property_array_object(Data, info, ClassInfoTbl, ClassInfo, infoNum),
_property_array_object(Data, info, ClassInfoTbl, ClassInfo),
_property_end()
};

View File

@ -34,6 +34,8 @@ typedef enum {
typedef void* cson_t;
typedef size_t cson_array_size_t;
/**
* @brief define the function type of json parse/pack function group
*/
@ -95,8 +97,7 @@ typedef struct reflect_item_t {
size_t size; /**< size of property */
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 */
char* arrayCountField; /**< field saving array size */
size_t arrayItemSize; /**< size of per array item. must be specified when type is array */
int nullable; /**< paser return failure when the field is not found and nullable equals to 0 */
} reflect_item_t;
@ -107,8 +108,8 @@ extern const reflect_item_t realReflectTbl[];
#define _offset(type, field) (&(((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, nullable}
#define _property_end() {NULL, 0, 0, CSON_NULL, NULL, 0, 1}
/**
* @brief Declaring integer properties.
@ -163,15 +164,14 @@ extern const reflect_item_t realReflectTbl[];
* @param field: field name of properties
* @param tbl: property description table of type of array
* @param subType: type of array
* @param count: property to save the array size
*
*/
#define _property_array(type, field, tbl, subType, count) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, 1}
#define _property_array_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) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), 1}
#define _property_array_object(type, field, tbl, subType) _property_array(type, field, tbl, subType)
#define _property_array_int(type, field, subType) _property_array(type, field, integerReflectTbl, subType)
#define _property_array_string(type, field, subType) _property_array(type, field, stringReflectTbl, subType)
#define _property_array_real(type, field, subType) _property_array(type, field, realReflectTbl, subType)
#define _property_array_bool(type, field, subType) _property_array(type, field, boolReflectTbl, subType)
/**
* @brief nonull definitions. parser will stop and return error code when field not found which declared whit it.
@ -183,12 +183,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) {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), 0}
#define _property_array_object_nonull(type, field, tbl, subType) _property_array_nonull(type, field, tbl, subType, count)
#define _property_array_int_nonull(type, field, subType) _property_array_nonull(type, field, integerReflectTbl, subType)
#define _property_array_string_nonull(type, field, subType) _property_array_nonull(type, field, stringReflectTbl, subType)
#define _property_array_real_nonull(type, field, subType) _property_array_nonull(type, field, realReflectTbl, subType)
#define _property_array_bool_nonull(type, field, subType) _property_array_nonull(type, field, boolReflectTbl, subType)
/**
* @brief function type of csonLoopProperty.
@ -253,4 +253,9 @@ void csonPrintProperty(void* pData, const reflect_item_t* tbl);
*/
void csonFreePointer(void* list, const reflect_item_t* tbl);
cson_array_size_t csonGetArraySize(void* pArray);
cson_array_size_t csonGetArraySizeByField(void* pData, const char* field, const reflect_item_t* tbl);
#endif

View File

@ -35,22 +35,22 @@ extern cson_interface csomImpl;
#define cson_is_bool(type) (type == CSON_TRUE || type == CSON_FALSE)
const reflect_item_t integerReflectTbl[] = {
{"0Integer", 0, sizeof(int), CSON_INTEGER, NULL, 0, NULL, 1},
{"0Integer", 0, sizeof(int), CSON_INTEGER, NULL, 0, 1},
{}
};
const reflect_item_t stringReflectTbl[] = {
{"0String", 0, sizeof(char*), CSON_STRING, NULL, 0, NULL, 1},
{"0String", 0, sizeof(char*), CSON_STRING, NULL, 0, 1},
{}
};
const reflect_item_t realReflectTbl[] = {
{"0Real", 0, sizeof(double), CSON_REAL, NULL, 0, NULL, 1},
{"0Real", 0, sizeof(double), CSON_REAL, NULL, 0, 1},
{}
};
const reflect_item_t boolReflectTbl[] = {
{"0Bool", 0, sizeof(int), CSON_TRUE, NULL, 0, NULL, 1},
{"0Bool", 0, sizeof(int), CSON_TRUE, NULL, 0, 1},
{}
};
@ -248,18 +248,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 = *((cson_array_size_t*)(pSrc - sizeof(cson_array_size_t)));
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. */
@ -421,30 +416,24 @@ int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int i
size_t arraySize = cson_array_size(jo_tmp);
if (arraySize == 0) {
csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl);
char* pTemp = NULL;
csonSetPropertyFast(output, &pTemp, tbl + index);
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);
char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize + sizeof(cson_array_size_t));
if (pMem == NULL) return ERR_MEMORY;
long long successCount = 0;
for (size_t j = 0; j < arraySize; j++) {
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);
ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + sizeof(cson_array_size_t) + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0);
} else {
ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl);
ret = csonJsonObj2Struct(item, pMem + sizeof(cson_array_size_t) + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl);
}
if (ret == ERR_NONE) {
@ -453,20 +442,15 @@ 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) {
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);
*((cson_array_size_t*)pMem) = successCount;
pMem += sizeof(cson_array_size_t);
csonSetPropertyFast(output, (char*)&pMem, tbl + index);
return ERR_NONE;
}
}
@ -708,15 +692,15 @@ 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 = **((cson_array_size_t**)(pProperty - sizeof(cson_array_size_t)));
for (long long j = 0; j < size; j++) {
cson_array_size_t size = *((cson_array_size_t*)(*((char**)pProperty) - sizeof(cson_array_size_t)));
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) {
@ -744,9 +728,14 @@ 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);
}else if(tbl->type == CSON_ARRAY){
printf("free field %s.\n", tbl->field);
free((*(char**)pData) - sizeof(cson_array_size_t));
}else{
}
return NULL;
}
@ -761,4 +750,17 @@ void csonFreePointer(void* list, const reflect_item_t* tbl)
{
/* 调用loopProperty迭代结构体中的属性,释放字符串和数组申请的内存空间 */
csonLoopProperty(list, tbl, freePointerSub);
}
cson_array_size_t csonGetArraySize(void* pArray){
if(pArray == NULL){
return 0;
}
return *((cson_array_size_t*)((char*)pArray - sizeof(cson_array_size_t)));
}
cson_array_size_t csonGetArraySizeByField(void* pData, const char* field, const reflect_item_t* tbl){
void* pArray = csonGetProperty(pData, field, tbl, NULL);
return csonGetArraySize(*((void**)pArray));
}