rlp: fix encoding of arrays with byte element type

This commit is contained in:
Felix Lange 2015-01-30 16:52:48 +01:00
parent 410b35e913
commit 8c3095faf0
2 changed files with 27 additions and 1 deletions

View File

@ -301,8 +301,10 @@ func makeWriter(typ reflect.Type) (writer, error) {
return writeUint, nil return writeUint, nil
case kind == reflect.String: case kind == reflect.String:
return writeString, nil return writeString, nil
case kind == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 && !typ.Elem().Implements(encoderInterface): case kind == reflect.Slice && isByte(typ.Elem()):
return writeBytes, nil return writeBytes, nil
case kind == reflect.Array && isByte(typ.Elem()):
return writeByteArray, nil
case kind == reflect.Slice || kind == reflect.Array: case kind == reflect.Slice || kind == reflect.Array:
return makeSliceWriter(typ) return makeSliceWriter(typ)
case kind == reflect.Struct: case kind == reflect.Struct:
@ -314,6 +316,10 @@ func makeWriter(typ reflect.Type) (writer, error) {
} }
} }
func isByte(typ reflect.Type) bool {
return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface)
}
func writeUint(val reflect.Value, w *encbuf) error { func writeUint(val reflect.Value, w *encbuf) error {
i := val.Uint() i := val.Uint()
if i == 0 { if i == 0 {
@ -358,6 +364,20 @@ func writeBytes(val reflect.Value, w *encbuf) error {
return nil return nil
} }
func writeByteArray(val reflect.Value, w *encbuf) error {
if !val.CanAddr() {
// Slice requires the value to be addressable.
// Make it addressable by copying.
copy := reflect.New(val.Type()).Elem()
copy.Set(val)
val = copy
}
size := val.Len()
slice := val.Slice(0, size).Bytes()
w.encodeString(slice)
return nil
}
func writeString(val reflect.Value, w *encbuf) error { func writeString(val reflect.Value, w *encbuf) error {
s := val.String() s := val.String()
w.encodeStringHeader(len(s)) w.encodeStringHeader(len(s))

View File

@ -40,6 +40,8 @@ func (e *encodableReader) Read(b []byte) (int, error) {
panic("called") panic("called")
} }
type namedByteType byte
var ( var (
_ = Encoder(&testEncoder{}) _ = Encoder(&testEncoder{})
_ = Encoder(byteEncoder(0)) _ = Encoder(byteEncoder(0))
@ -102,6 +104,10 @@ var encTests = []encTest{
// byte slices, strings // byte slices, strings
{val: []byte{}, output: "80"}, {val: []byte{}, output: "80"},
{val: []byte{1, 2, 3}, output: "83010203"}, {val: []byte{1, 2, 3}, output: "83010203"},
{val: []namedByteType{1, 2, 3}, output: "83010203"},
{val: [...]namedByteType{1, 2, 3}, output: "83010203"},
{val: "", output: "80"}, {val: "", output: "80"},
{val: "dog", output: "83646F67"}, {val: "dog", output: "83646F67"},
{ {