fix the array size.

This commit is contained in:
sunchb 2020-02-25 17:38:54 +08:00
parent 9d8cbf5c49
commit cf7d1953c9
7 changed files with 219 additions and 124 deletions

View File

@ -12,7 +12,7 @@ typedef struct {
char* icon; char* icon;
int id; int id;
char* name; char* name;
size_t childrenNum; char childrenNum;
ClassInfoChild* children; ClassInfoChild* children;
} ClassInfo; } ClassInfo;
@ -97,8 +97,8 @@ static void freePlayList(Response* list)
csonLoopProperty(list, ResponseTbl, freePointer); csonLoopProperty(list, ResponseTbl, freePointer);
} }
void test2()
void test2(){ {
printf("=========================================\n"); printf("=========================================\n");
printf("\t\tRunning %s\n", __FUNCTION__); printf("\t\tRunning %s\n", __FUNCTION__);
printf("=========================================\n"); printf("=========================================\n");

View File

@ -119,10 +119,11 @@ extern const reflect_item_t realReflectTbl[];
* @param obj: object to be operated. * @param obj: object to be operated.
* @param field: * @param field:
* @param tbl: property table of the type. * @param tbl: property table of the type.
* @param pIndex: return index of the field in tbl.
* *
* @return address of field. * @return address of field.
*/ */
void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl); void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex);
/** /**
* @brief set the field of object to specified data. * @brief set the field of object to specified data.

23
inc/cson_util.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _UTIL_H_
#define _UTIL_H_
#include "cson.h"
typedef union {
char c;
short s;
int i;
long long l;
}integer_val_t;
typedef struct {
integer_val_t val;
int size;
}integer_t;
int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i);
int checkIntegerValue(long long val, int size, integer_val_t* i);
long long getIntegerValueFromPointer(void* ptr, int size);
#endif

View File

@ -3,6 +3,7 @@
* @author sun_chb@126.com * @author sun_chb@126.com
*/ */
#include "cson.h" #include "cson.h"
#include "cson_util.h"
#include "stdio.h" #include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
@ -92,15 +93,9 @@ int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* ob
void* pSrc = (void*)((char*)input + tbl[index].offset); void* pSrc = (void*)((char*)input + tbl[index].offset);
if(tbl[index].size == sizeof(char)){ long long val = getIntegerValueFromPointer(pSrc, tbl[index].size);
*obj = cson_integer(*((char*)pSrc));
}else if(tbl[index].size == sizeof(short)){ *obj = cson_integer(val);
*obj = cson_integer(*((short*)pSrc));
}else if(tbl[index].size == sizeof(int)){
*obj = cson_integer(*((int*)pSrc));
}else{
*obj = cson_integer(*((long long*)pSrc));
}
return ERR_NONE; return ERR_NONE;
} }
@ -133,17 +128,23 @@ 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) int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{ {
int ret = ERR_NONE; int ret = ERR_NONE;
int countIndex = -1;
char* pSrc = (*(char**)((char*)input + tbl[index].offset)); char* pSrc = (*(char**)((char*)input + tbl[index].offset));
if (pSrc == NULL) return ERR_MISSING_FIELD; 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(); cson_t joArray = cson_array();
size_t size = *((size_t*)csonGetProperty(input, tbl[index].arrayCountField, tbl)); long long successCount = 0;
size_t successCount = 0; for (long long i = 0; i < size; i++) {
for (int i = 0; i < size; i++) {
cson_t jotmp; cson_t jotmp;
if(tbl[index].reflect_tbl[0].field[0] == '0'){ /* field start with '0' mean basic types. */ if(tbl[index].reflect_tbl[0].field[0] == '0'){ /* field start with '0' mean basic types. */
@ -199,6 +200,8 @@ int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
void* pSrc = (void*)((char*)input + tbl[index].offset); void* pSrc = (void*)((char*)input + tbl[index].offset);
if(tbl[index].size == sizeof(char)){ if(tbl[index].size == sizeof(char)){
*obj = cson_bool(*((char*)pSrc)); *obj = cson_bool(*((char*)pSrc));
}else if(tbl[index].size == sizeof(short)){ }else if(tbl[index].size == sizeof(short)){

View File

@ -3,6 +3,7 @@
* @author sun_chb@126.com * @author sun_chb@126.com
*/ */
#include "cson.h" #include "cson.h"
#include "cson_util.h"
#include "string.h" #include "string.h"
#include "limits.h" #include "limits.h"
#include "stdio.h" #include "stdio.h"
@ -117,60 +118,17 @@ int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int
int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{ {
union{ int ret;
char c; integer_val_t value;
short s; ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
int i;
long long l;
}ret;
long long temp; if(ret != ERR_NONE){
if(cson_typeof(jo_tmp) == CSON_INTEGER){ printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
temp = cson_integer_value(jo_tmp);
}else{ }else{
double tempDouble = cson_real_value(jo_tmp); csonSetPropertyFast(output, &value, tbl + index);
if(tempDouble > LLONG_MAX || tempDouble < LLONG_MIN){
printf("value of field %s overflow.size=%ld,value=%f.\n", tbl[index].field, tbl[index].size, tempDouble);
return ERR_OVERFLOW;
}else{
temp = tempDouble;
}
} }
if(tbl[index].size != sizeof(char) && return ret;
tbl[index].size != sizeof(short) &&
tbl[index].size != sizeof(int) &&
tbl[index].size != sizeof(long long)){
printf("Unsupported size(=%ld) of integer.\n", tbl[index].size);
printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field);
return ERR_OVERFLOW;
}
if(tbl[index].size == sizeof(char) && (temp > CHAR_MAX || temp < CHAR_MIN)){
printf("value of field %s overflow.size=%ld,value=%lld.\n", tbl[index].field, tbl[index].size, temp);
return ERR_OVERFLOW;
}else if(tbl[index].size == sizeof(short) && (temp > SHRT_MAX || temp < SHRT_MIN)){
printf("value of field %s overflow.size=%ld,value=%lld.\n", tbl[index].field, tbl[index].size, temp);
return ERR_OVERFLOW;
}else if(tbl[index].size == sizeof(int) && (temp > INT_MAX || temp < INT_MIN)){
printf("value of field %s overflow.size=%ld,value=%lld.\n", tbl[index].field, tbl[index].size, temp);
return ERR_OVERFLOW;
}else{
}
/* avoid error on big endian */
if(tbl[index].size == sizeof(char)){
ret.c = temp;
}else if(tbl[index].size == sizeof(short)){
ret.s = temp;
}else if(tbl[index].size == sizeof(int)){
ret.i = temp;
}else{
ret.l = temp;
}
csonSetPropertyFast(output, &ret, tbl + index);
return ERR_NONE;
} }
@ -181,18 +139,26 @@ 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) int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{ {
printf("parseJsonArray:%s\n", tbl[index].field);
size_t arraySize = cson_array_size(jo_tmp); size_t arraySize = cson_array_size(jo_tmp);
if (arraySize == 0) { if (arraySize == 0) {
csonSetProperty(output, tbl->arrayCountField, &arraySize, tbl); csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl);
return ERR_NONE; 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].arraySize); char* pMem = (char*)malloc(arraySize * tbl[index].arraySize);
if (pMem == NULL) return ERR_MEMORY; if (pMem == NULL) return ERR_MEMORY;
size_t successCount = 0; long long successCount = 0;
for (int j = 0; j < arraySize; j++) { for (size_t j = 0; j < arraySize; j++) {
cson_t item = cson_array_get(jo_tmp, j); cson_t item = cson_array_get(jo_tmp, j);
if (item != NULL) { if (item != NULL) {
int ret; int ret;
@ -209,14 +175,19 @@ int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int i
} }
} }
integer_val_t val;
if(checkIntegerValue(successCount, tbl[countIndex].size, &val) != ERR_NONE){
successCount = 0;
}
if (successCount == 0) { if (successCount == 0) {
csonSetProperty(output, tbl[index].arrayCountField, &successCount, tbl); csonSetPropertyFast(output, &successCount, tbl + countIndex);
free(pMem); free(pMem);
pMem = NULL; pMem = NULL;
csonSetPropertyFast(output, &pMem, tbl + index); csonSetPropertyFast(output, &pMem, tbl + index);
return ERR_MISSING_FIELD; return ERR_MISSING_FIELD;
} else { } else {
csonSetProperty(output, tbl[index].arrayCountField, &successCount, tbl); csonSetPropertyFast(output, &val, tbl + countIndex);
csonSetPropertyFast(output, &pMem, tbl + index); csonSetPropertyFast(output, &pMem, tbl + index);
return ERR_NONE; return ERR_NONE;
} }
@ -243,35 +214,15 @@ int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int in
int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index) int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{ {
if(tbl[index].size != sizeof(char) && int ret;
tbl[index].size != sizeof(short) && integer_val_t value;
tbl[index].size != sizeof(int) && ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
tbl[index].size != sizeof(long long)){ if(ret != ERR_NONE){
printf("Unsupported size(=%ld) of bool.\n", tbl[index].size); printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field);
return ERR_OVERFLOW;
}
union{
char c;
short s;
int i;
long long l;
}temp;
/* avoid error on big endian */
if(tbl[index].size == sizeof(char)){
temp.c = cson_bool_value(jo_tmp);
}else if(tbl[index].size == sizeof(short)){
temp.s = cson_bool_value(jo_tmp);
}else if(tbl[index].size == sizeof(int)){
temp.i = cson_bool_value(jo_tmp);
}else{ }else{
temp.l = cson_bool_value(jo_tmp); csonSetPropertyFast(output, &value, tbl + index);
} }
return ret;
csonSetPropertyFast(output, &temp, tbl + index);
return ERR_NONE;
} }
int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){ int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){

View File

@ -3,6 +3,7 @@
* @author sun_chb@126.com * @author sun_chb@126.com
*/ */
#include "cson_reflect.h" #include "cson_reflect.h"
#include "cson_util.h"
#include "string.h" #include "string.h"
#include "stdio.h" #include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
@ -27,7 +28,7 @@ const reflect_item_t boolReflectTbl[] = {
{} {}
}; };
static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl) static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex)
{ {
const reflect_item_t* ret = NULL; const reflect_item_t* ret = NULL;
@ -35,6 +36,8 @@ static const reflect_item_t* getReflexItem(const char* field, const reflect_item
if (!(tbl[i].field)) break; if (!(tbl[i].field)) break;
if (strcmp(field, tbl[i].field) == 0) { if (strcmp(field, tbl[i].field) == 0) {
ret = &(tbl[i]); ret = &(tbl[i]);
if(pIndex) *pIndex = i;
break; break;
} }
} }
@ -44,10 +47,10 @@ static const reflect_item_t* getReflexItem(const char* field, const reflect_item
return ret; return ret;
} }
void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl) void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex)
{ {
if (!(obj && field && tbl)) return NULL; if (!(obj && field && tbl)) return NULL;
const reflect_item_t* ret = getReflexItem(field, tbl); const reflect_item_t* ret = getReflexItem(field, tbl, pIndex);
if (!ret) return NULL; if (!ret) return NULL;
@ -58,7 +61,7 @@ void csonSetProperty(void* obj, const char* field, void* data, const reflect_
{ {
if (!(obj && field && data && tbl)) return; if (!(obj && field && data && tbl)) return;
const reflect_item_t* ret = getReflexItem(field, tbl); const reflect_item_t* ret = getReflexItem(field, tbl, NULL);
if (!ret) return; if (!ret) return;
@ -84,7 +87,14 @@ void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func)
char* pProperty = (char*)pData + tbl[i].offset; char* pProperty = (char*)pData + tbl[i].offset;
if (tbl[i].type == CSON_ARRAY) { if (tbl[i].type == CSON_ARRAY) {
size_t size = *((size_t*)csonGetProperty(pData, tbl[i].arrayCountField, tbl)); 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 (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
csonLoopProperty(*((char**)pProperty) + j * tbl[i].arraySize, tbl[i].reflect_tbl, func); csonLoopProperty(*((char**)pProperty) + j * tbl[i].arraySize, tbl[i].reflect_tbl, func);
} }

107
src/cson_util.c Normal file
View File

@ -0,0 +1,107 @@
#include "cson_util.h"
#include "cson_interface.h"
#include "limits.h"
#include "stdio.h"
int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i){
long long temp;
if(size != sizeof(char) &&
size != sizeof(short) &&
size != sizeof(int) &&
size != sizeof(long long)){
return ERR_OVERFLOW;
}
if(cson_typeof(jo_tmp) == CSON_INTEGER){
temp = cson_integer_value(jo_tmp);
}else if(cson_typeof(jo_tmp) == CSON_TRUE){
temp = 1;
}else if(cson_typeof(jo_tmp) == CSON_FALSE){
temp = 0;
}else if(cson_typeof(jo_tmp) == CSON_REAL){
double tempDouble = cson_real_value(jo_tmp);
if(tempDouble > LLONG_MAX || tempDouble < LLONG_MIN){
return ERR_OVERFLOW;
}else{
temp = tempDouble;
}
}else{
return ERR_ARGS;
}
if(size == sizeof(char) && (temp > CHAR_MAX || temp < CHAR_MIN)){
return ERR_OVERFLOW;
}else if(size == sizeof(short) && (temp > SHRT_MAX || temp < SHRT_MIN)){
return ERR_OVERFLOW;
}else if(size == sizeof(int) && (temp > INT_MAX || temp < INT_MIN)){
return ERR_OVERFLOW;
}else{
}
/* avoid error on big endian */
if(size == sizeof(char)){
i->c = temp;
}else if(size == sizeof(short)){
i->s = temp;
}else if(size == sizeof(int)){
i->i = temp;
}else{
i->l = temp;
}
return ERR_NONE;
}
int checkIntegerValue(long long val, int size, integer_val_t* i){
if(size != sizeof(char) &&
size != sizeof(short) &&
size != sizeof(int) &&
size != sizeof(long long)){
return ERR_OVERFLOW;
}
if(size == sizeof(char) && (val > CHAR_MAX || val < CHAR_MIN)){
return ERR_OVERFLOW;
}else if(size == sizeof(short) && (val > SHRT_MAX || val < SHRT_MIN)){
return ERR_OVERFLOW;
}else if(size == sizeof(int) && (val > INT_MAX || val < INT_MIN)){
return ERR_OVERFLOW;
}else{
}
/* avoid error on big endian */
if(size == sizeof(char)){
i->c = val;
}else if(size == sizeof(short)){
i->s = val;
}else if(size == sizeof(int)){
i->i = val;
}else{
i->l = val;
}
return ERR_NONE;
}
long long getIntegerValueFromPointer(void* ptr, int size){
long long ret = 0;
if(!ptr) return 0;
if(size == sizeof(char)){
ret = *((char*)ptr);
}else if(size == sizeof(short)){
ret = *((short*)ptr);
}else if(size == sizeof(int)){
ret = *((int*)ptr);
}else if(size == sizeof(long long)){
ret = *((long long*)ptr);
}else{
printf("Unsupported size(=%d) of integer.\n", size);
}
return ret;
}