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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list