2 Copyright 2015, 2016, 2017 IoT.bzh
4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
28 #include <sys/types.h>
30 #include <json-c/json.h>
32 #include "utils-json.h"
35 #include "wgt-strings.h"
42 ID: { name: ID, level: LEVEL, index: INDEX },
46 { name: ID, level: LEVEL, index: 0 },
51 { name: ID, level: LEVEL, index: 0 },
61 int (*action)(struct json_object *obj, const struct wgt_desc_param *param, void *closure);
67 static int apply_params(struct json_object *obj, const struct wgt_desc_param *param, const struct paramaction *actions)
70 const struct paramaction *a;
77 for (a = actions ; a->name && strcmp(a->name, param->name) ; a++);
78 if (a->action && a->action(obj, param, a->closure) < 0)
86 static int get_array(struct json_object **result, struct json_object *obj, const char *key, int create)
88 int rc = j_enter_m(&obj, &key, 1);
91 else if (!json_object_object_get_ex(obj, key, result)) {
96 if (!(*result = j_add_new_array(obj, key)))
103 /* get the param of 'name' for the feature 'feat' */
104 static const char *get_target_name(const struct wgt_desc_feature *feat, const char *defval)
106 const struct wgt_desc_param *param = feat->params;
107 while (param && strcmp(param->name, string_sharp_target))
110 defval = param->value;
113 if (!strcmp(param->name, string_sharp_target)) {
124 static struct json_object *get_array_item_by_key(struct json_object *array, const char *key, const char *val)
126 struct json_object *result, *k;
129 n = json_object_array_length(array);
130 for (i = 0 ; i < n ; i++) {
131 result = json_object_array_get_idx(array, i);
132 if (result && json_object_object_get_ex(result, key, &k)
133 && json_object_get_type(k) == json_type_string
134 && !strcmp(json_object_get_string(k), val))
140 static int get_target(struct json_object **result, struct json_object *targets, const char *name, int create)
143 struct json_object *t;
145 t = get_array_item_by_key(targets, string_sharp_target, name);
150 ERROR("duplicated target name: %s", name);
156 ERROR("target name not found: %s", name);
159 t = j_add_new_object(targets, NULL);
160 if (t && j_add_string(t, string_sharp_target, name))
173 static int make_target(struct json_object *targets, const struct wgt_desc_feature *feat)
176 struct json_object *target;
178 id = get_target_name(feat, NULL);
180 ERROR("target of feature %s is missing or repeated", feat->name);
184 return get_target(&target, targets, id, 1);
187 static int add_icon(struct json_object *target, const char *src, int width, int height)
190 struct json_object *icon, *array;
192 rc = get_array(&array, target, string_icon, 1);
194 icon = json_object_new_object();
196 || !j_add_string(icon, string_src, src)
197 || (width > 0 && !j_add_integer(icon, string_width, width))
198 || (height > 0 && !j_add_integer(icon, string_height, height))
199 || !j_add(array, NULL, icon)) {
200 json_object_put(icon);
207 static int make_main_target(struct json_object *targets, const struct wgt_desc *desc)
210 struct wgt_desc_icon *icon;
211 struct json_object *target;
213 /* create the target 'main' */
214 rc = get_target(&target, targets, string_main, 1);
216 /* adds icons if any */
218 while (rc >= 0 && icon) {
219 rc = add_icon(target, icon->src, icon->width, icon->height);
224 rc = j_add_many_strings_m(target,
225 "content.src", desc->content_src,
226 "content.type", desc->content_type,
227 "content.encoding", desc->content_encoding,
231 if((desc->width && !j_add_integer(target, string_width, desc->width))
232 || (desc->height && !j_add_integer(target, string_height, desc->height)))
238 /***********************************************************************************************************/
240 static struct json_object *object_of_param(const struct wgt_desc_param *param)
242 struct json_object *value;
244 value = json_object_new_object();
246 && j_add_string(value, string_name, param->name)
247 && j_add_string(value, string_value, param->value))
250 json_object_put(value);
254 static int add_param_simple(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
256 return j_add_string_m(obj, param->name, param->value);
259 static int add_param_array(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
261 struct json_object *array, *value;
265 else if (!json_object_object_get_ex(obj, closure, &array)) {
266 array = j_add_new_array(obj, closure);
270 value = object_of_param(param);
271 if (value && j_add(array, NULL, value))
274 json_object_put(value);
278 static int add_param_object(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
280 struct json_object *object, *value;
284 else if (!json_object_object_get_ex(obj, closure, &object)) {
285 object = j_add_new_object(obj, closure);
289 value = object_of_param(param);
290 if (value && j_add(object, param->name, value))
293 json_object_put(value);
297 static int add_targeted_params(struct json_object *targets, const struct wgt_desc_feature *feat, struct paramaction actions[])
301 struct json_object *obj;
303 id = get_target_name(feat, string_main);
304 rc = get_target(&obj, targets, id, 0);
305 return rc < 0 ? rc : apply_params(obj, feat->params, actions);
308 static int add_provided(struct json_object *targets, const struct wgt_desc_feature *feat)
310 static struct paramaction actions[] = {
311 { .name = string_sharp_target, .action = NULL, .closure = NULL },
312 { .name = NULL, .action = add_param_simple, .closure = NULL }
314 return add_targeted_params(targets, feat, actions);
317 static int add_required_api(struct json_object *targets, const struct wgt_desc_feature *feat)
319 static struct paramaction actions[] = {
320 { .name = string_sharp_target, .action = NULL, .closure = NULL },
321 { .name = NULL, .action = add_param_array, .closure = (void*)string_required_api }
323 return add_targeted_params(targets, feat, actions);
327 static int add_required_permission(struct json_object *targets, const struct wgt_desc_feature *feat)
329 static struct paramaction actions[] = {
330 { .name = string_sharp_target, .action = NULL, .closure = NULL },
331 { .name = NULL, .action = add_param_object, .closure = (void*)string_required_permission }
333 return add_targeted_params(targets, feat, actions);
336 static int add_defined_permission(struct json_object *defperm, const struct wgt_desc_feature *feat)
338 static struct paramaction actions[] = {
339 { .name = NULL, .action = add_param_array, .closure = NULL }
341 return apply_params(defperm, feat->params, actions);
344 /***********************************************************************************************************/
346 static struct json_object *to_json(const struct wgt_desc *desc)
349 const struct wgt_desc_feature *feat;
350 const char *featname;
351 struct json_object *result, *targets, *permissions;
354 /* create the application structure */
355 if(!(result = json_object_new_object())
356 || !(targets = j_add_new_array(result, string_targets))
357 || !(permissions = j_add_new_array(result, string_defined_permission))
361 /* first pass: declarations */
362 rc = make_main_target(targets, desc);
363 prefixlen = strlen(string_AGL_widget_prefix);
364 for (feat = desc->features ; feat ; feat = feat->next) {
365 featname = feat->name;
366 if (!memcmp(featname, string_AGL_widget_prefix, prefixlen)) {
367 if (!feat->required) {
368 ERROR("feature %s can't be optional", featname);
372 featname += prefixlen;
373 if (!strcmp(featname, string_provided_api)
374 || !strcmp(featname, string_provided_application)) {
375 rc2 = make_target(targets, feat);
382 /* second pass: definitions */
383 for (feat = desc->features ; feat ; feat = feat->next) {
384 featname = feat->name;
385 if (!memcmp(featname, string_AGL_widget_prefix, prefixlen)) {
386 featname += prefixlen;
387 if (!strcmp(featname, string_defined_permission)) {
388 rc2 = add_defined_permission(permissions, feat);
392 else if (!strcmp(featname, string_provided_application)
393 || !strcmp(featname, string_provided_api)) {
394 rc2 = add_provided(targets, feat);
398 else if (!strcmp(featname, string_required_api)) {
399 rc2 = add_required_api(targets, feat);
403 else if (!strcmp(featname, string_required_permission)) {
404 rc2 = add_required_permission(targets, feat);
412 rc2 = j_add_many_strings_m(result,
414 string_idaver, desc->idaver,
415 string_version, desc->version,
417 "author.content", desc->author,
418 "author.href", desc->author_href,
419 "author.email", desc->author_email,
420 "license.content", desc->license,
421 "license.href", desc->license_href,
422 "defaultlocale", desc->defaultlocale,
423 "name.content", desc->name,
424 "name.short", desc->name_short,
425 "description", desc->description,
438 json_object_put(result);
442 struct json_object *wgt_info_to_json(struct wgt_info *info)
444 return to_json(wgt_info_desc(info));
447 struct json_object *wgt_to_json(struct wgt *wgt)
449 struct json_object *result;
450 struct wgt_info *info;
452 info = wgt_info_create(wgt, 1, 1, 1);
456 result = wgt_info_to_json(info);
457 wgt_info_unref(info);
462 struct json_object *wgt_path_at_to_json(int dfd, const char *path)
464 struct json_object *result;
465 struct wgt_info *info;
467 info = wgt_info_createat(dfd, path, 1, 1, 1);
471 result = wgt_info_to_json(info);
472 wgt_info_unref(info);
477 struct json_object *wgt_path_to_json(const char *path)
479 return wgt_path_at_to_json(AT_FDCWD, path);