aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/wgt-json.c172
1 files changed, 126 insertions, 46 deletions
diff --git a/src/wgt-json.c b/src/wgt-json.c
index e0ff08b..c764ea8 100644
--- a/src/wgt-json.c
+++ b/src/wgt-json.c
@@ -35,59 +35,89 @@
#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);