[PATCH] util: json: Remove yajl bits from virJSONValueToStr

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

 



Rather than depending on yajl bits for creating the JSON structure
replace it by few virBuffer bits. This will make the JSON formatter
libary agnostic.

Additionally remove the debug statement from the worker function since
it was not very useful.

Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx>
---
 src/util/virjson.c | 188 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 101 insertions(+), 87 deletions(-)

diff --git a/src/util/virjson.c b/src/util/virjson.c
index 6a02ddf0cc..772a205e9e 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1834,144 +1834,158 @@ virJSONValueFromString(const char *jsonstring)
     return ret;
 }

+#else
+virJSONValuePtr
+virJSONValueFromString(const char *jsonstring ATTRIBUTE_UNUSED)
+{
+    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                   _("No JSON parser implementation is available"));
+    return NULL;
+}
+#endif
+
+
+static void
+virJSONValueToStringAddString(virBufferPtr buf,
+                              virJSONValuePtr string)
+{
+    const char *t;
+
+    virBufferAddLit(buf, "\"");
+
+    for (t = string->data.string; *t; t++) {
+        switch (*t) {
+        case '"':
+            virBufferAddLit(buf, "\\\"");
+            break;
+        case '\\':
+            virBufferAddLit(buf, "\\\\");
+            break;
+        case '\n':
+            virBufferAddLit(buf, "\\n");
+            break;
+        case '\t':
+            virBufferAddLit(buf, "\\t");
+            break;
+        default:
+            virBufferAdd(buf, t, 1);
+            break;
+        }
+    }
+
+    virBufferAddLit(buf, "\"");
+}
+
+
+#define VIR_JSON_PRETTY_NEWLINE \
+    if (pretty) \
+        virBufferAddLit(buf, "\n")

 static int
 virJSONValueToStringOne(virJSONValuePtr object,
-                        yajl_gen g)
+                        virBufferPtr buf,
+                        bool pretty)
 {
     size_t i;

-    VIR_DEBUG("object=%p type=%d gen=%p", object, object->type, g);
-
-    switch (object->type) {
+    switch ((virJSONType) object->type) {
     case VIR_JSON_TYPE_OBJECT:
-        if (yajl_gen_map_open(g) != yajl_gen_status_ok)
-            return -1;
+        virBufferAddLit(buf, "{");
+        VIR_JSON_PRETTY_NEWLINE;
+        virBufferAdjustIndent(buf, 2);
+
         for (i = 0; i < object->data.object.npairs; i++) {
-            if (yajl_gen_string(g,
-                                (unsigned char *)object->data.object.pairs[i].key,
-                                strlen(object->data.object.pairs[i].key))
-                                != yajl_gen_status_ok)
-                return -1;
-            if (virJSONValueToStringOne(object->data.object.pairs[i].value, g) < 0)
+            virBufferStrcat(buf, "\"", object->data.object.pairs[i].key, "\":", NULL);
+
+            if (pretty)
+                virBufferAddLit(buf, " ");
+
+            if (virJSONValueToStringOne(object->data.object.pairs[i].value,
+                                        buf, pretty) < 0)
                 return -1;
+
+            if (i != object->data.object.npairs - 1) {
+                virBufferAddLit(buf, ",");
+                VIR_JSON_PRETTY_NEWLINE;
+            }
         }
-        if (yajl_gen_map_close(g) != yajl_gen_status_ok)
-            return -1;
+
+        virBufferAdjustIndent(buf, -2);
+        VIR_JSON_PRETTY_NEWLINE;
+        virBufferAddLit(buf, "}");
         break;
+
     case VIR_JSON_TYPE_ARRAY:
-        if (yajl_gen_array_open(g) != yajl_gen_status_ok)
-            return -1;
+        virBufferAddLit(buf, "[");
+        VIR_JSON_PRETTY_NEWLINE;
+        virBufferAdjustIndent(buf, 2);
+
         for (i = 0; i < object->data.array.nvalues; i++) {
-            if (virJSONValueToStringOne(object->data.array.values[i], g) < 0)
+            if (virJSONValueToStringOne(object->data.array.values[i], buf, pretty) < 0)
                 return -1;
+
+            if (i != object->data.array.nvalues - 1) {
+                virBufferAddLit(buf, ",");
+                VIR_JSON_PRETTY_NEWLINE;
+            }
         }
-        if (yajl_gen_array_close(g) != yajl_gen_status_ok)
-            return -1;
+
+        virBufferAdjustIndent(buf, -2);
+        VIR_JSON_PRETTY_NEWLINE;
+        virBufferAddLit(buf, "]");
         break;

     case VIR_JSON_TYPE_STRING:
-        if (yajl_gen_string(g, (unsigned char *)object->data.string,
-                            strlen(object->data.string)) != yajl_gen_status_ok)
-            return -1;
+        virJSONValueToStringAddString(buf, object);
         break;

     case VIR_JSON_TYPE_NUMBER:
-        if (yajl_gen_number(g, object->data.number,
-                            strlen(object->data.number)) != yajl_gen_status_ok)
-            return -1;
+        virBufferAdd(buf, object->data.number, -1);
         break;

     case VIR_JSON_TYPE_BOOLEAN:
-        if (yajl_gen_bool(g, object->data.boolean) != yajl_gen_status_ok)
-            return -1;
+        if (object->data.boolean)
+            virBufferAddLit(buf, "true");
+        else
+            virBufferAddLit(buf, "false");
         break;

     case VIR_JSON_TYPE_NULL:
-        if (yajl_gen_null(g) != yajl_gen_status_ok)
-            return -1;
+        virBufferAddLit(buf, "null");
         break;

     default:
+        virReportEnumRangeError(virJSONType, object->type);
         return -1;
     }

     return 0;
 }

+#undef VIR_JSON_PRETTY_NEWLINE
+

 char *
 virJSONValueToString(virJSONValuePtr object,
                      bool pretty)
 {
-    yajl_gen g;
-    const unsigned char *str;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *ret = NULL;
-    yajl_size_t len;
-# ifndef WITH_YAJL2
-    yajl_gen_config conf = { pretty ? 1 : 0, pretty ? "  " : " "};
-# endif

     VIR_DEBUG("object=%p", object);

-# ifdef WITH_YAJL2
-    g = yajl_gen_alloc(NULL);
-    if (g) {
-        yajl_gen_config(g, yajl_gen_beautify, pretty ? 1 : 0);
-        yajl_gen_config(g, yajl_gen_indent_string, pretty ? "  " : " ");
-        yajl_gen_config(g, yajl_gen_validate_utf8, 1);
-    }
-# else
-    g = yajl_gen_alloc(&conf, NULL);
-# endif
-    if (!g) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Unable to create JSON formatter"));
-        goto cleanup;
-    }
-
-    if (virJSONValueToStringOne(object, g) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    if (yajl_gen_get_buf(g, &str, &len) != yajl_gen_status_ok) {
-        virReportOOMError();
-        goto cleanup;
+    if (virJSONValueToStringOne(object, &buf, pretty) < 0 ||
+        virBufferCheckError(&buf) < 0) {
+        virBufferFreeAndReset(&buf);
+        return NULL;
     }

-    ignore_value(VIR_STRDUP(ret, (const char *)str));
-
- cleanup:
-    yajl_gen_free(g);
-
-    VIR_DEBUG("result=%s", NULLSTR(ret));
-
+    ret = virBufferContentAndReset(&buf);
+    VIR_DEBUG("result=%s", ret);
     return ret;
 }


-#else
-virJSONValuePtr
-virJSONValueFromString(const char *jsonstring ATTRIBUTE_UNUSED)
-{
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("No JSON parser implementation is available"));
-    return NULL;
-}
-
-
-char *
-virJSONValueToString(virJSONValuePtr object ATTRIBUTE_UNUSED,
-                     bool pretty ATTRIBUTE_UNUSED)
-{
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("No JSON parser implementation is available"));
-    return NULL;
-}
-#endif
-
-
 /**
  * virJSONStringReformat:
  * @jsonstr: string to reformat
-- 
2.14.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux