added info retrieval
[src/app-framework-main.git] / src / wgt-info.c
1 /*
2  Copyright 2015 IoT.bzh
3
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8      http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <assert.h>
21 #include <syslog.h>
22 #include <libxml/tree.h>
23
24 #include "verbose.h"
25 #include "wgt.h"
26 #include "wgt-config.h"
27 #include "wgt-info.h"
28
29 static int getpropbool(xmlNodePtr node, const char *prop, int def)
30 {
31         int result;
32         char *val = xmlGetProp(node, prop);
33         if (!val)
34                 result = def;
35         else {
36                 if (!strcmp(val, "true"))
37                         result = 1;
38                 else if (!strcmp(val, "false"))
39                         result = 0;
40                 else
41                         result = def;
42                 xmlFree(val);
43         }
44         return result;
45 }
46
47 static int getpropnum(xmlNodePtr node, const char *prop, int def)
48 {
49         int result;
50         char *val = xmlGetProp(node, prop);
51         if (!val)
52                 result = def;
53         else {
54                 result = atoi(val);
55                 xmlFree(val);
56         }
57         return result;
58 }
59
60 static xmlChar *optprop(xmlNodePtr node, const char *prop)
61 {
62         return node ? xmlGetProp(node, prop) : NULL;
63 }
64
65 static xmlChar *optcontent(xmlNodePtr node)
66 {
67         return node ? xmlNodeGetContent(node) : NULL;
68 }
69
70 static int fill_info(struct wgt_info *ifo, int want_icons, int want_features, int want_preferences)
71 {
72         xmlNodePtr node, pnode;
73         struct wgt_info_icon *icon, **icontail;
74         struct wgt_info_feature *feature, **featuretail;
75         struct wgt_info_preference *preference, **preferencetail;
76         struct wgt_info_param *param, **paramtail;
77
78         node = wgt_config_widget();
79         if (!node) {
80                 warning("no widget");
81                 errno = EINVAL;
82                 return -1;
83         }
84         ifo->id = xmlGetProp(node, wgt_config_string_id);
85         ifo->version = xmlGetProp(node, wgt_config_string_version);
86         ifo->width = getpropnum(node, wgt_config_string_width, 0);
87         ifo->height = getpropnum(node, wgt_config_string_height, 0);
88         ifo->viewmodes = xmlGetProp(node, wgt_config_string_viewmodes);
89         ifo->defaultlocale = xmlGetProp(node, wgt_config_string_defaultlocale);
90
91         node = wgt_config_name();
92         ifo->name = optcontent(node);
93         ifo->name_short = optprop(node, wgt_config_string_short);
94
95         node = wgt_config_description();
96         ifo->description = optcontent(node);
97
98         node = wgt_config_author();
99         ifo->author = optcontent(node);
100         ifo->author_href = optprop(node, wgt_config_string_href);
101         ifo->author_email = optprop(node, wgt_config_string_email);
102
103         node = wgt_config_license();
104         ifo->license = optcontent(node);
105         ifo->license_href = optprop(node, wgt_config_string_href);
106         
107         node = wgt_config_content();
108         ifo->content_src = optprop(node, wgt_config_string_src);
109         if (node && ifo->content_src == NULL) {
110                 warning("content without src");
111                 errno = EINVAL;
112                 return -1;
113         }
114         ifo->content_type = optprop(node, wgt_config_string_type);
115         ifo->content_encoding = optprop(node, wgt_config_string_encoding);
116
117         if (want_icons) {
118                 icontail = &ifo->icons;
119                 node = wgt_config_first_icon();
120                 while (node) {
121                         icon = malloc(sizeof * icon);
122                         if (icon == NULL) {
123                                 errno = ENOMEM;
124                                 return -1;
125                         }
126                         icon->src = xmlGetProp(node, wgt_config_string_src);
127                         icon->width = getpropnum(node, wgt_config_string_width, 0);
128                         icon->height = getpropnum(node, wgt_config_string_height, 0);
129
130                         icon->next = NULL;
131                         *icontail = icon;
132
133                         if (icon->src == NULL) {
134                                 warning("icon without src");
135                                 errno = EINVAL;
136                                 return -1;
137                         }
138                         icontail = &icon->next;
139                         node = wgt_config_next_icon(node);
140                 }
141         }
142
143         if (want_features) {
144                 featuretail = &ifo->features;
145                 node = wgt_config_first_feature();
146                 while (node) {
147                         feature = malloc(sizeof * feature);
148                         if (feature == NULL) {
149                                 errno = ENOMEM;
150                                 return -1;
151                         }
152                         feature->name = xmlGetProp(node, wgt_config_string_name);
153                         feature->required = getpropbool(node, wgt_config_string_required, 1);
154
155                         feature->next = NULL;
156                         *featuretail = feature;
157
158                         if (feature->name == NULL) {
159                                 warning("feature without name");
160                                 errno = EINVAL;
161                                 return -1;
162                         }
163
164                         paramtail = &feature->params;
165                         pnode = wgt_config_first_param(node);
166                         while (pnode) {
167                                 param = malloc(sizeof * param);
168                                 if (param == NULL) {
169                                         errno = ENOMEM;
170                                         return -1;
171                                 }
172                                 param->name = xmlGetProp(pnode, wgt_config_string_name);
173                                 param->value = xmlGetProp(pnode, wgt_config_string_value);
174
175                                 param->next = NULL;
176                                 *paramtail = param;
177
178                                 if (param->name == NULL || param->value == NULL) {
179                                         warning("param without name or value");
180                                         errno = EINVAL;
181                                         return -1;
182                                 }
183
184                                 paramtail = &param->next;
185                                 pnode = wgt_config_next_param(pnode);
186                         }
187
188                         featuretail = &feature->next;
189                         node = wgt_config_next_feature(node);
190                 }
191         }
192
193         if (want_preferences) {
194                 preferencetail = &ifo->preferences;
195                 node = wgt_config_first_preference();
196                 while (node) {
197                         preference = malloc(sizeof * preference);
198                         if (preference == NULL) {
199                                 errno = ENOMEM;
200                                 return -1;
201                         }
202                         preference->name = xmlGetProp(node, wgt_config_string_name);
203                         preference->value = xmlGetProp(node, wgt_config_string_value);
204                         preference->readonly = getpropbool(node, wgt_config_string_readonly, 0);
205
206                         *preferencetail = preference;
207                         preference->next = NULL;
208
209                         if (preference->name == NULL) {
210                                 warning("preference without name");
211                                 errno = EINVAL;
212                                 return -1;
213                         }
214
215                         preferencetail = &preference->next;
216                         node = wgt_config_next_preference(node);
217                 }
218         }
219         return 0;
220 }
221
222 struct wgt_info *wgt_info_get(struct wgt *wgt, int icons, int features, int preferences)
223 {
224         int rc;
225         struct wgt_info *result;
226
227         assert(wgt);
228         assert(wgt_is_connected(wgt));
229         rc = wgt_config_open(wgt);
230         if (rc) {
231                 errno = EINVAL;
232                 return NULL;
233         }
234
235         result = calloc(sizeof * result, 1);
236         if (!result) {
237                 wgt_config_close();
238                 errno = ENOMEM;
239                 return NULL;
240         }
241         result->refcount = 1;
242
243         rc = fill_info(result, icons, features, preferences);
244         wgt_config_close();
245         if (rc) {
246                 wgt_info_unref(result);
247                 return NULL;
248         }
249         return result;
250 }
251
252 void wgt_info_addref(struct wgt_info *ifo)
253 {
254         assert(ifo);
255         assert(ifo->refcount > 0);
256         ifo->refcount++;
257 }
258
259 void wgt_info_unref(struct wgt_info *ifo)
260 {
261         struct wgt_info_icon *icon;
262         struct wgt_info_feature *feature;
263         struct wgt_info_preference *preference;
264         struct wgt_info_param *param;
265
266         assert(ifo);
267         assert(ifo->refcount > 0);
268         if (--ifo->refcount)
269                 return;
270
271         xmlFree(ifo->id);
272         xmlFree(ifo->version);
273         xmlFree(ifo->viewmodes);
274         xmlFree(ifo->defaultlocale);
275         xmlFree(ifo->name);
276         xmlFree(ifo->name_short);
277         xmlFree(ifo->description);
278         xmlFree(ifo->author);
279         xmlFree(ifo->author_href);
280         xmlFree(ifo->author_email);
281         xmlFree(ifo->license);
282         xmlFree(ifo->license_href);
283         xmlFree(ifo->content_src);
284         xmlFree(ifo->content_type);
285         xmlFree(ifo->content_encoding);
286
287         while(ifo->icons) {
288                 icon = ifo->icons;
289                 ifo->icons = icon->next;
290                 xmlFree(icon->src);
291                 free(icon);
292         }
293
294         while(ifo->features) {
295                 feature = ifo->features;
296                 ifo->features = feature->next;
297                 xmlFree(feature->name);
298                 while(feature->params) {
299                         param = feature->params;
300                         feature->params = param->next;
301                         xmlFree(param->name);
302                         xmlFree(param->value);
303                         free(param);
304                 }
305                 free(feature);
306         }
307
308         while(ifo->preferences) {
309                 preference = ifo->preferences;
310                 ifo->preferences = preference->next;
311                 xmlFree(preference->name);
312                 xmlFree(preference->value);
313                 free(preference);
314         }
315         free(ifo);
316 }
317
318 void wgt_info_dump(struct wgt_info *ifo, int fd, const char *prefix)
319 {
320         FILE *f;
321         struct wgt_info_icon *icon;
322         struct wgt_info_feature *feature;
323         struct wgt_info_preference *preference;
324         struct wgt_info_param *param;
325
326         assert(ifo);
327         f = fdopen(fd, "w");
328         if (f == NULL) {
329                 warning("can't fdopen in wgt_info_dump");
330                 return;
331         }
332         
333         if (ifo->id) fprintf(f, "%sid: %s\n", prefix, ifo->id);
334         if (ifo->width) fprintf(f, "%swidth: %d\n", prefix, ifo->width);
335         if (ifo->height) fprintf(f, "%sheight: %d\n", prefix, ifo->height);
336         if (ifo->version) fprintf(f, "%sversion: %s\n", prefix, ifo->version);
337         if (ifo->viewmodes) fprintf(f, "%sviewmodes: %s\n", prefix, ifo->viewmodes);
338         if (ifo->defaultlocale) fprintf(f, "%sdefaultlocale: %s\n", prefix, ifo->defaultlocale);
339         if (ifo->name) fprintf(f, "%sname: %s\n", prefix, ifo->name);
340         if (ifo->name_short) fprintf(f, "%sname_short: %s\n", prefix, ifo->name_short);
341         if (ifo->description) fprintf(f, "%sdescription: %s\n", prefix, ifo->description);
342         if (ifo->author) fprintf(f, "%sauthor: %s\n", prefix, ifo->author);
343         if (ifo->author_href) fprintf(f, "%sauthor_href: %s\n", prefix, ifo->author_href);
344         if (ifo->author_email) fprintf(f, "%sauthor_email: %s\n", prefix, ifo->author_email);
345         if (ifo->license) fprintf(f, "%slicense: %s\n", prefix, ifo->license);
346         if (ifo->license_href) fprintf(f, "%slicense_href: %s\n", prefix, ifo->license_href);
347         if (ifo->content_src) fprintf(f, "%scontent_src: %s\n", prefix, ifo->content_src);
348         if (ifo->content_type) fprintf(f, "%scontent_type: %s\n", prefix, ifo->content_type);
349         if (ifo->content_encoding) fprintf(f, "%scontent_encoding: %s\n", prefix, ifo->content_encoding);
350
351         icon = ifo->icons;
352         while(icon) {
353                 fprintf(f, "%s+ icon src: %s\n", prefix, icon->src);
354                 if (icon->width) fprintf(f, "%s       width: %d\n", prefix, icon->width);
355                 if (icon->height) fprintf(f, "%s       height: %d\n", prefix, icon->height);
356                 icon = icon->next;
357         }
358
359         feature = ifo->features;
360         while(feature) {
361                 fprintf(f, "%s+ feature name: %s\n", prefix, feature->name);
362                 fprintf(f, "%s          required: %s\n", prefix, feature->required ? "true" : "false");
363                 param = feature->params;
364                 while(param) {
365                         fprintf(f, "%s          + param name: %s\n", prefix, param->name);
366                         fprintf(f, "%s                  value: %s\n", prefix, param->value);
367                         param = param->next;
368                 }
369                 feature = feature->next;
370         }
371
372         preference = ifo->preferences;
373         while(preference) {
374                 fprintf(f, "%s+ preference name: %s\n", prefix, preference->name);
375                 if (preference->value) fprintf(f, "%s             value: %s\n", prefix, preference->value);
376                 fprintf(f, "%s             readonly: %s\n", prefix, preference->readonly ? "true" : "false");
377                 preference = preference->next;
378         }
379
380         fclose(f);
381 }
382