1 //Compile with:
2 // gcc -o complex-types-client-eina-value complex-types-client-eina-value.c `pkg-config --cflags --libs eldbus ecore eina`
3 
4 #include "Eldbus.h"
5 #include <Ecore.h>
6 
7 #define BUS "com.profusion"
8 #define PATH "/com/profusion/Test"
9 #define IFACE "com.profusion.Test"
10 
11 #define size_of_array 5
12 static const char *array_string[] = {
13    "aaaa", "bbbb", "cccc", "dddd", "eeee"
14 };
15 
16 typedef struct _sub_struct
17 {
18    char *txt;
19    int num;
20 } sub_struct;
21 
22 typedef struct _main_struct
23 {
24    int size;
25    sub_struct array[];
26 } main_struct;
27 
28 static unsigned int
_type_offset(unsigned base,unsigned size)29 _type_offset(unsigned base, unsigned size)
30 {
31    unsigned padding;
32    if (!(base % size))
33      return base;
34    padding = base - size;
35    return base + padding;
36 }
37 
38 static void
_fill_receive_array_of_string_int_with_size(Eldbus_Message * msg,int size,const char * array[])39 _fill_receive_array_of_string_int_with_size(Eldbus_Message *msg, int size, const char *array[])
40 {
41    Eina_Value *value_struct, *value_array;
42    int i;
43    unsigned offset;
44    Eina_Value_Struct_Member main_members[2];
45    Eina_Value_Struct_Member sub_members[] = {
46       EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_STRING, sub_struct, txt),
47       EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, sub_struct, num)
48    };
49    Eina_Value_Struct_Desc desc_sub_struct = {
50       EINA_VALUE_STRUCT_DESC_VERSION,
51       NULL, // no special operations
52       sub_members,
53       2,
54       sizeof(sub_struct)
55    };
56    Eina_Value_Struct_Desc desc_struct = {
57       EINA_VALUE_STRUCT_DESC_VERSION,
58       NULL, // no special operations
59       main_members,
60       2,
61       0//will be set below
62    };
63 
64    offset = _type_offset(sizeof(int), sizeof(Eina_Value_Array));
65    main_members[0].name = "size";
66    main_members[0].type = EINA_VALUE_TYPE_INT;
67    main_members[0].offset = 0;
68    main_members[1].name = "array";
69    main_members[1].type = EINA_VALUE_TYPE_ARRAY;
70    main_members[1].offset = offset;
71    desc_struct.size = offset + sizeof(Eina_Value_Array);
72 
73    value_struct = eina_value_struct_new(&desc_struct);
74    eina_value_struct_set(value_struct, "size", size);
75 
76    value_array = eina_value_array_new(EINA_VALUE_TYPE_STRUCT, size);
77    for (i = 0; i < size; i++)
78      {
79         Eina_Value *value_sub_struct = eina_value_struct_new(&desc_sub_struct);
80         Eina_Value_Struct st;
81         eina_value_struct_set(value_sub_struct, "txt", array[i]);
82         eina_value_struct_set(value_sub_struct, "num", i);
83         eina_value_get(value_sub_struct, &st);
84         eina_value_array_append(value_array, st);
85         eina_value_free(value_sub_struct);
86      }
87    eina_value_struct_value_set(value_struct, "array", value_array);
88 
89    eldbus_message_from_eina_value("ia(si)", msg, value_struct);
90 
91    eina_value_free(value_struct);
92    eina_value_free(value_array);
93 }
94 
95 static void
on_send_array(void * data EINA_UNUSED,const Eldbus_Message * msg,Eldbus_Pending * pending EINA_UNUSED)96 on_send_array(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
97 {
98    Eina_Value *v, array;
99    const char *txt;
100    unsigned i;
101    printf("2 - on_send_array()\n");
102 
103    if (eldbus_message_error_get(msg, NULL, NULL))
104      {
105         printf("Message error\n\n");
106         return;
107      }
108 
109    v = eldbus_message_to_eina_value(msg);
110    eina_value_struct_value_get(v, "arg0", &array);
111    for (i = 0; i < eina_value_array_count(&array); i++)
112      {
113         eina_value_array_get(&array, i, &txt);
114         printf("\t%s\n", txt);
115      }
116 
117    eina_value_free(v);
118    eina_value_flush(&array);
119 }
120 
121 static void
on_receive_array_with_size(void * data EINA_UNUSED,const Eldbus_Message * msg,Eldbus_Pending * pending EINA_UNUSED)122 on_receive_array_with_size(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
123 {
124    const char *errname;
125    const char *errmsg;
126 
127    printf("1 - on_receive_array_with_size()\n");
128    if (eldbus_message_error_get(msg, &errname, &errmsg))
129      {
130         fprintf(stderr, "Error: %s %s\n", errname, errmsg);
131      }
132 }
133 
134 static void
on_plus_one(void * data EINA_UNUSED,const Eldbus_Message * msg,Eldbus_Pending * pending EINA_UNUSED)135 on_plus_one(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
136 {
137    Eina_Value *v;
138    int num2;
139 
140    if (eldbus_message_error_get(msg, NULL, NULL))
141      {
142         printf("Message error\n\n");
143         return;
144      }
145 
146    v = eldbus_message_to_eina_value(msg);
147    eina_value_struct_get(v, "arg0", &num2);
148 
149    printf("3 - on_plus_one() %d\n", num2);
150    eina_value_free(v);
151 }
152 
153 static void
receive_variant_cb(void * data EINA_UNUSED,const Eldbus_Message * msg,Eldbus_Pending * pending EINA_UNUSED)154 receive_variant_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
155 {
156    Eina_Value *v, variant, array;
157    unsigned i;
158 
159    printf("4 - receive a variant with an array of strings\n");
160    if (eldbus_message_error_get(msg, NULL, NULL))
161      {
162         printf("Message error\n\n");
163         return;
164      }
165 
166    v = eldbus_message_to_eina_value(msg);
167 
168    eina_value_struct_value_get(v, "arg0", &variant);
169    eina_value_struct_value_get(&variant, "arg0", &array);
170    for (i = 0; i < eina_value_array_count(&array); i++)
171      {
172         const char *txt;
173         eina_value_array_get(&array, i, &txt);
174         printf("\t%s\n", txt);
175      }
176 
177    eina_value_flush(&array);
178    eina_value_flush(&variant);
179    eina_value_free(v);
180 }
181 
182 static void
_property_removed(void * data EINA_UNUSED,Eldbus_Proxy * proxy EINA_UNUSED,void * event_info)183 _property_removed(void *data EINA_UNUSED, Eldbus_Proxy *proxy EINA_UNUSED, void *event_info)
184 {
185    Eldbus_Proxy_Event_Property_Removed *event = event_info;
186 
187    printf("\nproperty removed: %s", event->name);
188 }
189 
190 static void
_property_changed(void * data EINA_UNUSED,Eldbus_Proxy * proxy EINA_UNUSED,void * event_info)191 _property_changed(void *data EINA_UNUSED, Eldbus_Proxy *proxy EINA_UNUSED, void *event_info)
192 {
193    Eldbus_Proxy_Event_Property_Changed *event = event_info;
194    const char *name;
195    const Eina_Value *value;
196    printf("\nproperty changed\n");
197 
198    name = event->name;
199    value = event->value;
200 
201    if (!strcmp(name, "text") || !strcmp(name, "Resp2"))
202      {
203         const char *txt;
204         eina_value_get(value, &txt);
205         printf("[%s] = %s\n", name, txt);
206      }
207    else if (!strcmp(name, "int32"))
208      {
209         int num;
210         eina_value_get(value, &num);
211         printf("[%s] = %d\n", name, num);
212      }
213    else if (!strcmp(name, "st"))
214      {
215         const char *txt;
216         eina_value_struct_get(value, "arg0", &txt);
217         printf("[%s] %s | ", name, txt);
218         eina_value_struct_get(value, "arg1", &txt);
219         printf("%s\n", txt);
220      }
221 }
222 
223 static Eina_Bool
_read_cache(void * data)224 _read_cache(void *data)
225 {
226    Eldbus_Proxy *proxy = data;
227    const char *txt;
228    int num;
229    Eina_Value *v;
230 
231    v = eldbus_proxy_property_local_get(proxy, "text");
232    if (v)
233      {
234         eina_value_get(v, &txt);
235         printf("Read cache: [txt] = %s\n", txt);
236      }
237 
238    v = eldbus_proxy_property_local_get(proxy, "int32");
239    if (v)
240      {
241         eina_value_get(v, &num);
242         printf("Read cache: [int32] = %d\n", num);
243      }
244 
245    v = eldbus_proxy_property_local_get(proxy, "st");
246    if (v)
247      {
248         eina_value_struct_get(v, "arg0", &txt);
249         printf("Read cache: [st] %s | ", txt);
250         eina_value_struct_get(v, "arg1", &txt);
251         printf("%s\n", txt);
252      }
253 
254    return EINA_FALSE;
255 }
256 
257 static void
_fill_plus_one(Eldbus_Message * msg,int num)258 _fill_plus_one(Eldbus_Message *msg, int num)
259 {
260    Eina_Value *v;
261    Eina_Value_Struct_Member main_members[] = {
262       {"num", EINA_VALUE_TYPE_INT, 0}
263    };
264    Eina_Value_Struct_Desc desc_struct = {
265          EINA_VALUE_STRUCT_DESC_VERSION,
266          NULL, // no special operations
267          main_members,
268          1,
269          sizeof(int)
270    };
271    v = eina_value_struct_new(&desc_struct);
272    eina_value_struct_set(v, "num", num);
273 
274    eldbus_message_from_eina_value("i", msg, v);
275 
276    eina_value_free(v);
277 }
278 
279 int
main(void)280 main(void)
281 {
282    Eldbus_Connection *conn;
283    Eldbus_Object *obj;
284    Eldbus_Proxy *proxy;
285    Eldbus_Message *msg;
286 
287    ecore_init();
288    eldbus_init();
289 
290    conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
291    obj = eldbus_object_get(conn, BUS, PATH);
292    proxy = eldbus_proxy_get(obj, IFACE);
293 
294    msg = eldbus_proxy_method_call_new(proxy, "ReceiveArrayOfStringIntWithSize");
295    _fill_receive_array_of_string_int_with_size(msg, size_of_array, array_string);
296    eldbus_proxy_send(proxy, msg, on_receive_array_with_size, NULL, -1);
297 
298    eldbus_proxy_call(proxy, "SendArray", on_send_array, NULL, -1 , "");
299 
300    msg = eldbus_proxy_method_call_new(proxy, "PlusOne");
301    _fill_plus_one(msg, 14);
302    eldbus_proxy_send(proxy, msg, on_plus_one, NULL, -1);
303 
304    eldbus_proxy_event_callback_add(proxy,
305                                   ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
306                                   _property_changed, NULL);
307    eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
308                                   _property_removed, NULL);
309 
310    eldbus_proxy_properties_monitor(proxy, EINA_TRUE);
311    ecore_timer_add(10, _read_cache, proxy);
312 
313    eldbus_proxy_call(proxy, "ReceiveVariantData", receive_variant_cb, NULL, -1, "");
314 
315    ecore_main_loop_begin();
316 
317    eldbus_proxy_event_callback_del(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
318                                   _property_changed, NULL);
319    eldbus_connection_unref(conn);
320 
321    eldbus_shutdown();
322    ecore_shutdown();
323    return 0;
324 }
325