From b9b9705b520cd3effaba3dc5e94c83e36f655bc4 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 7 Dec 2025 13:54:11 +0900 Subject: internal/pipewire: specify opcode and file count with message This adds checking of FileCount while writing a message. Message encoding is relocated to an exported method to be used externally, probably for test stubbing. Signed-off-by: Ophestra --- internal/pipewire/pod.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'internal/pipewire/pod.go') diff --git a/internal/pipewire/pod.go b/internal/pipewire/pod.go index 523322f7..15ff25c3 100644 --- a/internal/pipewire/pod.go +++ b/internal/pipewire/pod.go @@ -5,6 +5,7 @@ import ( "io" "math" "reflect" + "slices" "strconv" ) @@ -573,3 +574,48 @@ func (d *SPADict) UnmarshalPOD(data []byte) (Word, error) { } return wireSize, nil } + +// A Message is a value that can be transmitted as a message over PipeWire protocol native. +type Message interface { + // Opcode returns the opcode of this message. + Opcode() byte + // FileCount returns the number of files associated with this message. + FileCount() Int + + KnownSize +} + +// A MessageEncoder provides methods for encoding a [Message]. +type MessageEncoder struct{ Message } + +// SizeMessage returns the size of Message transmitted over protocol native. +func (m MessageEncoder) SizeMessage(footer KnownSize) (size Word) { + size = SizeHeader + m.Message.Size() + if footer != nil { + size += footer.Size() + } + return +} + +// AppendMessage appends the protocol native encoding of Message to dst and returns the appended slice. +func (m MessageEncoder) AppendMessage(dst []byte, Id, sequence Int, footer KnownSize) (data []byte, err error) { + size := m.SizeMessage(footer) + if size&^SizeMax != 0 { + return dst, ErrSizeRange + } + + data = slices.Grow(dst, int(size)) + data = (&Header{ + ID: Id, + Opcode: m.Message.Opcode(), + Size: size - SizeHeader, + Sequence: sequence, + FileCount: m.Message.FileCount(), + }).append(data) + data, err = MarshalAppend(data, m.Message) + if err == nil && footer != nil { + data, err = MarshalAppend(data, footer) + } + + return +} -- cgit v1.3.1