D-Bus message encoder that marshals data according to D-Bus wire format.
Implements the D-Bus marshaling format with proper alignment and byte ordering.
Summary
Functions
Encodes data according to a D-Bus type signature into the wire format.
Encode data with a specific starting position for alignment calculations.
Types
@type encoding_state() :: %{ endianness: endianness(), position: non_neg_integer(), buffer: iodata() }
@type endianness() :: :little | :big
Functions
@spec encode(binary(), [any()], endianness()) :: iodata()
Encodes data according to a D-Bus type signature into the wire format.
This function takes a D-Bus type signature string and corresponding data, then marshals it into the binary format specified by the D-Bus protocol. The output follows D-Bus alignment rules and byte ordering.
Parameters
signature- A D-Bus type signature string (e.g., "i", "s", "a(is)", etc.)data- A list of values to encode that match the signature typesendianness- Byte order for encoding (:littleor:big). Defaults to:little
Returns
Returns an iodata structure containing the encoded binary data that can be
converted to binary using IO.iodata_to_binary/1.
Examples
# Encode a simple integer
iex> Bluez.Rebus.Encoder.encode("i", [42])
[[[], <<42, 0, 0, 0>>]]
# Encode a string
iex> Bluez.Rebus.Encoder.encode("s", ["hello"])
[[[], <<5, 0, 0, 0>>, "hello", <<0>>]]
# Encode an array of integers
iex> Bluez.Rebus.Encoder.encode("ai", [[1, 2, 3]])
[[[], <<12, 0, 0, 0>>, <<1, 0, 0, 0>>, <<2, 0, 0, 0>>, <<3, 0, 0, 0>>]]
# Encode a struct with mixed types
iex> Bluez.Rebus.Encoder.encode("(si)", [["hello", 42]])
[[[], <<5, 0, 0, 0>>, "hello", [<<0>>, <<0, 0, 0>>], <<42, 0, 0, 0>>]]D-Bus Type Signatures
Common D-Bus type codes:
"y"- byte (0-255)"b"- boolean (0 or 1)"n"- signed 16-bit integer"q"- unsigned 16-bit integer"i"- signed 32-bit integer"u"- unsigned 32-bit integer"x"- signed 64-bit integer"t"- unsigned 64-bit integer"d"- IEEE 754 double"s"- UTF-8 string"o"- object path"g"- signature"a"- array (followed by element type)"("and")"- struct boundaries"v"- variant"{"and"}"- dictionary entry
Alignment Rules
The encoder automatically handles D-Bus alignment requirements:
- 1-byte alignment: byte, boolean
- 2-byte alignment: int16, uint16
- 4-byte alignment: int32, uint32, string length, array length
- 8-byte alignment: int64, uint64, double, struct start
@spec encode_at_position(binary(), [any()], endianness(), non_neg_integer()) :: iodata()
Encode data with a specific starting position for alignment calculations.
This is useful when the encoded data will be inserted at a specific position in a larger message, and alignment must be calculated relative to that position.