From 78a41236e40fe0c1ea55f1c2d63933c6fcb7b8ae Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 4 Jan 2019 13:24:32 +0100 Subject: [PATCH] json: add new json_variant_set_field() helper --- src/shared/json.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++ src/shared/json.h | 2 ++ 2 files changed, 71 insertions(+) diff --git a/src/shared/json.c b/src/shared/json.c index 32f0424510..d85cc9f116 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -1675,6 +1675,75 @@ int json_variant_filter(JsonVariant **v, char **to_remove) { return (int) n; } +int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value) { + _cleanup_(json_variant_unrefp) JsonVariant *field_variant = NULL, *w = NULL; + _cleanup_free_ JsonVariant **array = NULL; + size_t i, k = 0; + int r; + + assert(v); + assert(field); + + if (json_variant_is_blank_object(*v)) { + array = new(JsonVariant*, 2); + if (!array) + return -ENOMEM; + + } else { + if (!json_variant_is_object(*v)) + return -EINVAL; + + for (i = 0; i < json_variant_elements(*v); i += 2) { + JsonVariant *p; + + p = json_variant_by_index(*v, i); + if (!json_variant_is_string(p)) + return -EINVAL; + + if (streq(json_variant_string(p), field)) { + + if (!array) { + array = new(JsonVariant*, json_variant_elements(*v)); + if (!array) + return -ENOMEM; + + for (k = 0; k < i; k++) + array[k] = json_variant_by_index(*v, k); + } + + } else if (array) { + array[k++] = p; + array[k++] = json_variant_by_index(*v, i + 1); + } + } + + if (!array) { + array = new(JsonVariant*, json_variant_elements(*v) + 2); + if (!array) + return -ENOMEM; + + for (k = 0; k < json_variant_elements(*v); k++) + array[k] = json_variant_by_index(*v, k); + } + } + + r = json_variant_new_string(&field_variant, field); + if (r < 0) + return r; + + array[k++] = field_variant; + array[k++] = value; + + r = json_variant_new_object(&w, array, k); + if (r < 0) + return r; + + json_variant_unref(*v); + *v = TAKE_PTR(w); + + return 1; +} + 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 772ee67d7b..0a9b2e111a 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -169,6 +169,8 @@ void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const cha int json_variant_filter(JsonVariant **v, char **to_remove); +int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value); + 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);