[libvirt] [PATCH 01/15] util: add virJSONValueCopy

Martin Kletzander mkletzan at redhat.com
Thu Apr 16 14:46:36 UTC 2015


Faster version of virJSONValueFromString(virJSONValueToString()).

Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 src/libvirt_private.syms |   1 +
 src/util/virjson.c       |  65 ++++++++++++++++++++++++++-
 src/util/virjson.h       |   4 +-
 tests/jsontest.c         | 111 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index aafc385..0335313 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1573,6 +1573,7 @@ virJSONValueArrayAppend;
 virJSONValueArrayGet;
 virJSONValueArraySize;
 virJSONValueArraySteal;
+virJSONValueCopy;
 virJSONValueFree;
 virJSONValueFromString;
 virJSONValueGetArrayAsBitmap;
diff --git a/src/util/virjson.c b/src/util/virjson.c
index c8d761f..40ec613 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1,7 +1,7 @@
 /*
  * virjson.c: JSON object parsing/formatting
  *
- * Copyright (C) 2009-2010, 2012-2013 Red Hat, Inc.
+ * Copyright (C) 2009-2010, 2012-2015 Red Hat, Inc.
  * Copyright (C) 2009 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -1233,6 +1233,69 @@ virJSONValueObjectForeachKeyValue(virJSONValuePtr object,
 }


+virJSONValuePtr
+virJSONValueCopy(virJSONValuePtr in)
+{
+    size_t i;
+    virJSONValuePtr out = NULL;
+
+    if (!in)
+        return NULL;
+
+    switch ((virJSONType) in->type) {
+    case VIR_JSON_TYPE_OBJECT:
+        out = virJSONValueNewObject();
+        if (!out)
+            return NULL;
+        for (i = 0; i < in->data.object.npairs; i++) {
+            virJSONValuePtr val = NULL;
+            if (!(val = virJSONValueCopy(in->data.object.pairs[i].value)))
+                goto error;
+            if (virJSONValueObjectAppend(out, in->data.object.pairs[i].key,
+                                         val) < 0) {
+                virJSONValueFree(val);
+                goto error;
+            }
+        }
+        break;
+    case VIR_JSON_TYPE_ARRAY:
+        out = virJSONValueNewArray();
+        if (!out)
+            return NULL;
+        for (i = 0; i < in->data.array.nvalues; i++) {
+            virJSONValuePtr val = NULL;
+            if (!(val = virJSONValueCopy(in->data.array.values[i])))
+                goto error;
+            if (virJSONValueArrayAppend(out, val) < 0) {
+                virJSONValueFree(val);
+                goto error;
+            }
+        }
+        break;
+
+    /* No need to error out in the following cases */
+    case VIR_JSON_TYPE_STRING:
+        out = virJSONValueNewString(in->data.string);
+        break;
+    case VIR_JSON_TYPE_NUMBER:
+        out = virJSONValueNewNumber(in->data.number);
+        break;
+    case VIR_JSON_TYPE_BOOLEAN:
+        out = virJSONValueNewBoolean(in->data.boolean);
+        break;
+    case VIR_JSON_TYPE_NULL:
+        out = virJSONValueNewNull();
+        break;
+    }
+
+    return out;
+
+ error:
+    virJSONValueFree(out);
+    return NULL;
+}
+
+
 #if WITH_YAJL
 static int
 virJSONParserInsertValue(virJSONParserPtr parser,
diff --git a/src/util/virjson.h b/src/util/virjson.h
index 9bb7461..e871b2e 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -1,7 +1,7 @@
 /*
  * virjson.h: JSON object parsing/formatting
  *
- * Copyright (C) 2009, 2012-2013 Red Hat, Inc.
+ * Copyright (C) 2009, 2012-2015 Red Hat, Inc.
  * Copyright (C) 2009 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -165,4 +165,6 @@ int virJSONValueObjectForeachKeyValue(virJSONValuePtr object,
                                       virJSONValueObjectIteratorFunc cb,
                                       void *opaque);

+virJSONValuePtr virJSONValueCopy(virJSONValuePtr in);
+
 #endif /* __VIR_JSON_H_ */
diff --git a/tests/jsontest.c b/tests/jsontest.c
index a2a42e3..fca960f 100644
--- a/tests/jsontest.c
+++ b/tests/jsontest.c
@@ -131,6 +131,91 @@ testJSONAddRemove(const void *data)


 static int
+testJSONCopy(const void *data)
+{
+    const struct testInfo *info = data;
+    virJSONValuePtr json = NULL;
+    virJSONValuePtr jsonCopy = NULL;
+    char *result = NULL;
+    char *resultCopy = NULL;
+    int ret = -1;
+
+    json = virJSONValueFromString(info->doc);
+    if (!json) {
+        if (virTestGetVerbose())
+            fprintf(stderr, "Failed to parse %s\n", info->doc);
+        ret = -1;
+        goto cleanup;
+    }
+
+    jsonCopy = virJSONValueCopy(json);
+    if (!jsonCopy) {
+        if (virTestGetVerbose())
+            fprintf(stderr, "Failed to copy JSON data\n");
+        ret = -1;
+        goto cleanup;
+    }
+
+    result = virJSONValueToString(json, false);
+    if (!result) {
+        if (virTestGetVerbose())
+            fprintf(stderr, "Failed to format original JSON data\n");
+        ret = -1;
+        goto cleanup;
+    }
+
+    resultCopy = virJSONValueToString(json, false);
+    if (!resultCopy) {
+        if (virTestGetVerbose())
+            fprintf(stderr, "Failed to format copied JSON data\n");
+        ret = -1;
+        goto cleanup;
+    }
+
+    if (STRNEQ(result, resultCopy)) {
+        if (virTestGetVerbose())
+            virtTestDifference(stderr, result, resultCopy);
+        ret = -1;
+        goto cleanup;
+    }
+
+    VIR_FREE(result);
+    VIR_FREE(resultCopy);
+
+    result = virJSONValueToString(json, true);
+    if (!result) {
+        if (virTestGetVerbose())
+            fprintf(stderr, "Failed to format original JSON data\n");
+        ret = -1;
+        goto cleanup;
+    }
+
+    resultCopy = virJSONValueToString(json, true);
+    if (!resultCopy) {
+        if (virTestGetVerbose())
+            fprintf(stderr, "Failed to format copied JSON data\n");
+        ret = -1;
+        goto cleanup;
+    }
+
+    if (STRNEQ(result, resultCopy)) {
+        if (virTestGetVerbose())
+            virtTestDifference(stderr, result, resultCopy);
+        ret = -1;
+        goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(result);
+    VIR_FREE(resultCopy);
+    virJSONValueFree(json);
+    virJSONValueFree(jsonCopy);
+    return ret;
+}
+
+
+static int
 mymain(void)
 {
     int ret = 0;
@@ -192,6 +277,32 @@ mymain(void)
     DO_TEST_FULL("add and remove", AddRemove,
                  "[ 1 ]", NULL, false);

+    DO_TEST_FULL("copy and free", Copy,
+                 "{\"return\": [{\"name\": \"quit\"}, {\"name\": \"eject\"},"
+                 "{\"name\": \"change\"}, {\"name\": \"screendump\"},"
+                 "{\"name\": \"stop\"}, {\"name\": \"cont\"}, {\"name\": "
+                 "\"system_reset\"}, {\"name\": \"system_powerdown\"}, "
+                 "{\"name\": \"device_add\"}, {\"name\": \"device_del\"}, "
+                 "{\"name\": \"cpu\"}, {\"name\": \"memsave\"}, {\"name\": "
+                 "\"pmemsave\"}, {\"name\": \"migrate\"}, {\"name\": "
+                 "\"migrate_cancel\"}, {\"name\": \"migrate_set_speed\"},"
+                 "{\"name\": \"client_migrate_info\"}, {\"name\": "
+                 "\"migrate_set_downtime\"}, {\"name\": \"netdev_add\"}, "
+                 "{\"name\": \"netdev_del\"}, {\"name\": \"block_resize\"},"
+                 "{\"name\": \"balloon\"}, {\"name\": \"set_link\"}, {\"name\":"
+                 "\"getfd\"}, {\"name\": \"closefd\"}, {\"name\": \"block_passwd\"},"
+                 "{\"name\": \"set_password\"}, {\"name\": \"expire_password\"},"
+                 "{\"name\": \"qmp_capabilities\"}, {\"name\": "
+                 "\"human-monitor-command\"}, {\"name\": \"query-version\"},"
+                 "{\"name\": \"query-commands\"}, {\"name\": \"query-chardev\"},"
+                 "{\"name\": \"query-block\"}, {\"name\": \"query-blockstats\"}, "
+                 "{\"name\": \"query-cpus\"}, {\"name\": \"query-pci\"}, {\"name\":"
+                 "\"query-kvm\"}, {\"name\": \"query-status\"}, {\"name\": "
+                 "\"query-mice\"}, {\"name\": \"query-vnc\"}, {\"name\": "
+                 "\"query-spice\"}, {\"name\": \"query-name\"}, {\"name\": "
+                 "\"query-uuid\"}, {\"name\": \"query-migrate\"}, {\"name\": "
+                 "\"query-balloon\"}], \"id\": \"libvirt-2\"}", NULL, true);
+

     DO_TEST_PARSE("almost nothing", "[]");
     DO_TEST_PARSE_FAIL("nothing", "");
-- 
2.3.5




More information about the libvir-list mailing list