1
0
mirror of https://github.com/golang/go synced 2024-11-21 22:04:39 -07:00

json: treat renamed byte slices the same as []byte

Fixes #2163.

R=rsc
CC=golang-dev
https://golang.org/cl/5488068
This commit is contained in:
Rob Pike 2011-12-14 11:03:28 -08:00
parent 465aba66c1
commit 34c7765fe5
2 changed files with 32 additions and 6 deletions

View File

@ -339,13 +339,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.WriteString("null") e.WriteString("null")
break break
} }
// Slices can be marshalled as nil, but otherwise are handled if v.Type().Elem().Kind() == reflect.Uint8 {
// as arrays. // Byte slices get special treatment; arrays don't.
fallthrough s := v.Bytes()
case reflect.Array:
if v.Type() == byteSliceType {
e.WriteByte('"') e.WriteByte('"')
s := v.Interface().([]byte)
if len(s) < 1024 { if len(s) < 1024 {
// for small buffers, using Encode directly is much faster. // for small buffers, using Encode directly is much faster.
dst := make([]byte, base64.StdEncoding.EncodedLen(len(s))) dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
@ -361,6 +358,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.WriteByte('"') e.WriteByte('"')
break break
} }
// Slices can be marshalled as nil, but otherwise are handled
// as arrays.
fallthrough
case reflect.Array:
e.WriteByte('[') e.WriteByte('[')
n := v.Len() n := v.Len()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {

View File

@ -82,3 +82,28 @@ func TestStringTag(t *testing.T) {
t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2) t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
} }
} }
// byte slices are special even if they're renamed types.
type renamedByte byte
type renamedByteSlice []byte
type renamedRenamedByteSlice []renamedByte
func TestEncodeRenamedByteSlice(t *testing.T) {
s := renamedByteSlice("abc")
result, err := Marshal(s)
if err != nil {
t.Fatal(err)
}
expect := `"YWJj"`
if string(result) != expect {
t.Errorf(" got %s want %s", result, expect)
}
r := renamedRenamedByteSlice("abc")
result, err = Marshal(r)
if err != nil {
t.Fatal(err)
}
if string(result) != expect {
t.Errorf(" got %s want %s", result, expect)
}
}