return "String(p)"
}
+var barray = [5]renamedUint8{1, 2, 3, 4, 5}
+var bslice = barray[:]
+
var b byte
var fmttests = []struct {
// arrays
{"%v", array, "[1 2 3 4 5]"},
{"%v", iarray, "[1 hello 2.5 <nil>]"},
+ {"%v", barray, "[1 2 3 4 5]"},
{"%v", &array, "&[1 2 3 4 5]"},
{"%v", &iarray, "&[1 hello 2.5 <nil>]"},
+ {"%v", &barray, "&[1 2 3 4 5]"},
// slices
{"%v", slice, "[1 2 3 4 5]"},
{"%v", islice, "[1 hello 2.5 <nil>]"},
+ {"%v", bslice, "[1 2 3 4 5]"},
{"%v", &slice, "&[1 2 3 4 5]"},
{"%v", &islice, "&[1 hello 2.5 <nil>]"},
+ {"%v", &bslice, "&[1 2 3 4 5]"},
// complexes with %v
{"%v", 1 + 2i, "(1+2i)"},
{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
{"%#v", map[int]byte{}, `map[int]uint8{}`},
{"%#v", "foo", `"foo"`},
+ {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
+ {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
// slices with other formats
{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
{"%x", renamedString("thing"), "7468696e67"},
{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
{"%q", renamedBytes([]byte("hello")), `"hello"`},
+ {"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
+ {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
+ {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
{"%v", renamedFloat32(22), "22"},
{"%v", renamedFloat64(33), "33"},
{"%v", renamedComplex64(3 + 4i), "(3+4i)"},
}
}
-func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) {
+func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, typ reflect.Type, depth int) {
if verb == 'v' || verb == 'd' {
if goSyntax {
- p.buf.Write(bytesBytes)
+ if typ == nil {
+ p.buf.Write(bytesBytes)
+ } else {
+ p.buf.WriteString(typ.String())
+ p.buf.WriteByte('{')
+ }
} else {
p.buf.WriteByte('[')
}
p.fmtString(f, verb, goSyntax)
wasString = verb == 's' || verb == 'v'
case []byte:
- p.fmtBytes(f, verb, goSyntax, depth)
+ p.fmtBytes(f, verb, goSyntax, nil, depth)
wasString = verb == 's'
default:
// Restore flags in case handleMethods finds a Formatter.
}
case reflect.Array, reflect.Slice:
// Byte slices are special.
- if f.Type().Elem().Kind() == reflect.Uint8 {
- // We know it's a slice of bytes, but we also know it does not have static type
- // []byte, or it would have been caught above. Therefore we cannot convert
- // it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have
- // that type, and we can't write an expression of the right type and do a
- // conversion because we don't have a static way to write the right type.
- // So we build a slice by hand. This is a rare case but it would be nice
- // if reflection could help a little more.
- bytes := make([]byte, f.Len())
- for i := range bytes {
- bytes[i] = byte(f.Index(i).Uint())
+ if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 {
+ var bytes []byte
+ if f.Kind() == reflect.Slice {
+ bytes = f.Bytes()
+ } else if f.CanAddr() {
+ bytes = f.Slice(0, f.Len()).Bytes()
+ } else {
+ // We have an array, but we cannot Slice() a non-addressable array,
+ // so we build a slice by hand. This is a rare case but it would be nice
+ // if reflection could help a little more.
+ bytes = make([]byte, f.Len())
+ for i := range bytes {
+ bytes[i] = byte(f.Index(i).Uint())
+ }
}
- p.fmtBytes(bytes, verb, goSyntax, depth)
+ p.fmtBytes(bytes, verb, goSyntax, typ, depth)
wasString = verb == 's'
break
}