chiark / gitweb /
bus: add new sd_bus_message_verify_type() and sd_bus_message_copy() API calls
[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 #include <dbus.h>
31
32 #include "log.h"
33 #include "util.h"
34
35 #include "sd-bus.h"
36 #include "bus-message.h"
37 #include "bus-util.h"
38
39 int main(int argc, char *argv[]) {
40         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
41         int r, boolean;
42         const char *x, *y, *z, *a, *b, *c, *d;
43         uint8_t u, v;
44         void *buffer = NULL;
45         size_t sz;
46         char *h;
47         const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
48         char *s;
49         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
50         _cleanup_fclose_ FILE *ms = NULL;
51         size_t first_size = 0, second_size = 0, third_size = 0;
52
53         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m);
54         assert_se(r >= 0);
55
56         r = sd_bus_message_append(m, "s", "a string");
57         assert_se(r >= 0);
58
59         r = sd_bus_message_append(m, "s", NULL);
60         assert_se(r < 0);
61
62         r = sd_bus_message_append(m, "as", 2, "string #1", "string #2");
63         assert_se(r >= 0);
64
65         r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
66         assert_se(r >= 0);
67
68         r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
69         assert_se(r >= 0);
70
71         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
72         assert_se(r >= 0);
73
74         r = sd_bus_message_open_container(m, 'a', "s");
75         assert_se(r >= 0);
76
77         r = sd_bus_message_append_basic(m, 's', "foobar");
78         assert_se(r >= 0);
79
80         r = sd_bus_message_append_basic(m, 's', "waldo");
81         assert_se(r >= 0);
82
83         r = sd_bus_message_close_container(m);
84         assert_se(r >= 0);
85
86         r = sd_bus_message_append_string_space(m, 5, &s);
87         assert_se(r >= 0);
88         strcpy(s, "hallo");
89
90         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
91         assert_se(r >= 0);
92
93         r = bus_message_seal(m, 4711);
94         assert_se(r >= 0);
95
96         bus_message_dump(m, stdout, true);
97
98         ms = open_memstream(&first, &first_size);
99         bus_message_dump(m, ms, false);
100         fflush(ms);
101         assert_se(!ferror(ms));
102
103         r = bus_message_get_blob(m, &buffer, &sz);
104         assert_se(r >= 0);
105
106         h = hexmem(buffer, sz);
107         assert_se(h);
108
109         log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
110         free(h);
111
112 #ifdef HAVE_GLIB
113         {
114                 GDBusMessage *g;
115                 char *p;
116
117 #if !defined(GLIB_VERSION_2_36)
118                 g_type_init();
119 #endif
120
121                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
122                 p = g_dbus_message_print(g, 0);
123                 log_info("%s", p);
124                 g_free(p);
125                 g_object_unref(g);
126         }
127 #endif
128
129         {
130                 DBusMessage *w;
131                 DBusError error;
132
133                 dbus_error_init(&error);
134
135                 w = dbus_message_demarshal(buffer, sz, &error);
136                 if (!w) {
137                         log_error("%s", error.message);
138                 } else
139                         dbus_message_unref(w);
140         }
141
142         m = sd_bus_message_unref(m);
143
144         r = bus_message_from_malloc(buffer, sz, NULL, 0, NULL, NULL, &m);
145         assert_se(r >= 0);
146
147         bus_message_dump(m, stdout, true);
148
149         fclose(ms);
150         ms = open_memstream(&second, &second_size);
151         bus_message_dump(m, ms, false);
152         fflush(ms);
153         assert_se(!ferror(ms));
154         assert_se(first_size == second_size);
155         assert_se(memcmp(first, second, first_size) == 0);
156
157         assert_se(sd_bus_message_rewind(m, true) >= 0);
158
159         r = sd_bus_message_read(m, "sas", &x, 2, &y, &z);
160         assert_se(r > 0);
161         assert_se(streq(x, "a string"));
162         assert_se(streq(y, "string #1"));
163         assert_se(streq(z, "string #2"));
164
165         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
166         assert_se(r > 0);
167         assert_se(streq(x, "foobar"));
168         assert_se(streq(y, "foo"));
169         assert_se(streq(z, "bar"));
170         assert_se(streq(a, "waldo"));
171         assert_se(streq(b, "piep"));
172         assert_se(streq(c, "pap"));
173         assert_se(streq(d, "after"));
174
175         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
176         assert_se(r > 0);
177         assert_se(u == 3);
178         assert_se(streq(x, "foo"));
179         assert_se(v == 5);
180         assert_se(streq(y, "waldo"));
181
182         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
183         assert_se(r > 0);
184         assert_se(boolean);
185         assert_se(streq(x, "aaa"));
186         assert_se(streq(y, "1"));
187         assert_se(streq(a, "bbb"));
188         assert_se(streq(b, "2"));
189         assert_se(streq(c, "ccc"));
190         assert_se(streq(d, "3"));
191
192         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
193
194         r = sd_bus_message_read(m, "as", 2, &x, &y);
195         assert_se(r > 0);
196         assert_se(streq(x, "foobar"));
197         assert_se(streq(y, "waldo"));
198
199         r = sd_bus_message_read_basic(m, 's', &s);
200         assert_se(r > 0);
201         assert_se(streq(s, "hallo"));
202
203         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
204         assert_se(r > 0);
205         assert_se(sz == sizeof(integer_array));
206         assert_se(memcmp(integer_array, return_array, sz) == 0);
207
208         r = sd_bus_message_peek_type(m, NULL, NULL);
209         assert_se(r == 0);
210
211         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &copy);
212         assert_se(r >= 0);
213
214         r = sd_bus_message_rewind(m, true);
215         assert_se(r >= 0);
216
217         r = sd_bus_message_copy(copy, m, true);
218         assert_se(r >= 0);
219
220         r = bus_message_seal(copy, 4712);
221         assert_se(r >= 0);
222
223         fclose(ms);
224         ms = open_memstream(&third, &third_size);
225         bus_message_dump(copy, ms, false);
226         fflush(ms);
227         assert_se(!ferror(ms));
228
229         printf("<%.*s>", (int) first_size, first);
230         printf("<%.*s>", (int) third_size, third);
231
232         assert_se(first_size == third_size);
233         assert_se(memcmp(first, third, third_size) == 0);
234
235         return 0;
236 }