Update date of copyright notices
[src/app-framework-binder.git] / src / wrap-json.c
index 2354ea7..b25503a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2016, 2017 "IoT.bzh"
+ Copyright (C) 2016, 2017, 2018 "IoT.bzh"
 
  author: José Bollo <jose.bollo@iot.bzh>
 
@@ -121,9 +121,10 @@ int wrap_json_vpack(struct json_object **result, const char *desc, va_list args)
        top->cont = NULL;
        top->acc = pack_accept_any;
        top->type = 0;
-       if (!desc)
+       d = desc;
+       if (!d)
                goto null_spec;
-       d = skip(desc);
+       d = skip(d);
        for(;;) {
                c = *d;
                if (!c)
@@ -336,16 +337,16 @@ int wrap_json_pack(struct json_object **result, const char *desc, ...)
 
 static int vunpack(struct json_object *object, const char *desc, va_list args, int store)
 {
-       int rc, optionnal, ignore;
+       int rc = 0, optionnal, ignore;
        char c, xacc[2] = { 0, 0 };
        const char *acc;
-       const char *d, *fit;
-       const char *key;
-       const char **ps;
-       double *pf;
-       int *pi;
-       int64_t *pI;
-       size_t *pz;
+       const char *d, *fit = NULL;
+       const char *key = NULL;
+       const char **ps = NULL;
+       double *pf = NULL;
+       int *pi = NULL;
+       int64_t *pI = NULL;
+       size_t *pz = NULL;
        struct { struct json_object *parent; const char *acc; int index, count; char type; } stack[STACKCOUNT], *top;
        struct json_object *obj;
        struct json_object **po;
@@ -354,9 +355,10 @@ static int vunpack(struct json_object *object, const char *desc, va_list args, i
        ignore = 0;
        top = NULL;
        acc = unpack_accept_any;
-       if (!desc)
+       d = desc;
+       if (!d)
                goto null_spec;
-       d = skip(desc);
+       d = skip(d);
        obj = object;
        for(;;) {
                fit = d;
@@ -523,6 +525,7 @@ static int vunpack(struct json_object *object, const char *desc, va_list args, i
                                goto invalid_character;
                        if (!ignore && top->index != top->count)
                                goto incomplete;
+                       /*@fallthrough@*/
                case '*':
                        acc = xacc;
                        continue;
@@ -641,6 +644,68 @@ int wrap_json_unpack(struct json_object *object, const char *desc, ...)
        return rc;
 }
 
+static void object_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
+{
+       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)) {
+               callback(closure, json_object_iter_peek_value(&it), json_object_iter_peek_name(&it));
+               json_object_iter_next(&it);
+       }
+}
+
+static void array_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure)
+{
+       int n = json_object_array_length(object);
+       int i = 0;
+       while(i < n)
+               callback(closure, json_object_array_get_idx(object, i++));
+}
+
+void wrap_json_optarray_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure)
+{
+       if (json_object_is_type(object, json_type_array))
+               array_for_all(object, callback, closure);
+       else
+               callback(closure, object);
+}
+
+void wrap_json_array_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure)
+{
+       if (json_object_is_type(object, json_type_array))
+               array_for_all(object, callback, closure);
+}
+
+void wrap_json_object_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
+{
+       if (json_object_is_type(object, json_type_object))
+               object_for_all(object, callback, closure);
+}
+
+void wrap_json_optobject_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
+{
+       if (json_object_is_type(object, json_type_object))
+               object_for_all(object, callback, closure);
+       else
+               callback(closure, object, NULL);
+}
+
+void wrap_json_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
+{
+       if (!object)
+               /* do nothing */;
+       else if (json_object_is_type(object, json_type_object))
+               object_for_all(object, callback, closure);
+       else if (!json_object_is_type(object, json_type_array))
+               callback(closure, object, NULL);
+       else {
+               int n = json_object_array_length(object);
+               int i = 0;
+               while(i < n)
+                       callback(closure, json_object_array_get_idx(object, i++), NULL);
+       }
+}
+
 #if defined(WRAP_JSON_TEST)
 #include <stdio.h>
 
@@ -653,7 +718,7 @@ void p(const char *desc, ...)
        va_start(args, desc);
        rc = wrap_json_vpack(&result, desc, args);
        va_end(args);
-       if (!rc) 
+       if (!rc)
                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));
@@ -684,7 +749,7 @@ void u(const char *value, const char *desc, ...)
        va_start(args, desc);
        rc = wrap_json_vunpack(obj, desc, args);
        va_end(args);
-       if (rc) 
+       if (rc)
                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));
        else {
                value = NULL;