internal/pipewire: implement string type
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m23s
Test / Hakurei (push) Successful in 3m14s
Test / Hpkg (push) Successful in 4m16s
Test / Sandbox (race detector) (push) Successful in 4m20s
Test / Hakurei (race detector) (push) Successful in 5m11s
Test / Flake checks (push) Successful in 1m39s
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m23s
Test / Hakurei (push) Successful in 3m14s
Test / Hpkg (push) Successful in 4m16s
Test / Sandbox (race detector) (push) Successful in 4m20s
Test / Hakurei (race detector) (push) Successful in 5m11s
Test / Flake checks (push) Successful in 1m39s
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:
@@ -135,6 +135,12 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
||||
}
|
||||
return marshalValueAppendRaw(data, v.Elem())
|
||||
|
||||
case reflect.String:
|
||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_String)
|
||||
data = append(data, []byte(v.String())...)
|
||||
data = append(data, 0)
|
||||
return data, nil
|
||||
|
||||
default:
|
||||
return data, &UnsupportedTypeError{v.Type()}
|
||||
}
|
||||
@@ -183,6 +189,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 +250,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()}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user