From: "Daniel P. Berrange" <berrange(a)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