summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2018-05-29 10:10:27 +0200
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2018-06-07 07:46:59 +0000
commit98c64eae99425fb44d96d6775d6cde3d0058cf6d (patch)
tree6098bcaf30410df7d475e1d5586696fdb05f47db
parent5ae2a7a90dab46cb862005191f379a24618b7215 (diff)
wrap-json: Add clone facility
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 <jose.bollo@iot.bzh>
-rw-r--r--wrap-json.c86
-rw-r--r--wrap-json.h6
-rw-r--r--wrap-json.test.result6
3 files changed, 97 insertions, 1 deletions
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 <string.h>
+#include <limits.h>
#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 <stdio.h>
+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 <jose.bollo@iot.bzh>
@@ -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>>>>>>>