To allow constructing of value objects stepwise explode the helper into
separate steps and allow appending into existing value objects.
---

Notes:
    Version 2:
    - Fix freeing of the created JSON object on error -> use JSON freeing func

 src/libvirt_private.syms |  2 ++
 src/util/virjson.c       | 76 +++++++++++++++++++++++++++++++-----------------
 src/util/virjson.h       |  5 ++++
 3 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 24fd4da..7af8ee0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1534,6 +1534,8 @@ virJSONValueNewNumberUlong;
 virJSONValueNewObject;
 virJSONValueNewString;
 virJSONValueNewStringLen;
+virJSONValueObjectAdd;
+virJSONValueObjectAddVArgs;
 virJSONValueObjectAppend;
 virJSONValueObjectAppendBoolean;
 virJSONValueObjectAppendNull;
diff --git a/src/util/virjson.c b/src/util/virjson.c
index 9f2e1cf..fe3357a 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -64,12 +64,11 @@ struct _virJSONParser {


 /**
- * virJSONValueObjectCreateVArgs:
- * @obj: returns the created JSON object
- * @...: a key-value argument pairs, terminated by NULL
+ * virJSONValueObjectAddVArgs:
+ * @obj: JSON object to add the values to
+ * @args: a key-value argument pairs, terminated by NULL
  *
- * Creates a JSON value object filled with key-value pairs supplied as variable
- * argument list.
+ * Adds the key-value pairs supplied as variable argument list to @obj.
  *
  * Keys look like   s:name  the first letter is a type code:
  * Explanation of type codes:
@@ -104,22 +103,17 @@ struct _virJSONParser {
  * The value corresponds to the selected type.
  *
  * Returns -1 on error. 1 on success, if at least one key:pair was valid 0
- * in case of no error but nothing was filled (@obj will be NULL).
+ * in case of no error but nothing was filled.
  */
 int
-virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list args)
+virJSONValueObjectAddVArgs(virJSONValuePtr obj,
+                           va_list args)
 {
-    virJSONValuePtr jargs = NULL;
     char type;
     char *key;
     int ret = -1;
     int rc;

-    *obj = NULL;
-
-    if (!(jargs = virJSONValueNewObject()))
-        goto cleanup;
-
     while ((key = va_arg(args, char *)) != NULL) {

         if (strlen(key) < 3) {
@@ -146,7 +140,7 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list 
args)
                                key);
                 goto cleanup;
             }
-            rc = virJSONValueObjectAppendString(jargs, key, val);
+            rc = virJSONValueObjectAppendString(obj, key, val);
         }   break;

         case 'z':
@@ -165,7 +159,7 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list 
args)
             if (!val && (type == 'z' || type == 'y'))
                 continue;

-            rc = virJSONValueObjectAppendNumberInt(jargs, key, val);
+            rc = virJSONValueObjectAppendNumberInt(obj, key, val);
         }   break;

         case 'p':
@@ -175,7 +169,7 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list 
args)
             if (!val && type == 'p')
                 continue;

-            rc = virJSONValueObjectAppendNumberUint(jargs, key, val);
+            rc = virJSONValueObjectAppendNumberUint(obj, key, val);
         }   break;

         case 'Z':
@@ -194,7 +188,7 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list 
args)
             if (!val && (type == 'Z' || type == 'Y'))
                 continue;

-            rc = virJSONValueObjectAppendNumberLong(jargs, key, val);
+            rc = virJSONValueObjectAppendNumberLong(obj, key, val);
         }   break;

         case 'P':
@@ -209,12 +203,12 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, 
va_list args)
             if (!val && type == 'P')
                 continue;

-            rc = virJSONValueObjectAppendNumberLong(jargs, key, val);
+            rc = virJSONValueObjectAppendNumberLong(obj, key, val);
         }   break;

         case 'd': {
             double val = va_arg(args, double);
-            rc = virJSONValueObjectAppendNumberDouble(jargs, key, val);
+            rc = virJSONValueObjectAppendNumberDouble(obj, key, val);
         }   break;

         case 'B':
@@ -224,11 +218,11 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, 
va_list args)
             if (!val && type == 'B')
                 continue;

-            rc = virJSONValueObjectAppendBoolean(jargs, key, val);
+            rc = virJSONValueObjectAppendBoolean(obj, key, val);
         }   break;

         case 'n': {
-            rc = virJSONValueObjectAppendNull(jargs, key);
+            rc = virJSONValueObjectAppendNull(obj, key);
         }   break;

         case 'A':
@@ -245,7 +239,7 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list 
args)
                 goto cleanup;
             }

-            rc = virJSONValueObjectAppend(jargs, key, val);
+            rc = virJSONValueObjectAppend(obj, key, val);
         }   break;

         default:
@@ -259,17 +253,47 @@ virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, 
va_list args)
     }

     /* verify that we added at least one key-value pair */
-    if (virJSONValueObjectKeysNumber(jargs) == 0) {
+    if (virJSONValueObjectKeysNumber(obj) == 0) {
         ret = 0;
         goto cleanup;
     }

-    *obj = jargs;
-    jargs = NULL;
     ret = 1;

  cleanup:
-    virJSONValueFree(jargs);
+    return ret;
+}
+
+
+int
+virJSONValueObjectAdd(virJSONValuePtr obj, ...)
+{
+    va_list args;
+    int ret;
+
+    va_start(args, obj);
+    ret = virJSONValueObjectAddVArgs(obj, args);
+    va_end(args);
+
+    return ret;
+}
+
+
+int
+virJSONValueObjectCreateVArgs(virJSONValuePtr *obj,
+                              va_list args)
+{
+    int ret;
+
+    if (!(*obj = virJSONValueNewObject()))
+        return -1;
+
+    /* free the object on error, or if no value objects were added */
+    if ((ret = virJSONValueObjectAddVArgs(*obj, args)) <= 0) {
+        virJSONValueFree(*obj);
+        *obj = NULL;
+    }
+
     return ret;
 }

diff --git a/src/util/virjson.h b/src/util/virjson.h
index c0aefba..fc05ad9 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -85,6 +85,11 @@ int virJSONValueObjectCreate(virJSONValuePtr *obj, ...)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL;
 int virJSONValueObjectCreateVArgs(virJSONValuePtr *obj, va_list args)
     ATTRIBUTE_NONNULL(1);
+int virJSONValueObjectAdd(virJSONValuePtr obj, ...)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL;
+int virJSONValueObjectAddVArgs(virJSONValuePtr obj, va_list args)
+    ATTRIBUTE_NONNULL(1);
+

 virJSONValuePtr virJSONValueNewString(const char *data);
 virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length);
-- 
2.2.2

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

Reply via email to