All checks were successful
Test / Create distribution (push) Successful in 36s
Test / Sandbox (push) Successful in 2m35s
Test / Sandbox (race detector) (push) Successful in 4m45s
Test / Hakurei (push) Successful in 5m0s
Test / Hpkg (push) Successful in 5m7s
Test / Hakurei (race detector) (push) Successful in 6m37s
Test / Flake checks (push) Successful in 1m34s
This consumes the entire sample, is validated to send identical messages and correctly handle received messages. Signed-off-by: Ophestra <cat@gensokyo.uk>
74 lines
2.4 KiB
Go
74 lines
2.4 KiB
Go
package pipewire
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
)
|
|
|
|
const (
|
|
// SizeHeader is the fixed size of [Header].
|
|
SizeHeader = 16
|
|
// SizeMax is the largest value of [Header.Size] that can be represented in its 3-byte segment.
|
|
SizeMax = 0x00ffffff
|
|
)
|
|
|
|
var (
|
|
// ErrSizeRange indicates that the value of [Header.Size] cannot be represented in its 3-byte segment.
|
|
ErrSizeRange = errors.New("size out of range")
|
|
// ErrBadHeader indicates that the header slice does not have length [HeaderSize].
|
|
ErrBadHeader = errors.New("incorrect header size")
|
|
)
|
|
|
|
// A Header is the fixed-size message header described in protocol native.
|
|
type Header struct {
|
|
// The message id this is the destination resource/proxy id.
|
|
ID Int `json:"Id"`
|
|
// The opcode on the resource/proxy interface.
|
|
Opcode byte `json:"opcode"`
|
|
// The size of the payload and optional footer of the message.
|
|
// Note: this value is only 24 bits long in the format.
|
|
Size uint32 `json:"size"`
|
|
// An increasing sequence number for each message.
|
|
Sequence Int `json:"seq"`
|
|
// Number of file descriptors in this message.
|
|
FileCount Int `json:"n_fds"`
|
|
}
|
|
|
|
// append appends the protocol native message header to data.
|
|
//
|
|
// Callers must perform bounds check on [Header.Size].
|
|
func (h *Header) append(data []byte) []byte {
|
|
data = binary.NativeEndian.AppendUint32(data, Word(h.ID))
|
|
data = binary.NativeEndian.AppendUint32(data, Word(h.Opcode)<<24|h.Size)
|
|
data = binary.NativeEndian.AppendUint32(data, Word(h.Sequence))
|
|
data = binary.NativeEndian.AppendUint32(data, Word(h.FileCount))
|
|
return data
|
|
}
|
|
|
|
// MarshalBinary encodes the protocol native message header.
|
|
func (h *Header) MarshalBinary() (data []byte, err error) {
|
|
if h.Size&^SizeMax != 0 {
|
|
return nil, ErrSizeRange
|
|
}
|
|
return h.append(make([]byte, 0, SizeHeader)), nil
|
|
}
|
|
|
|
// unmarshalBinary decodes the protocol native message header.
|
|
func (h *Header) unmarshalBinary(data [SizeHeader]byte) {
|
|
h.ID = Int(binary.NativeEndian.Uint32(data[0:4]))
|
|
h.Size = binary.NativeEndian.Uint32(data[4:8])
|
|
h.Opcode = byte(h.Size >> 24)
|
|
h.Size &= SizeMax
|
|
h.Sequence = Int(binary.NativeEndian.Uint32(data[8:]))
|
|
h.FileCount = Int(binary.NativeEndian.Uint32(data[12:]))
|
|
}
|
|
|
|
// UnmarshalBinary decodes the protocol native message header.
|
|
func (h *Header) UnmarshalBinary(data []byte) error {
|
|
if len(data) != SizeHeader {
|
|
return ErrBadHeader
|
|
}
|
|
h.unmarshalBinary(([SizeHeader]byte)(data))
|
|
return nil
|
|
}
|