summaryrefslogtreecommitdiff
path: root/src/lib/eldbus/eldbus_introspection.c
diff options
context:
space:
mode:
authorGuilherme Lepsch <lepsch@expertisesolutions.com.br>2015-01-09 14:20:14 -0200
committerCedric BAIL <cedric@osg.samsung.com>2015-12-10 12:02:30 -0800
commit10fa1b5b4b2454437c00a9b8931bb3f9ddb9e99c (patch)
treeb4238f5f83b55463ad2e88e97dc968f2a607a668 /src/lib/eldbus/eldbus_introspection.c
parent48b22214493958fc852f101009b0e8a88aa77e05 (diff)
eldbus: add efl.model implementation.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib/eldbus/eldbus_introspection.c')
-rw-r--r--src/lib/eldbus/eldbus_introspection.c469
1 files changed, 469 insertions, 0 deletions
diff --git a/src/lib/eldbus/eldbus_introspection.c b/src/lib/eldbus/eldbus_introspection.c
new file mode 100644
index 0000000..dbacf74
--- /dev/null
+++ b/src/lib/eldbus/eldbus_introspection.c
@@ -0,0 +1,469 @@
1#include "eldbus_introspection.h"
2
3typedef struct _Eldbus_Introspection_Element_Parse_Table Eldbus_Introspection_Element_Parse_Table;
4
5struct _Eldbus_Introspection_Element_Parse_Table
6{
7 const char *name;
8 void *(*parse)(Eina_Simple_XML_Node_Tag *tag);
9 Eina_List **list;
10};
11
12static const char *_eldbus_introspection_attribute_value_get(Eina_Inlist *, const char *);
13static void *_eldbus_introspection_parse_node(Eina_Simple_XML_Node_Tag *);
14static void *_eldbus_introspection_parse_interface(Eina_Simple_XML_Node_Tag *);
15static void *_eldbus_introspection_parse_method(Eina_Simple_XML_Node_Tag *);
16static void *_eldbus_introspection_parse_signal(Eina_Simple_XML_Node_Tag *);
17static void *_eldbus_introspection_parse_argument(Eina_Simple_XML_Node_Tag *);
18static void *_eldbus_introspection_parse_property(Eina_Simple_XML_Node_Tag *);
19static void *_eldbus_introspection_parse_annotation(Eina_Simple_XML_Node_Tag *);
20static void _eldbus_introspection_parse_children(Eina_Inlist *, const Eldbus_Introspection_Element_Parse_Table[]);
21static void _eldbus_introspection_interface_free(Eldbus_Introspection_Interface *);
22static void _eldbus_introspection_method_free(Eldbus_Introspection_Method *);
23static void _eldbus_introspection_signal_free(Eldbus_Introspection_Signal *);
24static void _eldbus_introspection_argument_free(Eldbus_Introspection_Argument *);
25static void _eldbus_introspection_property_free(Eldbus_Introspection_Property *);
26static void _eldbus_introspection_annotation_free(Eldbus_Introspection_Annotation *);
27
28EAPI Eldbus_Introspection_Node *
29eldbus_introspection_parse(const char *xml)
30{
31 Eldbus_Introspection_Node *node;
32 Eina_Simple_XML_Node_Root *xml_root;
33 Eina_Simple_XML_Node *xml_node;
34
35 EINA_SAFETY_ON_NULL_RETURN_VAL(xml, NULL);
36
37 node = NULL;
38 xml_root = eina_simple_xml_node_load(xml, strlen(xml), EINA_TRUE);
39 xml_node = (Eina_Simple_XML_Node*)eina_inlist_last(xml_root->children);
40 EINA_SAFETY_ON_FALSE_GOTO(EINA_SIMPLE_XML_NODE_TAG == xml_node->type, free_root);
41
42 node = (Eldbus_Introspection_Node*)_eldbus_introspection_parse_node((Eina_Simple_XML_Node_Tag*)xml_node);
43
44 free_root:
45 eina_simple_xml_node_root_free(xml_root);
46
47 return node;
48}
49
50static void *
51_eldbus_introspection_parse_node(Eina_Simple_XML_Node_Tag *tag)
52{
53 Eldbus_Introspection_Node *node;;
54 Eldbus_Introspection_Element_Parse_Table table[] = {
55 { "node", _eldbus_introspection_parse_node, NULL },
56 { "interface", _eldbus_introspection_parse_interface, NULL },
57 { NULL, NULL, NULL }
58 };
59 const char *name;
60
61 node = calloc(1, sizeof(Eldbus_Introspection_Node));
62 EINA_SAFETY_ON_NULL_RETURN_VAL(node, NULL);
63
64 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
65 node->name = eina_stringshare_add(name);
66 table[0].list = &node->nodes;
67 table[1].list = &node->interfaces;
68
69 _eldbus_introspection_parse_children(tag->children, table);
70
71 return node;
72}
73
74EAPI void
75eldbus_introspection_node_free(Eldbus_Introspection_Node *node)
76{
77 Eldbus_Introspection_Node *child_node;
78 Eldbus_Introspection_Interface *interface;
79
80 EINA_SAFETY_ON_NULL_RETURN(node);
81
82 EINA_LIST_FREE(node->nodes, child_node)
83 eldbus_introspection_node_free(child_node);
84
85 EINA_LIST_FREE(node->interfaces, interface)
86 _eldbus_introspection_interface_free(interface);
87
88 eina_stringshare_del(node->name);
89 free(node);
90}
91
92static const char *
93_eldbus_introspection_attribute_value_get(Eina_Inlist *attributes, const char *key)
94{
95 Eina_Simple_XML_Attribute *attribute;
96
97 EINA_INLIST_FOREACH(attributes, attribute)
98 {
99 if (strcmp(attribute->key, key) == 0)
100 return attribute->value;
101 }
102
103 return NULL;
104}
105
106static void *
107_eldbus_introspection_parse_interface(Eina_Simple_XML_Node_Tag *tag)
108{
109 Eldbus_Introspection_Interface *interface;
110 Eldbus_Introspection_Element_Parse_Table table[] = {
111 { "method", _eldbus_introspection_parse_method, NULL },
112 { "signal", _eldbus_introspection_parse_signal, NULL },
113 { "property", _eldbus_introspection_parse_property, NULL },
114 { "annotation", _eldbus_introspection_parse_annotation, NULL },
115 { NULL, NULL, NULL }
116 };
117 const char *name;
118
119 interface = calloc(1, sizeof(Eldbus_Introspection_Interface));
120 EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
121
122 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
123 if (!name) goto error;
124 interface->name = eina_stringshare_add(name);
125 table[0].list = &interface->methods;
126 table[1].list = &interface->signals;
127 table[2].list = &interface->properties;
128 table[3].list = &interface->annotations;
129
130 _eldbus_introspection_parse_children(tag->children, table);
131
132 return interface;
133
134 error:
135 _eldbus_introspection_interface_free(interface);
136 return NULL;
137}
138
139static void
140_eldbus_introspection_interface_free(Eldbus_Introspection_Interface *interface)
141{
142 Eldbus_Introspection_Method *method;
143 Eldbus_Introspection_Signal *signal;
144 Eldbus_Introspection_Property *property;
145 Eldbus_Introspection_Annotation *annotation;
146
147 EINA_SAFETY_ON_NULL_RETURN(interface);
148
149 EINA_LIST_FREE(interface->methods, method)
150 _eldbus_introspection_method_free(method);
151
152 EINA_LIST_FREE(interface->signals, signal)
153 _eldbus_introspection_signal_free(signal);
154
155 EINA_LIST_FREE(interface->properties, property)
156 _eldbus_introspection_property_free(property);
157
158 EINA_LIST_FREE(interface->annotations, annotation)
159 _eldbus_introspection_annotation_free(annotation);
160
161 eina_stringshare_del(interface->name);
162 free(interface);
163}
164
165static void *
166_eldbus_introspection_parse_method(Eina_Simple_XML_Node_Tag *tag)
167{
168 Eldbus_Introspection_Method *method;
169 Eldbus_Introspection_Element_Parse_Table table[] = {
170 { "arg", _eldbus_introspection_parse_argument, NULL },
171 { "annotation", _eldbus_introspection_parse_annotation, NULL },
172 { NULL, NULL, NULL }
173 };
174 const char *name;
175
176 method = calloc(1, sizeof(Eldbus_Introspection_Method));
177 EINA_SAFETY_ON_NULL_RETURN_VAL(method, NULL);
178
179 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
180 if (!name) goto error;
181 method->name = eina_stringshare_add(name);
182 table[0].list = &method->arguments;
183 table[1].list = &method->annotations;
184
185 _eldbus_introspection_parse_children(tag->children, table);
186
187 return method;
188
189 error:
190 _eldbus_introspection_method_free(method);
191 return NULL;
192}
193
194static void
195_eldbus_introspection_method_free(Eldbus_Introspection_Method *method)
196{
197 Eldbus_Introspection_Argument *argument;
198 Eldbus_Introspection_Annotation *annotation;
199
200 EINA_SAFETY_ON_NULL_RETURN(method);
201
202 EINA_LIST_FREE(method->arguments, argument)
203 _eldbus_introspection_argument_free(argument);
204
205 EINA_LIST_FREE(method->annotations, annotation)
206 _eldbus_introspection_annotation_free(annotation);
207
208 eina_stringshare_del(method->name);
209 free(method);
210}
211
212static void *
213_eldbus_introspection_parse_signal(Eina_Simple_XML_Node_Tag *tag)
214{
215 Eldbus_Introspection_Signal *signal;
216 Eldbus_Introspection_Element_Parse_Table table[] = {
217 { "arg", _eldbus_introspection_parse_argument, NULL },
218 { "annotation", _eldbus_introspection_parse_annotation, NULL },
219 { NULL, NULL, NULL }
220 };
221 const char *name;
222
223 signal = calloc(1, sizeof(Eldbus_Introspection_Signal));
224 EINA_SAFETY_ON_NULL_RETURN_VAL(signal, NULL);
225
226 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
227 if (!name) goto error;
228 signal->name = eina_stringshare_add(name);
229 table[0].list = &signal->arguments;
230 table[1].list = &signal->annotations;
231
232 _eldbus_introspection_parse_children(tag->children, table);
233
234 return signal;
235
236 error:
237 _eldbus_introspection_signal_free(signal);
238 return NULL;
239}
240
241static void
242_eldbus_introspection_signal_free(Eldbus_Introspection_Signal *signal)
243{
244 Eldbus_Introspection_Argument *argument;
245 Eldbus_Introspection_Annotation *annotation;
246
247 EINA_SAFETY_ON_NULL_RETURN(signal);
248
249 EINA_LIST_FREE(signal->arguments, argument)
250 _eldbus_introspection_argument_free(argument);
251
252 EINA_LIST_FREE(signal->annotations, annotation)
253 _eldbus_introspection_annotation_free(annotation);
254
255 eina_stringshare_del(signal->name);
256 free(signal);
257}
258
259static void *
260_eldbus_introspection_parse_argument(Eina_Simple_XML_Node_Tag *tag)
261{
262 Eldbus_Introspection_Argument *argument;
263 const char *name;
264 const char *type;
265 const char *direction;
266
267 argument = calloc(1, sizeof(Eldbus_Introspection_Argument));
268 EINA_SAFETY_ON_NULL_RETURN_VAL(argument, NULL);
269
270 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
271 argument->name = eina_stringshare_add(name);
272
273 type = _eldbus_introspection_attribute_value_get(tag->attributes, "type");
274 if (!type) goto error;
275 argument->type = eina_stringshare_add(type);
276
277 direction = _eldbus_introspection_attribute_value_get(tag->attributes, "direction");
278 if (direction)
279 {
280 if (strcmp(direction, "in") == 0)
281 argument->direction = ELDBUS_INTROSPECTION_ARGUMENT_DIRECTION_IN;
282 else
283 if (strcmp(direction, "out") == 0)
284 argument->direction = ELDBUS_INTROSPECTION_ARGUMENT_DIRECTION_OUT;
285 else
286 argument->direction = ELDBUS_INTROSPECTION_ARGUMENT_DIRECTION_NONE;
287 }
288
289 return argument;
290
291 error:
292 _eldbus_introspection_argument_free(argument);
293 return NULL;
294}
295
296static void
297_eldbus_introspection_argument_free(Eldbus_Introspection_Argument *argument)
298{
299 EINA_SAFETY_ON_NULL_RETURN(argument);
300 eina_stringshare_del(argument->name);
301 eina_stringshare_del(argument->type);
302 free(argument);
303}
304
305static void *
306_eldbus_introspection_parse_property(Eina_Simple_XML_Node_Tag *tag)
307{
308 Eldbus_Introspection_Property *property;
309 Eldbus_Introspection_Element_Parse_Table table[] = {
310 { "annotation", _eldbus_introspection_parse_annotation, NULL },
311 { NULL, NULL, NULL }
312 };
313 const char *name;
314 const char *type;
315 const char *access;
316
317 property = calloc(1, sizeof(Eldbus_Introspection_Property));
318 EINA_SAFETY_ON_NULL_RETURN_VAL(property, NULL);
319
320 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
321 if (!name) goto error;
322 property->name = eina_stringshare_add(name);
323
324 type = _eldbus_introspection_attribute_value_get(tag->attributes, "type");
325 if (!type) goto error;
326 property->type = eina_stringshare_add(type);
327
328 access = _eldbus_introspection_attribute_value_get(tag->attributes, "access");
329 if (!access) goto error;
330
331 if (strcmp(access, "read") == 0)
332 property->access = ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READ;
333 else if (strcmp(access, "write") == 0)
334 property->access = ELDBUS_INTROSPECTION_PROPERTY_ACCESS_WRITE;
335 else if (strcmp(access, "readwrite") == 0)
336 property->access = ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE;
337 else
338 EINA_SAFETY_ON_TRUE_GOTO(!!"Unknown property access", error);
339 table[0].list = &property->annotations;
340
341 _eldbus_introspection_parse_children(tag->children, table);
342 return property;
343
344 error:
345 _eldbus_introspection_property_free(property);
346 return NULL;
347}
348
349static void
350_eldbus_introspection_property_free(Eldbus_Introspection_Property *property)
351{
352 Eldbus_Introspection_Annotation *annotation;
353
354 EINA_SAFETY_ON_NULL_RETURN(property);
355
356 EINA_LIST_FREE(property->annotations, annotation)
357 _eldbus_introspection_annotation_free(annotation);
358
359 eina_stringshare_del(property->name);
360 eina_stringshare_del(property->type);
361 free(property);
362}
363
364static void *
365_eldbus_introspection_parse_annotation(Eina_Simple_XML_Node_Tag *tag)
366{
367 Eldbus_Introspection_Annotation *annotation;
368 const char *name;
369 const char *value;
370
371 annotation = calloc(1, sizeof(Eldbus_Introspection_Annotation));
372 EINA_SAFETY_ON_NULL_RETURN_VAL(annotation, NULL);
373
374 name = _eldbus_introspection_attribute_value_get(tag->attributes, "name");
375 if (!name) goto error;
376 annotation->name = eina_stringshare_add(name);
377
378 value = _eldbus_introspection_attribute_value_get(tag->attributes, "value");
379 if (!value) goto error;
380 annotation->value = eina_stringshare_add(value);
381
382 return annotation;
383
384 error:
385 _eldbus_introspection_annotation_free(annotation);
386 return NULL;
387}
388
389static void
390_eldbus_introspection_annotation_free(Eldbus_Introspection_Annotation *annotation)
391{
392 EINA_SAFETY_ON_NULL_RETURN(annotation);
393 eina_stringshare_del(annotation->name);
394 eina_stringshare_del(annotation->value);
395 free(annotation);
396}
397
398static void
399_eldbus_introspection_parse_children(Eina_Inlist *children, const Eldbus_Introspection_Element_Parse_Table table[])
400{
401 Eina_Simple_XML_Node *child;
402
403 EINA_INLIST_FOREACH(children, child)
404 {
405 const Eldbus_Introspection_Element_Parse_Table *it;
406 Eina_Simple_XML_Node_Tag *tag;
407 void *item;
408
409 if (EINA_SIMPLE_XML_NODE_TAG != child->type)
410 continue;
411
412 tag = (Eina_Simple_XML_Node_Tag*) child;
413
414 for (it = table; it->name; ++it)
415 {
416 if (strcmp(tag->name, it->name) != 0)
417 continue;
418
419 item = it->parse(tag);
420 if (item)
421 *it->list = eina_list_append(*it->list, item);
422 }
423 }
424}
425
426EAPI Eldbus_Introspection_Interface *
427eldbus_introspection_interface_find(Eina_List *interfaces, const char *name)
428{
429 Eina_List *it;
430 Eldbus_Introspection_Interface *interface;
431
432 EINA_LIST_FOREACH(interfaces, it, interface)
433 {
434 if (strcmp(interface->name, name) == 0)
435 return interface;
436 }
437
438 return NULL;
439}
440
441EAPI Eldbus_Introspection_Property *
442eldbus_introspection_property_find(Eina_List *properties, const char *name)
443{
444 Eina_List *it;
445 Eldbus_Introspection_Property *property;
446
447 EINA_LIST_FOREACH(properties, it, property)
448 {
449 if (strcmp(property->name, name) == 0)
450 return property;
451 }
452
453 return NULL;
454}
455
456EAPI Eldbus_Introspection_Argument *
457eldbus_introspection_argument_find(Eina_List *arguments, const char *name)
458{
459 Eina_List *it;
460 Eldbus_Introspection_Argument *argument;
461
462 EINA_LIST_FOREACH(arguments, it, argument)
463 {
464 if (strcmp(argument->name, name) == 0)
465 return argument;
466 }
467
468 return NULL;
469}