internal/pipewire: implement string type
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m23s
Test / Hakurei (push) Successful in 3m13s
Test / Hpkg (push) Successful in 4m13s
Test / Sandbox (race detector) (push) Successful in 4m24s
Test / Hakurei (race detector) (push) Successful in 5m11s
Test / Flake checks (push) Successful in 1m28s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m23s
Test / Hakurei (push) Successful in 3m13s
Test / Hpkg (push) Successful in 4m13s
Test / Sandbox (race detector) (push) Successful in 4m24s
Test / Hakurei (race detector) (push) Successful in 5m11s
Test / Flake checks (push) Successful in 1m28s
This is still NUL terminated strings, and an extra NUL character on an 8-byte string does cause an extra 7 bytes of padding. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
d92de1c709
commit
a26f99460f
@ -183,6 +183,14 @@ func (e *TrailingGarbageError) Error() string {
|
||||
return "data has extra values starting with type " + strconv.Itoa(int(binary.NativeEndian.Uint32(e.Data[4:])))
|
||||
}
|
||||
|
||||
// A StringTerminationError describes an incorrectly terminated string
|
||||
// encountered during [Unmarshal].
|
||||
type StringTerminationError struct{ Value byte }
|
||||
|
||||
func (e StringTerminationError) Error() string {
|
||||
return "got byte " + strconv.Itoa(int(e.Value)) + " instead of NUL"
|
||||
}
|
||||
|
||||
// unmarshalValue implements [Unmarshal] on [reflect.Value].
|
||||
func unmarshalValue(data []byte, v reflect.Value, sizeP *Word) error {
|
||||
switch v.Kind() {
|
||||
@ -236,6 +244,25 @@ func unmarshalValue(data []byte, v reflect.Value, sizeP *Word) error {
|
||||
return unmarshalValue(data, v.Elem(), sizeP)
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
if err := unmarshalCheckTypeBounds(&data, SPA_TYPE_String, sizeP); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// string size, one extra NUL byte
|
||||
size := int(*sizeP)
|
||||
if len(data) < size {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
// the serialised strings still include NUL termination
|
||||
if data[size-1] != 0 {
|
||||
return StringTerminationError{data[size-1]}
|
||||
}
|
||||
|
||||
v.SetString(string(data[:size-1]))
|
||||
return nil
|
||||
|
||||
default:
|
||||
return &UnsupportedTypeError{v.Type()}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package pipewire_test
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -37,7 +38,7 @@ func (testCases encodingTestCases[V, S]) run(t *testing.T) {
|
||||
t.Fatalf("UnmarshalBinary: error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(&value, &tc.value) {
|
||||
t.Fatalf("UnmarshalBinary: %#v, want %#v", value, tc.value)
|
||||
t.Fatalf("UnmarshalBinary:\n%s\nwant\n%s", mustMarshalJSON(value), mustMarshalJSON(tc.value))
|
||||
}
|
||||
})
|
||||
|
||||
@ -53,3 +54,12 @@ func (testCases encodingTestCases[V, S]) run(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// mustMarshalJSON calls [json.Marshal] and returns the result.
|
||||
func mustMarshalJSON(v any) string {
|
||||
if data, err := json.Marshal(v); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
return string(data)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user