[libvirt] [PATCH 13/28] Rename json.{c,h} to virjson.{c,h}

Daniel P. Berrange berrange at redhat.com
Mon Dec 17 14:57:46 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

---
 po/POTFILES.in                  |    2 +-
 src/Makefile.am                 |    2 +-
 src/parallels/parallels_utils.c |    2 +-
 src/parallels/parallels_utils.h |    2 +-
 src/qemu/qemu_agent.c           |    2 +-
 src/qemu/qemu_monitor.h         |    2 +-
 src/qemu/qemu_monitor_json.c    |    2 +-
 src/rpc/virnetserver.h          |    2 +-
 src/rpc/virnetserverclient.h    |    2 +-
 src/rpc/virnetsocket.h          |    2 +-
 src/util/json.c                 | 1122 ---------------------------------------
 src/util/json.h                 |  138 -----
 src/util/virjson.c              | 1122 +++++++++++++++++++++++++++++++++++++++
 src/util/virjson.h              |  138 +++++
 src/util/virlockspace.h         |    2 +-
 tests/jsontest.c                |    2 +-
 tools/virsh-host.c              |    2 +-
 17 files changed, 1273 insertions(+), 1273 deletions(-)
 delete mode 100644 src/util/json.c
 delete mode 100644 src/util/json.h
 create mode 100644 src/util/virjson.c
 create mode 100644 src/util/virjson.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index f55a1b1..a9dfcf4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -138,7 +138,6 @@ src/test/test_driver.c
 src/uml/uml_conf.c
 src/uml/uml_driver.c
 src/util/iohelper.c
-src/util/json.c
 src/util/pci.c
 src/util/processinfo.c
 src/util/sexpr.c
@@ -160,6 +159,7 @@ src/util/virhash.c
 src/util/virhooks.c
 src/util/virinitctl.c
 src/util/viriptables.c
+src/util/virjson.c
 src/util/virkeyfile.c
 src/util/virlockspace.c
 src/util/virnetdev.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 45e6169..dd49851 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,7 +53,6 @@ augeastest_DATA =
 # These files are not related to driver APIs. Simply generic
 # helper APIs for various purposes
 UTIL_SOURCES =							\
-		util/json.c util/json.h				\
 		util/logging.c util/logging.h			\
 		util/memory.c util/memory.h			\
 		util/pci.c util/pci.h				\
@@ -84,6 +83,7 @@ UTIL_SOURCES =							\
 		util/virhooks.c util/virhooks.h			\
 		util/virnodesuspend.c util/virnodesuspend.h	\
 		util/viriptables.c util/viriptables.h		\
+		util/virjson.c util/virjson.h			\
 		util/virobject.c util/virobject.h		\
 		util/virpidfile.c util/virpidfile.h		\
 		util/virprocess.c util/virprocess.h		\
diff --git a/src/parallels/parallels_utils.c b/src/parallels/parallels_utils.c
index e47ff76..b032882 100644
--- a/src/parallels/parallels_utils.c
+++ b/src/parallels/parallels_utils.c
@@ -27,7 +27,7 @@
 #include "vircommand.h"
 #include "virterror_internal.h"
 #include "memory.h"
-#include "json.h"
+#include "virjson.h"
 
 #include "parallels_utils.h"
 
diff --git a/src/parallels/parallels_utils.h b/src/parallels/parallels_utils.h
index 0010f85..7c31707 100644
--- a/src/parallels/parallels_utils.h
+++ b/src/parallels/parallels_utils.h
@@ -29,7 +29,7 @@
 # include "conf/storage_conf.h"
 # include "conf/domain_event.h"
 # include "conf/network_conf.h"
