internal/pipewire: use type name in error strings
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m44s
Test / Sandbox (race detector) (push) Successful in 4m39s
Test / Hakurei (push) Successful in 4m52s
Test / Hpkg (push) Successful in 4m53s
Test / Hakurei (race detector) (push) Successful in 6m28s
Test / Flake checks (push) Successful in 1m33s
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m44s
Test / Sandbox (race detector) (push) Successful in 4m39s
Test / Hakurei (push) Successful in 4m52s
Test / Hpkg (push) Successful in 4m53s
Test / Hakurei (race detector) (push) Successful in 6m28s
Test / Flake checks (push) Successful in 1m33s
This provides more useful messages for protocol errors. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
2c0b92771a
commit
69b1131d66
@ -128,15 +128,15 @@ func TestCorePing(t *testing.T) {
|
||||
// handmade sample
|
||||
{"sample", []byte{
|
||||
/* size: rest of data */ 0x20, 0, 0, 0,
|
||||
/* type: Struct */ pipewire.SPA_TYPE_Struct, 0, 0, 0,
|
||||
/* type: Struct */ byte(pipewire.SPA_TYPE_Struct), 0, 0, 0,
|
||||
|
||||
/* size: 4 bytes */ 4, 0, 0, 0,
|
||||
/* type: Int */ pipewire.SPA_TYPE_Int, 0, 0, 0,
|
||||
/* type: Int */ byte(pipewire.SPA_TYPE_Int), 0, 0, 0,
|
||||
/* value: -1 */ 0xff, 0xff, 0xff, 0xff,
|
||||
/* padding */ 0, 0, 0, 0,
|
||||
|
||||
/* size: 4 bytes */ 4, 0, 0, 0,
|
||||
/* type: Int */ pipewire.SPA_TYPE_Int, 0, 0, 0,
|
||||
/* type: Int */ byte(pipewire.SPA_TYPE_Int), 0, 0, 0,
|
||||
/* value: 0 */ 0, 0, 0, 0,
|
||||
/* padding */ 0, 0, 0, 0,
|
||||
}, pipewire.CorePing{
|
||||
@ -257,15 +257,15 @@ func TestCorePong(t *testing.T) {
|
||||
// handmade sample
|
||||
{"sample", []byte{
|
||||
/* size: rest of data */ 0x20, 0, 0, 0,
|
||||
/* type: Struct */ pipewire.SPA_TYPE_Struct, 0, 0, 0,
|
||||
/* type: Struct */ byte(pipewire.SPA_TYPE_Struct), 0, 0, 0,
|
||||
|
||||
/* size: 4 bytes */ 4, 0, 0, 0,
|
||||
/* type: Int */ pipewire.SPA_TYPE_Int, 0, 0, 0,
|
||||
/* type: Int */ byte(pipewire.SPA_TYPE_Int), 0, 0, 0,
|
||||
/* value: -1 */ 0xff, 0xff, 0xff, 0xff,
|
||||
/* padding */ 0, 0, 0, 0,
|
||||
|
||||
/* size: 4 bytes */ 4, 0, 0, 0,
|
||||
/* type: Int */ pipewire.SPA_TYPE_Int, 0, 0, 0,
|
||||
/* type: Int */ byte(pipewire.SPA_TYPE_Int), 0, 0, 0,
|
||||
/* value: 0 */ 0, 0, 0, 0,
|
||||
/* padding */ 0, 0, 0, 0,
|
||||
}, pipewire.CorePong{
|
||||
|
||||
@ -150,7 +150,7 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
||||
if v.CanInterface() {
|
||||
switch c := v.Interface().(type) {
|
||||
case Fd:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Fd)
|
||||
data = SPA_TYPE_Fd.append(data)
|
||||
data = binary.NativeEndian.AppendUint64(data, uint64(c))
|
||||
return data, nil
|
||||
}
|
||||
@ -158,22 +158,22 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Uint32:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Id)
|
||||
data = SPA_TYPE_Id.append(data)
|
||||
data = binary.NativeEndian.AppendUint32(data, Word(v.Uint()))
|
||||
return data, nil
|
||||
|
||||
case reflect.Int32:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Int)
|
||||
data = SPA_TYPE_Int.append(data)
|
||||
data = binary.NativeEndian.AppendUint32(data, Word(v.Int()))
|
||||
return data, nil
|
||||
|
||||
case reflect.Int64:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Long)
|
||||
data = SPA_TYPE_Long.append(data)
|
||||
data = binary.NativeEndian.AppendUint64(data, uint64(v.Int()))
|
||||
return data, nil
|
||||
|
||||
case reflect.Struct:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Struct)
|
||||
data = SPA_TYPE_Struct.append(data)
|
||||
var err error
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
data, err = marshalValueAppend(data, v.Field(i))
|
||||
@ -185,13 +185,13 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
||||
|
||||
case reflect.Pointer:
|
||||
if v.IsNil() {
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_None)
|
||||
data = SPA_TYPE_None.append(data)
|
||||
return data, nil
|
||||
}
|
||||
return marshalValueAppendRaw(data, v.Elem())
|
||||
|
||||
case reflect.String:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_String)
|
||||
data = SPA_TYPE_String.append(data)
|
||||
data = append(data, []byte(v.String())...)
|
||||
data = append(data, 0)
|
||||
return data, nil
|
||||
@ -359,7 +359,7 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error {
|
||||
if len(data) < SizePrefix {
|
||||
return UnexpectedEOFError{}
|
||||
}
|
||||
switch binary.NativeEndian.Uint32(data[SizeSPrefix:]) {
|
||||
switch SPAKind(binary.NativeEndian.Uint32(data[SizeSPrefix:])) {
|
||||
case SPA_TYPE_None:
|
||||
v.SetZero()
|
||||
return nil
|
||||
@ -404,15 +404,15 @@ func (e *InconsistentSizeError) Error() string {
|
||||
|
||||
// An UnexpectedTypeError describes an unexpected type encountered
|
||||
// in data passed to [Unmarshal].
|
||||
type UnexpectedTypeError struct{ Type, Expect Word }
|
||||
type UnexpectedTypeError struct{ Type, Expect SPAKind }
|
||||
|
||||
func (u *UnexpectedTypeError) Error() string {
|
||||
return "unexpected type: " + strconv.Itoa(int(u.Type)) + ", want " + strconv.Itoa(int(u.Expect))
|
||||
return "received " + u.Type.String() + " for a value of type " + u.Expect.String()
|
||||
}
|
||||
|
||||
// unmarshalCheckTypeBounds performs bounds checks on data and validates the type and size prefixes.
|
||||
// An expected size of zero skips further bounds checks.
|
||||
func unmarshalCheckTypeBounds(data *[]byte, t Word, sizeP *Word) error {
|
||||
func unmarshalCheckTypeBounds(data *[]byte, t SPAKind, sizeP *Word) error {
|
||||
if len(*data) < SizePrefix {
|
||||
return UnexpectedEOFError{}
|
||||
}
|
||||
@ -428,7 +428,7 @@ func unmarshalCheckTypeBounds(data *[]byte, t Word, sizeP *Word) error {
|
||||
return UnexpectedEOFError{}
|
||||
}
|
||||
|
||||
gotType := binary.NativeEndian.Uint32((*data)[SizeSPrefix:])
|
||||
gotType := SPAKind(binary.NativeEndian.Uint32((*data)[SizeSPrefix:]))
|
||||
if gotType != t {
|
||||
return &UnexpectedTypeError{gotType, t}
|
||||
}
|
||||
@ -491,7 +491,7 @@ func (d *SPADict) Size() Word {
|
||||
// MarshalPOD satisfies [PODMarshaler] as [SPADict] violates the POD type system.
|
||||
func (d *SPADict) MarshalPOD(data []byte) ([]byte, error) {
|
||||
return appendInner(data, func(dataPrefix []byte) (data []byte, err error) {
|
||||
data = binary.NativeEndian.AppendUint32(dataPrefix, SPA_TYPE_Struct)
|
||||
data = SPA_TYPE_Struct.append(dataPrefix)
|
||||
if data, err = MarshalAppend(data, Int(len(*d))); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,10 +1,24 @@
|
||||
package pipewire
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// A SPAKind describes the kind of data being encoded right after it.
|
||||
//
|
||||
// These do not always follow the same rules, and encoding/decoding
|
||||
// is very much context-dependent. Callers should therefore not
|
||||
// attempt to use these values directly and rely on [Marshal] and
|
||||
// [Unmarshal] and their variants instead.
|
||||
type SPAKind Word
|
||||
|
||||
/* Basic types */
|
||||
const (
|
||||
/* POD's can contain a number of basic SPA types: */
|
||||
|
||||
SPA_TYPE_START = 0x00000 + iota
|
||||
SPA_TYPE_START SPAKind = 0x00000 + iota
|
||||
|
||||
SPA_TYPE_None // No value or a NULL pointer.
|
||||
SPA_TYPE_Bool // A boolean value.
|
||||
SPA_TYPE_Id // An enumerated value.
|
||||
@ -35,6 +49,60 @@ const (
|
||||
_SPA_TYPE_LAST // not part of ABI
|
||||
)
|
||||
|
||||
// append appends the representation of [SPAKind] to data and returns the appended slice.
|
||||
func (kind SPAKind) append(data []byte) []byte {
|
||||
return binary.NativeEndian.AppendUint32(data, Word(kind))
|
||||
}
|
||||
|
||||
// String returns the name of the [SPAKind] for basic types.
|
||||
func (kind SPAKind) String() string {
|
||||
switch kind {
|
||||
case SPA_TYPE_None:
|
||||
return "None"
|
||||
case SPA_TYPE_Bool:
|
||||
return "Bool"
|
||||
case SPA_TYPE_Id:
|
||||
return "Id"
|
||||
case SPA_TYPE_Int:
|
||||
return "Int"
|
||||
case SPA_TYPE_Long:
|
||||
return "Long"
|
||||
case SPA_TYPE_Float:
|
||||
return "Float"
|
||||
case SPA_TYPE_Double:
|
||||
return "Double"
|
||||
case SPA_TYPE_String:
|
||||
return "String"
|
||||
case SPA_TYPE_Bytes:
|
||||
return "Bytes"
|
||||
case SPA_TYPE_Rectangle:
|
||||
return "Rectangle"
|
||||
case SPA_TYPE_Fraction:
|
||||
return "Fraction"
|
||||
case SPA_TYPE_Bitmap:
|
||||
return "Bitmap"
|
||||
case SPA_TYPE_Array:
|
||||
return "Array"
|
||||
case SPA_TYPE_Struct:
|
||||
return "Struct"
|
||||
case SPA_TYPE_Object:
|
||||
return "Object"
|
||||
case SPA_TYPE_Sequence:
|
||||
return "Sequence"
|
||||
case SPA_TYPE_Pointer:
|
||||
return "Pointer"
|
||||
case SPA_TYPE_Fd:
|
||||
return "Fd"
|
||||
case SPA_TYPE_Choice:
|
||||
return "Choice"
|
||||
case SPA_TYPE_Pod:
|
||||
return "Pod"
|
||||
|
||||
default:
|
||||
return fmt.Sprintf("invalid type field %#x", Word(kind))
|
||||
}
|
||||
}
|
||||
|
||||
/* Pointers */
|
||||
const (
|
||||
SPA_TYPE_POINTER_START = 0x10000 + iota
|
||||
|
||||
@ -3,10 +3,32 @@ package pipewire_test
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/internal/pipewire"
|
||||
)
|
||||
|
||||
func TestSPAKind(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
v pipewire.SPAKind
|
||||
want string
|
||||
}{
|
||||
{"invalid", 0xdeadbeef, "invalid type field 0xdeadbeef"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if got := tc.v.String(); got != tc.want {
|
||||
t.Errorf("String: %q, want %q", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// splitMessages splits concatenated messages into groups of
|
||||
// header, payload, footer of each individual message.
|
||||
// splitMessages panics on any decoding error.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user