chiark / gitweb /
8f36a71d4b5d9032508e5fc365298d2656b7795f
[elogind.git] / src / libsystemd-bus / test-bus-marshal.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <byteswap.h>
25
26 #ifdef HAVE_GLIB
27 #include <gio/gio.h>
28 #endif
29
30 #ifdef HAVE_DBUS
31 #include <dbus.h>
32 #endif
33
34 #include "log.h"
35 #include "util.h"
36
37 #include "sd-bus.h"
38 #include "bus-message.h"
39 #include "bus-util.h"
40
41 int main(int argc, char *argv[]) {
42         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
43         int r, boolean;
44         const char *x, *x2, *y, *z, *a, *b, *c, *d;
45         uint8_t u, v;
46         void *buffer = NULL;
47         size_t sz;
48         char *h;
49         const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
50         char *s;
51         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
52         _cleanup_fclose_ FILE *ms = NULL;
53         size_t first_size = 0, second_size = 0, third_size = 0;
54
55         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m);
56         assert_se(r >= 0);
57
58         r = sd_bus_message_append(m, "s", "a string");
59         assert_se(r >= 0);
60
61         r = sd_bus_message_append(m, "s", NULL);
62         assert_se(r >= 0);
63
64         r = sd_bus_message_append(m, "as", 2, "string #1", "string #2");
65         assert_se(r >= 0);
66
67         r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
68         assert_se(r >= 0);
69
70         r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
71         assert_se(r >= 0);
72
73         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
74         assert_se(r >= 0);
75
76         r = sd_bus_message_open_container(m, 'a', "s");
77         assert_se(r >= 0);
78
79         r = sd_bus_message_append_basic(m, 's', "foobar");
80         assert_se(r >= 0);
81
82         r = sd_bus_message_append_basic(m, 's', "waldo");
83         assert_se(r >= 0);
84
85         r = sd_bus_message_close_container(m);
86         assert_se(r >= 0);
87
88         r = sd_bus_message_append_string_space(m, 5, &s);
89         assert_se(r >= 0);
90         strcpy(s, "hallo");
91
92         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
93         assert_se(r >= 0);
94
95         r = sd_bus_message_append_array(m, 'u', NULL, 0);
96         assert_se(r >= 0);
97
98         r = bus_message_seal(m, 4711);
99         assert_se(r >= 0);
100
101         bus_message_dump(m, stdout, true);
102
103         ms = open_memstream(&first, &first_size);
104         bus_message_dump(m, ms, false);
105         fflush(ms);
106         assert_se(!ferror(ms));
107
108         r = bus_message_get_blob(m, &buffer, &sz);
109         assert_se(r >= 0);
110
111         h = hexmem(buffer, sz);
112         assert_se(h);
113
114         log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
115         free(h);
116
117 #ifdef HAVE_GLIB
118         {
119                 GDBusMessage *g;
120                 char *p;
121
122 #if !defined(GLIB_VERSION_2_36)
123                 g_type_init();
124 #endif
125
126                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
127                 p = g_dbus_message_print(g, 0);
128                 log_info("%s", p);
129                 g_free(p);
130                 g_object_unref(g);
131         }
132 #endif
133
134 #ifdef HAVE_DBUS
135         {
136                 DBusMessage *w;
137                 DBusError error;
138
139                 dbus_error_init(&error);
140
141                 w = dbus_message_demarshal(buffer, sz, &error);
142                 if (!w) {
143                         log_error("%s", error.message);
144                 } else
145                         dbus_message_unref(w);
146         }
147 #endif
148
149         m = sd_bus_message_unref(m);
150
151         r = bus_message_from_malloc(buffer, sz, NULL, 0, NULL, NULL, &m);
152         assert_se(r >= 0);
153
154         bus_message_dump(m, stdout, true);
155
156         fclose(ms);
157         ms = open_memstream(&second, &second_size);
158         bus_message_dump(m, ms, false);
159         fflush(ms);
160         assert_se(!ferror(ms));
161         assert_se(first_size == second_size);
162         assert_se(memcmp(first, second, first_size) == 0);
163
164         assert_se(sd_bus_message_rewind(m, true) >= 0);
165
166         r = sd_bus_message_read(m, "ssas", &x, &x2, 2, &y, &z);
167         assert_se(r > 0);
168         assert_se(streq(x, "a string"));
169         assert_se(streq(x2, ""));
170         assert_se(streq(y, "string #1"));
171         assert_se(streq(z, "string #2"));
172
173         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
174         assert_se(r > 0);
175         assert_se(streq(x, "foobar"));
176         assert_se(streq(y, "foo"));
177         assert_se(streq(z, "bar"));
178         assert_se(streq(a, "waldo"));
179         assert_se(streq(b, "piep"));
180         assert_se(streq(c, "pap"));
181         assert_se(streq(d, "after"));
182
183         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
184         assert_se(r > 0);
185         assert_se(u == 3);
186         assert_se(streq(x, "foo"));
187         assert_se(v == 5);
188         assert_se(streq(y, "waldo"));
189
190         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
191         assert_se(r > 0);
192         assert_se(boolean);
193         assert_se(streq(x, "aaa"));
194         assert_se(streq(y, "1"));
195         assert_se(streq(a, "bbb"));
196         assert_se(streq(b, "2"));
197         assert_se(streq(c, "ccc"));
198         assert_se(streq(d, "3"));
199
200         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
201
202         r = sd_bus_message_read(m, "as", 2, &x, &y);
203         assert_se(r > 0);
204         assert_se(streq(x, "foobar"));
205         assert_se(streq(y, "waldo"));
206
207         r = sd_bus_message_read_basic(m, 's', &s);
208         assert_se(r > 0);
209         assert_se(streq(s, "hallo"));
210
211         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
212         assert_se(r > 0);
213         assert_se(sz == sizeof(integer_array));
214         assert_se(memcmp(integer_array, return_array, sz) == 0);
215
216         r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
217         assert_se(r > 0);
218         assert_se(sz == 0);
219
220         r = sd_bus_message_peek_type(m, NULL, NULL);
221         assert_se(r == 0);
222
223         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &copy);
224         assert_se(r >= 0);
225
226         r = sd_bus_message_rewind(m, true);
227         assert_se(r >= 0);
228
229         r = sd_bus_message_copy(copy, m, true);
230         assert_se(r >= 0);
231
232         r = bus_message_seal(copy, 4712);
233         assert_se(r >= 0);
234
235         fclose(ms);
236         ms = open_memstream(&third, &third_size);
237         bus_message_dump(copy, ms, false);
238         fflush(ms);
239         assert_se(!ferror(ms));
240
241         printf("<%.*s>", (int) first_size, first);
242         printf("<%.*s>", (int) third_size, third);
243
244         assert_se(first_size == third_size);
245         assert_se(memcmp(first, third, third_size) == 0);
246
247         r = sd_bus_message_rewind(m, true);
248         assert_se(r >= 0);
249
250         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
251
252         r = sd_bus_message_skip(m, "ssas");
253         assert_se(r > 0);
254
255         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
256
257         r = sd_bus_message_skip(m, "sass");
258         assert_se(r >= 0);
259
260         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
261
262         r = sd_bus_message_skip(m, "a{yv}");
263         assert_se(r >= 0);
264
265         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
266
267         r = sd_bus_message_read(m, "b", &boolean);
268         assert_se(r > 0);
269         assert_se(boolean);
270
271         r = sd_bus_message_enter_container(m, 0, NULL);
272         assert_se(r > 0);
273
274         r = sd_bus_message_read(m, "(ss)", &x, &y);
275         assert_se(r > 0);
276
277         r = sd_bus_message_read(m, "(ss)", &a, &b);
278         assert_se(r > 0);
279
280         r = sd_bus_message_read(m, "(ss)", &c, &d);
281         assert_se(r > 0);
282
283         r = sd_bus_message_read(m, "(ss)", &x, &y);
284         assert_se(r == 0);
285
286         r = sd_bus_message_exit_container(m);
287         assert_se(r >= 0);
288
289         assert_se(streq(x, "aaa"));
290         assert_se(streq(y, "1"));
291         assert_se(streq(a, "bbb"));
292         assert_se(streq(b, "2"));
293         assert_se(streq(c, "ccc"));
294         assert_se(streq(d, "3"));
295
296         return 0;
297 }