From a96fc4099b21371db766969fe2daf861a0adc599 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 21 Nov 2017 19:46:56 +0000 Subject: [PATCH 1/9] DBusHeader: Add a diagram of the header Signed-off-by: Simon McVittie --- dbus/dbus-marshal-header.c | 4 +++- dbus/dbus-marshal-header.h | 55 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c index 74b39cdc..8c2d5d49 100644 --- a/dbus/dbus-marshal-header.c +++ b/dbus/dbus-marshal-header.c @@ -119,7 +119,9 @@ correct_header_padding (DBusHeader *header) header->padding = _dbus_string_get_length (&header->data) - unpadded_len; } -/** Compute the end of the header, ignoring padding */ +/** + * Compute the end of the header, ignoring padding. + * In the #DBusHeader diagram, this is the distance from 0 to [B]. */ #define HEADER_END_BEFORE_PADDING(header) \ (_dbus_string_get_length (&(header)->data) - (header)->padding) diff --git a/dbus/dbus-marshal-header.h b/dbus/dbus-marshal-header.h index c8c01129..d885c532 100644 --- a/dbus/dbus-marshal-header.h +++ b/dbus/dbus-marshal-header.h @@ -43,20 +43,69 @@ struct DBusHeaderField /** * Message header data and some cached details of it. + * + * A message looks like this: + * + * @code + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | <- index % 8 + * |-------|-------|-------|------|-----|-----|-----|-----| + * | Order | Type | Flags | Vers | Body length | + * | Serial | Fields array length [A] + * [A] Code |Sig.len| Signature + \0 | Content...| <- first field + * | Content ... | Pad to 8-byte boundary| + * | Code |Sig.len| Signature + \0 | Content... | <- second field + * ... + * | Code |Sig.len| Signature | Content... | <- last field + * | Content ... [B] Padding to 8-byte boundary [C] + * [C] Body ... | + * ... + * | Body ... [D] <- no padding after natural length + * @endcode + * + * Each field is a struct. All structs have 8-byte alignment, + * so each field is preceded by 0-7 bytes of padding to an 8-byte boundary + * (for the first field it happens to be 0 bytes). The overall header + * is followed by 0-7 bytes of padding to align the body. + * + * Key to content, with variable name references for _dbus_header_load(): + * + * Order: byte order, currently 'l' or 'B' (byte_order) + * Type: message type such as DBUS_MESSAGE_TYPE_METHOD_CALL + * Flags: message flags such as DBUS_HEADER_FLAG_NO_REPLY_EXPECTED + * Vers: D-Bus wire protocol version, currently always 1 + * Body length: Distance from [C] to [D] + * Serial: Message serial number + * Fields array length: Distance from [A] to [B] (fields_array_len) + * + * To understand _dbus_header_load(): + * + * [A] is FIRST_FIELD_OFFSET. + * header_len is from 0 to [C]. + * padding_start is [B], adjusted because the header is not necessarily + * the first thing in str. + * padding_len is the padding from [B] to [C]. */ struct DBusHeader { DBusString data; /**< Header network data, stored * separately from body so we can - * independently realloc it. + * independently realloc it. Its length includes + * up to 8 bytes of padding to align the body to + * an 8-byte boundary. + * + * In a steady state, this has length [C]. During + * editing, it is temporarily extended to have the + * maximum possible padding. */ DBusHeaderField fields[DBUS_HEADER_FIELD_LAST + 1]; /**< Track the location * of each field in header */ - dbus_uint32_t padding : 3; /**< bytes of alignment in header */ - dbus_uint32_t byte_order : 8; /**< byte order of header */ + dbus_uint32_t padding : 3; /**< 0-7 bytes of alignment in header, + the distance from [B] to [C] */ + dbus_uint32_t byte_order : 8; /**< byte order of header (must always + match the content of byte 0) */ }; dbus_bool_t _dbus_header_init (DBusHeader *header); -- 2.15.0