wgt-json: Add comments
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 14 Dec 2017 10:59:00 +0000 (11:59 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 14 Dec 2017 10:59:00 +0000 (11:59 +0100)
Change-Id: If75c3089c9506219601d35b49c132a9b670c026e
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/wgt-json.c

index e0ff08b..c764ea8 100644 (file)
 #include "wgt-strings.h"
 #include "verbose.h"
 
+/*
+ * This describes an action to be performed for a parameter of name.
+ * The action takes a not null json object, the param matched and a given closure.
+ */
 struct paramaction
 {
-       const char *name;
-       int (*action)(struct json_object *obj, const struct wgt_desc_param *param, void *closure);
-       void *closure;
+       const char *name;       /* the name of the parameter trigerring the action or null (mark end) */
+       int (*action)(struct json_object *obj, const struct wgt_desc_param *param, void *closure); /* the action to perform or null (no action) */
+       void *closure;          /* the closure to pass to the action */
 };
 
 
-/* apply params */
-static int apply_params(struct json_object *obj, const struct wgt_desc_param *param, const struct paramaction *actions)
+/*
+ * Apply the first matching 'actions' to each of the given 'params' and for the given json 'obj' (that shouldn't be null)
+ * Returns 0 in case of success or -1 on error.
+ */
+static int apply_params(struct json_object *obj, const struct wgt_desc_param *params, const struct paramaction *actions)
 {
        int rc;
        const struct paramaction *a;
 
-       if (!obj)
+       if (!obj) {
+               /* obj can't be null */
+               errno = EINVAL;
                rc = -1;
-       else {
+       } else {
+               /* iterate over the params */
                rc = 0;
-               while(param) {
-                       for (a = actions ; a->name && strcmp(a->name, param->name) ; a++);
-                       if (a->action && a->action(obj, param, a->closure) < 0)
+               while(params) {
+                       /* search the first match */
+                       for (a = actions ; a->name && strcmp(a->name, params->name) ; a++);
+                       /* invoke the action (or not if null) */
+                       if (a->action && a->action(obj, params, a->closure) < 0)
                                rc = -1;
-                       param = param->next;
+                       /* next */
+                       params = params->next;
                }
        }
        return rc;
 }
 
-static int get_array(struct json_object **result, struct json_object *obj, const char *key, int create)
+/*
+ * Get the array at the 'mkey' in 'obj'. 'create' it if needed and requested.
+ * Returns 0 in case of success or a negative number otherwise.
+ */
+static int get_array(struct json_object **result, struct json_object *obj, const char *mkey, int create)
 {
-       int rc = j_enter_m(&obj, &key, 1);
+       /* enter the multiple key */
+       int rc = j_enter_m(&obj, &mkey, create);
        if (rc < 0)
+               /* parent keys doesn't exist */
                *result = NULL;
-       else if (!json_object_object_get_ex(obj, key, result)) {
+       else if (!json_object_object_get_ex(obj, mkey, result)) {
+               /* parent keys exist but not the final key */
                if (!create) {
                        *result = NULL;
                        rc = -ENOENT;
                } else {
-                       if (!(*result = j_add_new_array(obj, key)))
+                       /* try to create the array */
+                       if (!(*result = j_add_new_array(obj, mkey)))
                                rc = -ENOMEM;
                }
        }
        return rc;
 }
 
-/* get the param of 'name' for the feature 'feat' */
+/*
+ * Returns the target name (#target) of the feature 'feat'.
+ * Returns 'defval' if not found or NULL is duplicated
+ */
 static const char *get_target_name(const struct wgt_desc_feature *feat, const char *defval)
 {
        const struct wgt_desc_param *param = feat->params;
+
+       /* search the parameter of name '#target' */
        while (param && strcmp(param->name, string_sharp_target))
                param = param->next;
        if (param) {
+               /* found, get itsd value */
                defval = param->value;
+
+               /* check it is defined only one time */
+               /* TODO: validate it in an other place? */
                param = param->next;
                while (param) {
                        if (!strcmp(param->name, string_sharp_target)) {
@@ -100,7 +130,10 @@ static const char *get_target_name(const struct wgt_desc_feature *feat, const ch
        return defval;
 }
 
-/* get the target */
+/*
+ * Search in 'array' the first object having a field of name 'key' and of string value 'val'
+ * Returns NULL if not found
+ */
 static struct json_object *get_array_item_by_key(struct json_object *array, const char *key, const char *val)
 {
        struct json_object *result, *k;
@@ -117,13 +150,20 @@ static struct json_object *get_array_item_by_key(struct json_object *array, cons
        return NULL;
 }
 
+/*
+ * Get or create from the array 'targets' the structure for the target of 'name'
+ * Should create if 'create' is not not otherwise just get.
+ * Returns zero on success or a errno negative code
+ */
 static int get_target(struct json_object **result, struct json_object *targets, const char *name, int create)
 {
        int rc;
        struct json_object *t;
 
+       /* search in targets a structure of target name */
        t = get_array_item_by_key(targets, string_sharp_target, name);
        if (t) {
+               /* found */
                if (!create)
                        rc = 0;
                else {
@@ -132,10 +172,12 @@ static int get_target(struct json_object **result, struct json_object *targets,
                        rc = -EEXIST;
                }
        } else {
+               /* not found */
                if (!create) {
                        ERROR("target name not found: %s", name);
                        rc = -ENOENT;
                } else {
+                       /* create a new value */
                        t = j_add_new_object(targets, NULL);
                        if (t && j_add_string(t, string_sharp_target, name))
                                rc = 0;
@@ -150,41 +192,50 @@ static int get_target(struct json_object **result, struct json_object *targets,
        return rc;
 }
 
-static int make_target(struct json_object *targets, const struct wgt_desc_feature *feat)
+/* create the target value for the feature */
+static int create_target(struct json_object *targets, const struct wgt_desc_feature *feat)
 {
        const char *id;
        struct json_object *target;
 
+       /* search within the feature the parameter naming the target */
        id = get_target_name(feat, NULL);
        if (id == NULL) {
-               ERROR("target of feature %s is missing or repeated", feat->name);
+               ERROR("target of feature %s is %s", feat->name, get_target_name(feat, feat->name) ? "repeated" : "missing");
                return -EINVAL;
        }
 
+       /* create the target */
        return get_target(&target, targets, id, 1);
 }
 
-static int add_icon(struct json_object *target, const char *src, int width, int height)
+/*
+ * Adds icon data to the target
+ */
+static int add_icon(struct json_object *target, const struct wgt_desc_icon *icon)
 {
        int rc;
-       struct json_object *icon, *array;
+       struct json_object *object, *array;
 
        rc = get_array(&array, target, string_icon, 1);
        if (rc >= 0) {
-               icon = json_object_new_object();
-               if(!icon
-               || !j_add_string(icon, string_src, src)
-               || (width > 0 && !j_add_integer(icon, string_width, width))
-               || (height > 0 && !j_add_integer(icon, string_height, height))
-               || !j_add(array, NULL, icon)) {
-                       json_object_put(icon);
+               object = json_object_new_object();
+               if(!object
+               || !j_add_string(object, string_src, icon->src)
+               || (icon->width > 0 && !j_add_integer(object, string_width, icon->width))
+               || (icon->height > 0 && !j_add_integer(object, string_height, icon->height))
+               || !j_add(array, NULL, object)) {
+                       json_object_put(object);
                        rc = -ENOMEM;
                }
        }
        return rc;
 }
 
-static int make_main_target(struct json_object *targets, const struct wgt_desc *desc)
+/*
+ * Creates the main target
+ */
+static int create_main_target(struct json_object *targets, const struct wgt_desc *desc)
 {
        int rc;
        struct wgt_desc_icon *icon;
@@ -193,13 +244,14 @@ static int make_main_target(struct json_object *targets, const struct wgt_desc *
        /* create the target 'main' */
        rc = get_target(&target, targets, string_main, 1);
 
-       /* adds icons if any */
+       /* add icons if any */
        icon = desc->icons;
        while (rc >= 0 && icon) {
-               rc = add_icon(target, icon->src, icon->width, icon->height);
+               rc = add_icon(target, icon);
                icon = icon->next;
        }
 
+       /* add content */
        if (rc >= 0)
                rc = j_add_many_strings_m(target,
                        "content.src", desc->content_src,
@@ -207,9 +259,12 @@ static int make_main_target(struct json_object *targets, const struct wgt_desc *
                        "content.encoding", desc->content_encoding,
                        NULL) ? 0 : -errno;
 
+       /* add other info */
        if (rc >= 0)
                if((desc->width && !j_add_integer(target, string_width, desc->width))
-               || (desc->height && !j_add_integer(target, string_height, desc->height)))
+               || (desc->height && !j_add_integer(target, string_height, desc->height))
+               || (desc->viewmodes && !j_add_string(target, string_viewmodes,  desc->viewmodes))
+               || (desc->defaultlocale && !j_add_string(target, string_defaultlocale,  desc->defaultlocale)))
                        rc = -ENOMEM;
 
        return rc;
@@ -217,6 +272,9 @@ static int make_main_target(struct json_object *targets, const struct wgt_desc *
 
 /***********************************************************************************************************/
 
+/*
+ * translate a param to an object { "name": name, "value": value }
+ */
 static struct json_object *object_of_param(const struct wgt_desc_param *param)
 {
        struct json_object *value;
@@ -231,16 +289,21 @@ static struct json_object *object_of_param(const struct wgt_desc_param *param)
        return NULL;
 }
 
+/*
+ * Add the field of mkey 'param'.name with 'param'.value to the object 'obj'
+ */
 static int add_param_simple(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
 {
        return j_add_string_m(obj, param->name, param->value);
 }
 
+/* add a param object to an array of param objects */
 static int add_param_array(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
 {
        const char *array_name = closure;
        struct json_object *array, *value;
 
+       /* the array is either pointed by 'closure=array_name' or the given 'obj' */
        if (!array_name)
                array = obj;
        else if (!json_object_object_get_ex(obj, array_name, &array)) {
@@ -248,6 +311,8 @@ static int add_param_array(struct json_object *obj, const struct wgt_desc_param
                if (!array)
                        return -ENOMEM;
        }
+
+       /* append the param object */
        value = object_of_param(param);
        if (value && j_add(array, NULL, value))
                return 0;
@@ -256,17 +321,22 @@ static int add_param_array(struct json_object *obj, const struct wgt_desc_param
        return -ENOMEM;
 }
 
+/* add a param object to an object of param objects, indexed by the param name */
 static int add_param_object(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
 {
+       const char *object_name = closure;
        struct json_object *object, *value;
 
-       if (!closure)
+       /* the object is either pointed by 'object_name=closure' or the given 'obj' */
+       if (!object_name)
                object = obj;
-       else if (!json_object_object_get_ex(obj, closure, &object)) {
-               object = j_add_new_object(obj, closure);
+       else if (!json_object_object_get_ex(obj, object_name, &object)) {
+               object = j_add_new_object(obj, object_name);
                if (!object)
                        return -ENOMEM;
        }
+
+       /* append the param object */
        value = object_of_param(param);
        if (value && j_add(object, param->name, value))
                return 0;
@@ -275,6 +345,7 @@ static int add_param_object(struct json_object *obj, const struct wgt_desc_param
        return -ENOMEM;
 }
 
+/* Retrieve within 'targets' the target of the feature 'feat' and applies 'actions' to it */
 static int add_targeted_params(struct json_object *targets, const struct wgt_desc_feature *feat, struct paramaction actions[])
 {
        int rc;
@@ -286,42 +357,47 @@ static int add_targeted_params(struct json_object *targets, const struct wgt_des
        return rc < 0 ? rc : apply_params(obj, feat->params, actions);
 }
 
+/* Treats the feature "provided_unit" */
 static int add_provided_unit(struct json_object *targets, const struct wgt_desc_feature *feat)
 {
        static struct paramaction actions[] = {
-               { .name = string_sharp_target, .action = NULL, .closure = NULL },
+               { .name = string_sharp_target, .action = NULL, .closure = NULL }, /* skip #target */
                { .name = NULL, .action = add_param_simple, .closure = NULL }
        };
        return add_targeted_params(targets, feat, actions);
 }
 
+/* Treats the feature "provided_api" */
 static int add_provided_api(struct json_object *targets, const struct wgt_desc_feature *feat)
 {
        static struct paramaction actions[] = {
-               { .name = string_sharp_target, .action = NULL, .closure = NULL },
+               { .name = string_sharp_target, .action = NULL, .closure = NULL }, /* skip #target */
                { .name = NULL, .action = add_param_array, .closure = (void*)string_provided_api }
        };
        return add_targeted_params(targets, feat, actions);
 }
 
+/* Treats the feature "required_api" */
 static int add_required_api(struct json_object *targets, const struct wgt_desc_feature *feat)
 {
        static struct paramaction actions[] = {
-               { .name = string_sharp_target, .action = NULL, .closure = NULL },
+               { .name = string_sharp_target, .action = NULL, .closure = NULL }, /* skip #target */
                { .name = NULL, .action = add_param_array, .closure = (void*)string_required_api }
        };
        return add_targeted_params(targets, feat, actions);
 }
 
+/* Treats the feature "required_permission" */
 static int add_required_permission(struct json_object *targets, const struct wgt_desc_feature *feat)
 {
        static struct paramaction actions[] = {
-               { .name = string_sharp_target, .action = NULL, .closure = NULL },
+               { .name = string_sharp_target, .action = NULL, .closure = NULL }, /* skip #target */
                { .name = NULL, .action = add_param_object, .closure = (void*)string_required_permission }
        };
        return add_targeted_params(targets, feat, actions);
 }
 
+/* Treats the feature "defined_permission" */
 static int add_defined_permission(struct json_object *defperm, const struct wgt_desc_feature *feat)
 {
        static struct paramaction actions[] = {
@@ -332,6 +408,9 @@ static int add_defined_permission(struct json_object *defperm, const struct wgt_
 
 /***********************************************************************************************************/
 
+/*
+ * Create the json object from 'desc'
+ */
 static struct json_object *to_json(const struct wgt_desc *desc)
 {
        size_t prefixlen;
@@ -348,7 +427,7 @@ static struct json_object *to_json(const struct wgt_desc *desc)
                goto error;
 
        /* first pass: declarations */
-       rc = make_main_target(targets, desc);
+       rc = create_main_target(targets, desc);
        prefixlen = strlen(string_AGL_widget_prefix);
        for (feat = desc->features ; feat ; feat = feat->next) {
                featname = feat->name;
@@ -360,7 +439,7 @@ static struct json_object *to_json(const struct wgt_desc *desc)
                        }
                        featname += prefixlen;
                        if (!strcmp(featname, string_provided_unit)) {
-                               rc2 = make_target(targets, feat);
+                               rc2 = create_target(targets, feat);
                                if (rc2 < 0 && !rc)
                                        rc = rc2;
                        }
@@ -414,23 +493,22 @@ static struct json_object *to_json(const struct wgt_desc *desc)
        if (rc2 < 0 && !rc)
                rc = rc2;
 
-       /* */
-
-       /* */
-       if (!rc) {
+       /* returns the result if there is no error*/
+       if (!rc)
                return result;
-       }
 
 error:
        json_object_put(result);
        return NULL;
 }
 
+/* get the json_object of the wgt_info 'info' or NULL if error */
 struct json_object *wgt_info_to_json(struct wgt_info *info)
 {
        return to_json(wgt_info_desc(info));
 }
 
+/* get the json_object of the 'wgt' or NULL if error */
 struct json_object *wgt_to_json(struct wgt *wgt)
 {
        struct json_object *result;
@@ -446,6 +524,7 @@ struct json_object *wgt_to_json(struct wgt *wgt)
        return result;
 }
 
+/* get the json_object of the widget of 'path' relative to 'dfd' or NULL if error */
 struct json_object *wgt_path_at_to_json(int dfd, const char *path)
 {
        struct json_object *result;
@@ -461,6 +540,7 @@ struct json_object *wgt_path_at_to_json(int dfd, const char *path)
        return result;
 }
 
+/* get the json_object of the widget of 'path' or NULL if error */
 struct json_object *wgt_path_to_json(const char *path)
 {
        return wgt_path_at_to_json(AT_FDCWD, path);