/** * NEURON IIoT System for Industry 4.0 * Copyright (C) 2020-2021 EMQ Technologies Co., Ltd All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include #include #include #include "neu_log.h" #include "json/json.h" static json_t *encode_object_value(neu_json_elem_t *ele) { json_t *ob = NULL; switch (ele->t) { case NEU_JSON_BIT: ob = json_integer(ele->v.val_bit); break; case NEU_JSON_INT: ob = json_integer(ele->v.val_int); break; case NEU_JSON_STR: ob = json_string(ele->v.val_str); break; case NEU_JSON_DOUBLE: ob = json_real(ele->v.val_double); break; case NEU_JSON_FLOAT: ob = json_real(ele->v.val_float); break; case NEU_JSON_BOOL: ob = json_boolean(ele->v.val_bool); break; default: break; } return ob; } static json_t *encode_object(json_t *object, neu_json_elem_t ele) { json_t *ob = object; switch (ele.t) { case NEU_JSON_BIT: json_object_set_new(ob, ele.name, json_integer(ele.v.val_bit)); break; case NEU_JSON_INT: json_object_set_new(ob, ele.name, json_integer(ele.v.val_int)); break; case NEU_JSON_STR: json_object_set_new(ob, ele.name, json_string(ele.v.val_str)); break; case NEU_JSON_FLOAT: json_object_set_new(ob, ele.name, json_real(ele.v.val_float)); break; case NEU_JSON_DOUBLE: json_object_set_new(ob, ele.name, json_real(ele.v.val_double)); break; case NEU_JSON_BOOL: json_object_set_new(ob, ele.name, json_boolean(ele.v.val_bool)); break; case NEU_JSON_OBJECT: json_object_set_new(ob, ele.name, ele.v.val_object); break; default: break; } return ob; } static int decode_object(json_t *root, neu_json_elem_t *ele) { json_t *ob = NULL; if (ele->name == NULL) { ob = root; } else { ob = json_object_get(root, ele->name); } if (ob == NULL) { log_error("json decode: %s failed", ele->name); return -1; } if (ele->t == NEU_JSON_UNDEFINE) { if (json_is_string(ob)) { ele->t = NEU_JSON_STR; } else if (json_is_real(ob)) { ele->t = NEU_JSON_DOUBLE; } else if (json_is_boolean(ob)) { ele->t = NEU_JSON_BOOL; } else if (json_is_integer(ob)) { ele->t = NEU_JSON_INT; } } switch (ele->t) { case NEU_JSON_BIT: ele->v.val_bit = json_integer_value(ob); break; 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_FLOAT: ele->v.val_float = json_real_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.val_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); 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; } for (int i = 0; i < size; i++) { if (decode_object(root, &ele[i]) == -1) { json_decref(root); return -1; } } json_decref(root); return 0; } int neu_json_decode_array(char *buf, char *name, int index, int size, neu_json_elem_t *ele) { json_t * child = NULL; json_t * object = NULL; json_error_t error; json_t * root = json_loads(buf, 0, &error); 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; } object = json_object_get(root, name); if (object == NULL) { json_decref(root); return -1; } child = json_array_get(object, index); if (child == NULL) { json_decref(root); return -1; } for (int i = 0; i < size; i++) { if (decode_object(child, &ele[i]) == -1) { json_decref(root); return -1; } } json_decref(root); return 0; } int neu_json_decode_array_by_json(void *json, char *name, int index, int size, neu_json_elem_t *ele) { json_t *child = NULL; json_t *object = NULL; object = json_object_get(json, name); if (object == NULL) { return -1; } child = json_array_get(object, index); if (child == NULL) { return -1; } for (int i = 0; i < size; i++) { if (decode_object(child, &ele[i]) == -1) { return -1; } } return 0; } int neu_json_decode_array_size_by_json(void *json, char *child) { json_t *ob; int ret = -1; ob = json_object_get(json, child); if (ob != NULL && json_is_array(ob)) { ret = json_array_size(ob); } else { log_error("json get array object fail, %s", child); } return ret; } 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; } void *neu_json_encode_array_value(void *array, neu_json_elem_t *t, int n) { if (array == NULL) { array = json_array(); } for (int i = 0; i < n; i++) { json_array_append_new(array, encode_object_value(&t[i])); } return array; } void *neu_json_encode_array(void *array, neu_json_elem_t *t, int n) { if (array == NULL) { array = json_array(); } json_t *ob = json_object(); for (int j = 0; j < n; j++) { encode_object(ob, t[j]); } json_array_append_new(array, ob); return array; } void *neu_json_encode_new() { return json_object(); } void neu_json_encode_free(void *json_object) { free(json_object); } int neu_json_encode_field(void *json_object, neu_json_elem_t *elem, int n) { for (int i = 0; i < n; i++) { encode_object(json_object, elem[i]); } return 0; } int neu_json_encode(void *json_object, char **str) { *str = json_dumps(json_object, JSON_REAL_PRECISION(16)); json_decref(json_object); return 0; } void *neu_json_decode_new(char *buf) { json_error_t error; json_t * root = json_loads(buf, 0, &error); 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; } return root; } void neu_json_decode_free(void *ob) { json_decref(ob); } int neu_json_decode_value(void *object, neu_json_elem_t *ele) { return decode_object(object, ele); }