mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
libxl: Convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object
Convert yajl_gen to json_object from lib json-c. And make use of it in qmp_prepare_cmd(), which can be compiled with either lib. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
This commit is contained in:
1 parent
7e95dab9eb
commit
a6fd4a1c55
4 files changed
+166
No files matched your search
@@ -15,12 +15,18 @@
|
||||
#ifndef LIBXL_JSON_H
|
||||
#define LIBXL_JSON_H
|
||||
|
||||
#ifdef HAVE_LIBJSONC
|
||||
#include <json-c/json.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBYAJL
|
||||
#include <yajl/yajl_gen.h>
|
||||
#include <yajl/yajl_parse.h>
|
||||
|
||||
#ifdef HAVE_YAJL_YAJL_VERSION_H
|
||||
# include <yajl/yajl_version.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val);
|
||||
yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p);
|
||||
|
||||
@@ -2234,9 +2234,16 @@ _hidden const libxl__json_object *libxl__json_map_get(const char *key,
|
||||
*/
|
||||
_hidden libxl__json_object *libxl__json_object_alloc(libxl__gc *gc_opt,
|
||||
libxl__json_node_type type);
|
||||
#ifdef HAVE_LIBJSONC
|
||||
_hidden int libxl__json_object_to_json_object(libxl__gc *gc,
|
||||
json_object **jso_out,
|
||||
const libxl__json_object *obj);
|
||||
#endif
|
||||
#ifdef HAVE_LIBYAJL
|
||||
_hidden yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc_opt,
|
||||
yajl_gen hand,
|
||||
const libxl__json_object *param);
|
||||
#endif
|
||||
_hidden void libxl__json_object_free(libxl__gc *gc_opt,
|
||||
libxl__json_object *obj);
|
||||
|
||||
|
||||
@@ -631,6 +631,105 @@ const libxl__json_object *libxl__json_map_get(const char *key,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBJSONC
|
||||
int libxl__json_object_to_json_object(libxl__gc *gc,
|
||||
json_object **jso_out,
|
||||
const libxl__json_object *obj)
|
||||
{
|
||||
int idx = 0;
|
||||
int rc, r;
|
||||
|
||||
switch (obj->type) {
|
||||
case JSON_NULL:
|
||||
*jso_out = json_object_new_null();
|
||||
return 0;
|
||||
case JSON_BOOL:
|
||||
*jso_out = json_object_new_boolean(obj->u.b);
|
||||
if (!*jso_out)
|
||||
return ERROR_NOMEM;
|
||||
return 0;
|
||||
case JSON_INTEGER:
|
||||
*jso_out = json_object_new_int64(obj->u.i);
|
||||
if (!*jso_out)
|
||||
return ERROR_NOMEM;
|
||||
return 0;
|
||||
case JSON_DOUBLE:
|
||||
*jso_out = json_object_new_double(obj->u.d);
|
||||
if (!*jso_out)
|
||||
return ERROR_NOMEM;
|
||||
return 0;
|
||||
case JSON_NUMBER:
|
||||
/*
|
||||
* Use json_object_new_double_s() to rewrite the number exactly as
|
||||
* we parsed it. When generating the JSON string the value `0` will
|
||||
* be ignored and `obj->u.string` will be written instead.
|
||||
*/
|
||||
*jso_out = json_object_new_double_s(0, obj->u.string);
|
||||
if (!*jso_out)
|
||||
return ERROR_NOMEM;
|
||||
return 0;
|
||||
case JSON_STRING:
|
||||
*jso_out = json_object_new_string(obj->u.string);
|
||||
if (!*jso_out)
|
||||
return ERROR_NOMEM;
|
||||
return 0;
|
||||
case JSON_MAP: {
|
||||
libxl__json_map_node *node = NULL;
|
||||
json_object *map_root = json_object_new_object();
|
||||
json_object *node_value;
|
||||
|
||||
for (idx = 0; idx < obj->u.map->count; idx++) {
|
||||
if (flexarray_get(obj->u.map, idx, (void**)&node) != 0)
|
||||
break;
|
||||
|
||||
rc = libxl__json_object_to_json_object(gc, &node_value, node->obj);
|
||||
if (rc) {
|
||||
json_object_put(map_root);
|
||||
return rc;
|
||||
}
|
||||
|
||||
r = json_object_object_add(map_root, node->map_key, node_value);
|
||||
if (r < 0) {
|
||||
json_object_put(node_value);
|
||||
json_object_put(map_root);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
*jso_out = map_root;
|
||||
return 0;
|
||||
}
|
||||
case JSON_ARRAY: {
|
||||
libxl__json_object *node = NULL;
|
||||
json_object *array_root = json_object_new_array_ext(obj->u.array->count);
|
||||
json_object *node_value;
|
||||
|
||||
for (idx = 0; idx < obj->u.array->count; idx++) {
|
||||
if (flexarray_get(obj->u.array, idx, (void**)&node) != 0)
|
||||
break;
|
||||
|
||||
rc = libxl__json_object_to_json_object(gc, &node_value, node);
|
||||
if (rc) {
|
||||
json_object_put(array_root);
|
||||
return rc;
|
||||
}
|
||||
r = json_object_array_add(array_root, node_value);
|
||||
if (r < 0) {
|
||||
json_object_put(node_value);
|
||||
json_object_put(array_root);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
*jso_out = array_root;
|
||||
return 0;
|
||||
}
|
||||
case JSON_ANY:
|
||||
default:
|
||||
/* JSON_ANY is not a valid value for obj->type. */
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LIBYAJL
|
||||
yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc,
|
||||
yajl_gen hand,
|
||||
const libxl__json_object *obj)
|
||||
@@ -698,6 +797,7 @@ yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc,
|
||||
abort();
|
||||
#undef CONVERT_YAJL_GEN_TO_STATUS
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -61,7 +61,11 @@
|
||||
|
||||
#include <sys/un.h>
|
||||
|
||||
#ifdef HAVE_LIBJSONC
|
||||
#include <json-c/json.h>
|
||||
#elif defined(HAVE_LIBYAJL)
|
||||
#include <yajl/yajl_gen.h>
|
||||
#endif
|
||||
|
||||
#include "xen_list.h"
|
||||
#include "libxl_internal.h"
|
||||
@@ -481,13 +485,56 @@ static char *qmp_prepare_cmd(libxl__gc *gc, const char *cmd,
|
||||
const libxl__json_object *args,
|
||||
int id)
|
||||
{
|
||||
#ifdef HAVE_LIBJSONC
|
||||
json_object *jso = NULL;
|
||||
json_object *jso_value = NULL;
|
||||
/* memory for 'buf' is owned by 'jso' */
|
||||
const char *buf;
|
||||
int rc, r;
|
||||
#elif defined(HAVE_LIBYAJL)
|
||||
yajl_gen hand = NULL;
|
||||
/* memory for 'buf' is owned by 'hand' */
|
||||
const unsigned char *buf;
|
||||
libxl_yajl_length len;
|
||||
yajl_gen_status s;
|
||||
#else
|
||||
# error Missing JSON library
|
||||
#endif
|
||||
char *ret = NULL;
|
||||
|
||||
#ifdef HAVE_LIBJSONC
|
||||
jso = json_object_new_object();
|
||||
if (!jso)
|
||||
goto out;
|
||||
|
||||
jso_value = json_object_new_string(cmd);
|
||||
if (!jso_value)
|
||||
goto out;
|
||||
r = json_object_object_add(jso, "execute", jso_value);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
jso_value = json_object_new_int(id);
|
||||
if (!jso_value)
|
||||
goto out;
|
||||
r = json_object_object_add(jso, "id", jso_value);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
/* `jso_value` now part of `jso`, shouldn't free it anymore */
|
||||
jso_value = NULL;
|
||||
if (args) {
|
||||
rc = libxl__json_object_to_json_object(gc, &jso_value, args);
|
||||
if (rc)
|
||||
goto out;
|
||||
r = json_object_object_add(jso, "arguments", jso_value);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
jso_value = NULL;
|
||||
}
|
||||
|
||||
buf = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PLAIN);
|
||||
ret = libxl__sprintf(gc, "%s\r\n", buf);
|
||||
|
||||
#elif defined(HAVE_LIBYAJL)
|
||||
hand = libxl_yajl_gen_alloc(NULL);
|
||||
|
||||
if (!hand) {
|
||||
@@ -516,9 +563,15 @@ static char *qmp_prepare_cmd(libxl__gc *gc, const char *cmd,
|
||||
goto out;
|
||||
|
||||
ret = libxl__sprintf(gc, "%*.*s\r\n", (int)len, (int)len, buf);
|
||||
#endif
|
||||
|
||||
out:
|
||||
#ifdef HAVE_LIBJSONC
|
||||
json_object_put(jso_value);
|
||||
json_object_put(jso);
|
||||
#elif defined(HAVE_LIBYAJL)
|
||||
yajl_gen_free(hand);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||