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"
41 int (*action)(struct json_object *obj, const struct wgt_desc_param *param, void *closure);
47 static int apply_params(struct json_object *obj, const struct wgt_desc_param *param, const struct paramaction *actions)
50 const struct paramaction *a;
57 for (a = actions ; a->name && strcmp(a->name, param->name) ; a++);
58 if (a->action && a->action(obj, param, a->closure) < 0)
66 static int get_array(struct json_object **result, struct json_object *obj, const char *key, int create)
68 int rc = j_enter_m(&obj, &key, 1);
71 else if (!json_object_object_get_ex(obj, key, result)) {
76 if (!(*result = j_add_new_array(obj, key)))
83 /* get the param of 'name' for the feature 'feat' */
84 static const char *get_target_name(const struct wgt_desc_feature *feat, const char *defval)
86 const struct wgt_desc_param *param = feat->params;
87 while (param && strcmp(param->name, string_sharp_target))
90 defval = param->value;
93 if (!strcmp(param->name, string_sharp_target)) {
104 static struct json_object *get_array_item_by_key(struct json_object *array, const char *key, const char *val)
106 struct json_object *result, *k;
109 n = json_object_array_length(array);
110 for (i = 0 ; i < n ; i++) {
111 result = json_object_array_get_idx(array, i);
112 if (result && json_object_object_get_ex(result, key, &k)
113 && json_object_get_type(k) == json_type_string
114 && !strcmp(json_object_get_string(k), val))
120 static int get_target(struct json_object **result, struct json_object *targets, const char *name, int create)
123 struct json_object *t;
125 t = get_array_item_by_key(targets, string_sharp_target, name);
130 ERROR("duplicated target name: %s", name);
136 ERROR("target name not found: %s", name);
139 t = j_add_new_object(targets, NULL);
140 if (t && j_add_string(t, string_sharp_target, name))
153 static int make_target(struct json_object *targets, const struct wgt_desc_feature *feat)
156 struct json_object *target;
158 id = get_target_name(feat, NULL);
160 ERROR("target of feature %s is missing or repeated", feat->name);
164 return get_target(&target, targets, id, 1);
167 static int add_icon(struct json_object *target, const char *src, int width, int height)
170 struct json_object *icon, *array;
172 rc = get_array(&array, target, string_icon, 1);
174 icon = json_object_new_object();
176 || !j_add_string(icon, string_src, src)
177 || (width > 0 && !j_add_integer(icon, string_width, width))
178 || (height > 0 && !j_add_integer(icon, string_height, height))
179 || !j_add(array, NULL, icon)) {
180 json_object_put(icon);
187 static int make_main_target(struct json_object *targets, const struct wgt_desc *desc)
190 struct wgt_desc_icon *icon;
191 struct json_object *target;
193 /* create the target 'main' */
194 rc = get_target(&target, targets, string_main, 1);
196 /* adds icons if any */
198 while (rc >= 0 && icon) {
199 rc = add_icon(target, icon->src, icon->width, icon->height);
204 rc = j_add_many_strings_m(target,
205 "content.src", desc->content_src,
206 "content.type", desc->content_type,
207 "content.encoding", desc->content_encoding,
211 if((desc->width && !j_add_integer(target, string_width, desc->width))
212 || (desc->height && !j_add_integer(target, string_height, desc->height)))
218 /***********************************************************************************************************/
220 static struct json_object *object_of_param(const struct wgt_desc_param *param)
222 struct json_object *value;
224 value = json_object_new_object();
226 && j_add_string(value, string_name, param->name)
227 && j_add_string(value, string_value, param->value))
230 json_object_put(value);
234 static int add_param_simple(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
236 return j_add_string_m(obj, param->name, param->value);
239 static int add_param_array(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
241 const char *array_name = closure;
242 struct json_object *array, *value;
246 else if (!json_object_object_get_ex(obj, array_name, &array)) {
247 array = j_add_new_array(obj, array_name);
251 value = object_of_param(param);
252 if (value && j_add(array, NULL, value))
255 json_object_put(value);
259 static int add_param_object(struct json_object *obj, const struct wgt_desc_param *param, void *closure)
261 struct json_object *object, *value;
265 else if (!json_object_object_get_ex(obj, closure, &object)) {
266 object = j_add_new_object(obj, closure);
270 value = object_of_param(param);
271 if (value && j_add(object, param->name, value))
274 json_object_put(value);
278 static int add_targeted_params(struct json_object *targets, const struct wgt_desc_feature *feat, struct paramaction actions[])
282 struct json_object *obj;
284 id = get_target_name(feat, string_main);
285 rc = get_target(&obj, targets, id, 0);
286 return rc < 0 ? rc : apply_params(obj, feat->params, actions);
289 static int add_provided_unit(struct json_object *targets, const struct wgt_desc_feature *feat)
291 static struct paramaction actions[] = {
292 { .name = string_sharp_target, .action = NULL, .closure = NULL },
293 { .name = NULL, .action = add_param_simple, .closure = NULL }
295 return add_targeted_params(targets, feat, actions);
298 static int add_provided_api(struct json_object *targets, const struct wgt_desc_feature *feat)
300 static struct paramaction actions[] = {
301 { .name = string_sharp_target, .action = NULL, .closure = NULL },
302 { .name = NULL, .action = add_param_array, .closure = (void*)string_provided_api }
304 return add_targeted_params(targets, feat, actions);
307 static int add_required_api(struct json_object *targets, const struct wgt_desc_feature *feat)
309 static struct paramaction actions[] = {
310 { .name = string_sharp_target, .action = NULL, .closure = NULL },
311 { .name = NULL, .action = add_param_array, .closure = (void*)string_required_api }
313 return add_targeted_params(targets, feat, actions);
316 static int add_required_permission(struct json_object *targets, const struct wgt_desc_feature *feat)
318 static struct paramaction actions[] = {
319 { .name = string_sharp_target, .action = NULL, .closure = NULL },
320 { .name = NULL, .action = add_param_object, .closure = (void*)string_required_permission }
322 return add_targeted_params(targets, feat, actions);
325 static int add_defined_permission(struct json_object *defperm, const struct wgt_desc_feature *feat)
327 static struct paramaction actions[] = {
328 { .name = NULL, .action = add_param_array, .closure = NULL }
330 return apply_params(defperm, feat->params, actions);
333 /***********************************************************************************************************/
335 static struct json_object *to_json(const struct wgt_desc *desc)
338 const struct wgt_desc_feature *feat;
339 const char *featname;
340 struct json_object *result, *targets, *permissions;
343 /* create the application structure */
344 if(!(result = json_object_new_object())
345 || !(targets = j_add_new_array(result, string_targets))
346 || !(permissions = j_add_new_array(result, string_defined_permission))
350 /* first pass: declarations */
351 rc = make_main_target(targets, desc);
352 prefixlen = strlen(string_AGL_widget_prefix);
353 for (feat = desc->features ; feat ; feat = feat->next) {
354 featname = feat->name;
355 if (!memcmp(featname, string_AGL_widget_prefix, prefixlen)) {
356 if (!feat->required) {
357 ERROR("feature %s can't be optional", featname);
361 featname += prefixlen;
362 if (!strcmp(featname, string_provided_unit)) {
363 rc2 = make_target(targets, feat);
370 /* second pass: definitions */
371 for (feat = desc->features ; feat ; feat = feat->next) {
372 featname = feat->name;
373 if (!memcmp(featname, string_AGL_widget_prefix, prefixlen)) {
374 featname += prefixlen;
375 if (!strcmp(featname, string_defined_permission)) {
376 rc2 = add_defined_permission(permissions, feat);
378 else if (!strcmp(featname, string_provided_unit)) {
379 rc2 = add_provided_unit(targets, feat);
381 else if (!strcmp(featname, string_provided_api)) {
382 rc2 = add_provided_api(targets, feat);
384 else if (!strcmp(featname, string_required_api)) {
385 rc2 = add_required_api(targets, feat);
387 else if (!strcmp(featname, string_required_permission)) {
388 rc2 = add_required_permission(targets, feat);
390 /* gently ignore other features */
399 rc2 = j_add_many_strings_m(result,
401 string_idaver, desc->idaver,
402 string_version, desc->version,
404 "author.content", desc->author,
405 "author.href", desc->author_href,
406 "author.email", desc->author_email,
407 "license.content", desc->license,
408 "license.href", desc->license_href,
409 "defaultlocale", desc->defaultlocale,
410 "name.content", desc->name,
411 "name.short", desc->name_short,
412 "description", desc->description,
425 json_object_put(result);
429 struct json_object *wgt_info_to_json(struct wgt_info *info)
431 return to_json(wgt_info_desc(info));
434 struct json_object *wgt_to_json(struct wgt *wgt)
436 struct json_object *result;
437 struct wgt_info *info;
439 info = wgt_info_create(wgt, 1, 1, 1);
443 result = wgt_info_to_json(info);
444 wgt_info_unref(info);
449 struct json_object *wgt_path_at_to_json(int dfd, const char *path)
451 struct json_object *result;
452 struct wgt_info *info;
454 info = wgt_info_createat(dfd, path, 1, 1, 1);
458 result = wgt_info_to_json(info);
459 wgt_info_unref(info);
464 struct json_object *wgt_path_to_json(const char *path)
466 return wgt_path_at_to_json(AT_FDCWD, path);