Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/zbxjson/jsonobj.c')
-rw-r--r--src/libs/zbxjson/jsonobj.c366
1 files changed, 366 insertions, 0 deletions
diff --git a/src/libs/zbxjson/jsonobj.c b/src/libs/zbxjson/jsonobj.c
new file mode 100644
index 00000000000..2a7c365284c
--- /dev/null
+++ b/src/libs/zbxjson/jsonobj.c
@@ -0,0 +1,366 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 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 General Public License for more details.
+**
+** You should have received a copy of the GNU 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 "jsonobj.h"
+
+#include "json_parser.h"
+#include "json.h"
+#include "zbxstr.h"
+
+ZBX_PTR_VECTOR_IMPL(jsonobj_ptr, zbx_jsonobj_t *)
+ZBX_VECTOR_IMPL(jsonobj_ref, zbx_jsonobj_ref_t)
+
+/* jsonobject index hashset support */
+
+static zbx_hash_t jsonobj_index_el_hash(const void *v)
+{
+ const zbx_jsonobj_index_el_t *el = (const zbx_jsonobj_index_el_t *)v;
+
+ return ZBX_DEFAULT_STRING_HASH_FUNC(el->value);
+}
+
+static int jsonobj_index_el_compare(const void *v1, const void *v2)
+{
+ const zbx_jsonobj_index_el_t *el1 = (const zbx_jsonobj_index_el_t *)v1;
+ const zbx_jsonobj_index_el_t *el2 = (const zbx_jsonobj_index_el_t *)v2;
+
+ return strcmp(el1->value, el2->value);
+}
+
+/* jsonobject values hashset support */
+
+static zbx_hash_t jsonobj_el_hash(const void *v)
+{
+ const zbx_jsonobj_el_t *el = (const zbx_jsonobj_el_t *)v;
+
+ return ZBX_DEFAULT_STRING_HASH_FUNC(el->name);
+}
+
+static int jsonobj_el_compare(const void *v1, const void *v2)
+{
+ const zbx_jsonobj_el_t *el1 = (const zbx_jsonobj_el_t *)v1;
+ const zbx_jsonobj_el_t *el2 = (const zbx_jsonobj_el_t *)v2;
+
+ return strcmp(el1->name, el2->name);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: initialize json object structure *
+ * *
+ * Parameters: obj - [IN/OUT] the json object to initialize *
+ * type - [IN] the json object type *
+ * *
+ ******************************************************************************/
+void jsonobj_init(zbx_jsonobj_t *obj, zbx_json_type_t type)
+{
+ obj->type = type;
+
+ switch (type)
+ {
+ case ZBX_JSON_TYPE_ARRAY:
+ zbx_vector_jsonobj_ptr_create(&obj->data.array);
+ break;
+ case ZBX_JSON_TYPE_OBJECT:
+ zbx_hashset_create(&obj->data.object, 0, jsonobj_el_hash, jsonobj_el_compare);
+ break;
+ default:
+ memset(&obj->data, 0, sizeof(obj->data));
+ break;
+ }
+
+ obj->index = NULL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: free resources allocated by json object index element *
+ * *
+ * Parameters: v - [IN] the json index element *
+ * *
+ ******************************************************************************/
+static void jsonobj_index_el_clear(void *v)
+{
+ zbx_jsonobj_index_el_t *el = (zbx_jsonobj_index_el_t *)v;
+ int i;
+
+ zbx_free(el->value);
+ for (i = 0; i < el->objects.values_num; i++)
+ {
+ zbx_free(el->objects.values[i].name);
+
+ if (0 != el->objects.values[i].external)
+ {
+ zbx_jsonobj_clear(el->objects.values[i].value);
+ zbx_free(el->objects.values[i].value);
+ }
+ }
+
+ zbx_vector_jsonobj_ref_destroy(&el->objects);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: initialize json object index *
+ * *
+ * Parameters: obj - [IN/OUT] the json object *
+ * path - [IN] the indexed relative path *
+ * *
+ ******************************************************************************/
+void jsonobj_init_index(zbx_jsonobj_t *obj, const char *path)
+{
+ obj->index = (zbx_jsonobj_index_t *)zbx_malloc(NULL, sizeof(zbx_jsonobj_index_t));
+ obj->index->path = zbx_strdup(NULL, path);
+ zbx_hashset_create_ext(&obj->index->objects, 0, jsonobj_index_el_hash, jsonobj_index_el_compare,
+ jsonobj_index_el_clear, ZBX_DEFAULT_MEM_MALLOC_FUNC, ZBX_DEFAULT_MEM_REALLOC_FUNC,
+ ZBX_DEFAULT_MEM_FREE_FUNC);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: set string value to json object *
+ * *
+ ******************************************************************************/
+void jsonobj_set_string(zbx_jsonobj_t *obj, char *str)
+{
+ obj->type = ZBX_JSON_TYPE_STRING;
+ obj->data.string = str;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: set numeric value to json object *
+ * *
+ ******************************************************************************/
+void jsonobj_set_number(zbx_jsonobj_t *obj, double number)
+{
+ obj->type = ZBX_JSON_TYPE_NUMBER;
+ obj->data.number = number;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: set true value to json object *
+ * *
+ ******************************************************************************/
+void jsonobj_set_true(zbx_jsonobj_t *obj)
+{
+ obj->type = ZBX_JSON_TYPE_TRUE;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: set false value to json object *
+ * *
+ ******************************************************************************/
+void jsonobj_set_false(zbx_jsonobj_t *obj)
+{
+ obj->type = ZBX_JSON_TYPE_FALSE;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: set null value to json object *
+ * *
+ ******************************************************************************/
+void jsonobj_set_null(zbx_jsonobj_t *obj)
+{
+ obj->type = ZBX_JSON_TYPE_NULL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: initialize json object element *
+ * *
+ ******************************************************************************/
+void jsonobj_el_init(zbx_jsonobj_el_t *el)
+{
+ el->name = NULL;
+ jsonobj_init(&el->value, ZBX_JSON_TYPE_UNKNOWN);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: free resources allocated by json object element *
+ * *
+ ******************************************************************************/
+void jsonobj_el_clear(zbx_jsonobj_el_t *el)
+{
+ zbx_free(el->name);
+ zbx_jsonobj_clear(&el->value);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: free json object *
+ * *
+ ******************************************************************************/
+static void jsonobj_free(zbx_jsonobj_t *obj)
+{
+ zbx_jsonobj_clear(obj);
+ zbx_free(obj);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: free resources allocated by json object *
+ * *
+ ******************************************************************************/
+void zbx_jsonobj_clear(zbx_jsonobj_t *obj)
+{
+ zbx_jsonobj_el_t *el;
+ zbx_hashset_iter_t iter;
+
+ switch (obj->type)
+ {
+ case ZBX_JSON_TYPE_STRING:
+ zbx_free(obj->data.string);
+ break;
+ case ZBX_JSON_TYPE_ARRAY:
+ zbx_vector_jsonobj_ptr_clear_ext(&obj->data.array, jsonobj_free);
+ zbx_vector_jsonobj_ptr_destroy(&obj->data.array);
+ break;
+ case ZBX_JSON_TYPE_OBJECT:
+ zbx_hashset_iter_reset(&obj->data.object, &iter);
+ while (NULL != (el = (zbx_jsonobj_el_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zbx_free(el->name);
+ zbx_jsonobj_clear(&el->value);
+ }
+ zbx_hashset_destroy(&obj->data.object);
+ break;
+ default:
+ break;
+ }
+
+ if (NULL != obj->index)
+ {
+ zbx_free(obj->index->path);
+ zbx_hashset_destroy(&obj->index->objects);
+ zbx_free(obj->index);
+ }
+}
+
+/******************************************************************************
+ * *
+ * Purpose: convert json object to text format *
+ * *
+ ******************************************************************************/
+int zbx_jsonobj_to_string(char **str, size_t *str_alloc, size_t *str_offset, zbx_jsonobj_t *obj)
+{
+ char *tmp, buf[32], delim;
+ int i;
+ zbx_hashset_iter_t iter;
+ zbx_jsonobj_el_t *el;
+
+ switch (obj->type)
+ {
+ case ZBX_JSON_TYPE_TRUE:
+ zbx_strcpy_alloc(str, str_alloc, str_offset, "true");
+ break;
+ case ZBX_JSON_TYPE_FALSE:
+ zbx_strcpy_alloc(str, str_alloc, str_offset, "false");
+ break;
+ case ZBX_JSON_TYPE_NULL:
+ zbx_strcpy_alloc(str, str_alloc, str_offset, "null");
+ break;
+ case ZBX_JSON_TYPE_STRING:
+ tmp = zbx_strdup(NULL, obj->data.string);
+ zbx_json_escape(&tmp);
+ zbx_snprintf_alloc(str, str_alloc, str_offset, "\"%s\"", tmp);
+ zbx_free(tmp);
+ break;
+ case ZBX_JSON_TYPE_NUMBER:
+ zbx_print_double(buf, sizeof(buf), obj->data.number);
+ zbx_strcpy_alloc(str, str_alloc, str_offset, buf);
+ break;
+ case ZBX_JSON_TYPE_ARRAY:
+ delim = '[';
+ for (i = 0; i < obj->data.array.values_num; i++)
+ {
+ zbx_chrcpy_alloc(str, str_alloc, str_offset, delim);
+ delim = ',';
+ zbx_jsonobj_to_string(str, str_alloc, str_offset, obj->data.array.values[i]);
+ }
+ zbx_chrcpy_alloc(str, str_alloc, str_offset, ']');
+ break;
+ case ZBX_JSON_TYPE_OBJECT:
+ delim = '{';
+ zbx_hashset_iter_reset(&obj->data.object, &iter);
+ while (NULL != (el = (zbx_jsonobj_el_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zbx_chrcpy_alloc(str, str_alloc, str_offset, delim);
+ delim = ',';
+
+ tmp = zbx_strdup(NULL, el->name);
+ zbx_json_escape(&tmp);
+ zbx_snprintf_alloc(str, str_alloc, str_offset, "\"%s\"", tmp);
+ zbx_chrcpy_alloc(str, str_alloc, str_offset, ':');
+ zbx_free(tmp);
+
+ zbx_jsonobj_to_string(str, str_alloc, str_offset, &el->value);
+ }
+ zbx_chrcpy_alloc(str, str_alloc, str_offset, '}');
+ break;
+ default:
+ zbx_set_json_strerror("unknown json object with type: %u", obj->type);
+ return FAIL;
+ }
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: parses json formatted data into json object structure *
+ * *
+ ******************************************************************************/
+int zbx_jsonobj_open(const char *data, zbx_jsonobj_t *obj)
+{
+ int ret = FAIL;
+ char *error = NULL;
+
+ switch (*data)
+ {
+ case '{':
+ if (0 == json_parse_object(data, obj, &error))
+ goto out;
+ break;
+ case '[':
+ if (0 == json_parse_array(data, obj, &error))
+ goto out;
+ break;
+ default:
+ /* not json data, failing */
+ jsonobj_init(obj, ZBX_JSON_TYPE_UNKNOWN);
+ (void)json_error("invalid object format, expected opening character '{' or '['", data, &error);
+ goto out;
+ }
+
+ ret = SUCCEED;
+out:
+ if (FAIL == ret)
+ {
+ zbx_jsonobj_clear(obj);
+ zbx_set_json_strerror("%s", error);
+ zbx_free(error);
+ }
+
+ return ret;
+}