From: Lennart Poettering Date: Thu, 3 Jan 2019 16:51:12 +0000 (+0100) Subject: json: add new API json_variant_filter() for dropping fields from objects X-Git-Tag: v245-rc1~249^2~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2ff34ff2aaafd313a5c62b4b9f13ba6777731e5;p=thirdparty%2Fsystemd.git json: add new API json_variant_filter() for dropping fields from objects --- diff --git a/src/shared/json.c b/src/shared/json.c index 84ad6dd02ba..32f04245101 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -1622,6 +1622,59 @@ void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const cha fputc('\n', f); /* In case of SSE add a second newline */ } +int json_variant_filter(JsonVariant **v, char **to_remove) { + _cleanup_(json_variant_unrefp) JsonVariant *w = NULL; + _cleanup_free_ JsonVariant **array = NULL; + size_t i, n = 0, k = 0; + int r; + + assert(v); + + if (json_variant_is_blank_object(*v)) + return 0; + if (!json_variant_is_object(*v)) + return -EINVAL; + + if (strv_isempty(to_remove)) + return 0; + + for (i = 0; i < json_variant_elements(*v); i += 2) { + JsonVariant *p; + + p = json_variant_by_index(*v, i); + if (!json_variant_has_type(p, JSON_VARIANT_STRING)) + return -EINVAL; + + if (strv_contains(to_remove, json_variant_string(p))) { + if (!array) { + array = new(JsonVariant*, json_variant_elements(*v) - 2); + if (!array) + return -ENOMEM; + + for (k = 0; k < i; k++) + array[k] = json_variant_by_index(*v, k); + } + + n++; + } else if (array) { + array[k++] = p; + array[k++] = json_variant_by_index(*v, i + 1); + } + } + + if (n == 0) + return 0; + + r = json_variant_new_object(&w, array, k); + if (r < 0) + return r; + + json_variant_unref(*v); + *v = TAKE_PTR(w); + + return (int) n; +} + static int json_variant_copy(JsonVariant **nv, JsonVariant *v) { JsonVariantType t; JsonVariant *c; diff --git a/src/shared/json.h b/src/shared/json.h index 59962049d70..772ee67d7ba 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -167,6 +167,8 @@ typedef enum JsonFormatFlags { int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret); void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix); +int json_variant_filter(JsonVariant **v, char **to_remove); + int json_parse(const char *string, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column); int json_parse_continue(const char **p, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column); int json_parse_file(FILE *f, const char *path, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);