Re: [libvirt] [PATCH 1/4] json: support removing a value from an object

2013-05-13 Thread Osier Yang

On 27/04/13 05:01, Eric Blake wrote:

In an upcoming patch, I need the way to safely transfer a nested
virJSON object out of its parent container for independent use,
even after the parent is freed.

* src/util/virjson.h (virJSONValueObjectRemoveKey): New function.
(_virJSONObject, _virJSONArray): Use correct type.
* src/util/virjson.c (virJSONValueObjectRemoveKey): Implement it.
* src/libvirt_private.syms (virjson.h): Export it.
* tests/jsontest.c (mymain): Test it.

Signed-off-by: Eric Blake ebl...@redhat.com
---
  src/libvirt_private.syms |  1 +
  src/util/virjson.c   | 34 +++-
  src/util/virjson.h   |  9 --
  tests/jsontest.c | 83 ++--
  4 files changed, 120 insertions(+), 7 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0bb6f5f..b502ed8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1392,6 +1392,7 @@ virJSONValueObjectGetValue;
  virJSONValueObjectHasKey;
  virJSONValueObjectIsNull;
  virJSONValueObjectKeysNumber;
+virJSONValueObjectRemoveKey;
  virJSONValueToString;


diff --git a/src/util/virjson.c b/src/util/virjson.c
index e6a3b1b..10afe88 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1,7 +1,7 @@
  /*
   * virjson.c: JSON object parsing/formatting
   *
- * Copyright (C) 2009-2010, 2012 Red Hat, Inc.
+ * Copyright (C) 2009-2010, 2012-2013 Red Hat, Inc.
   * Copyright (C) 2009 Daniel P. Berrange
   *
   * This library is free software; you can redistribute it and/or
@@ -447,6 +447,38 @@ const char *virJSONValueObjectGetKey(virJSONValuePtr 
object, unsigned int n)
  return object-data.object.pairs[n].key;
  }

+/* Remove the key-value pair tied to KEY out of OBJECT.  If VALUE is
+ * not NULL, the dropped value object is returned instead of freed.


How about:

s/KEY/@key/, s/OBJECT/@object/, s/VALUE/@value/, ?


+ * Returns 1 on success, 0 if no key was found, and -1 on error.  */
+int
+virJSONValueObjectRemoveKey(virJSONValuePtr object, const char *key,
+virJSONValuePtr *value)
+{
+int i;
+
+if (value)
+*value = NULL;
+
+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)) {
+if (value) {
+*value = object-data.object.pairs[i].value;
+object-data.object.pairs[i].value = NULL;
+}
+VIR_FREE(object-data.object.pairs[i].key);
+virJSONValueFree(object-data.object.pairs[i].value);
+VIR_DELETE_ELEMENT(object-data.object.pairs, i,
+   object-data.object.npairs);
+return 1;
+}
+}
+
+return 0;
+}
+
  virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned 
