fix array size process
This commit is contained in:
parent
eddf45f4c6
commit
03abd19fdb
16
demo/test.c
16
demo/test.c
@ -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);
|
||||
|
@ -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()
|
||||
};
|
||||
|
||||
|
39
inc/cson.h
39
inc/cson.h
@ -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
|
82
src/cson.c
82
src/cson.c
@ -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));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user