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:
parent
2e996f4d4b
commit
f8e013f8bf
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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, ...);
|
||||
|
Loading…
Reference in New Issue
Block a user