int n)
  {
  if (object-type != VIR_JSON_TYPE_OBJECT)
diff --git a/src/util/virjson.h b/src/util/virjson.h
index 67f4398..ff0fe75 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -1,7 +1,7 @@
  /*
   * virjson.h: JSON object parsing/formatting
   *
- * Copyright (C) 2009, 2012 Red Hat, Inc.
+ * Copyright (C) 2009, 2012-2013 Red Hat, Inc.
   * Copyright (C) 2009 Daniel P. Berrange
   *
   * This library is free software; you can redistribute it and/or
@@ -55,12 +55,12 @@ struct _virJSONObjectPair {
  };

  struct _virJSONObject {
-unsigned int npairs;
+size_t npairs;
  virJSONObjectPairPtr pairs;
  };

  struct _virJSONArray {
-unsigned int nvalues;
+size_t nvalues;
  virJSONValuePtr *values;
  };

@@ -131,6 +131,9 @@ int virJSONValueObjectAppendNumberDouble(virJSONValuePtr 
object, const char *key
  int virJSONValueObjectAppendBoolean(virJSONValuePtr object, const char *key, 
int boolean);
  int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key);

+int virJSONValueObjectRemoveKey(virJSONValuePtr object, const char *key,


Worth to add ATTRIBUTE_NONNULL for object and key?
 with the questions.

ACK with the two questions resolved.

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


Re: [libvirt] [PATCH 1/4] json: support removing a value from an object

2013-05-13 Thread Eric Blake
On 05/13/2013 02:05 AM, Osier Yang wrote:
 On 27/04/13 05:01, Eric Blake wrote:
 In an upcoming patch, I need the way to safely transfer a nested
 virJSON object out of its parent container for independent use,
 even after the parent is freed.

 * src/util/virjson.h (virJSONValueObjectRemoveKey): New function.
 (_virJSONObject, _virJSONArray): Use correct type.
 * src/util/virjson.c (virJSONValueObjectRemoveKey): Implement it.
 * src/libvirt_private.syms (virjson.h): Export it.
 * tests/jsontest.c (mymain): Test it.



 +/* Remove the key-value pair tied to KEY out of OBJECT.  If VALUE is
 + * not NULL, the dropped value object is returned instead of freed.
 
 How about:
 
 s/KEY/@key/, s/OBJECT/@object/, s/VALUE/@value/, ?

Sure thing.  Some of my old habits slipping through (not every project
uses doxygen-style markup :)


 +int virJSONValueObjectRemoveKey(virJSONValuePtr object, const char *key,
 
 Worth to add ATTRIBUTE_NONNULL for object and key?

Good idea.  Consider it done :)

  with the questions.
 
 ACK with the two questions resolved.

Will push shortly as amended.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH 1/4] json: support removing a value from an object

2013-04-26 Thread Eric Blake
In an upcoming patch, I need the way to safely transfer a nested
virJSON object out of its parent container for independent use,
even after the parent is freed.

* src/util/virjson.h (virJSONValueObjectRemoveKey): New function.
(_virJSONObject, _virJSONArray): Use correct type.
* src/util/virjson.c (virJSONValueObjectRemoveKey): Implement it.
* src/libvirt_private.syms (virjson.h): Export it.
* tests/jsontest.c (mymain): Test it.

Signed-off-by: Eric Blake ebl...@redhat.com
---
 src/libvirt_private.syms |  1 +
 src/util/virjson.c   | 34 +++-
 src/util/virjson.h   |  9 --
 tests/jsontest.c | 83 ++--
 4 files changed, 120 insertions(+), 7 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0bb6f5f..b502ed8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1392,6 +1392,7 @@ virJSONValueObjectGetValue;
 virJSONValueObjectHasKey;
 virJSONValueObjectIsNull;
 virJSONValueObjectKeysNumber;
+virJSONValueObjectRemoveKey;
 virJSONValueToString;


diff --git a/src/util/virjson.c b/src/util/virjson.c
index e6a3b1b..10afe88 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1,7 +1,7 @@
 /*
  * virjson.c: JSON object parsing/formatting
  *
- * Copyright (C) 2009-2010, 2012 Red Hat, Inc.
+ * Copyright (C) 2009-2010, 2012-2013 Red Hat, Inc.
  * Copyright (C) 2009 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -447,6 +447,38 @@ const char *virJSONValueObjectGetKey(virJSONValuePtr 
object, unsigned int n)
 return object-data.object.pairs[n].key;
 }

+/* Remove the key-value pair tied to KEY out of OBJECT.  If VALUE is
+ * not NULL, the dropped value object is returned instead of freed.
+ * Returns 1 on success, 0 if no key was found, and -1 on error.  */
+int
+virJSONValueObjectRemoveKey(virJSONValuePtr object, const char *key,
+virJSONValuePtr *value)
+{
+int i;
+
+if (value)
+*value = NULL;
+
+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)) {
+if (value) {
+*value = object-data.object.pairs[i].value;
+object-data.object.pairs[i].value = NULL;
+}
+VIR_FREE(object-data.object.pairs[i].key);
+virJSONValueFree(object-data.object.pairs[i].value);
+VIR_DELETE_ELEMENT(object-data.object.pairs, i,
+   object-data.object.npairs);
+return 1;
+}
+}
+
+return 0;
+}
+
 virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned 
int n)
 {
 if (object-type != VIR_JSON_TYPE_OBJECT)
diff --git a/src/util/virjson.h b/src/util/virjson.h
index 67f4398..ff0fe75 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -1,7 +1,7 @@
 /*
  * virjson.h: JSON object parsing/formatting
  *
- * Copyright (C) 2009, 2012 Red Hat, Inc.
+ * Copyright (C) 2009, 2012-2013 Red Hat, Inc.
  * Copyright (C) 2009 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -55,12 +55,12 @@ struct _virJSONObjectPair {
 };

 struct _virJSONObject {
-unsigned int npairs;
+size_t npairs;
 virJSONObjectPairPtr pairs;
 };

 struct _virJSONArray {
-unsigned int nvalues;
+size_t nvalues;
 virJSONValuePtr *values;
 };

@@ -131,6 +131,9 @@ int virJSONValueObjectAppendNumberDouble(virJSONValuePtr 
object, const char *key
 int virJSONValueObjectAppendBoolean(virJSONValuePtr object, const char *key, 
int boolean);
 int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key);

+int virJSONValueObjectRemoveKey(virJSONValuePtr object, const char *key,
+virJSONValuePtr *value);
+
 virJSONValuePtr virJSONValueFromString(const char *jsonstring);
 char *virJSONValueToString(virJSONValuePtr object,
bool pretty);
diff --git a/tests/jsontest.c b/tests/jsontest.c
index 98a6069..a37a980 100644
--- a/tests/jsontest.c
+++ b/tests/jsontest.c
@@ -11,6 +11,7 @@

 struct testInfo {
 const char *doc;
+const char *expect;
 bool pass;
 };

@@ -55,19 +56,88 @@ cleanup:


 static int
+testJSONAddRemove(const void *data)
+{
+const struct testInfo *info = data;
+virJSONValuePtr json;
+virJSONValuePtr name;
+char *result = NULL;
+int ret = -1;
+
+json = virJSONValueFromString(info-doc);
+
+switch (virJSONValueObjectRemoveKey(json, name, name)) {
+case 1:
+if (!info-pass) {
+if (virTestGetVerbose())
+fprintf(stderr, should not remove from non-object %s\n,
+info-doc);
+goto cleanup;
+}
+break;
+case -1:
+if (!info-pass)
+ret = 0;
+else if (virTestGetVerbose())
+