1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

bus: add sd_bus_message_append_string_space() for zero-copy string appending

This commit is contained in:
Lennart Poettering 2013-05-10 01:12:15 +02:00
parent 2e996f4d4b
commit f8e013f8bf
3 changed files with 69 additions and 7 deletions

View File

@ -1207,6 +1207,60 @@ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
return message_append_basic(m, type, p, NULL);
}
int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
struct bus_container *c;
char *e;
void *a;
int r;
if (!m)
return -EINVAL;
if (!s)
return -EINVAL;
if (m->sealed)
return -EPERM;
c = message_get_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
if (c->signature[c->index] != SD_BUS_TYPE_STRING)
return -ENXIO;
} else {
/* Maybe we can append to the signature? But only if this is the top-level container*/
if (c->enclosing != 0)
return -ENXIO;
e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
if (!e)
return -ENOMEM;
}
a = message_extend_body(m, 4, 4 + size + 1);
if (!a) {
r = -ENOMEM;
goto fail;
}
*(uint32_t*) a = size;
*s = (char*) a + 4;
(*s)[size] = 0;
if (c->enclosing != SD_BUS_TYPE_ARRAY)
c->index++;
return 0;
fail:
if (e)
c->signature[c->index] = 0;
return r;
}
static int bus_message_open_array(
sd_bus_message *m,
struct bus_container *c,
@ -1799,7 +1853,7 @@ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
return r;
}
int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr) {
int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
ssize_t align, sz;
void *a;
int r;
@ -1851,7 +1905,7 @@ int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, s
if (!ptr && size > 0)
return -EINVAL;
r = sd_bus_message_append_array_ptr(m, type, size, &p);
r = sd_bus_message_append_array_space(m, type, size, &p);
if (r < 0)
return r;

View File

@ -44,6 +44,7 @@ int main(int argc, char *argv[]) {
size_t sz;
char *h;
const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
char *s;
r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m);
assert_se(r >= 0);
@ -78,6 +79,10 @@ int main(int argc, char *argv[]) {
r = sd_bus_message_close_container(m);
assert_se(r >= 0);
r = sd_bus_message_append_string_space(m, 5, &s);
assert_se(r >= 0);
strcpy(s, "hallo");
r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
assert_se(r >= 0);
@ -172,6 +177,10 @@ int main(int argc, char *argv[]) {
assert_se(streq(x, "foobar"));
assert_se(streq(y, "waldo"));
r = sd_bus_message_read_basic(m, 's', &s);
assert_se(r > 0);
assert_se(streq(s, "hallo"));
r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
assert_se(r > 0);
assert_se(sz == sizeof(integer_array));

View File

@ -158,21 +158,20 @@ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination);
int sd_bus_message_append(sd_bus_message *m, const char *types, ...);
int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p);
int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size);
int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr);
int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s);
int sd_bus_message_open_container(sd_bus_message *m, char type, const char *contents);
int sd_bus_message_close_container(sd_bus_message *m);
int sd_bus_message_read(sd_bus_message *m, const char *types, ...);
int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p);
int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size);
int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents);
int sd_bus_message_exit_container(sd_bus_message *m);
int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents);
int sd_bus_message_rewind(sd_bus_message *m, int complete);
int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size);
int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr);
int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size);
/* Convenience calls */
int sd_bus_emit_signal(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, ...);