summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/bus-gvariant.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-01-26 21:48:08 +0100
committerLennart Poettering <lennart@poettering.net>2015-01-26 21:52:07 +0100
commitb381de4197157748ed96e469fcc372c23f842ae1 (patch)
tree5f5fa7cc7a4a703c294d92b9501772857a286fdb /src/libsystemd/sd-bus/bus-gvariant.c
parentee04388a54f0e045377eeaf33c17eb357fe12d69 (diff)
sd-bus: change serialization of kdbus messages to qualify in their entirety as gvariant objects
Previously, we only minimally altered the dbus1 framing for kdbus, and while the header and its fields where compliant Gvariant objects, and so was the body, the entire message together was not. As result of discussions with Ryan Lortie this is now changed, so that the messages in there entirely are fully compliant GVariants. This follows the framing description described here: https://wiki.gnome.org/Projects/GLib/GDBus/Version2 Note that this change changes the framing of *all* messages sent via kdbus, this means you have to reboot your kdbus system, after compiling and installing this new version.
Diffstat (limited to 'src/libsystemd/sd-bus/bus-gvariant.c')
-rw-r--r--src/libsystemd/sd-bus/bus-gvariant.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/libsystemd/sd-bus/bus-gvariant.c b/src/libsystemd/sd-bus/bus-gvariant.c
index dc40009925..02b95cd136 100644
--- a/src/libsystemd/sd-bus/bus-gvariant.c
+++ b/src/libsystemd/sd-bus/bus-gvariant.c
@@ -247,3 +247,63 @@ int bus_gvariant_is_fixed_size(const char *signature) {
return true;
}
+
+size_t bus_gvariant_determine_word_size(size_t sz, size_t extra) {
+ if (sz + extra <= 0xFF)
+ return 1;
+ else if (sz + extra*2 <= 0xFFFF)
+ return 2;
+ else if (sz + extra*4 <= 0xFFFFFFFF)
+ return 4;
+ else
+ return 8;
+}
+
+size_t bus_gvariant_read_word_le(void *p, size_t sz) {
+ union {
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ } x;
+
+ assert(p);
+
+ if (sz == 1)
+ return *(uint8_t*) p;
+
+ memcpy(&x, p, sz);
+
+ if (sz == 2)
+ return le16toh(x.u16);
+ else if (sz == 4)
+ return le32toh(x.u32);
+ else if (sz == 8)
+ return le64toh(x.u64);
+
+ assert_not_reached("unknown word width");
+}
+
+void bus_gvariant_write_word_le(void *p, size_t sz, size_t value) {
+ union {
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ } x;
+
+ assert(p);
+ assert(sz == 8 || (value < (1ULL << (sz*8))));
+
+ if (sz == 1) {
+ *(uint8_t*) p = value;
+ return;
+ } else if (sz == 2)
+ x.u16 = htole16((uint16_t) value);
+ else if (sz == 4)
+ x.u32 = htole32((uint32_t) value);
+ else if (sz == 8)
+ x.u64 = htole64((uint64_t) value);
+ else
+ assert_not_reached("unknown word width");
+
+ memcpy(p, &x, sz);
+}