chiark / gitweb /
bus: beautify bus_message_dump() output a bit
[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 #include "bus-dump.h"
41
42 int main(int argc, char *argv[]) {
43         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
44         int r, boolean;
45         const char *x, *x2, *y, *z, *a, *b, *c, *d;
46         uint8_t u, v;
47         void *buffer = NULL;
48         size_t sz;
49         char *h;
50         const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
51         char *s;
52         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
53         _cleanup_fclose_ FILE *ms = NULL;
54         size_t first_size = 0, second_size = 0, third_size = 0;
55
56         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m);
57         assert_se(r >= 0);
58
59         r = sd_bus_message_append(m, "s", "a string");
60         assert_se(r >= 0);
61
62         r = sd_bus_message_append(m, "s", NULL);
63         assert_se(r >= 0);
64
65         r = sd_bus_message_append(m, "as", 2, "string #1", "string #2");
66         assert_se(r >= 0);
67
68         r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
69         assert_se(r >= 0);
70
71         r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
72         assert_se(r >= 0);
73
74         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
75         assert_se(r >= 0);
76
77         r = sd_bus_message_open_container(m, 'a', "s");
78         assert_se(r >= 0);
79
80         r = sd_bus_message_append_basic(m, 's', "foobar");
81         assert_se(r >= 0);
82
83         r = sd_bus_message_append_basic(m, 's', "waldo");
84         assert_se(r >= 0);
85
86         r = sd_bus_message_close_container(m);
87         assert_se(r >= 0);
88
89         r = sd_bus_message_append_string_space(m, 5, &s);
90         assert_se(r >= 0);
91         strcpy(s, "hallo");
92
93         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
94         assert_se(r >= 0);
95
96         r = sd_bus_message_append_array(m, 'u', NULL, 0);
97         assert_se(r >= 0);
98
99         r = bus_message_seal(m, 4711);
100         assert_se(r >= 0);
101
102         bus_message_dump(m, stdout, true);
103
104         ms = open_memstream(&first, &first_size);
105         bus_message_dump(m, ms, false);
106         fflush(ms);
107         assert_se(!ferror(ms));
108
109         r = bus_message_get_blob(m, &buffer, &sz);
110         assert_se(r >= 0);
111
112         h = hexmem(buffer, sz);
113         assert_se(h);
114
115         log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
116         free(h);
117
118 #ifdef HAVE_GLIB
119         {
120                 GDBusMessage *g;
121                 char *p;
122
123 #if !defined(GLIB_VERSION_2_36)
124                 g_type_init();
125 #endif
126
127                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
128                 p = g_dbus_message_print(g, 0);
129                 log_info("%s", p);
130                 g_free(p);
131                 g_object_unref(g);
132         }
133 #endif
134
135 #ifdef HAVE_DBUS
136         {
137                 DBusMessage *w;
138                 DBusError error;
139
140                 dbus_error_init(&error);
141
142                 w = dbus_message_demarshal(buffer, sz, &error);
143                 if (!w) {
144                         log_error("%s", error.message);
145                 } else
146                         dbus_message_unref(w);
147         }
148 #endif
149
150         m = sd_bus_message_unref(m);
151
152         r = bus_message_from_malloc(buffer, sz, NULL, 0, NULL, NULL, &m);
153         assert_se(r >= 0);
154
155         bus_message_dump(m, stdout, true);
156
157         fclose(ms);
158         ms = open_memstream(&second, &second_size);
159         bus_message_dump(m, ms, false);
160         fflush(ms);
161         assert_se(!ferror(ms));
162         assert_se(first_size == second_size);
163         assert_se(memcmp(first, second, first_size) == 0);
164
165         assert_se(sd_bus_message_rewind(m, true) >= 0);
166
167         r = sd_bus_message_read(m, "ssas", &x, &x2, 2, &y, &z);
168         assert_se(r > 0);
169         assert_se(streq(x, "a string"));
170         assert_se(streq(x2, ""));
171         assert_se(streq(y, "string #1"));
172         assert_se(streq(z, "string #2"));
173
174         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
175         assert_se(r > 0);
176         assert_se(streq(x, "foobar"));
177         assert_se(streq(y, "foo"));
178         assert_se(streq(z, "bar"));
179         assert_se(streq(a, "waldo"));
180         assert_se(streq(b, "piep"));
181         assert_se(streq(c, "pap"));
182         assert_se(streq(d, "after"));
183
184         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
185         assert_se(r > 0);
186         assert_se(u == 3);
187         assert_se(streq(x, "foo"));
188         assert_se(v == 5);
189         assert_se(streq(y, "waldo"));
190
191         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
192         assert_se(r > 0);
193         assert_se(boolean);
194         assert_se(streq(x, "aaa"));
195         assert_se(streq(y, "1"));
196         assert_se(streq(a, "bbb"));
197         assert_se(streq(b, "2"));
198         assert_se(streq(c, "ccc"));
199         assert_se(streq(d, "3"));
200
201         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
202
203         r = sd_bus_message_read(m, "as", 2, &x, &y);
204         assert_se(r > 0);
205         assert_se(streq(x, "foobar"));
206         assert_se(streq(y, "waldo"));
207
208         r = sd_bus_message_read_basic(m, 's', &s);
209         assert_se(r > 0);
210         assert_se(streq(s, "hallo"));
211
212         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
213         assert_se(r > 0);
214         assert_se(sz == sizeof(integer_array));
215         assert_se(memcmp(integer_array, return_array, sz) == 0);
216
217         r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
218         assert_se(r > 0);
219         assert_se(sz == 0);
220
221         r = sd_bus_message_peek_type(m, NULL, NULL);
222         assert_se(r == 0);
223
224         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &copy);
225         assert_se(r >= 0);
226
227         r = sd_bus_message_rewind(m, true);
228         assert_se(r >= 0);
229
230         r = sd_bus_message_copy(copy, m, true);
231         assert_se(r >= 0);
232
233         r = bus_message_seal(copy, 4712);
234         assert_se(r >= 0);
235
236         fclose(ms);
237         ms = open_memstream(&third, &third_size);
238         bus_message_dump(copy, ms, false);
239         fflush(ms);
240         assert_se(!ferror(ms));
241
242         printf("<%.*s>", (int) first_size, first);
243         printf("<%.*s>", (int) third_size, third);
244
245         assert_se(first_size == third_size);
246         assert_se(memcmp(first, third, third_size) == 0);
247
248         r = sd_bus_message_rewind(m, true);
249         assert_se(r >= 0);
250
251         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
252
253         r = sd_bus_message_skip(m, "ssas");
254         assert_se(r > 0);
255
256         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
257
258         r = sd_bus_message_skip(m, "sass");
259         assert_se(r >= 0);
260
261         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
262
263         r = sd_bus_message_skip(m, "a{yv}");
264         assert_se(r >= 0);
265
266         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
267
268         r = sd_bus_message_read(m, "b", &boolean);
269         assert_se(r > 0);
270         assert_se(boolean);
271
272         r = sd_bus_message_enter_container(m, 0, NULL);
273         assert_se(r > 0);
274
275         r = sd_bus_message_read(m, "(ss)", &x, &y);
276         assert_se(r > 0);
277
278         r = sd_bus_message_read(m, "(ss)", &a, &b);
279         assert_se(r > 0);
280
281         r = sd_bus_message_read(m, "(ss)", &c, &d);
282         assert_se(r > 0);
283
284         r = sd_bus_message_read(m, "(ss)", &x, &y);
285         assert_se(r == 0);
286
287         r = sd_bus_message_exit_container(m);
288         assert_se(r >= 0);
289
290         assert_se(streq(x, "aaa"));
291         assert_se(streq(y, "1"));
292         assert_se(streq(a, "bbb"));
293         assert_se(streq(b, "2"));
294         assert_se(streq(c, "ccc"));
295         assert_se(streq(d, "3"));
296
297         return 0;
298 }