From 529d3e0b43d161475023437e947624550687f092 Mon Sep 17 00:00:00 2001 From: José Bollo Date: Tue, 29 May 2018 10:10:27 +0200 Subject: wrap-json: Add clone facility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds 3 new facilities: - wrap_json_clone: clones any json object superficially - wrap_json_clone_deep: clones any json object deeply - wrap_json_add: adds to an object the fields of an other object Change-Id: I3844d972aa6477c9dde6f66ad0b0604284a853a7 Signed-off-by: José Bollo --- wrap-json.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'wrap-json.c') diff --git a/wrap-json.c b/wrap-json.c index eace887..e5090ac 100644 --- a/wrap-json.c +++ b/wrap-json.c @@ -17,6 +17,7 @@ */ #include +#include #include "wrap-json.h" @@ -913,9 +914,92 @@ void wrap_json_for_all(struct json_object *object, void (*callback)(void*,struct } } +static struct json_object *clone_any(struct json_object *object, int deep); + +static struct json_object *clone_object(struct json_object *object, int subdeep) +{ + struct json_object *r = json_object_new_object(); + struct json_object_iterator it = json_object_iter_begin(object); + struct json_object_iterator end = json_object_iter_end(object); + while (!json_object_iter_equal(&it, &end)) { + json_object_object_add(r, + json_object_iter_peek_name(&it), + clone_any(json_object_iter_peek_value(&it), subdeep)); + json_object_iter_next(&it); + } + return r; +} + +static struct json_object *clone_array(struct json_object *object, int subdeep) +{ + int n = json_object_array_length(object); + struct json_object *r = json_object_new_array(); + while (n) { + n--; + json_object_array_put_idx(r, n, + clone_any(json_object_array_get_idx(object, n), subdeep)); + } + return r; +} + +static struct json_object *clone_any(struct json_object *object, int deep) +{ + if (deep) { + switch (json_object_get_type(object)) { + case json_type_object: + return clone_object(object, deep - 1); + case json_type_array: + return clone_array(object, deep - 1); + default: + break; + } + } + return json_object_get(object); +} + +struct json_object *wrap_json_clone(struct json_object *object) +{ + return clone_any(object, 1); +} + +struct json_object *wrap_json_clone_deep(struct json_object *object) +{ + return clone_any(object, INT_MAX); +} + +void wrap_json_object_add(struct json_object *dest, struct json_object *added) +{ + struct json_object_iterator it, end; + if (json_object_is_type(dest, json_type_object) && json_object_is_type(added, json_type_object)) { + it = json_object_iter_begin(added); + end = json_object_iter_end(added); + while (!json_object_iter_equal(&it, &end)) { + json_object_object_add(dest, + json_object_iter_peek_name(&it), + json_object_get(json_object_iter_peek_value(&it))); + json_object_iter_next(&it); + } + } +} + #if defined(WRAP_JSON_TEST) #include +void tclone(struct json_object *obj) +{ + struct json_object *o; + + o = wrap_json_clone(obj); + if (strcmp(json_object_to_json_string(obj), json_object_to_json_string(o))) + printf("ERROR in clone: %s VERSUS %s\n", json_object_to_json_string(obj), json_object_to_json_string(o)); + json_object_put(o); + + o = wrap_json_clone_deep(obj); + if (strcmp(json_object_to_json_string(obj), json_object_to_json_string(o))) + printf("ERROR in clone_deep: %s VERSUS %s\n", json_object_to_json_string(obj), json_object_to_json_string(o)); + json_object_put(o); +} + void p(const char *desc, ...) { int rc; @@ -929,6 +1013,7 @@ void p(const char *desc, ...) printf(" SUCCESS %s\n\n", json_object_to_json_string(result)); else printf(" ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc)); + tclone(result); json_object_put(result); } @@ -996,6 +1081,7 @@ void u(const char *value, const char *desc, ...) va_end(args); printf("\n\n"); } + tclone(obj); json_object_put(obj); } -- cgit 1.2.3-korg