Simplify source file structure
This commit is contained in:
parent
665193ad72
commit
9926a9901c
|
@ -3,7 +3,7 @@
|
|||
* @author sun_chb@126.com
|
||||
*/
|
||||
#include "cJSON.h"
|
||||
#include "cson_interface.h"
|
||||
#include "cson.h"
|
||||
#include "string.h"
|
||||
|
||||
cson_t cjson_impl_object_get(const cson_t object, const char* key){
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @file jansson_impl.c
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#include "cson_interface.h"
|
||||
#include "cson.h"
|
||||
#include "jansson.h"
|
||||
|
||||
cson_t jansson_impl_object_get(const cson_t object, const char* key){
|
||||
|
|
195
inc/cson.h
195
inc/cson.h
|
@ -5,7 +5,7 @@
|
|||
#ifndef _CSON_H_
|
||||
#define _CSON_H_
|
||||
|
||||
#include "cson_reflect.h"
|
||||
#include "stddef.h"
|
||||
|
||||
/**
|
||||
* @brief error code of parser.
|
||||
|
@ -18,6 +18,199 @@
|
|||
#define ERR_ARGS (-5) /**< args error */
|
||||
#define ERR_OVERFLOW (-6) /**< value overflow */
|
||||
|
||||
/**
|
||||
* @brief the type of json object.
|
||||
*/
|
||||
typedef enum {
|
||||
CSON_OBJECT,
|
||||
CSON_ARRAY,
|
||||
CSON_STRING,
|
||||
CSON_INTEGER,
|
||||
CSON_REAL,
|
||||
CSON_TRUE,
|
||||
CSON_FALSE,
|
||||
CSON_NULL
|
||||
} cson_type;
|
||||
|
||||
typedef void* cson_t;
|
||||
|
||||
/**
|
||||
* @brief define the function type of json parse/pack function group
|
||||
*/
|
||||
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 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);
|
||||
typedef long long (*func_cson_integer_value)(const cson_t object);
|
||||
typedef double (*func_cson_real_value)(const cson_t object);
|
||||
typedef char (*func_cson_bool_value)(const cson_t object);
|
||||
typedef size_t (*func_cson_array_size)(const cson_t object);
|
||||
typedef cson_t (*func_cson_array_get)(const cson_t object, size_t index);
|
||||
typedef cson_t (*func_cson_new)();
|
||||
typedef char* (*func_cson_to_string)(cson_t object);
|
||||
typedef cson_t (*func_cson_integer)(long long val);
|
||||
typedef cson_t (*func_cson_string)(const char* val);
|
||||
typedef cson_t (*func_cson_bool)(char val);
|
||||
typedef cson_t (*func_cson_real)(double val);
|
||||
typedef cson_t (*func_cson_array)();
|
||||
typedef int (*func_cson_array_add)(cson_t array, cson_t obj);
|
||||
typedef int (*func_cson_object_set_new)(cson_t rootObj, const char* field, cson_t obj);
|
||||
|
||||
/**
|
||||
* @brief define the cson interface
|
||||
*/
|
||||
typedef struct {
|
||||
func_cson_object_get cson_object_get;
|
||||
func_cson_typeof cson_typeof;
|
||||
func_cson_loadb cson_loadb;
|
||||
func_cson_decref cson_decref;
|
||||
func_cson_string_value cson_string_value;
|
||||
func_cson_string_length cson_string_length;
|
||||
func_cson_integer_value cson_integer_value;
|
||||
func_cson_real_value cson_real_value;
|
||||
func_cson_bool_value cson_bool_value;
|
||||
func_cson_array_size cson_array_size;
|
||||
func_cson_array_get cson_array_get;
|
||||
func_cson_new cson_object;
|
||||
func_cson_to_string cson_to_string;
|
||||
func_cson_integer cson_integer;
|
||||
func_cson_string cson_string;
|
||||
func_cson_bool cson_bool;
|
||||
func_cson_real cson_real;
|
||||
func_cson_array cson_array;
|
||||
func_cson_array_add cson_array_add;
|
||||
func_cson_object_set_new cson_object_set_new;
|
||||
} cson_interface;
|
||||
|
||||
/**
|
||||
* @brief the description of property in struct.
|
||||
*
|
||||
* @TODO: Try to simplify the struct
|
||||
*/
|
||||
typedef struct reflect_item_t {
|
||||
char* field; /**< field */
|
||||
size_t offset; /**< offset of property */
|
||||
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 arraySize; /**< size of per array item. must be specified when type is array */
|
||||
char* arrayCountField; /**< field saving array size */
|
||||
int nullable; /**< paser return failure when the field is not found and nullable equals to 0 */
|
||||
} reflect_item_t;
|
||||
|
||||
extern const reflect_item_t integerReflectTbl[];
|
||||
extern const reflect_item_t stringReflectTbl[];
|
||||
extern const reflect_item_t boolReflectTbl[];
|
||||
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}
|
||||
|
||||
/**
|
||||
* @brief Declaring integer properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_int(type, field) _property(type, field, CSON_INTEGER, integerReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring real properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_real(type, field) _property(type, field, CSON_REAL, realReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring bool properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_bool(type, field) _property(type, field, CSON_TRUE, boolReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring string properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_string(type, field) _property(type, field, CSON_STRING, stringReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring struct properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
* @param tbl: property description table of sub-struct
|
||||
*
|
||||
*/
|
||||
#define _property_obj(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring array properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @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)
|
||||
|
||||
/**
|
||||
* @brief nonull definitions. parser will stop and return error code when field not found which declared whit it.
|
||||
*
|
||||
* @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) {#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)
|
||||
|
||||
/**
|
||||
* @brief function type of csonLoopProperty.
|
||||
*
|
||||
* @param obj: pointer of property.
|
||||
* @param tbl: property of field.
|
||||
*
|
||||
* @return void*(reserved).
|
||||
*/
|
||||
typedef void* (*loop_func_t)(void* pData, const reflect_item_t* tbl);
|
||||
|
||||
/**
|
||||
* @brief loop all property and process property by @func
|
||||
*
|
||||
* @param obj: object to be operated.
|
||||
* @param tbl: property of field.
|
||||
* @param func: callback
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
void csonLoopProperty(void* obj, const reflect_item_t* tbl, loop_func_t func);
|
||||
|
||||
/**
|
||||
* @brief convert json string to struct object.
|
||||
*
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
/**
|
||||
* @file cson_interface.h
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#ifndef _CSON_INTERFACE_
|
||||
#define _CSON_INTERFACE_
|
||||
|
||||
/**
|
||||
* Initially I used the Jansson library as a parser. The Jansson library
|
||||
* is powerful, but it obviously increases the size of the executable.
|
||||
* So, I found cjson, which is very small and convenient for code
|
||||
* integration. Now I want to support Jansson and cjson, so I need
|
||||
* to abstract the parser into an interface. Users can choose which one
|
||||
* to use, or define other parser which conforms to this interface.
|
||||
* */
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
/**
|
||||
* @brief the type of json object.
|
||||
*/
|
||||
typedef enum {
|
||||
CSON_OBJECT,
|
||||
CSON_ARRAY,
|
||||
CSON_STRING,
|
||||
CSON_INTEGER,
|
||||
CSON_REAL,
|
||||
CSON_TRUE,
|
||||
CSON_FALSE,
|
||||
CSON_NULL
|
||||
} cson_type;
|
||||
|
||||
typedef void* cson_t;
|
||||
|
||||
/**
|
||||
* @brief define the function type of json parse/pack function group
|
||||
*/
|
||||
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 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);
|
||||
typedef long long (*func_cson_integer_value)(const cson_t object);
|
||||
typedef double (*func_cson_real_value)(const cson_t object);
|
||||
typedef char (*func_cson_bool_value)(const cson_t object);
|
||||
typedef size_t (*func_cson_array_size)(const cson_t object);
|
||||
typedef cson_t (*func_cson_array_get)(const cson_t object, size_t index);
|
||||
typedef cson_t (*func_cson_new)();
|
||||
typedef char* (*func_cson_to_string)(cson_t object);
|
||||
typedef cson_t (*func_cson_integer)(long long val);
|
||||
typedef cson_t (*func_cson_string)(const char* val);
|
||||
typedef cson_t (*func_cson_bool)(char val);
|
||||
typedef cson_t (*func_cson_real)(double val);
|
||||
typedef cson_t (*func_cson_array)();
|
||||
typedef int (*func_cson_array_add)(cson_t array, cson_t obj);
|
||||
typedef int (*func_cson_object_set_new)(cson_t rootObj, const char* field, cson_t obj);
|
||||
|
||||
/**
|
||||
* @brief define the cson interface
|
||||
*/
|
||||
typedef struct {
|
||||
func_cson_object_get cson_object_get;
|
||||
func_cson_typeof cson_typeof;
|
||||
func_cson_loadb cson_loadb;
|
||||
func_cson_decref cson_decref;
|
||||
func_cson_string_value cson_string_value;
|
||||
func_cson_string_length cson_string_length;
|
||||
func_cson_integer_value cson_integer_value;
|
||||
func_cson_real_value cson_real_value;
|
||||
func_cson_bool_value cson_bool_value;
|
||||
func_cson_array_size cson_array_size;
|
||||
func_cson_array_get cson_array_get;
|
||||
func_cson_new cson_object;
|
||||
func_cson_to_string cson_to_string;
|
||||
func_cson_integer cson_integer;
|
||||
func_cson_string cson_string;
|
||||
func_cson_bool cson_bool;
|
||||
func_cson_real cson_real;
|
||||
func_cson_array cson_array;
|
||||
func_cson_array_add cson_array_add;
|
||||
func_cson_object_set_new cson_object_set_new;
|
||||
} cson_interface;
|
||||
|
||||
extern cson_interface csomImpl;
|
||||
|
||||
#define cson_object_get csomImpl.cson_object_get
|
||||
#define cson_typeof csomImpl.cson_typeof
|
||||
#define cson_loadb csomImpl.cson_loadb
|
||||
#define cson_decref csomImpl.cson_decref
|
||||
#define cson_string_value csomImpl.cson_string_value
|
||||
#define cson_string_length csomImpl.cson_string_length
|
||||
#define cson_integer_value csomImpl.cson_integer_value
|
||||
#define cson_real_value csomImpl.cson_real_value
|
||||
#define cson_bool_value csomImpl.cson_bool_value
|
||||
#define cson_array_size csomImpl.cson_array_size
|
||||
#define cson_array_get csomImpl.cson_array_get
|
||||
#define cson_object csomImpl.cson_object
|
||||
#define cson_to_string csomImpl.cson_to_string
|
||||
#define cson_integer csomImpl.cson_integer
|
||||
#define cson_string csomImpl.cson_string
|
||||
#define cson_bool csomImpl.cson_bool
|
||||
#define cson_real csomImpl.cson_real
|
||||
#define cson_array csomImpl.cson_array
|
||||
#define cson_array_add csomImpl.cson_array_add
|
||||
#define cson_object_set_new csomImpl.cson_object_set_new
|
||||
|
||||
#define cson_is_number(type) (type == CSON_REAL || type == CSON_INTEGER)
|
||||
#define cson_is_bool(type) (type == CSON_TRUE || type == CSON_FALSE)
|
||||
|
||||
#endif
|
|
@ -1,171 +0,0 @@
|
|||
/**
|
||||
* @file cson_reflect.h
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#ifndef _REFLECT_H_
|
||||
#define _REFLECT_H_
|
||||
|
||||
#include "stddef.h"
|
||||
#include "cson_interface.h"
|
||||
|
||||
/**
|
||||
* @brief the description of property in struct.
|
||||
*
|
||||
* @TODO: Try to simplify the struct
|
||||
*/
|
||||
typedef struct reflect_item_t {
|
||||
char* field; /**< field */
|
||||
size_t offset; /**< offset of property */
|
||||
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 object array */
|
||||
size_t arraySize; /**< size of per array item. must be specified when type is array */
|
||||
char* arrayCountField; /**< field saving array size */
|
||||
int nullable; /**< paser return failure when the field is not found and nullable equals to 0 */
|
||||
} reflect_item_t;
|
||||
|
||||
extern const reflect_item_t integerReflectTbl[];
|
||||
extern const reflect_item_t stringReflectTbl[];
|
||||
extern const reflect_item_t boolReflectTbl[];
|
||||
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}
|
||||
|
||||
/**
|
||||
* @brief Declaring integer properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_int(type, field) _property(type, field, CSON_INTEGER, integerReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring real properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_real(type, field) _property(type, field, CSON_REAL, realReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring bool properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_bool(type, field) _property(type, field, CSON_TRUE, boolReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring string properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
*
|
||||
*/
|
||||
#define _property_string(type, field) _property(type, field, CSON_STRING, stringReflectTbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring struct properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @param field: field name of properties
|
||||
* @param tbl: property description table of sub-struct
|
||||
*
|
||||
*/
|
||||
#define _property_obj(type, field, tbl) _property(type, field, CSON_OBJECT, tbl, 1)
|
||||
|
||||
/**
|
||||
* @brief Declaring array properties.
|
||||
*
|
||||
* @param type: type of struct
|
||||
* @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)
|
||||
|
||||
/**
|
||||
* @brief nonull definitions. parser will stop and return error code when field not found which declared whit it.
|
||||
*
|
||||
* @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) {#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)
|
||||
/**
|
||||
* @brief get the address of field by retrieve the property table.
|
||||
*
|
||||
* @param obj: object to be operated.
|
||||
* @param field:
|
||||
* @param tbl: property table of the type.
|
||||
* @param pIndex: return index of the field in tbl. @nullable
|
||||
*
|
||||
* @return address of field.
|
||||
*/
|
||||
void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex);
|
||||
|
||||
/**
|
||||
* @brief set the field of object to specified data.
|
||||
*
|
||||
* @param obj: object to be operated.
|
||||
* @param field:
|
||||
* @param data: pointer of specified data.
|
||||
* @param tbl: property table of the type.
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
void csonSetProperty(void* obj, const char* field, void* data, const reflect_item_t* tbl);
|
||||
|
||||
/**
|
||||
* @brief set the field of object to specified data without retrieve the property table.
|
||||
*
|
||||
* @param obj: object to be operated.
|
||||
* @param data: pointer of specified data.
|
||||
* @param tbl: property of field.
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl);
|
||||
|
||||
/**
|
||||
* @brief function type of csonLoopProperty.
|
||||
*
|
||||
* @param obj: pointer of property.
|
||||
* @param tbl: property of field.
|
||||
*
|
||||
* @return void*(reserved).
|
||||
*/
|
||||
typedef void* (*loop_func_t)(void* pData, const reflect_item_t* tbl);
|
||||
|
||||
/**
|
||||
* @brief loop all property and process property by @func
|
||||
*
|
||||
* @param obj: object to be operated.
|
||||
* @param tbl: property of field.
|
||||
* @param func: callback
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
void csonLoopProperty(void* obj, const reflect_item_t* tbl, loop_func_t func);
|
||||
#endif
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "cson.h"
|
||||
|
||||
long long getIntegerValueFromPointer(void* ptr, int size);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,730 @@
|
|||
/**
|
||||
* @file cson.c
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#include "cson.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "stddef.h"
|
||||
#include "limits.h"
|
||||
#include "string.h"
|
||||
|
||||
extern cson_interface csomImpl;
|
||||
|
||||
#define cson_object_get csomImpl.cson_object_get
|
||||
#define cson_typeof csomImpl.cson_typeof
|
||||
#define cson_loadb csomImpl.cson_loadb
|
||||
#define cson_decref csomImpl.cson_decref
|
||||
#define cson_string_value csomImpl.cson_string_value
|
||||
#define cson_string_length csomImpl.cson_string_length
|
||||
#define cson_integer_value csomImpl.cson_integer_value
|
||||
#define cson_real_value csomImpl.cson_real_value
|
||||
#define cson_bool_value csomImpl.cson_bool_value
|
||||
#define cson_array_size csomImpl.cson_array_size
|
||||
#define cson_array_get csomImpl.cson_array_get
|
||||
#define cson_object csomImpl.cson_object
|
||||
#define cson_to_string csomImpl.cson_to_string
|
||||
#define cson_integer csomImpl.cson_integer
|
||||
#define cson_string csomImpl.cson_string
|
||||
#define cson_bool csomImpl.cson_bool
|
||||
#define cson_real csomImpl.cson_real
|
||||
#define cson_array csomImpl.cson_array
|
||||
#define cson_array_add csomImpl.cson_array_add
|
||||
#define cson_object_set_new csomImpl.cson_object_set_new
|
||||
#define cson_is_number(type) (type == CSON_REAL || type == CSON_INTEGER)
|
||||
#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},
|
||||
{}
|
||||
};
|
||||
|
||||
const reflect_item_t stringReflectTbl[] = {
|
||||
{"0String", 0, sizeof(char*), CSON_STRING, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
const reflect_item_t realReflectTbl[] = {
|
||||
{"0Real", 0, sizeof(double), CSON_REAL, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
const reflect_item_t boolReflectTbl[] = {
|
||||
{"0Bool", 0, sizeof(int), CSON_TRUE, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* reflecter functions
|
||||
*/
|
||||
static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex);
|
||||
static void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex);
|
||||
static void csonSetProperty(void* obj, const char* field, void* data, const reflect_item_t* tbl);
|
||||
static void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl);
|
||||
|
||||
/*
|
||||
* integer util functions
|
||||
*/
|
||||
typedef union {
|
||||
char c;
|
||||
short s;
|
||||
int i;
|
||||
long long l;
|
||||
} integer_val_t;
|
||||
|
||||
static long long getIntegerValueFromPointer(void* ptr, int size);
|
||||
static int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i);
|
||||
static int convertInteger(long long val, int size, integer_val_t* i);
|
||||
static int checkInteger(long long val, int size);
|
||||
|
||||
/*
|
||||
* packer functions
|
||||
*/
|
||||
typedef int (*json_pack_proc)(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
|
||||
static int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonString(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
|
||||
json_pack_proc jsonPackTbl[] = {
|
||||
getJsonObject,
|
||||
getJsonArray,
|
||||
getJsonString,
|
||||
getJsonInteger,
|
||||
getJsonReal,
|
||||
getJsonBool,
|
||||
getJsonBool,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl);
|
||||
|
||||
/*
|
||||
* parser functions
|
||||
*/
|
||||
typedef int (*json_obj_proc)(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
|
||||
static int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
|
||||
json_obj_proc jsonObjProcTbl[] = {
|
||||
parseJsonObject,
|
||||
parseJsonArray,
|
||||
parseJsonString,
|
||||
parseJsonInteger,
|
||||
parseJsonReal,
|
||||
parseJsonBool,
|
||||
parseJsonBool,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonArrayDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonStringDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonIntegerDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonRealDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
|
||||
json_obj_proc jsonObjDefaultTbl[] = {
|
||||
parseJsonObjectDefault,
|
||||
parseJsonArrayDefault,
|
||||
parseJsonStringDefault,
|
||||
parseJsonIntegerDefault,
|
||||
parseJsonRealDefault,
|
||||
parseJsonIntegerDefault,
|
||||
parseJsonIntegerDefault,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl);
|
||||
|
||||
int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl)
|
||||
{
|
||||
cson_t jsonPack = cson_object();
|
||||
|
||||
if (!jsonPack) return ERR_MEMORY;
|
||||
|
||||
int ret = csonStruct2JsonObj(jsonPack, input, tbl);
|
||||
|
||||
if (ret == ERR_NONE) {
|
||||
char* dumpStr = cson_to_string(jsonPack);
|
||||
if (dumpStr == NULL) {
|
||||
ret = ERR_MEMORY;
|
||||
} else {
|
||||
*jstr = dumpStr;
|
||||
}
|
||||
}
|
||||
|
||||
cson_decref(jsonPack);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = ERR_NONE;
|
||||
|
||||
if (!obj || !input || !tbl) return ERR_ARGS;
|
||||
|
||||
while (1) {
|
||||
if (tbl[i].field == NULL) break;
|
||||
|
||||
cson_t joTmp = NULL;
|
||||
int jsonType = tbl[i].type;
|
||||
|
||||
if (jsonPackTbl[jsonType] != NULL) {
|
||||
ret = jsonPackTbl[jsonType](input, tbl, i, &joTmp);
|
||||
}
|
||||
|
||||
if (ret != ERR_NONE ) {
|
||||
printf("!!!!pack error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
|
||||
if (!tbl[i].nullable) return ret;
|
||||
} else {
|
||||
cson_object_set_new(obj, tbl[i].field, joTmp);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
if (tbl[index].size != sizeof(char) &&
|
||||
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;
|
||||
}
|
||||
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
|
||||
long long val = getIntegerValueFromPointer(pSrc, tbl[index].size);
|
||||
|
||||
*obj = cson_integer(val);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonString(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
|
||||
if (*((char**)pSrc) == NULL) return ERR_MISSING_FIELD;
|
||||
|
||||
*obj = cson_string(*((char**)pSrc));
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
cson_t jotmp = cson_object();
|
||||
int ret = csonStruct2JsonObj(jotmp, pSrc, tbl[index].reflect_tbl);
|
||||
|
||||
if (ret == ERR_NONE) {
|
||||
*obj = jotmp;
|
||||
} else {
|
||||
cson_decref(jotmp);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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].arraySize), tbl[index].reflect_tbl, 0, &jotmp);
|
||||
} else {
|
||||
jotmp = cson_object();
|
||||
ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arraySize), 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 getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
if (tbl[index].size != sizeof(double)) {
|
||||
printf("Unsupported size(=%ld) of real.\n", tbl[index].size);
|
||||
printf("Please check if the type of field %s is double!\n", tbl[index].field);
|
||||
return ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
*obj = cson_real(*((double*)pSrc));
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
if (tbl[index].size != sizeof(char) &&
|
||||
tbl[index].size != sizeof(short) &&
|
||||
tbl[index].size != sizeof(int) &&
|
||||
tbl[index].size != sizeof(long long)) {
|
||||
printf("Unsupported size(=%ld) of bool.\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;
|
||||
}
|
||||
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
|
||||
if (tbl[index].size == sizeof(char)) {
|
||||
*obj = cson_bool(*((char*)pSrc));
|
||||
} else if (tbl[index].size == sizeof(short)) {
|
||||
*obj = cson_bool(*((short*)pSrc));
|
||||
} else if (tbl[index].size == sizeof(int)) {
|
||||
*obj = cson_bool(*((int*)pSrc));
|
||||
} else {
|
||||
*obj = cson_bool(*((long long*)pSrc));
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
int csonJsonStr2Struct(const char* jstr, void* output, const reflect_item_t* tbl)
|
||||
{
|
||||
/* load json string */
|
||||
cson_t jo = cson_loadb(jstr, strlen(jstr));
|
||||
|
||||
if (!jo) return ERR_FORMAT;
|
||||
|
||||
int ret = csonJsonObj2Struct(jo, output, tbl);
|
||||
cson_decref(jo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl)
|
||||
{
|
||||
if (!jo || !output || !tbl) return ERR_ARGS;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
int ret = ERR_NONE;
|
||||
if (tbl[i].field == NULL) break;
|
||||
|
||||
cson_t jo_tmp = cson_object_get(jo, tbl[i].field);
|
||||
|
||||
if (jo_tmp == NULL) {
|
||||
ret = ERR_MISSING_FIELD;
|
||||
} else {
|
||||
|
||||
int jsonType = cson_typeof(jo_tmp);
|
||||
|
||||
if (jsonType == tbl[i].type ||
|
||||
(cson_is_number(cson_typeof(jo_tmp)) && cson_is_number(tbl[i].type)) ||
|
||||
(cson_is_bool(cson_typeof(jo_tmp)) && cson_is_bool(tbl[i].type))) {
|
||||
if (jsonObjProcTbl[tbl[i].type] != NULL) {
|
||||
ret = jsonObjProcTbl[tbl[i].type](jo_tmp, output, tbl, i);
|
||||
}
|
||||
} else {
|
||||
ret = ERR_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != ERR_NONE ) {
|
||||
printf("!!!!parse error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
|
||||
jsonObjDefaultTbl[tbl[i].type](NULL, output, tbl, i);
|
||||
if (!tbl[i].nullable) return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
const char* tempstr = cson_string_value(jo_tmp);
|
||||
if (NULL != tempstr) {
|
||||
char* pDst = malloc(strlen(tempstr) + 1);
|
||||
if (pDst == NULL) {
|
||||
return ERR_MEMORY;
|
||||
}
|
||||
strcpy(pDst, tempstr);
|
||||
csonSetPropertyFast(output, &pDst, tbl + index);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
return ERR_MISSING_FIELD;
|
||||
}
|
||||
|
||||
int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
int ret;
|
||||
integer_val_t value;
|
||||
ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
|
||||
|
||||
if (ret != ERR_NONE) {
|
||||
printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
|
||||
} else {
|
||||
csonSetPropertyFast(output, &value, tbl + index);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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].arraySize);
|
||||
if (pMem == NULL) return ERR_MEMORY;
|
||||
|
||||
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].arraySize), tbl[index].reflect_tbl, 0);
|
||||
} else {
|
||||
ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arraySize), 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;
|
||||
}
|
||||
}
|
||||
|
||||
int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
if (tbl[index].size != sizeof(double)) {
|
||||
printf("Unsupported size(=%ld) of real.\n", tbl[index].size);
|
||||
printf("Please check if the type of field %s is double!\n", tbl[index].field);
|
||||
return ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
double temp;
|
||||
if (cson_typeof(jo_tmp) == CSON_REAL) {
|
||||
temp = cson_real_value(jo_tmp);
|
||||
} else {
|
||||
temp = cson_integer_value(jo_tmp);
|
||||
}
|
||||
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
int ret;
|
||||
integer_val_t value;
|
||||
ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
|
||||
if (ret != ERR_NONE) {
|
||||
printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
|
||||
} else {
|
||||
csonSetPropertyFast(output, &value, tbl + index);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
int i = 0;
|
||||
while (1) {
|
||||
if (tbl[index].reflect_tbl[i].field == NULL) break;
|
||||
jsonObjDefaultTbl[tbl[index].reflect_tbl[i].type](NULL, output, tbl[index].reflect_tbl, i);
|
||||
i++;
|
||||
};
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonArrayDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
void* temp = NULL;
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonStringDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
char* temp = NULL;
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonIntegerDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
long long temp = 0;
|
||||
|
||||
if (tbl[index].size != sizeof(char) &&
|
||||
tbl[index].size != sizeof(short) &&
|
||||
tbl[index].size != sizeof(int) &&
|
||||
tbl[index].size != sizeof(long long)) {
|
||||
printf("Unsupported size(=%ld) of bool.\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;
|
||||
}
|
||||
|
||||
integer_val_t ret;
|
||||
convertInteger(temp, tbl[index].size, &ret);
|
||||
|
||||
csonSetPropertyFast(output, &ret, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonRealDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
if (tbl[index].size != sizeof(double)) {
|
||||
printf("Unsupported size(=%ld) of bool.\n", tbl[index].size);
|
||||
printf("Please check if the type of field %s is double!\n", tbl[index].field);
|
||||
return ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
double temp = 0.0;
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i)
|
||||
{
|
||||
long long temp;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return convertInteger(temp, size, i);
|
||||
}
|
||||
|
||||
int convertInteger(long long val, int size, integer_val_t* i)
|
||||
{
|
||||
int ret = checkInteger(val, size);
|
||||
|
||||
if (ret != ERR_NONE) return ret;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int checkInteger(long long val, int size)
|
||||
{
|
||||
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 {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* reflect */
|
||||
const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex)
|
||||
{
|
||||
const reflect_item_t* ret = NULL;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
if (!(tbl[i].field)) break;
|
||||
if (strcmp(field, tbl[i].field) == 0) {
|
||||
ret = &(tbl[i]);
|
||||
|
||||
if (pIndex) *pIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret) printf("Can not find field:%s.", field);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex)
|
||||
{
|
||||
if (!(obj && field && tbl)) return NULL;
|
||||
const reflect_item_t* ret = getReflexItem(field, tbl, pIndex);
|
||||
|
||||
if (!ret) return NULL;
|
||||
|
||||
return (void*)((char*)obj + ret->offset);
|
||||
}
|
||||
|
||||
void csonSetProperty(void* obj, const char* field, void* data, const reflect_item_t* tbl)
|
||||
{
|
||||
if (!(obj && field && data && tbl)) return;
|
||||
|
||||
const reflect_item_t* ret = getReflexItem(field, tbl, NULL);
|
||||
|
||||
if (!ret) return;
|
||||
|
||||
void* pDst = (void*)((char*)obj + ret->offset);
|
||||
memcpy(pDst, data, ret->size);
|
||||
return;
|
||||
}
|
||||
|
||||
void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl)
|
||||
{
|
||||
if (!(obj && data && tbl)) return;
|
||||
|
||||
void* pDst = (void*)((char*)obj + tbl->offset);
|
||||
memcpy(pDst, data, tbl->size);
|
||||
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) {
|
||||
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].arraySize, tbl[i].reflect_tbl, func);
|
||||
}
|
||||
} else if (tbl[i].type == CSON_OBJECT) {
|
||||
csonLoopProperty(pProperty, tbl[i].reflect_tbl, func);
|
||||
}
|
||||
|
||||
func(pProperty, tbl + i);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
/**
|
||||
* @file cson_packer.c
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#include "cson.h"
|
||||
#include "cson_util.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
typedef int (*json_pack_proc)(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
|
||||
static int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonString(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
static int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
|
||||
|
||||
json_pack_proc jsonPackTbl[] = {
|
||||
getJsonObject,
|
||||
getJsonArray,
|
||||
getJsonString,
|
||||
getJsonInteger,
|
||||
getJsonReal,
|
||||
getJsonBool,
|
||||
getJsonBool,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl);
|
||||
|
||||
int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl)
|
||||
{
|
||||
cson_t jsonPack = cson_object();
|
||||
|
||||
if (!jsonPack) return ERR_MEMORY;
|
||||
|
||||
int ret = csonStruct2JsonObj(jsonPack, input, tbl);
|
||||
|
||||
if (ret == ERR_NONE) {
|
||||
char* dumpStr = cson_to_string(jsonPack);
|
||||
if (dumpStr == NULL) {
|
||||
ret = ERR_MEMORY;
|
||||
} else {
|
||||
*jstr = dumpStr;
|
||||
}
|
||||
}
|
||||
|
||||
cson_decref(jsonPack);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = ERR_NONE;
|
||||
|
||||
if (!obj || !input || !tbl) return ERR_ARGS;
|
||||
|
||||
while (1) {
|
||||
if (tbl[i].field == NULL) break;
|
||||
|
||||
cson_t joTmp = NULL;
|
||||
int jsonType = tbl[i].type;
|
||||
|
||||
if (jsonPackTbl[jsonType] != NULL) {
|
||||
ret = jsonPackTbl[jsonType](input, tbl, i, &joTmp);
|
||||
}
|
||||
|
||||
if (ret != ERR_NONE ) {
|
||||
printf("!!!!pack error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
|
||||
if (!tbl[i].nullable) return ret;
|
||||
} else {
|
||||
cson_object_set_new(obj, tbl[i].field, joTmp);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
if(tbl[index].size != sizeof(char) &&
|
||||
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;
|
||||
}
|
||||
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
|
||||
long long val = getIntegerValueFromPointer(pSrc, tbl[index].size);
|
||||
|
||||
*obj = cson_integer(val);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonString(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
|
||||
if (*((char**)pSrc) == NULL) return ERR_MISSING_FIELD;
|
||||
|
||||
*obj = cson_string(*((char**)pSrc));
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
cson_t jotmp = cson_object();
|
||||
int ret = csonStruct2JsonObj(jotmp, pSrc, tbl[index].reflect_tbl);
|
||||
|
||||
if (ret == ERR_NONE) {
|
||||
*obj = jotmp;
|
||||
} else {
|
||||
cson_decref(jotmp);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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].arraySize), tbl[index].reflect_tbl, 0, &jotmp);
|
||||
}else{
|
||||
jotmp = cson_object();
|
||||
ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arraySize), 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 getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
if(tbl[index].size != sizeof(double)){
|
||||
printf("Unsupported size(=%ld) of real.\n", tbl[index].size);
|
||||
printf("Please check if the type of field %s is double!\n", tbl[index].field);
|
||||
return ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
*obj = cson_real(*((double*)pSrc));
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
|
||||
{
|
||||
if(tbl[index].size != sizeof(char) &&
|
||||
tbl[index].size != sizeof(short) &&
|
||||
tbl[index].size != sizeof(int) &&
|
||||
tbl[index].size != sizeof(long long)){
|
||||
printf("Unsupported size(=%ld) of bool.\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;
|
||||
}
|
||||
|
||||
void* pSrc = (void*)((char*)input + tbl[index].offset);
|
||||
|
||||
|
||||
|
||||
if(tbl[index].size == sizeof(char)){
|
||||
*obj = cson_bool(*((char*)pSrc));
|
||||
}else if(tbl[index].size == sizeof(short)){
|
||||
*obj = cson_bool(*((short*)pSrc));
|
||||
}else if(tbl[index].size == sizeof(int)){
|
||||
*obj = cson_bool(*((int*)pSrc));
|
||||
}else{
|
||||
*obj = cson_bool(*((long long*)pSrc));
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
|
@ -1,366 +0,0 @@
|
|||
/**
|
||||
* @file cson_parser.h
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#include "cson.h"
|
||||
#include "cson_util.h"
|
||||
#include "string.h"
|
||||
#include "limits.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
typedef int (*json_obj_proc)(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
|
||||
static int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
|
||||
json_obj_proc jsonObjProcTbl[] = {
|
||||
parseJsonObject,
|
||||
parseJsonArray,
|
||||
parseJsonString,
|
||||
parseJsonInteger,
|
||||
parseJsonReal,
|
||||
parseJsonBool,
|
||||
parseJsonBool,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonArrayDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonStringDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonIntegerDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
static int parseJsonRealDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
|
||||
|
||||
json_obj_proc jsonObjDefaultTbl[] = {
|
||||
parseJsonObjectDefault,
|
||||
parseJsonArrayDefault,
|
||||
parseJsonStringDefault,
|
||||
parseJsonIntegerDefault,
|
||||
parseJsonRealDefault,
|
||||
parseJsonIntegerDefault,
|
||||
parseJsonIntegerDefault,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
typedef union {
|
||||
char c;
|
||||
short s;
|
||||
int i;
|
||||
long long l;
|
||||
}integer_val_t;
|
||||
static int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i);
|
||||
static int convertInteger(long long val, int size, integer_val_t* i);
|
||||
static int checkInteger(long long val, int size);
|
||||
static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl);
|
||||
|
||||
int csonJsonStr2Struct(const char* jstr, void* output, const reflect_item_t* tbl)
|
||||
{
|
||||
/* load json string */
|
||||
cson_t jo = cson_loadb(jstr, strlen(jstr));
|
||||
|
||||
if (!jo) return ERR_FORMAT;
|
||||
|
||||
int ret = csonJsonObj2Struct(jo, output, tbl);
|
||||
cson_decref(jo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl)
|
||||
{
|
||||
if (!jo || !output || !tbl) return ERR_ARGS;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
int ret = ERR_NONE;
|
||||
if (tbl[i].field == NULL) break;
|
||||
|
||||
cson_t jo_tmp = cson_object_get(jo, tbl[i].field);
|
||||
|
||||
if (jo_tmp == NULL) {
|
||||
ret = ERR_MISSING_FIELD;
|
||||
} else {
|
||||
|
||||
int jsonType = cson_typeof(jo_tmp);
|
||||
|
||||
if (jsonType == tbl[i].type ||
|
||||
(cson_is_number(cson_typeof(jo_tmp)) && cson_is_number(tbl[i].type)) ||
|
||||
(cson_is_bool(cson_typeof(jo_tmp)) && cson_is_bool(tbl[i].type))) {
|
||||
if (jsonObjProcTbl[tbl[i].type] != NULL) {
|
||||
ret = jsonObjProcTbl[tbl[i].type](jo_tmp, output, tbl, i);
|
||||
}
|
||||
} else {
|
||||
ret = ERR_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != ERR_NONE ) {
|
||||
printf("!!!!parse error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
|
||||
jsonObjDefaultTbl[tbl[i].type](NULL, output, tbl, i);
|
||||
if (!tbl[i].nullable) return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
const char* tempstr = cson_string_value(jo_tmp);
|
||||
if (NULL != tempstr) {
|
||||
char* pDst = malloc(strlen(tempstr) + 1);
|
||||
if (pDst == NULL) {
|
||||
return ERR_MEMORY;
|
||||
}
|
||||
strcpy(pDst, tempstr);
|
||||
csonSetPropertyFast(output, &pDst, tbl + index);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
return ERR_MISSING_FIELD;
|
||||
}
|
||||
|
||||
|
||||
int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
int ret;
|
||||
integer_val_t value;
|
||||
ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
|
||||
|
||||
if(ret != ERR_NONE){
|
||||
printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
|
||||
}else{
|
||||
csonSetPropertyFast(output, &value, tbl + index);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
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)
|
||||
{
|
||||
printf("parseJsonArray:%s\n", tbl[index].field);
|
||||
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].arraySize);
|
||||
if (pMem == NULL) return ERR_MEMORY;
|
||||
|
||||
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].arraySize), tbl[index].reflect_tbl, 0);
|
||||
}else{
|
||||
ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arraySize), 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;
|
||||
}
|
||||
}
|
||||
|
||||
int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
if(tbl[index].size != sizeof(double)){
|
||||
printf("Unsupported size(=%ld) of real.\n", tbl[index].size);
|
||||
printf("Please check if the type of field %s is double!\n", tbl[index].field);
|
||||
return ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
double temp;
|
||||
if(cson_typeof(jo_tmp) == CSON_REAL){
|
||||
temp = cson_real_value(jo_tmp);
|
||||
}else{
|
||||
temp = cson_integer_value(jo_tmp);
|
||||
}
|
||||
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
|
||||
{
|
||||
int ret;
|
||||
integer_val_t value;
|
||||
ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
|
||||
if(ret != ERR_NONE){
|
||||
printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
|
||||
}else{
|
||||
csonSetPropertyFast(output, &value, tbl + index);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){
|
||||
int i = 0;
|
||||
while(1){
|
||||
if (tbl[index].reflect_tbl[i].field == NULL) break;
|
||||
jsonObjDefaultTbl[tbl[index].reflect_tbl[i].type](NULL, output, tbl[index].reflect_tbl, i);
|
||||
i++;
|
||||
};
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonArrayDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){
|
||||
void* temp = NULL;
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonStringDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){
|
||||
char* temp = NULL;
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int parseJsonIntegerDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){
|
||||
long long temp = 0;
|
||||
|
||||
if(tbl[index].size != sizeof(char) &&
|
||||
tbl[index].size != sizeof(short) &&
|
||||
tbl[index].size != sizeof(int) &&
|
||||
tbl[index].size != sizeof(long long)){
|
||||
printf("Unsupported size(=%ld) of bool.\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;
|
||||
}
|
||||
|
||||
union{
|
||||
char c;
|
||||
short s;
|
||||
int i;
|
||||
long long l;
|
||||
}ret;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int parseJsonRealDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index){
|
||||
if(tbl[index].size != sizeof(double)){
|
||||
printf("Unsupported size(=%ld) of bool.\n", tbl[index].size);
|
||||
printf("Please check if the type of field %s is double!\n", tbl[index].field);
|
||||
return ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
double temp = 0.0;
|
||||
csonSetPropertyFast(output, &temp, tbl + index);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i){
|
||||
long long temp;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return convertInteger(temp, size, i);
|
||||
}
|
||||
|
||||
int convertInteger(long long val, int size, integer_val_t* i){
|
||||
int ret = checkInteger(val, size);
|
||||
|
||||
if(ret != ERR_NONE) return ret;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int checkInteger(long long val, int size){
|
||||
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{
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/**
|
||||
* @file cson_reflect.c
|
||||
* @author sun_chb@126.com
|
||||
*/
|
||||
#include "cson_reflect.h"
|
||||
#include "cson_util.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
const reflect_item_t integerReflectTbl[] = {
|
||||
{"0Integer", 0, sizeof(int), CSON_INTEGER, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
const reflect_item_t stringReflectTbl[] = {
|
||||
{"0String", 0, sizeof(char*), CSON_STRING, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
const reflect_item_t realReflectTbl[] = {
|
||||
{"0Real", 0, sizeof(double), CSON_REAL, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
const reflect_item_t boolReflectTbl[] = {
|
||||
{"0Bool", 0, sizeof(int), CSON_TRUE, NULL, 0, NULL, 1},
|
||||
{}
|
||||
};
|
||||
|
||||
static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex)
|
||||
{
|
||||
const reflect_item_t* ret = NULL;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
if (!(tbl[i].field)) break;
|
||||
if (strcmp(field, tbl[i].field) == 0) {
|
||||
ret = &(tbl[i]);
|
||||
|
||||
if(pIndex) *pIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret) printf("Can not find field:%s.", field);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex)
|
||||
{
|
||||
if (!(obj && field && tbl)) return NULL;
|
||||
const reflect_item_t* ret = getReflexItem(field, tbl, pIndex);
|
||||
|
||||
if (!ret) return NULL;
|
||||
|
||||
return (void*)((char*)obj + ret->offset);
|
||||
}
|
||||
|
||||
void csonSetProperty(void* obj, const char* field, void* data, const reflect_item_t* tbl)
|
||||
{
|
||||
if (!(obj && field && data && tbl)) return;
|
||||
|
||||
const reflect_item_t* ret = getReflexItem(field, tbl, NULL);
|
||||
|
||||
if (!ret) return;
|
||||
|
||||
void* pDst = (void*)((char*)obj + ret->offset);
|
||||
memcpy(pDst, data, ret->size);
|
||||
return;
|
||||
}
|
||||
|
||||
void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl)
|
||||
{
|
||||
if (!(obj && data && tbl)) return;
|
||||
|
||||
void* pDst = (void*)((char*)obj + tbl->offset);
|
||||
memcpy(pDst, data, tbl->size);
|
||||
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) {
|
||||
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].arraySize, tbl[i].reflect_tbl, func);
|
||||
}
|
||||
} else if (tbl[i].type == CSON_OBJECT) {
|
||||
csonLoopProperty(pProperty, tbl[i].reflect_tbl, func);
|
||||
}
|
||||
|
||||
func(pProperty, tbl + i);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#include "cson_util.h"
|
||||
#include "cson_interface.h"
|
||||
#include "limits.h"
|
||||
#include "stdio.h"
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue