9a3ae869290d8e53d2c21eac25af47e13c5eb475
[platform/core/uifw/at-spi2-atk.git] / dbind / dbtest.c
1 #include <stdio.h>
2 #include <glib.h>
3 #include <string.h>
4 #define DBUS_API_SUBJECT_TO_CHANGE
5 #include <dbind/dbind.h>
6 #include <dbind/dbind-any.h>
7
8 /* Wow! dbus is unpleasant to use */
9
10 #define DESKICE_PATH      "/Novell/ICEDesktop/Daemon"
11 #define DESKICE_NAMESPACE "Novell.ICEDesktop.Daemon"
12
13 void marshal (DBusMessage *msg, char *type, void *ptr)
14 {
15     DBusMessageIter iter;
16
17     dbus_message_iter_init_append (msg, &iter);
18     dbind_any_marshal (&iter, &type, &ptr);
19 }
20
21 void demarshal (DBusMessage *msg, char *type, void *ptr)
22 {
23     DBusMessageIter iter;
24
25     if (!dbus_message_iter_init (msg, &iter))
26         fprintf (stderr, "no data in msg\n");
27     else
28         dbind_any_demarshal (&iter, &type, &ptr);
29 }
30
31 #if 0
32 dbus_bool_t  dbus_message_marshal   (DBusMessage  *msg,
33                                      char        **marshalled_data_p,
34                                      int          *len_p);
35
36 void dump_msg (DBusMessage *msg)
37 {
38     char *data = NULL;
39     int   len, i, j;
40
41     dbus_message_marshal (msg, &data, &len);
42     for (i = 0; i < (len+15)/16; i++) {
43         fprintf (stderr, "%4.d | ", i * 16);
44         for (j = 0; j < 16; j++) {
45             unsigned char c = (i*16+j <= len) ? data[i*16+j] : 0;
46             fprintf (stderr, "0x%.2x ", c);
47         }
48         fprintf (stderr, " | ");
49         for (j = 0; j < 16; j++) {
50             char c = (i*16+j <= len) ? data[i*16+j] : '\0';
51             fprintf (stderr, "%c", g_ascii_isprint (c) ? c : '.');
52         }
53     }
54 }
55 #endif
56
57 void test_simple ()
58 {
59     dbus_int32_t v1, v2;
60     DBusMessage *msg;
61
62     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
63     v1 = 42;
64     marshal (msg, "i", &v1);
65     demarshal (msg, "i", &v2);
66     g_assert (v2 == 42);
67     g_assert (v1 == v2);
68
69     dbind_any_free ("i", &v2); /* nop */
70     dbus_message_unref (msg);
71
72     fprintf (stderr, "simple ok\n");
73 }
74
75 void test_array ()
76 {
77     GArray *a1, *a2;
78     DBusMessage *msg;
79
80     /* pod types */
81     a1 = g_array_new (FALSE, FALSE, sizeof (dbus_int32_t));
82     g_array_set_size (a1, 4);
83     g_array_index (a1, dbus_int32_t, 0) = 42;
84     g_array_index (a1, dbus_int32_t, 1) = 17;
85     g_array_index (a1, dbus_int32_t, 2) = 26;
86     g_array_index (a1, dbus_int32_t, 3) = 38;
87
88     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
89     marshal (msg, "ai", &a1);
90     demarshal (msg, "ai", &a2);
91
92     g_assert (a2 != NULL);
93     g_assert (a2->len == 4);
94     g_assert (g_array_index (a2, dbus_int32_t, 0) == 42);
95     g_assert (g_array_index (a2, dbus_int32_t, 1) == 17);
96     g_assert (g_array_index (a2, dbus_int32_t, 2) == 26);
97     g_assert (g_array_index (a2, dbus_int32_t, 3) == 38);
98     g_array_free (a1, TRUE);
99
100     dbind_any_free ("ai", &a2);
101     dbus_message_unref (msg);
102
103     fprintf (stderr, "array ok\n");
104 }
105
106 /* this taught me that the struct type is a mis-nomer, 
107    it is generated by brackets */
108 void test_struct_native ()
109 {
110     DBusMessage *msg;
111     DBusMessageIter iter, arr, str;
112
113     /* manually create ar(ss) */
114     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
115
116     dbus_message_iter_init_append (msg, &iter);
117
118     dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ss)", &arr);
119     {
120         char *foo;
121         dbus_message_iter_open_container (&arr, DBUS_TYPE_STRUCT, NULL, &str);
122
123         foo = "foo";
124         dbus_message_iter_append_basic (&str, DBUS_TYPE_STRING, &foo);
125         foo = "baa";
126         dbus_message_iter_append_basic (&str, DBUS_TYPE_STRING, &foo);
127         
128         dbus_message_iter_close_container (&arr, &str);
129     }
130     dbus_message_iter_close_container (&iter, &arr);
131
132     fprintf (stderr, "native struct marshalling ok\n");
133     
134     dbus_message_unref (msg);
135 }
136
137
138 void test_struct_simple ()
139 {
140     typedef struct {
141         char *foo;
142         char *baa;
143         char *baz;
144     } FooBaa;
145     GArray *a1 = NULL, *a2 = NULL;
146     DBusMessage *msg;
147
148     a1 = g_array_new (FALSE, FALSE, sizeof (FooBaa));
149     g_array_set_size (a1, 2);
150     g_array_index (a1, FooBaa, 0).foo = "foo";
151     g_array_index (a1, FooBaa, 0).baa = "baa";
152     g_array_index (a1, FooBaa, 0).baz = "baz";
153     g_array_index (a1, FooBaa, 1).foo = "Foo";
154     g_array_index (a1, FooBaa, 1).baa = "baA";
155     g_array_index (a1, FooBaa, 1).baz = "BaZ";
156
157     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
158     marshal (msg, "a(sss)", &a1);
159     demarshal (msg, "a(sss)", &a2);
160
161     g_assert (a2 != NULL);
162     g_assert (a2 != a1);
163     g_assert (a2->len == 2);
164     g_assert (!strcmp (g_array_index (a2, FooBaa, 0).foo, "foo"));
165     g_assert (!strcmp (g_array_index (a2, FooBaa, 0).baa, "baa"));
166     g_assert (!strcmp (g_array_index (a2, FooBaa, 0).baz, "baz"));
167     g_assert (!strcmp (g_array_index (a2, FooBaa, 1).foo, "Foo"));
168     g_assert (!strcmp (g_array_index (a2, FooBaa, 1).baa, "baA"));
169     g_assert (!strcmp (g_array_index (a2, FooBaa, 1).baz, "BaZ"));
170     
171     fprintf (stderr, "simple struct ok\n");
172
173     dbind_any_free ("a(sss)", &a2);
174     dbus_message_unref (msg);
175 }
176
177 void test_struct_complex ()
178 {
179     typedef struct {
180         dbus_int32_t x, y;
181     } Point;
182     typedef struct {
183         unsigned char pad1;
184         double        val;
185         Point         tl, br;
186         char          pad2;
187         char         *name;
188     } Complex;
189 #define TYPEOF_POINT \
190     DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
191         DBUS_TYPE_INT32_AS_STRING \
192         DBUS_TYPE_INT32_AS_STRING \
193     DBUS_STRUCT_END_CHAR_AS_STRING
194 #define TYPEOF_COMPLEX \
195     DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
196         DBUS_TYPE_BYTE_AS_STRING \
197         DBUS_TYPE_DOUBLE_AS_STRING \
198         TYPEOF_POINT \
199         TYPEOF_POINT \
200         DBUS_TYPE_BYTE_AS_STRING \
201         DBUS_TYPE_STRING_AS_STRING \
202     DBUS_STRUCT_END_CHAR_AS_STRING
203
204
205     DBusMessage *msg;
206     Complex c1, c2;
207
208     memset (&c1, 0, sizeof (c1));
209     memset (&c2, 0, sizeof (c2));
210
211     c1.pad1 = 2;
212     c1.val = 0.1327569;
213     c1.tl.x = 1;
214     c1.tl.y = 17;
215     c1.br.x = 2587;
216     c1.br.y = -1;
217     c1.pad2 = 1;
218     c1.name = "stroustrup";
219
220     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
221     marshal (msg, TYPEOF_COMPLEX, &c1);
222     demarshal (msg, TYPEOF_COMPLEX, &c2);
223
224     g_assert (c2.pad1 == 2);
225     g_assert (c2.val == c1.val);
226     g_assert (c2.val != 0);
227     g_assert (c2.tl.x == 1);
228     g_assert (c2.tl.y == 17);
229     g_assert (c2.br.x == 2587);
230     g_assert (c2.br.y == -1);
231     g_assert (c2.pad2 == 1);
232     g_assert (!strcmp (c1.name, "stroustrup"));
233     
234     fprintf (stderr, "complex struct ok\n");
235
236     dbind_any_free (TYPEOF_COMPLEX, &c2);
237     dbus_message_unref (msg);
238 }
239
240 void test_struct_with_array ()
241 {
242     typedef struct {
243         GArray *vals;
244         unsigned char pad1;
245     } ArrayStruct;
246 #define TYPEOF_ARRAYSTRUCT \
247         DBUS_TYPE_ARRAY_AS_STRING \
248     DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
249         DBUS_TYPE_ARRAY_AS_STRING \
250         DBUS_TYPE_UINT32_AS_STRING \
251         DBUS_TYPE_BYTE_AS_STRING \
252     DBUS_STRUCT_END_CHAR_AS_STRING
253
254
255     DBusMessage *msg;
256     GArray *a1, *a2;
257     ArrayStruct *p, *q;
258
259
260     a1 = g_array_new (FALSE, FALSE, sizeof (ArrayStruct));
261     g_array_set_size (a1, 2);
262     p = &g_array_index (a1, ArrayStruct, 0);
263     p[0].vals = g_array_new (FALSE, FALSE, sizeof (dbus_uint32_t));
264     g_array_set_size (p[0].vals, 2);
265     g_array_index (p[0].vals, dbus_uint32_t, 0) = 1;
266     g_array_index (p[0].vals, dbus_uint32_t, 1) = 1000;
267     p[0].pad1 = 2;
268     p[1].vals = g_array_new (FALSE, FALSE, sizeof (dbus_uint32_t));
269     g_array_set_size (p[1].vals, 2);
270     g_array_index (p[1].vals, dbus_uint32_t, 0) = 1000000;
271     g_array_index (p[1].vals, dbus_uint32_t, 1) = 1000000000;
272     p[1].pad1 = 8;
273
274     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
275     marshal (msg, TYPEOF_ARRAYSTRUCT, &a1);
276     demarshal (msg, TYPEOF_ARRAYSTRUCT, &a2);
277
278     q = &g_array_index (a2, ArrayStruct, 0);
279     g_assert (p[0].pad1 == 2);
280     g_assert (g_array_index (p[1].vals, dbus_uint32_t, 1) == 1000000000);
281     
282     fprintf (stderr, "struct with array ok\n");
283
284     dbind_any_free (TYPEOF_ARRAYSTRUCT, &a2);
285     dbus_message_unref (msg);
286     g_array_free (p[0].vals, TRUE);
287     g_array_free (p[1].vals, TRUE);
288 }
289
290 void test_twovals ()
291 {
292     typedef struct {
293         dbus_int32_t v1;
294         dbus_int32_t v2;
295     } TwoVal;
296 #define TYPEOF_TWOVAL \
297         DBUS_TYPE_INT32_AS_STRING \
298         DBUS_TYPE_INT32_AS_STRING \
299
300     DBusMessage *msg;
301     DBusMessageIter iter;
302     TwoVal i, o;
303     char *type_twoval = TYPEOF_TWOVAL;
304     char *type;
305     void *ptr;
306
307     msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
308     i.v1 = 42;
309   i.v2 = 1764;
310     dbus_message_iter_init_append (msg, &iter);
311     type = type_twoval;
312     ptr = &i;
313     dbind_any_marshal (&iter, &type, &ptr);
314     dbind_any_marshal (&iter, &type, &ptr);
315     dbus_message_iter_init (msg, &iter);
316     type = type_twoval;
317     ptr = &o;
318     dbind_any_demarshal (&iter, &type, &ptr);
319     dbind_any_demarshal (&iter, &type, &ptr);
320     g_assert (o.v1 == 42);
321     g_assert (o.v2 == 1764);
322     g_assert (i.v1 == o.v1);
323     g_assert (i.v2 == o.v2);
324
325     dbind_any_free ("ii", &o); /* nop */
326     dbus_message_unref (msg);
327
328     fprintf (stderr, "two-val ok\n");
329 }
330
331 void test_marshalling ()
332 {
333     test_simple ();
334     test_array ();
335     test_struct_native ();
336     test_struct_simple ();
337     test_struct_complex ();
338     test_struct_with_array ();
339     test_twovals ();
340
341     fprintf (stderr, "Marshalling ok\n");
342 }
343
344 void test_teamspaces (DBindContext *ctx)
345 {
346     GArray *spaces;
347     DBusError error;
348     int i;
349     typedef struct {
350         char *name;
351         char *id;
352         char *url;
353     } TeamSpace;
354
355     dbus_error_init (&error);
356     if (!dbind_context_method_call (ctx, NULL, DESKICE_PATH, DESKICE_NAMESPACE,
357                                     "GetTeamList", &error,
358                                     "=>a(sss)", &spaces)) {
359         fprintf (stderr, "Error getting team spaces %s: %s\n",
360                  error.name, error.message);
361         dbus_error_free (&error);
362         return;
363     }
364
365     if (!spaces) {
366         fprintf (stderr, "no teamspaces\n");
367         return;
368     }
369     fprintf (stderr, "%d teamspace(s)\n", spaces->len);
370     for (i = 0; i < spaces->len; i++) {
371         TeamSpace *space = &g_array_index (spaces, TeamSpace, i);
372         fprintf (stderr, "\t%d: %s, %s, %s\n", i, space->name, space->id, space->url);
373     }
374
375     dbind_any_free_ptr ("a(sss)", spaces);
376 }
377
378 extern dbind_find_c_alignment (char *type);
379
380 void test_helpers ()
381 {
382     dbind_find_c_alignment ("(sss)");
383     dbind_find_c_alignment ("a(sss)");
384     dbind_find_c_alignment ("(s(s)yd(d)s)");
385     fprintf (stderr, "helpers passed\n");
386 }
387
388 int main (int argc, char **argv)
389 {
390     DBindContext *ctx;
391
392     ctx = dbind_create_context (DBUS_BUS_SESSION, NULL);
393     if (!ctx)
394         return 1;
395
396     test_helpers ();
397     test_marshalling ();
398     test_teamspaces (ctx);
399
400     dbind_context_free (ctx);
401
402     return 0;
403 }