Re: [libvirt] [PATCH 1/4] json: support removing a value from an object
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
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
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()) +