diff --git a/pkg/io/binaryReader.go b/pkg/io/binaryReader.go index 645aee5c1..1283537b2 100644 --- a/pkg/io/binaryReader.go +++ b/pkg/io/binaryReader.go @@ -47,19 +47,14 @@ func (r *BinReader) ReadArray(t interface{}, maxSize ...int) { panic(value.Type().String() + " is not a pointer to a slice") } - sliceType := value.Elem().Type() - elemType := sliceType.Elem() - isPtr := elemType.Kind() == reflect.Ptr - if isPtr { - checkHasDecodeBinary(elemType) - } else { - checkHasDecodeBinary(reflect.PtrTo(elemType)) - } - if r.Err != nil { return } + sliceType := value.Elem().Type() + elemType := sliceType.Elem() + isPtr := elemType.Kind() == reflect.Ptr + ms := maxArraySize if len(maxSize) != 0 { ms = maxSize[0] @@ -82,27 +77,18 @@ func (r *BinReader) ReadArray(t interface{}, maxSize ...int) { } else { elem = arr.Index(i).Addr() } - method := elem.MethodByName("DecodeBinary") - method.Call([]reflect.Value{reflect.ValueOf(r)}) + + el, ok := elem.Interface().(decodable) + if !ok { + panic(elemType.String() + "is not decodable") + } + + el.DecodeBinary(r) } value.Elem().Set(arr) } -func checkHasDecodeBinary(v reflect.Type) { - method, ok := v.MethodByName("DecodeBinary") - if !ok || !isDecodeBinaryMethod(method) { - panic(v.String() + " does not have DecodeBinary(*io.BinReader)") - } -} - -func isDecodeBinaryMethod(method reflect.Method) bool { - t := method.Type - return t != nil && - t.NumIn() == 2 && t.In(1) == reflect.TypeOf((*BinReader)(nil)) && - t.NumOut() == 0 -} - // ReadBE reads from the underlying io.Reader // into the interface v in big-endian format. func (r *BinReader) ReadBE(v interface{}) { diff --git a/pkg/io/binaryrw_test.go b/pkg/io/binaryrw_test.go index 19a8c2a55..4ce265d2a 100644 --- a/pkg/io/binaryrw_test.go +++ b/pkg/io/binaryrw_test.go @@ -326,15 +326,10 @@ func TestBinReader_ReadArray(t *testing.T) { require.NoError(t, r.Err) require.Equal(t, []testSerializable{}, arrVal) - r = NewBinReaderFromBuf([]byte{0}) - r.Err = errors.New("error") - require.Panics(t, func() { r.ReadArray(&[]*int{}) }) + r = NewBinReaderFromBuf([]byte{1}) + require.Panics(t, func() { r.ReadArray(&[]int{1}) }) r = NewBinReaderFromBuf([]byte{0}) r.Err = errors.New("error") - require.Panics(t, func() { r.ReadArray(&[]int{}) }) - - r = NewBinReaderFromBuf([]byte{0}) - r.Err = errors.New("error") - require.Panics(t, func() { r.ReadArray(0) }) + require.Panics(t, func() { r.ReadArray(1) }) } diff --git a/pkg/io/serializable.go b/pkg/io/serializable.go index 8e132b86b..c878d8ddb 100644 --- a/pkg/io/serializable.go +++ b/pkg/io/serializable.go @@ -10,3 +10,7 @@ type Serializable interface { DecodeBinary(*BinReader) EncodeBinary(*BinWriter) } + +type decodable interface { + DecodeBinary(*BinReader) +}