Rewrite HomeKit client
This commit is contained in:
+27
-35
@@ -85,10 +85,6 @@ func appendValue(b []byte, tag byte, value reflect.Value) ([]byte, error) {
|
||||
v := value.Uint()
|
||||
return append(b, tag, 1, byte(v)), nil
|
||||
|
||||
case reflect.Int8:
|
||||
v := value.Int()
|
||||
return append(b, tag, 1, byte(v)), nil
|
||||
|
||||
case reflect.Uint16:
|
||||
v := value.Uint()
|
||||
return append(b, tag, 2, byte(v), byte(v>>8)), nil
|
||||
@@ -103,7 +99,13 @@ func appendValue(b []byte, tag byte, value reflect.Value) ([]byte, error) {
|
||||
|
||||
case reflect.String:
|
||||
v := value.String()
|
||||
b = append(b, tag, byte(len(v)))
|
||||
l := len(v) // support "big" string
|
||||
for ; l > 255; l -= 255 {
|
||||
b = append(b, tag, 255)
|
||||
b = append(b, v[:255]...)
|
||||
v = v[255:]
|
||||
}
|
||||
b = append(b, tag, byte(l))
|
||||
return append(b, v...), nil
|
||||
|
||||
case reflect.Array:
|
||||
@@ -117,19 +119,6 @@ func appendValue(b []byte, tag byte, value reflect.Value) ([]byte, error) {
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
// byte array
|
||||
if value.Type().Elem().Kind() == reflect.Uint8 {
|
||||
v := value.Bytes()
|
||||
l := len(v)
|
||||
for ; l > 255; l -= 255 {
|
||||
b = append(b, tag, 255)
|
||||
b = append(b, v[:255]...)
|
||||
v = v[255:]
|
||||
}
|
||||
b = append(b, tag, byte(l))
|
||||
return append(b, v...), nil
|
||||
}
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
if i > 0 {
|
||||
b = append(b, 0, 0)
|
||||
@@ -175,24 +164,30 @@ func Unmarshal(data []byte, v any) error {
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(v)
|
||||
kind := value.Type().Kind()
|
||||
kind := value.Kind()
|
||||
|
||||
if kind != reflect.Pointer {
|
||||
return errors.New("tlv8: value should be pointer: " + kind.String())
|
||||
}
|
||||
|
||||
value = value.Elem()
|
||||
kind = value.Type().Kind()
|
||||
kind = value.Kind()
|
||||
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
return unmarshalStruct(data, value)
|
||||
if kind == reflect.Interface {
|
||||
value = value.Elem()
|
||||
kind = value.Kind()
|
||||
}
|
||||
|
||||
return errors.New("tlv8: not implemented: " + kind.String())
|
||||
if kind != reflect.Struct {
|
||||
return errors.New("tlv8: not implemented: " + kind.String())
|
||||
}
|
||||
|
||||
return unmarshalStruct(data, value)
|
||||
}
|
||||
|
||||
func unmarshalStruct(b []byte, value reflect.Value) error {
|
||||
var waitSlice bool
|
||||
|
||||
for len(b) >= 2 {
|
||||
t := b[0]
|
||||
l := int(b[1])
|
||||
@@ -200,6 +195,7 @@ func unmarshalStruct(b []byte, value reflect.Value) error {
|
||||
// array item divider
|
||||
if t == 0 && l == 0 {
|
||||
b = b[2:]
|
||||
waitSlice = true
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -228,6 +224,13 @@ func unmarshalStruct(b []byte, value reflect.Value) error {
|
||||
return fmt.Errorf("tlv8: can't find T=%d,L=%d,V=%x for: %s", t, l, v, value.Type().Name())
|
||||
}
|
||||
|
||||
if waitSlice {
|
||||
if valueField.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("tlv8: should be slice T=%d,L=%d,V=%x for: %s", t, l, v, value.Type().Name())
|
||||
}
|
||||
waitSlice = false
|
||||
}
|
||||
|
||||
if err := unmarshalValue(v, valueField); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -244,12 +247,6 @@ func unmarshalValue(v []byte, value reflect.Value) error {
|
||||
}
|
||||
value.SetUint(uint64(v[0]))
|
||||
|
||||
case reflect.Int8:
|
||||
if len(v) != 1 {
|
||||
return errors.New("tlv8: wrong size: " + value.Type().Name())
|
||||
}
|
||||
value.SetInt(int64(v[0]))
|
||||
|
||||
case reflect.Uint16:
|
||||
if len(v) != 2 {
|
||||
return errors.New("tlv8: wrong size: " + value.Type().Name())
|
||||
@@ -280,11 +277,6 @@ func unmarshalValue(v []byte, value reflect.Value) error {
|
||||
return nil
|
||||
|
||||
case reflect.Slice:
|
||||
if value.Type().Elem().Kind() == reflect.Uint8 {
|
||||
value.SetBytes(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
i := growSlice(value)
|
||||
return unmarshalValue(v, value.Index(i))
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tlv8
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -36,3 +37,73 @@ func TestMarshal(t *testing.T) {
|
||||
|
||||
require.Equal(t, src, dst)
|
||||
}
|
||||
|
||||
func TestBytes(t *testing.T) {
|
||||
bytes := make([]byte, 255)
|
||||
for i := 0; i < len(bytes); i++ {
|
||||
bytes[i] = byte(i)
|
||||
}
|
||||
|
||||
type Struct struct {
|
||||
String string `tlv8:"1"`
|
||||
}
|
||||
src := Struct{
|
||||
String: string(bytes),
|
||||
}
|
||||
|
||||
b, err := Marshal(src)
|
||||
require.Nil(t, err)
|
||||
|
||||
var dst Struct
|
||||
err = Unmarshal(b, &dst)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, src, dst)
|
||||
require.Equal(t, bytes, []byte(dst.String))
|
||||
}
|
||||
|
||||
func TestVideoCodecParams(t *testing.T) {
|
||||
type VideoCodecParams struct {
|
||||
ProfileID []byte `tlv8:"1"`
|
||||
Level []byte `tlv8:"2"`
|
||||
PacketizationMode byte `tlv8:"3"`
|
||||
CVOEnabled []byte `tlv8:"4"`
|
||||
CVOID []byte `tlv8:"5"`
|
||||
}
|
||||
|
||||
src, err := hex.DecodeString("0101010201000000020102030100040100")
|
||||
require.Nil(t, err)
|
||||
|
||||
var v VideoCodecParams
|
||||
err = Unmarshal(src, &v)
|
||||
require.Nil(t, err)
|
||||
|
||||
dst, err := Marshal(v)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, src, dst)
|
||||
}
|
||||
|
||||
func TestInterface(t *testing.T) {
|
||||
type Struct struct {
|
||||
Byte byte `tlv8:"1"`
|
||||
}
|
||||
|
||||
src := Struct{
|
||||
Byte: 1,
|
||||
}
|
||||
var v1 any = &src
|
||||
|
||||
b, err := Marshal(v1)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, []byte{1, 1, 1}, b)
|
||||
|
||||
var dst Struct
|
||||
var v2 any = &dst
|
||||
|
||||
err = Unmarshal(b, v2)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, src, dst)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user