[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object



From: Anthony PERARD <anthony.perard@xxxxxxxxxx>

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@xxxxxxxxxx>
---
 tools/include/libxl_json.h        |  6 ++
 tools/libs/light/libxl_internal.h |  7 +++
 tools/libs/light/libxl_json.c     | 95 +++++++++++++++++++++++++++++++
 tools/libs/light/libxl_qmp.c      | 53 +++++++++++++++++
 4 files changed, 161 insertions(+)

diff --git a/tools/include/libxl_json.h b/tools/include/libxl_json.h
index f0b4871e0e..e2ef8151f0 100644
--- a/tools/include/libxl_json.h
+++ b/tools/include/libxl_json.h
@@ -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);
diff --git a/tools/libs/light/libxl_internal.h 
b/tools/libs/light/libxl_internal.h
index 4b6587a27a..b66aaa779d 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -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);
 
diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c
index 44ee6e213f..b26ac901d6 100644
--- a/tools/libs/light/libxl_json.c
+++ b/tools/libs/light/libxl_json.c
@@ -631,6 +631,100 @@ 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:
+        *jso_out = json_object_new_string(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 +792,7 @@ yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc,
     abort();
 #undef CONVERT_YAJL_GEN_TO_STATUS
 }
+#endif
 
 
 /*
diff --git a/tools/libs/light/libxl_qmp.c b/tools/libs/light/libxl_qmp.c
index 84740bd4b3..94b6fdb559 100644
--- a/tools/libs/light/libxl_qmp.c
+++ b/tools/libs/light/libxl_qmp.c
@@ -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;
 }
 
-- 
Anthony PERARD




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.