From 98c64eae99425fb44d96d6775d6cde3d0058cf6d 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 +++++++++++++++++++++++++++++++++++++++++++++++++++ wrap-json.h | 6 +++- wrap-json.test.result | 6 ++++ 3 files changed, 97 insertions(+), 1 deletion(-) 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); } diff --git a/wrap-json.h b/wrap-json.h index f5e6996..fd5b7c3 100644 --- a/wrap-json.h +++ b/wrap-json.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016, 2017 "IoT.bzh" + Copyright (C) 2016, 2017, 2018 "IoT.bzh" author: José Bollo @@ -48,6 +48,10 @@ extern void wrap_json_object_for_all(struct json_object *object, void (*callback extern void wrap_json_optobject_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure); extern void wrap_json_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure); +extern struct json_object *wrap_json_clone(struct json_object *object); +extern struct json_object *wrap_json_clone_deep(struct json_object *object); +extern void wrap_json_object_add(struct json_object *dest, struct json_object *added); + #ifdef __cplusplus } #endif diff --git a/wrap-json.test.result b/wrap-json.test.result index b7acbb5..0edaf75 100644 --- a/wrap-json.test.result +++ b/wrap-json.test.result @@ -394,6 +394,12 @@ unpack("{\"foo\":42}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]) unpack("\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"", "y", &xy[0], &xz[0]) SUCCESS y/19:???????hello>>>>>>> +unpack("\"\"", "y", &xy[0], &xz[0]) + SUCCESS y/0: + +unpack("null", "y", &xy[0], &xz[0]) + SUCCESS y/0: + unpack("{\"foo\":\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"}", "{s?y}", "foo", &xy[0], &xz[0]) SUCCESS s:foo y/19:???????hello>>>>>>> -- cgit 1.2.3-korg