diff --git a/binary/README.md b/binary/README.md index cd8d7f2c1..ccdae119a 100644 --- a/binary/README.md +++ b/binary/README.md @@ -123,9 +123,8 @@ func GreeterEncoder(o interface{}, w io.Writer, n *int64, err *error) { } } -func GreeterDecoder(r *bytes.Reader, n *int64, err *error) interface{} { - // We must peek the type byte because ReadBinary() expects it. - switch t := PeekByte(r, n, err); t { +func GreeterDecoder(r Unreader, n *int64, err *error) interface{} { + switch t := ReadByte(r, n, err); t { case GreeterTypeDog: return ReadBinary(Dog{}, r, n, err) case GreeterTypeCat: @@ -149,7 +148,7 @@ Sometimes you want to always prefix a globally unique type byte while encoding, whether or not the declared type is an interface or concrete type. In this case, you can declare a "TypeByte() byte" function on the struct (as a value receiver, not a pointer receiver!), and you can skip the declaration of -a custom decoder. +a custom encoder. The decoder must "peek" the byte instead of consuming it. ```go @@ -161,6 +160,19 @@ type Cat struct{} func (c Cat) TypeByte() byte { return GreeterTypeCat } func (c Cat) Greet() string { return "Meow!" } +func GreeterDecoder(r Unreader, n *int64, err *error) interface{} { + // We must peek the type byte because ReadBinary() expects it. + switch t := PeekByte(r, n, err); t { + case GreeterTypeDog: + return ReadBinary(Dog{}, r, n, err) + case GreeterTypeCat: + return ReadBinary(Cat{}, r, n, err) + default: + *err = errors.New(fmt.Sprintf("Unknown greeter type byte %X", t)) + return nil + } +} + var _ = RegisterType(&TypeInfo{ Type: reflect.TypeOf((*Greeter)(nil)).Elem(), Decoder: GreeterDecoder,