-# include "json.h"
+# include "virjson.h"
 
 # define parallelsParseError()                                                 \
     virReportErrorHelper(VIR_FROM_TEST, VIR_ERR_OPERATION_FAILED, __FILE__,    \
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 893f7f2..6727294 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -37,7 +37,7 @@
 #include "memory.h"
 #include "logging.h"
 #include "virterror_internal.h"
-#include "json.h"
+#include "virjson.h"
 #include "virfile.h"
 #include "virprocess.h"
 #include "virtime.h"
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8c42b12..d7faa90 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -30,7 +30,7 @@
 # include "domain_conf.h"
 # include "virbitmap.h"
 # include "virhash.h"
-# include "json.h"
+# include "virjson.h"
 # include "device_conf.h"
 
 typedef struct _qemuMonitor qemuMonitor;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 0cd66b6..6181668 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -40,7 +40,7 @@
 #include "driver.h"
 #include "datatypes.h"
 #include "virterror_internal.h"
-#include "json.h"
+#include "virjson.h"
 
 #ifdef WITH_DTRACE_PROBES
 # include "libvirt_qemu_probes.h"
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 38cccfe..da7dc9e 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -31,7 +31,7 @@
 # include "virnetserverclient.h"
 # include "virnetserverservice.h"
 # include "virobject.h"
-# include "json.h"
+# include "virjson.h"
 
 virNetServerPtr virNetServerNew(size_t min_workers,
                                 size_t max_workers,
diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
index 041ffde..65084e2 100644
--- a/src/rpc/virnetserverclient.h
+++ b/src/rpc/virnetserverclient.h
@@ -27,7 +27,7 @@
 # include "virnetsocket.h"
 # include "virnetmessage.h"
 # include "virobject.h"
-# include "json.h"
+# include "virjson.h"
 
 typedef struct _virNetServerClient virNetServerClient;
 typedef virNetServerClient *virNetServerClientPtr;
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index fcd54dd..7016c09 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -31,7 +31,7 @@
 # ifdef HAVE_SASL
 #  include "virnetsaslcontext.h"
 # endif
-# include "json.h"
+# include "virjson.h"
 
 typedef struct _virNetSocket virNetSocket;
 typedef virNetSocket *virNetSocketPtr;
diff --git a/src/util/json.c b/src/util/json.c
deleted file mode 100644
index 41e0311..0000000
--- a/src/util/json.c
+++ /dev/null
@@ -1,1122 +0,0 @@
-/*
- * json.c: JSON object parsing/formatting
- *
- * Copyright (C) 2009-2010, 2012 Red Hat, Inc.
- * Copyright (C) 2009 Daniel P. Berrange
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#include <config.h>
-
-#include "json.h"
-#include "memory.h"
-#include "virterror_internal.h"
-#include "logging.h"
-#include "util.h"
-
-#if HAVE_YAJL
-# include <yajl/yajl_gen.h>
-# include <yajl/yajl_parse.h>
-
-# ifdef HAVE_YAJL2
-#  define yajl_size_t size_t
-# else
-#  define yajl_size_t unsigned int
-# endif
-
-#endif
-
-/* XXX fixme */
-#define VIR_FROM_THIS VIR_FROM_NONE
-
-
-typedef struct _virJSONParserState virJSONParserState;
-typedef virJSONParserState *virJSONParserStatePtr;
-struct _virJSONParserState {
-    virJSONValuePtr value;
-    char *key;
-};
-
-typedef struct _virJSONParser virJSONParser;
-typedef virJSONParser *virJSONParserPtr;
-struct _virJSONParser {
-    virJSONValuePtr head;
-    virJSONParserStatePtr state;
-    unsigned int nstate;
-};
-
-
-void virJSONValueFree(virJSONValuePtr value)
-{
-    int i;
-    if (!value || value->protect)
-        return;
-
-    switch ((virJSONType) value->type) {
-    case VIR_JSON_TYPE_OBJECT:
-        for (i = 0 ; i < value->data.object.npairs; i++) {
-            VIR_FREE(value->data.object.pairs[i].key);
-            virJSONValueFree(value->data.object.pairs[i].value);
-        }
-        VIR_FREE(value->data.object.pairs);
-        break;
-    case VIR_JSON_TYPE_ARRAY:
-        for (i = 0 ; i < value->data.array.nvalues ; i++)
-            virJSONValueFree(value->data.array.values[i]);
-        VIR_FREE(value->data.array.values);
-        break;
-    case VIR_JSON_TYPE_STRING:
-        VIR_FREE(value->data.string);
-        break;
-    case VIR_JSON_TYPE_NUMBER:
-        VIR_FREE(value->data.number);
-        break;
-    case VIR_JSON_TYPE_BOOLEAN:
-    case VIR_JSON_TYPE_NULL:
-        break;
-    }
-
-    VIR_FREE(value);
-}
-
-
-virJSONValuePtr virJSONValueNewString(const char *data)
-{
-    virJSONValuePtr val;
-
-    if (!data)
-        return virJSONValueNewNull();
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_STRING;
-    if (!(val->data.string = strdup(data))) {
-        VIR_FREE(val);
-        return NULL;
-    }
-
-    return val;
-}
-
-virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length)
-{
-    virJSONValuePtr val;
-
-    if (!data)
-        return virJSONValueNewNull();
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_STRING;
-    if (!(val->data.string = strndup(data, length))) {
-        VIR_FREE(val);
-        return NULL;
-    }
-
-    return val;
-}
-
-static virJSONValuePtr virJSONValueNewNumber(const char *data)
-{
-    virJSONValuePtr val;
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_NUMBER;
-    if (!(val->data.number = strdup(data))) {
-        VIR_FREE(val);
-        return NULL;
-    }
-
-    return val;
-}
-
-virJSONValuePtr virJSONValueNewNumberInt(int data)
-{
-    virJSONValuePtr val = NULL;
-    char *str;
-    if (virAsprintf(&str, "%i", data) < 0)
-        return NULL;
-    val = virJSONValueNewNumber(str);
-    VIR_FREE(str);
-    return val;
-}
-
-
-virJSONValuePtr virJSONValueNewNumberUint(unsigned int data)
-{
-    virJSONValuePtr val = NULL;
-    char *str;
-    if (virAsprintf(&str, "%u", data) < 0)
-        return NULL;
-    val = virJSONValueNewNumber(str);
-    VIR_FREE(str);
-    return val;
-}
-
-
-virJSONValuePtr virJSONValueNewNumberLong(long long data)
-{
-    virJSONValuePtr val = NULL;
-    char *str;
-    if (virAsprintf(&str, "%lld", data) < 0)
-        return NULL;
-    val = virJSONValueNewNumber(str);
-    VIR_FREE(str);
-    return val;
-}
-
-
-virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data)
-{
-    virJSONValuePtr val = NULL;
-    char *str;
-    if (virAsprintf(&str, "%llu", data) < 0)
-        return NULL;
-    val = virJSONValueNewNumber(str);
-    VIR_FREE(str);
-    return val;
-}
-
-
-virJSONValuePtr virJSONValueNewNumberDouble(double data)
-{
-    virJSONValuePtr val = NULL;
-    char *str;
-    if (virDoubleToStr(&str, data) < 0)
-        return NULL;
-    val = virJSONValueNewNumber(str);
-    VIR_FREE(str);
-    return val;
-}
-
-
-virJSONValuePtr virJSONValueNewBoolean(int boolean_)
-{
-    virJSONValuePtr val;
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_BOOLEAN;
-    val->data.boolean = boolean_;
-
-    return val;
-}
-
-virJSONValuePtr virJSONValueNewNull(void)
-{
-    virJSONValuePtr val;
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_NULL;
-
-    return val;
-}
-
-virJSONValuePtr virJSONValueNewArray(void)
-{
-    virJSONValuePtr val;
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_ARRAY;
-
-    return val;
-}
-
-virJSONValuePtr virJSONValueNewObject(void)
-{
-    virJSONValuePtr val;
-
-    if (VIR_ALLOC(val) < 0)
-        return NULL;
-
-    val->type = VIR_JSON_TYPE_OBJECT;
-
-    return val;
-}
-
-int virJSONValueObjectAppend(virJSONValuePtr object, const char *key, virJSONValuePtr value)
-{
-    char *newkey;
-
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    if (virJSONValueObjectHasKey(object, key))
-        return -1;
-
-    if (!(newkey = strdup(key)))
-        return -1;
-
-    if (VIR_REALLOC_N(object->data.object.pairs,
-                      object->data.object.npairs + 1) < 0) {
-        VIR_FREE(newkey);
-        return -1;
-    }
-
-    object->data.object.pairs[object->data.object.npairs].key = newkey;
-    object->data.object.pairs[object->data.object.npairs].value = value;
-    object->data.object.npairs++;
-
-    return 0;
-}
-
-
-int virJSONValueObjectAppendString(virJSONValuePtr object, const char *key, const char *value)
-{
-    virJSONValuePtr jvalue = virJSONValueNewString(value);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-int virJSONValueObjectAppendNumberInt(virJSONValuePtr object, const char *key, int number)
-{
-    virJSONValuePtr jvalue = virJSONValueNewNumberInt(number);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-
-int virJSONValueObjectAppendNumberUint(virJSONValuePtr object, const char *key, unsigned int number)
-{
-    virJSONValuePtr jvalue = virJSONValueNewNumberUint(number);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-int virJSONValueObjectAppendNumberLong(virJSONValuePtr object, const char *key, long long number)
-{
-    virJSONValuePtr jvalue = virJSONValueNewNumberLong(number);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-int virJSONValueObjectAppendNumberUlong(virJSONValuePtr object, const char *key, unsigned long long number)
-{
-    virJSONValuePtr jvalue = virJSONValueNewNumberUlong(number);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-int virJSONValueObjectAppendNumberDouble(virJSONValuePtr object, const char *key, double number)
-{
-    virJSONValuePtr jvalue = virJSONValueNewNumberDouble(number);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-int virJSONValueObjectAppendBoolean(virJSONValuePtr object, const char *key, int boolean_)
-{
-    virJSONValuePtr jvalue = virJSONValueNewBoolean(boolean_);
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key)
-{
-    virJSONValuePtr jvalue = virJSONValueNewNull();
-    if (!jvalue)
-        return -1;
-    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
-        virJSONValueFree(jvalue);
-        return -1;
-    }
-    return 0;
-}
-
-
-int virJSONValueArrayAppend(virJSONValuePtr array, virJSONValuePtr value)
-{
-    if (array->type != VIR_JSON_TYPE_ARRAY)
-        return -1;
-
-    if (VIR_REALLOC_N(array->data.array.values,
-                      array->data.array.nvalues + 1) < 0)
-        return -1;
-
-    array->data.array.values[array->data.array.nvalues] = value;
-    array->data.array.nvalues++;
-
-    return 0;
-}
-
-int virJSONValueObjectHasKey(virJSONValuePtr object, const char *key)
-{
-    int i;
-
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    for (i = 0 ; i < object->data.object.npairs ; i++) {
-        if (STREQ(object->data.object.pairs[i].key, key))
-            return 1;
-    }
-
-    return 0;
-}
-
-virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr object, const char *key)
-{
-    int i;
-
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return NULL;
-
-    for (i = 0 ; i < object->data.object.npairs ; i++) {
-        if (STREQ(object->data.object.pairs[i].key, key))
-            return object->data.object.pairs[i].value;
-    }
-
-    return NULL;
-}
-
-int virJSONValueObjectKeysNumber(virJSONValuePtr object)
-{
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    return object->data.object.npairs;
-}
-
-const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n)
-{
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return NULL;
-
-    if (n >= object->data.object.npairs)
-        return NULL;
-
-    return object->data.object.pairs[n].key;
-}
-
-virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned int n)
-{
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return NULL;
-
-    if (n >= object->data.object.npairs)
-        return NULL;
-
-    return object->data.object.pairs[n].value;
-}
-
-int virJSONValueArraySize(virJSONValuePtr array)
-{
-    if (array->type != VIR_JSON_TYPE_ARRAY)
-        return -1;
-
-    return array->data.array.nvalues;
-}
-
-
-virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr array, unsigned int element)
-{
-    if (array->type != VIR_JSON_TYPE_ARRAY)
-        return NULL;
-
-    if (element >= array->data.array.nvalues)
-        return NULL;
-
-    return array->data.array.values[element];
-}
-
-const char *virJSONValueGetString(virJSONValuePtr string)
-{
-    if (string->type != VIR_JSON_TYPE_STRING)
-        return NULL;
-
-    return string->data.string;
-}
-
-
-int virJSONValueGetNumberInt(virJSONValuePtr number, int *value)
-{
-    if (number->type != VIR_JSON_TYPE_NUMBER)
-        return -1;
-
-    return virStrToLong_i(number->data.number, NULL, 10, value);
-}
-
-int virJSONValueGetNumberUint(virJSONValuePtr number, unsigned int *value)
-{
-    if (number->type != VIR_JSON_TYPE_NUMBER)
-        return -1;
-
-    return virStrToLong_ui(number->data.number, NULL, 10, value);
-}
-
-int virJSONValueGetNumberLong(virJSONValuePtr number, long long *value)
-{
-    if (number->type != VIR_JSON_TYPE_NUMBER)
-        return -1;
-
-    return virStrToLong_ll(number->data.number, NULL, 10, value);
-}
-
-int virJSONValueGetNumberUlong(virJSONValuePtr number, unsigned long long *value)
-{
-    if (number->type != VIR_JSON_TYPE_NUMBER)
-        return -1;
-
-    return virStrToLong_ull(number->data.number, NULL, 10, value);
-}
-
-int virJSONValueGetNumberDouble(virJSONValuePtr number, double *value)
-{
-    if (number->type != VIR_JSON_TYPE_NUMBER)
-        return -1;
-
-    return virStrToDouble(number->data.number, NULL, value);
-}
-
-
-int virJSONValueGetBoolean(virJSONValuePtr val, bool *value)
-{
-    if (val->type != VIR_JSON_TYPE_BOOLEAN)
-        return -1;
-
-    *value = val->data.boolean;
-    return 0;
-}
-
-
-int virJSONValueIsNull(virJSONValuePtr val)
-{
-    if (val->type != VIR_JSON_TYPE_NULL)
-        return 0;
-
-    return 1;
-}
-
-
-const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return NULL;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return NULL;
-
-    return virJSONValueGetString(val);
-}
-
-
-int virJSONValueObjectGetNumberInt(virJSONValuePtr object, const char *key, int *value)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueGetNumberInt(val, value);
-}
-
-
-int virJSONValueObjectGetNumberUint(virJSONValuePtr object, const char *key, unsigned int *value)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueGetNumberUint(val, value);
-}
-
-
-int virJSONValueObjectGetNumberLong(virJSONValuePtr object, const char *key, long long *value)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueGetNumberLong(val, value);
-}
-
-
-int virJSONValueObjectGetNumberUlong(virJSONValuePtr object, const char *key, unsigned long long *value)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueGetNumberUlong(val, value);
-}
-
-
-int virJSONValueObjectGetNumberDouble(virJSONValuePtr object, const char *key, double *value)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueGetNumberDouble(val, value);
-}
-
-
-int virJSONValueObjectGetBoolean(virJSONValuePtr object, const char *key, bool *value)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueGetBoolean(val, value);
-}
-
-
-int virJSONValueObjectIsNull(virJSONValuePtr object, const char *key)
-{
-    virJSONValuePtr val;
-    if (object->type != VIR_JSON_TYPE_OBJECT)
-        return -1;
-
-    val = virJSONValueObjectGet(object, key);
-    if (!val)
-        return -1;
-
-    return virJSONValueIsNull(val);
-}
-
-
-#if HAVE_YAJL
-static int virJSONParserInsertValue(virJSONParserPtr parser,
-                                    virJSONValuePtr value)
-{
-    if (!parser->head) {
-        parser->head = value;
-    } else {
-        virJSONParserStatePtr state;
-        if (!parser->nstate) {
-            VIR_DEBUG("got a value to insert without a container");
-            return -1;
-        }
-
-        state = &parser->state[parser->nstate-1];
-
-        switch (state->value->type) {
-        case VIR_JSON_TYPE_OBJECT: {
-            if (!state->key) {
-                VIR_DEBUG("missing key when inserting object value");
-                return -1;
-            }
-
-            if (virJSONValueObjectAppend(state->value,
-                                         state->key,
-                                         value) < 0)
-                return -1;
-
-            VIR_FREE(state->key);
-        }   break;
-
-        case VIR_JSON_TYPE_ARRAY: {
-            if (state->key) {
-                VIR_DEBUG("unexpected key when inserting array value");
-                return -1;
-            }
-
-            if (virJSONValueArrayAppend(state->value,
-                                        value) < 0)
-                return -1;
-        }   break;
-
-        default:
-            VIR_DEBUG("unexpected value type, not a container");
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-static int virJSONParserHandleNull(void *ctx)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONValuePtr value = virJSONValueNewNull();
-
-    VIR_DEBUG("parser=%p", parser);
-
-    if (!value)
-        return 0;
-
-    if (virJSONParserInsertValue(parser, value) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    return 1;
-}
-
-static int virJSONParserHandleBoolean(void *ctx, int boolean_)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONValuePtr value = virJSONValueNewBoolean(boolean_);
-
-    VIR_DEBUG("parser=%p boolean=%d", parser, boolean_);
-
-    if (!value)
-        return 0;
-
-    if (virJSONParserInsertValue(parser, value) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    return 1;
-}
-
-static int virJSONParserHandleNumber(void *ctx,
-                                     const char *s,
-                                     yajl_size_t l)
-{
-    virJSONParserPtr parser = ctx;
-    char *str = strndup(s, l);
-    virJSONValuePtr value;
-
-    if (!str)
-        return -1;
-    value = virJSONValueNewNumber(str);
-    VIR_FREE(str);
-
-    VIR_DEBUG("parser=%p str=%s", parser, str);
-
-    if (!value)
-        return 0;
-
-    if (virJSONParserInsertValue(parser, value) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    return 1;
-}
-
-static int virJSONParserHandleString(void *ctx,
-                                     const unsigned char *stringVal,
-                                     yajl_size_t stringLen)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONValuePtr value = virJSONValueNewStringLen((const char *)stringVal,
-                                                     stringLen);
-
-    VIR_DEBUG("parser=%p str=%p", parser, (const char *)stringVal);
-
-    if (!value)
-        return 0;
-
-    if (virJSONParserInsertValue(parser, value) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    return 1;
-}
-
-static int virJSONParserHandleMapKey(void *ctx,
-                                     const unsigned char *stringVal,
-                                     yajl_size_t stringLen)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONParserStatePtr state;
-
-    VIR_DEBUG("parser=%p key=%p", parser, (const char *)stringVal);
-
-    if (!parser->nstate)
-        return 0;
-
-    state = &parser->state[parser->nstate-1];
-    if (state->key)
-        return 0;
-    state->key = strndup((const char *)stringVal, stringLen);
-    if (!state->key)
-        return 0;
-    return 1;
-}
-
-static int virJSONParserHandleStartMap(void *ctx)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONValuePtr value = virJSONValueNewObject();
-
-    VIR_DEBUG("parser=%p", parser);
-
-    if (!value)
-        return 0;
-
-    if (virJSONParserInsertValue(parser, value) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    if (VIR_REALLOC_N(parser->state,
-                      parser->nstate + 1) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    parser->state[parser->nstate].value = value;
-    parser->state[parser->nstate].key = NULL;
-    parser->nstate++;
-
-    return 1;
-}
-
-
-static int virJSONParserHandleEndMap(void *ctx)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONParserStatePtr state;
-
-    VIR_DEBUG("parser=%p", parser);
-
-    if (!parser->nstate)
-        return 0;
-
-    state = &(parser->state[parser->nstate-1]);
-    if (state->key) {
-        VIR_FREE(state->key);
-        return 0;
-    }
-
-    if (VIR_REALLOC_N(parser->state,
-                      parser->nstate - 1) < 0)
-        return 0;
-    parser->nstate--;
-
-    return 1;
-}
-
-static int virJSONParserHandleStartArray(void *ctx)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONValuePtr value = virJSONValueNewArray();
-
-    VIR_DEBUG("parser=%p", parser);
-
-    if (!value)
-        return 0;
-
-    if (virJSONParserInsertValue(parser, value) < 0) {
-        virJSONValueFree(value);
-        return 0;
-    }
-
-    if (VIR_REALLOC_N(parser->state,
-                      parser->nstate + 1) < 0)
-        return 0;
-
-    parser->state[parser->nstate].value = value;
-    parser->state[parser->nstate].key = NULL;
-    parser->nstate++;
-
-    return 1;
-}
-
-static int virJSONParserHandleEndArray(void *ctx)
-{
-    virJSONParserPtr parser = ctx;
-    virJSONParserStatePtr state;
-
-    VIR_DEBUG("parser=%p", parser);
-
-    if (!parser->nstate)
-        return 0;
-
-    state = &(parser->state[parser->nstate-1]);
-    if (state->key) {
-        VIR_FREE(state->key);
-        return 0;
-    }
-
-    if (VIR_REALLOC_N(parser->state,
-                      parser->nstate - 1) < 0)
-        return 0;
-    parser->nstate--;
-
-    return 1;
-}
-
-static const yajl_callbacks parserCallbacks = {
-    virJSONParserHandleNull,
-    virJSONParserHandleBoolean,
-    NULL,
-    NULL,
-    virJSONParserHandleNumber,
-    virJSONParserHandleString,
-    virJSONParserHandleStartMap,
-    virJSONParserHandleMapKey,
-    virJSONParserHandleEndMap,
-    virJSONParserHandleStartArray,
-    virJSONParserHandleEndArray
-};
-
-
-/* XXX add an incremental streaming parser - yajl trivially supports it */
-virJSONValuePtr virJSONValueFromString(const char *jsonstring)
-{
-    yajl_handle hand;
-    virJSONParser parser = { NULL, NULL, 0 };
-    virJSONValuePtr ret = NULL;
-# ifndef HAVE_YAJL2
-    yajl_parser_config cfg = { 1, 1 };
-# endif
-
-    VIR_DEBUG("string=%s", jsonstring);
-
-# ifdef HAVE_YAJL2
-    hand = yajl_alloc(&parserCallbacks, NULL, &parser);
-    if (hand) {
-        yajl_config(hand, yajl_allow_comments, 1);
-        yajl_config(hand, yajl_dont_validate_strings, 0);
-    }
-# else
-    hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser);
-# endif
-    if (!hand) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Unable to create JSON parser"));
-        goto cleanup;
-    }
-
-    if (yajl_parse(hand,
-                   (const unsigned char *)jsonstring,
-                   strlen(jsonstring)) != yajl_status_ok) {
-        unsigned char *errstr = yajl_get_error(hand, 1,
-                                               (const unsigned char*)jsonstring,
-                                               strlen(jsonstring));
-
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("cannot parse json %s: %s"),
-                       jsonstring, (const char*) errstr);
-        VIR_FREE(errstr);
-        virJSONValueFree(parser.head);
-        goto cleanup;
-    }
-
-    ret = parser.head;
-
-cleanup:
-    yajl_free(hand);
-
-    if (parser.nstate) {
-        int i;
-        for (i = 0 ; i < parser.nstate ; i++) {
-            VIR_FREE(parser.state[i].key);
-        }
-    }
-
-    VIR_DEBUG("result=%p", parser.head);
-
-    return ret;
-}
-
-
-static int virJSONValueToStringOne(virJSONValuePtr object,
-                                   yajl_gen g)
-{
-    int i;
-
-    VIR_DEBUG("object=%p type=%d gen=%p", object, object->type, g);
-
-    switch (object->type) {
-    case VIR_JSON_TYPE_OBJECT:
-        if (yajl_gen_map_open(g) != yajl_gen_status_ok)
-            return -1;
-        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)
-                return -1;
-        }
-        if (yajl_gen_map_close(g) != yajl_gen_status_ok)
-            return -1;
-        break;
-    case VIR_JSON_TYPE_ARRAY:
-        if (yajl_gen_array_open(g) != yajl_gen_status_ok)
-            return -1;
-        for (i = 0; i < object->data.array.nvalues ; i++) {
-            if (virJSONValueToStringOne(object->data.array.values[i], g) < 0)
-                return -1;
-        }
-        if (yajl_gen_array_close(g) != yajl_gen_status_ok)
-            return -1;
-        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;
-        break;
-
-    case VIR_JSON_TYPE_NUMBER:
-        if (yajl_gen_number(g, object->data.number,
-                            strlen(object->data.number)) != yajl_gen_status_ok)
-            return -1;
-        break;
-
-    case VIR_JSON_TYPE_BOOLEAN:
-        if (yajl_gen_bool(g, object->data.boolean) != yajl_gen_status_ok)
-            return -1;
-        break;
-
-    case VIR_JSON_TYPE_NULL:
-        if (yajl_gen_null(g) != yajl_gen_status_ok)
-            return -1;
-        break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-char *virJSONValueToString(virJSONValuePtr object,
-                           bool pretty)
-{
-    yajl_gen g;
-    const unsigned char *str;
-    char *ret = NULL;
-    yajl_size_t len;
-# ifndef HAVE_YAJL2
-    yajl_gen_config conf = { pretty ? 1 : 0, pretty ? "    " : " "};
-# endif
-
-    VIR_DEBUG("object=%p", object);
-
-# ifdef HAVE_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 (!(ret = strdup((const char *)str)))
-        virReportOOMError();
-
-cleanup:
-    yajl_gen_free(g);
-
-    VIR_DEBUG("result=%s", NULLSTR(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
diff --git a/src/util/json.h b/src/util/json.h
deleted file mode 100644
index 0a76b3a..0000000
--- a/src/util/json.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * json.h: JSON object parsing/formatting
- *
- * Copyright (C) 2009, 2012 Red Hat, Inc.
- * Copyright (C) 2009 Daniel P. Berrange
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifndef __VIR_JSON_H_
-# define __VIR_JSON_H_
-
-# include "internal.h"
-
-
-typedef enum {
-    VIR_JSON_TYPE_OBJECT,
-    VIR_JSON_TYPE_ARRAY,
-    VIR_JSON_TYPE_STRING,
-    VIR_JSON_TYPE_NUMBER,
-    VIR_JSON_TYPE_BOOLEAN,
-    VIR_JSON_TYPE_NULL,
-} virJSONType;
-
-typedef struct _virJSONValue virJSONValue;
-typedef virJSONValue *virJSONValuePtr;
-
-typedef struct _virJSONObject virJSONObject;
-typedef virJSONObject *virJSONObjectPtr;
-
-typedef struct _virJSONObjectPair virJSONObjectPair;
-typedef virJSONObjectPair *virJSONObjectPairPtr;
-
-typedef struct _virJSONArray virJSONArray;
-typedef virJSONArray *virJSONArrayPtr;
-
-
-struct _virJSONObjectPair {
-    char *key;
-    virJSONValuePtr value;
-};
-
-struct _virJSONObject {
-    unsigned int npairs;
-    virJSONObjectPairPtr pairs;
-};
-
-struct _virJSONArray {
-    unsigned int nvalues;
-    virJSONValuePtr *values;
-};
-
-struct _virJSONValue {
-    int type; /* enum virJSONType */
-    bool protect; /* prevents deletion when embedded in another object */
-
-    union {
-        virJSONObject object;
-        virJSONArray array;
-        char *string;
-        char *number; /* int/float/etc format is context defined so we can't parse it here :-( */
-        int boolean;
-    } data;
-};
-
-void virJSONValueFree(virJSONValuePtr value);
-
-virJSONValuePtr virJSONValueNewString(const char *data);
-virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length);
-virJSONValuePtr virJSONValueNewNumberInt(int data);
-virJSONValuePtr virJSONValueNewNumberUint(unsigned int data);
-virJSONValuePtr virJSONValueNewNumberLong(long long data);
-virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data);
-virJSONValuePtr virJSONValueNewNumberDouble(double data);
-virJSONValuePtr virJSONValueNewBoolean(int boolean);
-virJSONValuePtr virJSONValueNewNull(void);
-virJSONValuePtr virJSONValueNewArray(void);
-virJSONValuePtr virJSONValueNewObject(void);
-
-int virJSONValueObjectAppend(virJSONValuePtr object, const char *key, virJSONValuePtr value);
-int virJSONValueArrayAppend(virJSONValuePtr object, virJSONValuePtr value);
-
-int virJSONValueObjectHasKey(virJSONValuePtr object, const char *key);
-virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr object, const char *key);
-
-int virJSONValueArraySize(virJSONValuePtr object);
-virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr object, unsigned int element);
-
-int virJSONValueObjectKeysNumber(virJSONValuePtr object);
-const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n);
-virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned int n);
-
-const char *virJSONValueGetString(virJSONValuePtr object);
-int virJSONValueGetNumberInt(virJSONValuePtr object, int *value);
-int virJSONValueGetNumberUint(virJSONValuePtr object, unsigned int *value);
-int virJSONValueGetNumberLong(virJSONValuePtr object, long long *value);
-int virJSONValueGetNumberUlong(virJSONValuePtr object, unsigned long long *value);
-int virJSONValueGetNumberDouble(virJSONValuePtr object, double *value);
-int virJSONValueGetBoolean(virJSONValuePtr object, bool *value);
-int virJSONValueIsNull(virJSONValuePtr object);
-
-const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key);
-int virJSONValueObjectGetNumberInt(virJSONValuePtr object, const char *key, int *value);
-int virJSONValueObjectGetNumberUint(virJSONValuePtr object, const char *key, unsigned int *value);
-int virJSONValueObjectGetNumberLong(virJSONValuePtr object, const char *key, long long *value);
-int virJSONValueObjectGetNumberUlong(virJSONValuePtr object, const char *key, unsigned long long *value);
-int virJSONValueObjectGetNumberDouble(virJSONValuePtr object, const char *key, double *value);
-int virJSONValueObjectGetBoolean(virJSONValuePtr object, const char *key, bool *value);
-int virJSONValueObjectIsNull(virJSONValuePtr object, const char *key);
-
-int virJSONValueObjectAppendString(virJSONValuePtr object, const char *key, const char *value);
-int virJSONValueObjectAppendNumberInt(virJSONValuePtr object, const char *key, int number);
-int virJSONValueObjectAppendNumberUint(virJSONValuePtr object, const char *key, unsigned int number);
-int virJSONValueObjectAppendNumberLong(virJSONValuePtr object, const char *key, long long number);
-int virJSONValueObjectAppendNumberUlong(virJSONValuePtr object, const char *key, unsigned long long number);
-int virJSONValueObjectAppendNumberDouble(virJSONValuePtr object, const char *key, double number);
-int virJSONValueObjectAppendBoolean(virJSONValuePtr object, const char *key, int boolean);
-int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key);
-
-virJSONValuePtr virJSONValueFromString(const char *jsonstring);
-char *virJSONValueToString(virJSONValuePtr object,
-                           bool pretty);
-
-#endif /* __VIR_JSON_H_ */
diff --git a/src/util/virjson.c b/src/util/virjson.c
new file mode 100644
index 0000000..a07dd5c
--- /dev/null
+++ b/src/util/virjson.c
@@ -0,0 +1,1122 @@
+/*
+ * json.c: JSON object parsing/formatting
+ *
+ * Copyright (C) 2009-2010, 2012 Red Hat, Inc.
+ * Copyright (C) 2009 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <config.h>
+
+#include "virjson.h"
+#include "memory.h"
+#include "virterror_internal.h"
+#include "logging.h"
+#include "util.h"
+
+#if HAVE_YAJL
+# include <yajl/yajl_gen.h>
+# include <yajl/yajl_parse.h>
+
+# ifdef HAVE_YAJL2
+#  define yajl_size_t size_t
+# else
+#  define yajl_size_t unsigned int
+# endif
+
+#endif
+
+/* XXX fixme */
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+
+typedef struct _virJSONParserState virJSONParserState;
+typedef virJSONParserState *virJSONParserStatePtr;
+struct _virJSONParserState {
+    virJSONValuePtr value;
+    char *key;
+};
+
+typedef struct _virJSONParser virJSONParser;
+typedef virJSONParser *virJSONParserPtr;
+struct _virJSONParser {
+    virJSONValuePtr head;
+    virJSONParserStatePtr state;
+    unsigned int nstate;
+};
+
+
+void virJSONValueFree(virJSONValuePtr value)
+{
+    int i;
+    if (!value || value->protect)
+        return;
+
+    switch ((virJSONType) value->type) {
+    case VIR_JSON_TYPE_OBJECT:
+        for (i = 0 ; i < value->data.object.npairs; i++) {
+            VIR_FREE(value->data.object.pairs[i].key);
+            virJSONValueFree(value->data.object.pairs[i].value);
+        }
+        VIR_FREE(value->data.object.pairs);
+        break;
+    case VIR_JSON_TYPE_ARRAY:
+        for (i = 0 ; i < value->data.array.nvalues ; i++)
+            virJSONValueFree(value->data.array.values[i]);
+        VIR_FREE(value->data.array.values);
+        break;
+    case VIR_JSON_TYPE_STRING:
+        VIR_FREE(value->data.string);
+        break;
+    case VIR_JSON_TYPE_NUMBER:
+        VIR_FREE(value->data.number);
+        break;
+    case VIR_JSON_TYPE_BOOLEAN:
+    case VIR_JSON_TYPE_NULL:
+        break;
+    }
+
+    VIR_FREE(value);
+}
+
+
+virJSONValuePtr virJSONValueNewString(const char *data)
+{
+    virJSONValuePtr val;
+
+    if (!data)
+        return virJSONValueNewNull();
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_STRING;
+    if (!(val->data.string = strdup(data))) {
+        VIR_FREE(val);
+        return NULL;
+    }
+
+    return val;
+}
+
+virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length)
+{
+    virJSONValuePtr val;
+
+    if (!data)
+        return virJSONValueNewNull();
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_STRING;
+    if (!(val->data.string = strndup(data, length))) {
+        VIR_FREE(val);
+        return NULL;
+    }
+
+    return val;
+}
+
+static virJSONValuePtr virJSONValueNewNumber(const char *data)
+{
+    virJSONValuePtr val;
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_NUMBER;
+    if (!(val->data.number = strdup(data))) {
+        VIR_FREE(val);
+        return NULL;
+    }
+
+    return val;
+}
+
+virJSONValuePtr virJSONValueNewNumberInt(int data)
+{
+    virJSONValuePtr val = NULL;
+    char *str;
+    if (virAsprintf(&str, "%i", data) < 0)
+        return NULL;
+    val = virJSONValueNewNumber(str);
+    VIR_FREE(str);
+    return val;
+}
+
+
+virJSONValuePtr virJSONValueNewNumberUint(unsigned int data)
+{
+    virJSONValuePtr val = NULL;
+    char *str;
+    if (virAsprintf(&str, "%u", data) < 0)
+        return NULL;
+    val = virJSONValueNewNumber(str);
+    VIR_FREE(str);
+    return val;
+}
+
+
+virJSONValuePtr virJSONValueNewNumberLong(long long data)
+{
+    virJSONValuePtr val = NULL;
+    char *str;
+    if (virAsprintf(&str, "%lld", data) < 0)
+        return NULL;
+    val = virJSONValueNewNumber(str);
+    VIR_FREE(str);
+    return val;
+}
+
+
+virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data)
+{
+    virJSONValuePtr val = NULL;
+    char *str;
+    if (virAsprintf(&str, "%llu", data) < 0)
+        return NULL;
+    val = virJSONValueNewNumber(str);
+    VIR_FREE(str);
+    return val;
+}
+
+
+virJSONValuePtr virJSONValueNewNumberDouble(double data)
+{
+    virJSONValuePtr val = NULL;
+    char *str;
+    if (virDoubleToStr(&str, data) < 0)
+        return NULL;
+    val = virJSONValueNewNumber(str);
+    VIR_FREE(str);
+    return val;
+}
+
+
+virJSONValuePtr virJSONValueNewBoolean(int boolean_)
+{
+    virJSONValuePtr val;
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_BOOLEAN;
+    val->data.boolean = boolean_;
+
+    return val;
+}
+
+virJSONValuePtr virJSONValueNewNull(void)
+{
+    virJSONValuePtr val;
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_NULL;
+
+    return val;
+}
+
+virJSONValuePtr virJSONValueNewArray(void)
+{
+    virJSONValuePtr val;
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_ARRAY;
+
+    return val;
+}
+
+virJSONValuePtr virJSONValueNewObject(void)
+{
+    virJSONValuePtr val;
+
+    if (VIR_ALLOC(val) < 0)
+        return NULL;
+
+    val->type = VIR_JSON_TYPE_OBJECT;
+
+    return val;
+}
+
+int virJSONValueObjectAppend(virJSONValuePtr object, const char *key, virJSONValuePtr value)
+{
+    char *newkey;
+
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    if (virJSONValueObjectHasKey(object, key))
+        return -1;
+
+    if (!(newkey = strdup(key)))
+        return -1;
+
+    if (VIR_REALLOC_N(object->data.object.pairs,
+                      object->data.object.npairs + 1) < 0) {
+        VIR_FREE(newkey);
+        return -1;
+    }
+
+    object->data.object.pairs[object->data.object.npairs].key = newkey;
+    object->data.object.pairs[object->data.object.npairs].value = value;
+    object->data.object.npairs++;
+
+    return 0;
+}
+
+
+int virJSONValueObjectAppendString(virJSONValuePtr object, const char *key, const char *value)
+{
+    virJSONValuePtr jvalue = virJSONValueNewString(value);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+int virJSONValueObjectAppendNumberInt(virJSONValuePtr object, const char *key, int number)
+{
+    virJSONValuePtr jvalue = virJSONValueNewNumberInt(number);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+
+int virJSONValueObjectAppendNumberUint(virJSONValuePtr object, const char *key, unsigned int number)
+{
+    virJSONValuePtr jvalue = virJSONValueNewNumberUint(number);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+int virJSONValueObjectAppendNumberLong(virJSONValuePtr object, const char *key, long long number)
+{
+    virJSONValuePtr jvalue = virJSONValueNewNumberLong(number);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+int virJSONValueObjectAppendNumberUlong(virJSONValuePtr object, const char *key, unsigned long long number)
+{
+    virJSONValuePtr jvalue = virJSONValueNewNumberUlong(number);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+int virJSONValueObjectAppendNumberDouble(virJSONValuePtr object, const char *key, double number)
+{
+    virJSONValuePtr jvalue = virJSONValueNewNumberDouble(number);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+int virJSONValueObjectAppendBoolean(virJSONValuePtr object, const char *key, int boolean_)
+{
+    virJSONValuePtr jvalue = virJSONValueNewBoolean(boolean_);
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key)
+{
+    virJSONValuePtr jvalue = virJSONValueNewNull();
+    if (!jvalue)
+        return -1;
+    if (virJSONValueObjectAppend(object, key, jvalue) < 0) {
+        virJSONValueFree(jvalue);
+        return -1;
+    }
+    return 0;
+}
+
+
+int virJSONValueArrayAppend(virJSONValuePtr array, virJSONValuePtr value)
+{
+    if (array->type != VIR_JSON_TYPE_ARRAY)
+        return -1;
+
+    if (VIR_REALLOC_N(array->data.array.values,
+                      array->data.array.nvalues + 1) < 0)
+        return -1;
+
+    array->data.array.values[array->data.array.nvalues] = value;
+    array->data.array.nvalues++;
+
+    return 0;
+}
+
+int virJSONValueObjectHasKey(virJSONValuePtr object, const char *key)
+{
+    int i;
+
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    for (i = 0 ; i < object->data.object.npairs ; i++) {
+        if (STREQ(object->data.object.pairs[i].key, key))
+            return 1;
+    }
+
+    return 0;
+}
+
+virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr object, const char *key)
+{
+    int i;
+
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return NULL;
+
+    for (i = 0 ; i < object->data.object.npairs ; i++) {
+        if (STREQ(object->data.object.pairs[i].key, key))
+            return object->data.object.pairs[i].value;
+    }
+
+    return NULL;
+}
+
+int virJSONValueObjectKeysNumber(virJSONValuePtr object)
+{
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    return object->data.object.npairs;
+}
+
+const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n)
+{
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return NULL;
+
+    if (n >= object->data.object.npairs)
+        return NULL;
+
+    return object->data.object.pairs[n].key;
+}
+
+virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned int n)
+{
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return NULL;
+
+    if (n >= object->data.object.npairs)
+        return NULL;
+
+    return object->data.object.pairs[n].value;
+}
+
+int virJSONValueArraySize(virJSONValuePtr array)
+{
+    if (array->type != VIR_JSON_TYPE_ARRAY)
+        return -1;
+
+    return array->data.array.nvalues;
+}
+
+
+virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr array, unsigned int element)
+{
+    if (array->type != VIR_JSON_TYPE_ARRAY)
+        return NULL;
+
+    if (element >= array->data.array.nvalues)
+        return NULL;
+
+    return array->data.array.values[element];
+}
+
+const char *virJSONValueGetString(virJSONValuePtr string)
+{
+    if (string->type != VIR_JSON_TYPE_STRING)
+        return NULL;
+
+    return string->data.string;
+}
+
+
+int virJSONValueGetNumberInt(virJSONValuePtr number, int *value)
+{
+    if (number->type != VIR_JSON_TYPE_NUMBER)
+        return -1;
+
+    return virStrToLong_i(number->data.number, NULL, 10, value);
+}
+
+int virJSONValueGetNumberUint(virJSONValuePtr number, unsigned int *value)
+{
+    if (number->type != VIR_JSON_TYPE_NUMBER)
+        return -1;
+
+    return virStrToLong_ui(number->data.number, NULL, 10, value);
+}
+
+int virJSONValueGetNumberLong(virJSONValuePtr number, long long *value)
+{
+    if (number->type != VIR_JSON_TYPE_NUMBER)
+        return -1;
+
+    return virStrToLong_ll(number->data.number, NULL, 10, value);
+}
+
+int virJSONValueGetNumberUlong(virJSONValuePtr number, unsigned long long *value)
+{
+    if (number->type != VIR_JSON_TYPE_NUMBER)
+        return -1;
+
+    return virStrToLong_ull(number->data.number, NULL, 10, value);
+}
+
+int virJSONValueGetNumberDouble(virJSONValuePtr number, double *value)
+{
+    if (number->type != VIR_JSON_TYPE_NUMBER)
+        return -1;
+
+    return virStrToDouble(number->data.number, NULL, value);
+}
+
+
+int virJSONValueGetBoolean(virJSONValuePtr val, bool *value)
+{
+    if (val->type != VIR_JSON_TYPE_BOOLEAN)
+        return -1;
+
+    *value = val->data.boolean;
+    return 0;
+}
+
+
+int virJSONValueIsNull(virJSONValuePtr val)
+{
+    if (val->type != VIR_JSON_TYPE_NULL)
+        return 0;
+
+    return 1;
+}
+
+
+const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return NULL;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return NULL;
+
+    return virJSONValueGetString(val);
+}
+
+
+int virJSONValueObjectGetNumberInt(virJSONValuePtr object, const char *key, int *value)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueGetNumberInt(val, value);
+}
+
+
+int virJSONValueObjectGetNumberUint(virJSONValuePtr object, const char *key, unsigned int *value)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueGetNumberUint(val, value);
+}
+
+
+int virJSONValueObjectGetNumberLong(virJSONValuePtr object, const char *key, long long *value)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueGetNumberLong(val, value);
+}
+
+
+int virJSONValueObjectGetNumberUlong(virJSONValuePtr object, const char *key, unsigned long long *value)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueGetNumberUlong(val, value);
+}
+
+
+int virJSONValueObjectGetNumberDouble(virJSONValuePtr object, const char *key, double *value)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueGetNumberDouble(val, value);
+}
+
+
+int virJSONValueObjectGetBoolean(virJSONValuePtr object, const char *key, bool *value)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueGetBoolean(val, value);
+}
+
+
+int virJSONValueObjectIsNull(virJSONValuePtr object, const char *key)
+{
+    virJSONValuePtr val;
+    if (object->type != VIR_JSON_TYPE_OBJECT)
+        return -1;
+
+    val = virJSONValueObjectGet(object, key);
+    if (!val)
+        return -1;
+
+    return virJSONValueIsNull(val);
+}
+
+
+#if HAVE_YAJL
+static int virJSONParserInsertValue(virJSONParserPtr parser,
+                                    virJSONValuePtr value)
+{
+    if (!parser->head) {
+        parser->head = value;
+    } else {
+        virJSONParserStatePtr state;
+        if (!parser->nstate) {
+            VIR_DEBUG("got a value to insert without a container");
+            return -1;
+        }
+
+        state = &parser->state[parser->nstate-1];
+
+        switch (state->value->type) {
+        case VIR_JSON_TYPE_OBJECT: {
+            if (!state->key) {
+                VIR_DEBUG("missing key when inserting object value");
+                return -1;
+            }
+
+            if (virJSONValueObjectAppend(state->value,
+                                         state->key,
+                                         value) < 0)
+                return -1;
+
+            VIR_FREE(state->key);
+        }   break;
+
+        case VIR_JSON_TYPE_ARRAY: {
+            if (state->key) {
+                VIR_DEBUG("unexpected key when inserting array value");
+                return -1;
+            }
+
+            if (virJSONValueArrayAppend(state->value,
+                                        value) < 0)
+                return -1;
+        }   break;
+
+        default:
+            VIR_DEBUG("unexpected value type, not a container");
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int virJSONParserHandleNull(void *ctx)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONValuePtr value = virJSONValueNewNull();
+
+    VIR_DEBUG("parser=%p", parser);
+
+    if (!value)
+        return 0;
+
+    if (virJSONParserInsertValue(parser, value) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int virJSONParserHandleBoolean(void *ctx, int boolean_)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONValuePtr value = virJSONValueNewBoolean(boolean_);
+
+    VIR_DEBUG("parser=%p boolean=%d", parser, boolean_);
+
+    if (!value)
+        return 0;
+
+    if (virJSONParserInsertValue(parser, value) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int virJSONParserHandleNumber(void *ctx,
+                                     const char *s,
+                                     yajl_size_t l)
+{
+    virJSONParserPtr parser = ctx;
+    char *str = strndup(s, l);
+    virJSONValuePtr value;
+
+    if (!str)
+        return -1;
+    value = virJSONValueNewNumber(str);
+    VIR_FREE(str);
+
+    VIR_DEBUG("parser=%p str=%s", parser, str);
+
+    if (!value)
+        return 0;
+
+    if (virJSONParserInsertValue(parser, value) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int virJSONParserHandleString(void *ctx,
+                                     const unsigned char *stringVal,
+                                     yajl_size_t stringLen)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONValuePtr value = virJSONValueNewStringLen((const char *)stringVal,
+                                                     stringLen);
+
+    VIR_DEBUG("parser=%p str=%p", parser, (const char *)stringVal);
+
+    if (!value)
+        return 0;
+
+    if (virJSONParserInsertValue(parser, value) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int virJSONParserHandleMapKey(void *ctx,
+                                     const unsigned char *stringVal,
+                                     yajl_size_t stringLen)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONParserStatePtr state;
+
+    VIR_DEBUG("parser=%p key=%p", parser, (const char *)stringVal);
+
+    if (!parser->nstate)
+        return 0;
+
+    state = &parser->state[parser->nstate-1];
+    if (state->key)
+        return 0;
+    state->key = strndup((const char *)stringVal, stringLen);
+    if (!state->key)
+        return 0;
+    return 1;
+}
+
+static int virJSONParserHandleStartMap(void *ctx)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONValuePtr value = virJSONValueNewObject();
+
+    VIR_DEBUG("parser=%p", parser);
+
+    if (!value)
+        return 0;
+
+    if (virJSONParserInsertValue(parser, value) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    if (VIR_REALLOC_N(parser->state,
+                      parser->nstate + 1) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    parser->state[parser->nstate].value = value;
+    parser->state[parser->nstate].key = NULL;
+    parser->nstate++;
+
+    return 1;
+}
+
+
+static int virJSONParserHandleEndMap(void *ctx)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONParserStatePtr state;
+
+    VIR_DEBUG("parser=%p", parser);
+
+    if (!parser->nstate)
+        return 0;
+
+    state = &(parser->state[parser->nstate-1]);
+    if (state->key) {
+        VIR_FREE(state->key);
+        return 0;
+    }
+
+    if (VIR_REALLOC_N(parser->state,
+                      parser->nstate - 1) < 0)
+        return 0;
+    parser->nstate--;
+
+    return 1;
+}
+
+static int virJSONParserHandleStartArray(void *ctx)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONValuePtr value = virJSONValueNewArray();
+
+    VIR_DEBUG("parser=%p", parser);
+
+    if (!value)
+        return 0;
+
+    if (virJSONParserInsertValue(parser, value) < 0) {
+        virJSONValueFree(value);
+        return 0;
+    }
+
+    if (VIR_REALLOC_N(parser->state,
+                      parser->nstate + 1) < 0)
+        return 0;
+
+    parser->state[parser->nstate].value = value;
+    parser->state[parser->nstate].key = NULL;
+    parser->nstate++;
+
+    return 1;
+}
+
+static int virJSONParserHandleEndArray(void *ctx)
+{
+    virJSONParserPtr parser = ctx;
+    virJSONParserStatePtr state;
+
+    VIR_DEBUG("parser=%p", parser);
+
+    if (!parser->nstate)
+        return 0;
+
+    state = &(parser->state[parser->nstate-1]);
+    if (state->key) {
+        VIR_FREE(state->key);
+        return 0;
+    }
+
+    if (VIR_REALLOC_N(parser->state,
+                      parser->nstate - 1) < 0)
+        return 0;
+    parser->nstate--;
+
+    return 1;
+}
+
+static const yajl_callbacks parserCallbacks = {
+    virJSONParserHandleNull,
+    virJSONParserHandleBoolean,
+    NULL,
+    NULL,
+    virJSONParserHandleNumber,
+    virJSONParserHandleString,
+    virJSONParserHandleStartMap,
+    virJSONParserHandleMapKey,
+    virJSONParserHandleEndMap,
+    virJSONParserHandleStartArray,
+    virJSONParserHandleEndArray
+};
+
+
+/* XXX add an incremental streaming parser - yajl trivially supports it */
+virJSONValuePtr virJSONValueFromString(const char *jsonstring)
+{
+    yajl_handle hand;
+    virJSONParser parser = { NULL, NULL, 0 };
+    virJSONValuePtr ret = NULL;
+# ifndef HAVE_YAJL2
+    yajl_parser_config cfg = { 1, 1 };
+# endif
+
+    VIR_DEBUG("string=%s", jsonstring);
+
+# ifdef HAVE_YAJL2
+    hand = yajl_alloc(&parserCallbacks, NULL, &parser);
+    if (hand) {
+        yajl_config(hand, yajl_allow_comments, 1);
+        yajl_config(hand, yajl_dont_validate_strings, 0);
+    }
+# else
+    hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser);
+# endif
+    if (!hand) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Unable to create JSON parser"));
+        goto cleanup;
+    }
+
+    if (yajl_parse(hand,
+                   (const unsigned char *)jsonstring,
+                   strlen(jsonstring)) != yajl_status_ok) {
+        unsigned char *errstr = yajl_get_error(hand, 1,
+                                               (const unsigned char*)jsonstring,
+                                               strlen(jsonstring));
+
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot parse json %s: %s"),
+                       jsonstring, (const char*) errstr);
+        VIR_FREE(errstr);
+        virJSONValueFree(parser.head);
+        goto cleanup;
+    }
+
+    ret = parser.head;
+
+cleanup:
+    yajl_free(hand);
+
+    if (parser.nstate) {
+        int i;
+        for (i = 0 ; i < parser.nstate ; i++) {
+            VIR_FREE(parser.state[i].key);
+        }
+    }
+
+    VIR_DEBUG("result=%p", parser.head);
+
+    return ret;
+}
+
+
+static int virJSONValueToStringOne(virJSONValuePtr object,
+                                   yajl_gen g)
+{
+    int i;
+
+    VIR_DEBUG("object=%p type=%d gen=%p", object, object->type, g);
+
+    switch (object->type) {
+    case VIR_JSON_TYPE_OBJECT:
+        if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+            return -1;
+        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)
+                return -1;
+        }
+        if (yajl_gen_map_close(g) != yajl_gen_status_ok)
+            return -1;
+        break;
+    case VIR_JSON_TYPE_ARRAY:
+        if (yajl_gen_array_open(g) != yajl_gen_status_ok)
+            return -1;
+        for (i = 0; i < object->data.array.nvalues ; i++) {
+            if (virJSONValueToStringOne(object->data.array.values[i], g) < 0)
+                return -1;
+        }
+        if (yajl_gen_array_close(g) != yajl_gen_status_ok)
+            return -1;
+        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;
+        break;
+
+    case VIR_JSON_TYPE_NUMBER:
+        if (yajl_gen_number(g, object->data.number,
+                            strlen(object->data.number)) != yajl_gen_status_ok)
+            return -1;
+        break;
+
+    case VIR_JSON_TYPE_BOOLEAN:
+        if (yajl_gen_bool(g, object->data.boolean) != yajl_gen_status_ok)
+            return -1;
+        break;
+
+    case VIR_JSON_TYPE_NULL:
+        if (yajl_gen_null(g) != yajl_gen_status_ok)
+            return -1;
+        break;
+
+    default:
+        return -1;
+    }
+
+    return 0;
+}
+
+char *virJSONValueToString(virJSONValuePtr object,
+                           bool pretty)
+{
+    yajl_gen g;
+    const unsigned char *str;
+    char *ret = NULL;
+    yajl_size_t len;
+# ifndef HAVE_YAJL2
+    yajl_gen_config conf = { pretty ? 1 : 0, pretty ? "    " : " "};
+# endif
+
+    VIR_DEBUG("object=%p", object);
+
+# ifdef HAVE_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 (!(ret = strdup((const char *)str)))
+        virReportOOMError();
+
+cleanup:
+    yajl_gen_free(g);
+
+    VIR_DEBUG("result=%s", NULLSTR(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
diff --git a/src/util/virjson.h b/src/util/virjson.h
new file mode 100644
index 0000000..0a76b3a
--- /dev/null
+++ b/src/util/virjson.h
@@ -0,0 +1,138 @@
+/*
+ * json.h: JSON object parsing/formatting
+ *
+ * Copyright (C) 2009, 2012 Red Hat, Inc.
+ * Copyright (C) 2009 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifndef __VIR_JSON_H_
+# define __VIR_JSON_H_
+
+# include "internal.h"
+
+
+typedef enum {
+    VIR_JSON_TYPE_OBJECT,
+    VIR_JSON_TYPE_ARRAY,
+    VIR_JSON_TYPE_STRING,
+    VIR_JSON_TYPE_NUMBER,
+    VIR_JSON_TYPE_BOOLEAN,
+    VIR_JSON_TYPE_NULL,
+} virJSONType;
+
+typedef struct _virJSONValue virJSONValue;
+typedef virJSONValue *virJSONValuePtr;
+
+typedef struct _virJSONObject virJSONObject;
+typedef virJSONObject *virJSONObjectPtr;
+
+typedef struct _virJSONObjectPair virJSONObjectPair;
+typedef virJSONObjectPair *virJSONObjectPairPtr;
+
+typedef struct _virJSONArray virJSONArray;
+typedef virJSONArray *virJSONArrayPtr;
+
+
+struct _virJSONObjectPair {
+    char *key;
+    virJSONValuePtr value;
+};
+
+struct _virJSONObject {
+    unsigned int npairs;
+    virJSONObjectPairPtr pairs;
+};
+
+struct _virJSONArray {
+    unsigned int nvalues;
+    virJSONValuePtr *values;
+};
+
+struct _virJSONValue {
+    int type; /* enum virJSONType */
+    bool protect; /* prevents deletion when embedded in another object */
+
+    union {
+        virJSONObject object;
+        virJSONArray array;
+        char *string;
+        char *number; /* int/float/etc format is context defined so we can't parse it here :-( */
+        int boolean;
+    } data;
+};
+
+void virJSONValueFree(virJSONValuePtr value);
+
+virJSONValuePtr virJSONValueNewString(const char *data);
+virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length);
+virJSONValuePtr virJSONValueNewNumberInt(int data);
+virJSONValuePtr virJSONValueNewNumberUint(unsigned int data);
+virJSONValuePtr virJSONValueNewNumberLong(long long data);
+virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data);
+virJSONValuePtr virJSONValueNewNumberDouble(double data);
+virJSONValuePtr virJSONValueNewBoolean(int boolean);
+virJSONValuePtr virJSONValueNewNull(void);
+virJSONValuePtr virJSONValueNewArray(void);
+virJSONValuePtr virJSONValueNewObject(void);
+
+int virJSONValueObjectAppend(virJSONValuePtr object, const char *key, virJSONValuePtr value);
+int virJSONValueArrayAppend(virJSONValuePtr object, virJSONValuePtr value);
+
+int virJSONValueObjectHasKey(virJSONValuePtr object, const char *key);
+virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr object, const char *key);
+
+int virJSONValueArraySize(virJSONValuePtr object);
+virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr object, unsigned int element);
+
+int virJSONValueObjectKeysNumber(virJSONValuePtr object);
+const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n);
+virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned int n);
+
+const char *virJSONValueGetString(virJSONValuePtr object);
+int virJSONValueGetNumberInt(virJSONValuePtr object, int *value);
+int virJSONValueGetNumberUint(virJSONValuePtr object, unsigned int *value);
+int virJSONValueGetNumberLong(virJSONValuePtr object, long long *value);
+int virJSONValueGetNumberUlong(virJSONValuePtr object, unsigned long long *value);
+int virJSONValueGetNumberDouble(virJSONValuePtr object, double *value);
+int virJSONValueGetBoolean(virJSONValuePtr object, bool *value);
+int virJSONValueIsNull(virJSONValuePtr object);
+
+const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key);
+int virJSONValueObjectGetNumberInt(virJSONValuePtr object, const char *key, int *value);
+int virJSONValueObjectGetNumberUint(virJSONValuePtr object, const char *key, unsigned int *value);
+int virJSONValueObjectGetNumberLong(virJSONValuePtr object, const char *key, long long *value);
+int virJSONValueObjectGetNumberUlong(virJSONValuePtr object, const char *key, unsigned long long *value);
+int virJSONValueObjectGetNumberDouble(virJSONValuePtr object, const char *key, double *value);
+int virJSONValueObjectGetBoolean(virJSONValuePtr object, const char *key, bool *value);
+int virJSONValueObjectIsNull(virJSONValuePtr object, const char *key);
+
+int virJSONValueObjectAppendString(virJSONValuePtr object, const char *key, const char *value);
+int virJSONValueObjectAppendNumberInt(virJSONValuePtr object, const char *key, int number);
+int virJSONValueObjectAppendNumberUint(virJSONValuePtr object, const char *key, unsigned int number);
+int virJSONValueObjectAppendNumberLong(virJSONValuePtr object, const char *key, long long number);
+int virJSONValueObjectAppendNumberUlong(virJSONValuePtr object, const char *key, unsigned long long number);
+int virJSONValueObjectAppendNumberDouble(virJSONValuePtr object, const char *key, double number);
+int virJSONValueObjectAppendBoolean(virJSONValuePtr object, const char *key, int boolean);
+int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key);
+
+virJSONValuePtr virJSONValueFromString(const char *jsonstring);
+char *virJSONValueToString(virJSONValuePtr object,
+                           bool pretty);
+
+#endif /* __VIR_JSON_H_ */
diff --git a/src/util/virlockspace.h b/src/util/virlockspace.h
index 9c5128b..041cf20 100644
--- a/src/util/virlockspace.h
+++ b/src/util/virlockspace.h
@@ -23,7 +23,7 @@
 # define __VIR_LOCK_SPACE_H__
 
 # include "internal.h"
-# include "json.h"
+# include "virjson.h"
 
 typedef struct _virLockSpace virLockSpace;
 typedef virLockSpace *virLockSpacePtr;
diff --git a/tests/jsontest.c b/tests/jsontest.c
index 412f475..98a6069 100644
--- a/tests/jsontest.c
+++ b/tests/jsontest.c
@@ -6,7 +6,7 @@
 #include <time.h>
 
 #include "internal.h"
-#include "json.h"
+#include "virjson.h"
 #include "testutils.h"
 
 struct testInfo {
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index f687780..6f129d1 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -38,7 +38,7 @@
 #include "virsh-domain.h"
 #include "xml.h"
 #include "virtypedparam.h"
-#include "json.h"
+#include "virjson.h"
 
 /*
  * "capabilities" command
-- 
1.7.11.7




More information about the libvir-list mailing list