io: optimize BinWriter.WriteArray()
Replace reflect.MethodByName with a simple interface cast.
This commit is contained in:
parent
1784a14148
commit
f01fc1cc29
3 changed files with 13 additions and 17 deletions
|
@ -39,33 +39,26 @@ func (w *BinWriter) WriteBE(v interface{}) {
|
|||
func (w *BinWriter) WriteArray(arr interface{}) {
|
||||
switch val := reflect.ValueOf(arr); val.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
typ := val.Type().Elem()
|
||||
method, ok := typ.MethodByName("EncodeBinary")
|
||||
if !ok || !isEncodeBinaryMethod(method) {
|
||||
panic(typ.String() + " does not have EncodeBinary(*BinWriter)")
|
||||
}
|
||||
|
||||
if w.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
typ := val.Type().Elem()
|
||||
|
||||
w.WriteVarUint(uint64(val.Len()))
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
method := val.Index(i).MethodByName("EncodeBinary")
|
||||
method.Call([]reflect.Value{reflect.ValueOf(w)})
|
||||
el, ok := val.Index(i).Interface().(encodable)
|
||||
if !ok {
|
||||
panic(typ.String() + "is not encodable")
|
||||
}
|
||||
|
||||
el.EncodeBinary(w)
|
||||
}
|
||||
default:
|
||||
panic("not an array")
|
||||
}
|
||||
}
|
||||
|
||||
func isEncodeBinaryMethod(method reflect.Method) bool {
|
||||
t := method.Type
|
||||
return t != nil &&
|
||||
t.NumIn() == 2 && t.In(1) == reflect.TypeOf((*BinWriter)(nil)) &&
|
||||
t.NumOut() == 0
|
||||
}
|
||||
|
||||
// WriteVarUint writes a uint64 into the underlying writer using variable-length encoding.
|
||||
func (w *BinWriter) WriteVarUint(val uint64) {
|
||||
if w.Err != nil {
|
||||
|
|
|
@ -267,8 +267,7 @@ func TestBinWriter_WriteArray(t *testing.T) {
|
|||
require.Equal(t, w.Bytes(), []byte(nil))
|
||||
|
||||
w.Reset()
|
||||
w.Err = errors.New("error")
|
||||
require.Panics(t, func() { w.WriteArray([]int{}) })
|
||||
require.Panics(t, func() { w.WriteArray([]int{1}) })
|
||||
|
||||
w.Reset()
|
||||
w.Err = errors.New("error")
|
||||
|
|
|
@ -14,3 +14,7 @@ type Serializable interface {
|
|||
type decodable interface {
|
||||
DecodeBinary(*BinReader)
|
||||
}
|
||||
|
||||
type encodable interface {
|
||||
EncodeBinary(*BinWriter)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue