Files
neuron/src/utils/json.c
T
2022-09-06 08:23:30 +00:00

409 lines
9.6 KiB
C

/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2022 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 <stdlib.h>
#include <string.h>
#include <jansson.h>
#include "utils/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_realp(ele->v.val_double, ele->precision);
break;
case NEU_JSON_FLOAT:
ob = json_realp(ele->v.val_float, ele->precision);
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_realp(ele.v.val_float, ele.precision));
break;
case NEU_JSON_DOUBLE:
json_object_set_new(ob, ele.name,
json_realp(ele.v.val_double, ele.precision));
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) {
if (ele->attribute == NEU_JSON_ATTRIBUTE_OPTIONAL) {
return 0;
}
zlog_error(neuron, "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:
if (json_is_integer(ob)) {
ele->v.val_float = (float) json_integer_value(ob);
} else {
ele->v.val_float = json_real_value(ob);
}
break;
case NEU_JSON_DOUBLE:
if (json_is_integer(ob)) {
ele->v.val_double = (double) json_integer_value(ob);
} else {
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:
zlog_error(neuron, "json decode unknown type: %d", ele->t);
return -1;
}
return 0;
}
void *neu_json_array()
{
return json_array();
}
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) {
zlog_error(neuron,
"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_by_json(void *json, int size, neu_json_elem_t *ele)
{
if (json == NULL) {
zlog_error(neuron, "The param json is NULL");
return -1;
}
for (int i = 0; i < size; i++) {
if (decode_object(json, &ele[i]) == -1) {
return -1;
}
}
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) {
zlog_error(
neuron,
"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 {
zlog_error(neuron, "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) {
zlog_error(
neuron,
"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 {
zlog_error(neuron, "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) {
zlog_error(
neuron,
"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_newb(char *buf, size_t len)
{
json_error_t error;
json_t * root = json_loadb(buf, len, 0, &error);
if (root == NULL) {
zlog_error(
neuron,
"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);
}