From afea66195f8819f27df4ea160c277c5dc115e4dd Mon Sep 17 00:00:00 2001 From: fengzero Date: Mon, 9 Aug 2021 01:26:54 +0000 Subject: [PATCH] wrap json encode/decode --- CMakeLists.txt | 6 +- src/adapter/adapter.c | 4 +- src/utils/json.c | 245 ++++++++++++++++++++++++++++++++++++++++++ src/utils/json.h | 41 ++++++- 4 files changed, 290 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36b6966d..382d627f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ set(CMAKE_C_FLAGS_DEBUG -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking -static-libsan" ) else() -set(CMAKE_C_FLAGS_DEBUG +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -O0 -fsanitize=address \ -fsanitize-recover=address -fsanitize-address-use-after-scope \ -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking -static-libasan" @@ -73,7 +73,7 @@ target_include_directories(neuron PRIVATE ${NEURON_INCLUDE_DIRECTORIES}) if(APPLE) target_link_libraries(neuron nng::nng neuron-base) else() - target_link_libraries(neuron dl nng neuron-base) + target_link_libraries(neuron dl nng jansson neuron-base) endif() target_link_libraries(neuron ${CMAKE_THREAD_LIBS_INIT}) @@ -93,7 +93,7 @@ add_library(neuron-base SHARED) target_sources(neuron-base PRIVATE ${NEURON_BASE_SOURCES}) target_include_directories(neuron-base PRIVATE ${NEURON_BASE_INCLUDE_DIRECTORIES}) -target_link_libraries(neuron-base vector-static ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(neuron-base vector-static jansson ${CMAKE_THREAD_LIBS_INIT}) # define for plugins set(SAMPLE_PLUGIN_SOURCES plugins/plugin_sample.c) diff --git a/src/adapter/adapter.c b/src/adapter/adapter.c index bca3a9b0..d19e93d6 100644 --- a/src/adapter/adapter.c +++ b/src/adapter/adapter.c @@ -71,7 +71,7 @@ static void *load_plugin_library(char * plugin_lib_name, lib_handle = dlopen(plugin_lib_name, RTLD_NOW); if (lib_handle == NULL) { log_error("Failed to open dynamic library %s: %s", plugin_lib_name, - strerror(errno)); + dlerror()); return NULL; } @@ -225,7 +225,7 @@ static int adapter_response(neu_adapter_t *adapter, neu_response_t *resp) core_databuf_t *databuf; databuf = core_databuf_new_with_buf(resp->buf, resp->buf_len); // for debug - log_debug("Get respose buf: %s", core_databuf_get_ptr(databuf)); + log_debug("Get respose buf: %p", core_databuf_get_ptr(databuf)); nng_msg *msg; size_t msg_size; diff --git a/src/utils/json.c b/src/utils/json.c index 7f99976d..228dffcf 100644 --- a/src/utils/json.c +++ b/src/utils/json.c @@ -17,4 +17,249 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ +#include +#include +#include + +#include + #include "json.h" +#include "neu_log.h" + +struct neu_json_ctx { + json_t *root; + json_t *child; + int index; + int size; +}; + +static json_t *encode_object(json_t *object, neu_json_elem_t ele) +{ + json_t *ob = object; + + switch (ele.t) { + case NEU_JSON_INT: + json_object_set(ob, ele.name, json_integer(ele.v.val_int)); + break; + case NEU_JSON_STR: + json_object_set(ob, ele.name, json_string(ele.v.val_str)); + break; + case NEU_JSON_DOUBLE: + json_object_set(ob, ele.name, json_real(ele.v.val_double)); + break; + case NEU_JSON_BOOL: + json_object_set(ob, ele.name, json_boolean(ele.v.val_bool)); + break; + case NEU_JSON_OBJECT: + json_object_set(ob, ele.name, ele.v.object); + break; + default: + break; + } + + return ob; +} + +static int decode_object(json_t *root, neu_json_elem_t *ele) +{ + json_t *ob = NULL; + + ob = json_object_get(root, ele->name); + if (ob == NULL) { + log_error("json decode: %s failed", ele->name); + return -1; + } + + switch (ele->t) { + case NEU_JSON_INT: + ele->v.val_int = json_integer_value(ob); + break; + case NEU_JSON_STR: + ele->v.val_str = strdup(json_string_value(ob)); + break; + case NEU_JSON_DOUBLE: + ele->v.val_double = json_real_value(ob); + break; + case NEU_JSON_BOOL: + ele->v.val_bool = json_boolean_value(ob); + break; + case NEU_JSON_OBJECT: + ele->v.object = ob; + break; + default: + log_error("json decode unknown type: %d", ele->t); + return -1; + } + + return 0; +} + +int neu_json_decode(char *buf, int size, neu_json_elem_t *ele, ...) +{ + json_error_t error; + json_t * root = json_loads(buf, 0, &error); + neu_json_elem_t *tmp = NULL; + + if (root == NULL) { + log_error( + "json load error, line: %d, column: %d, position: %d, info: %s", + error.line, error.column, error.position, error.text); + return -1; + } + + if (decode_object(root, ele) == -1) { + json_decref(root); + return -1; + } + + va_list vl; + va_start(vl, ele); + for (int i = 0; i < size - 1; i++) { + tmp = va_arg(vl, neu_json_elem_t *); + if (decode_object(root, tmp) == -1) { + json_decref(root); + return -1; + } + } + va_end(vl); + + json_decref(root); + return 0; +} + +int neu_json_decode_array_size(char *buf, char *child) +{ + json_error_t error; + json_t * root = json_loads(buf, 0, &error); + json_t * ob; + int ret = -1; + + if (root == NULL) { + log_error( + "json load error, line: %d, column: %d, position: %d, info: %s", + error.line, error.column, error.position, error.text); + return -1; + } + + ob = json_object_get(root, child); + if (ob != NULL && json_is_array(ob)) { + ret = json_array_size(ob); + } else { + log_error("json get array object fail, %s", child); + } + + json_decref(root); + return ret; +} + +neu_json_ctx_t *neu_json_decode_object_get(char *buf, char *child) +{ + json_error_t error; + json_t * root = json_loads(buf, 0, &error); + json_t * ob; + + if (root == NULL) { + log_error( + "json load error, line: %d, column: %d, position: %d, info: %s", + error.line, error.column, error.position, error.text); + return NULL; + } + + ob = json_object_get(root, child); + if (ob != NULL) { + neu_json_ctx_t *ret = calloc(1, sizeof(neu_json_ctx_t)); + + ret->root = root; + ret->child = ob; + + return ret; + } else { + return NULL; + } +} +neu_json_ctx_t *neu_json_decode_object_get_next(neu_json_ctx_t *iter, + char * child) +{ + json_t *ob = json_object_get(iter->child, child); + if (ob != NULL) { + iter->child = ob; + if (json_is_array(ob)) { + iter->index = 0; + iter->size = json_array_size(ob); + } + return iter; + } else { + return NULL; + } +} + +void neu_json_decode_ctx_free(neu_json_ctx_t *t) +{ + json_decref(t->root); + free(t); +} + +neu_json_ctx_t *neu_json_decode_array_next(neu_json_ctx_t *iter, int size, + neu_json_elem_t *ele, ...) +{ + json_t * child = NULL; + neu_json_elem_t *tmp; + + if (iter->size <= 0 || iter->index >= iter->size) { + return NULL; + } + + child = json_array_get(iter->child, iter->index); + if (child == NULL) { + return NULL; + } + + if (decode_object(child, ele) == -1) { + return NULL; + } + + va_list vl; + va_start(vl, ele); + for (int i = 0; i < size - 1; i++) { + tmp = va_arg(vl, neu_json_elem_t *); + if (decode_object(child, tmp) == -1) { + return NULL; + } + } + va_end(vl); + + iter->index += 1; + + return iter; +} + +void *neu_json_encode_array(neu_json_elem_t **t, int n_x, int n_y) +{ + json_t *array = json_array(); + + for (int i = 0; i < n_x; i++) { + json_t *ob = json_object(); + for (int j = 0; j < n_y; j++) { + encode_object(ob, t[i][j]); + } + + json_array_append_new(array, ob); + } + + return array; +} + +int neu_json_encode(neu_json_elem_t *t, int n, char **str) +{ + json_t *root = json_object(); + + for (int i = 0; i < n; i++) { + encode_object(root, t[i]); + } + + *str = json_dumps(root, 0); + + json_decref(root); + + return 0; +} \ No newline at end of file diff --git a/src/utils/json.h b/src/utils/json.h index 74359a1a..e1b1e878 100644 --- a/src/utils/json.h +++ b/src/utils/json.h @@ -18,6 +18,45 @@ **/ #ifndef _NEU_JSON__H_ -#define _NEU_JSON_H_ +#define _NEU_JSON__H_ +#include +#include + +enum neu_json_type { + NEU_JSON_INT = 0, + NEU_JSON_STR, + NEU_JSON_DOUBLE, + NEU_JSON_BOOL, + NEU_JSON_OBJECT +}; + +union neu_json_value { + int64_t val_int; + char * val_str; + double val_double; + bool val_bool; + void * object; +}; + +typedef struct neu_json_elem { + char * name; + enum neu_json_type t; + union neu_json_value v; +} neu_json_elem_t; + +int neu_json_decode(char *buf, int size, neu_json_elem_t *t, ...); + +typedef struct neu_json_ctx neu_json_ctx_t; + +int neu_json_decode_array_size(char *buf, char *child); +void neu_json_decode_ctx_free(neu_json_ctx_t *t); +neu_json_ctx_t *neu_json_decode_object_get(char *buf, char *child); +neu_json_ctx_t *neu_json_decode_object_get_next(neu_json_ctx_t *iter, + char * child); +neu_json_ctx_t *neu_json_decode_array_next(neu_json_ctx_t *iter, int size, + neu_json_elem_t *t, ...); + +void *neu_json_encode_array(neu_json_elem_t **t, int n_x, int n_y); +int neu_json_encode(neu_json_elem_t *t, int n, char **str); #endif