internal/pipewire: implement spa_dict type
All checks were successful
Test / Create distribution (push) Successful in 40s
Test / Sandbox (push) Successful in 2m33s
Test / Hakurei (push) Successful in 3m22s
Test / Hpkg (push) Successful in 4m18s
Test / Sandbox (race detector) (push) Successful in 4m35s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Flake checks (push) Successful in 1m26s
All checks were successful
Test / Create distribution (push) Successful in 40s
Test / Sandbox (push) Successful in 2m33s
Test / Hakurei (push) Successful in 3m22s
Test / Hpkg (push) Successful in 4m18s
Test / Sandbox (race detector) (push) Successful in 4m35s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Flake checks (push) Successful in 1m26s
This is a terrible type that defies the type system. It is implemented on the concrete type to avoid special cases. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
8f4a3bcf9f
commit
e51e81bb22
@ -360,6 +360,74 @@ func unmarshalCheckTypeBounds(data *[]byte, t Word, sizeP *Word) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPADictItem is an encoding-compatible representation of spa_dict_item.
|
||||||
|
type SPADictItem struct{ Key, Value string }
|
||||||
|
|
||||||
|
// SPADict is an encoding-compatible representation of spa_dict.
|
||||||
|
type SPADict struct {
|
||||||
|
NItems Int
|
||||||
|
Items []SPADictItem
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *SPADict) MarshalPOD() ([]byte, error) {
|
||||||
|
return appendInner(nil, func(data []byte) ([]byte, error) {
|
||||||
|
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Struct)
|
||||||
|
if extraData, err := Marshal(d.NItems); err != nil {
|
||||||
|
return data, err
|
||||||
|
} else {
|
||||||
|
data = append(data, extraData...)
|
||||||
|
}
|
||||||
|
for i := range d.Items {
|
||||||
|
if extraData, err := Marshal(d.Items[i].Key); err != nil {
|
||||||
|
return data, err
|
||||||
|
} else {
|
||||||
|
data = append(data, extraData...)
|
||||||
|
}
|
||||||
|
if extraData, err := Marshal(d.Items[i].Value); err != nil {
|
||||||
|
return data, err
|
||||||
|
} else {
|
||||||
|
data = append(data, extraData...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *SPADict) UnmarshalPOD(data []byte) (Word, error) {
|
||||||
|
var wireSize Word
|
||||||
|
if err := unmarshalCheckTypeBounds(&data, SPA_TYPE_Struct, &wireSize); err != nil {
|
||||||
|
return wireSize, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if size, err := Unmarshal(data, &d.NItems); err != nil {
|
||||||
|
return wireSize, err
|
||||||
|
} else {
|
||||||
|
// bounds check completed in successful call to Unmarshal
|
||||||
|
data = data[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Items = make([]SPADictItem, d.NItems)
|
||||||
|
for i := range d.Items {
|
||||||
|
if size, err := Unmarshal(data, &d.Items[i].Key); err != nil {
|
||||||
|
return wireSize, err
|
||||||
|
} else {
|
||||||
|
// bounds check completed in successful call to Unmarshal
|
||||||
|
data = data[size:]
|
||||||
|
}
|
||||||
|
if size, err := Unmarshal(data, &d.Items[i].Value); err != nil {
|
||||||
|
return wireSize, err
|
||||||
|
} else {
|
||||||
|
// bounds check completed in successful call to Unmarshal
|
||||||
|
data = data[size:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) != 0 {
|
||||||
|
return wireSize, &TrailingGarbageError{data}
|
||||||
|
}
|
||||||
|
return wireSize, nil
|
||||||
|
}
|
||||||
|
|
||||||
/* Pointers */
|
/* Pointers */
|
||||||
const (
|
const (
|
||||||
SPA_TYPE_POINTER_START = 0x10000 + iota
|
SPA_TYPE_POINTER_START = 0x10000 + iota
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user