}
func (e *Encoder) reflectString(s string) {
- b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10)
- e.write(b)
- e.writeString(":")
+ e.writeStringPrefix(int64(len(s)))
e.writeString(s)
}
-func (e *Encoder) reflectByteSlice(s []byte) {
- b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10)
+func (e *Encoder) writeStringPrefix(l int64) {
+ b := strconv.AppendInt(e.scratch[:0], l, 10)
e.write(b)
e.writeString(":")
+}
+
+func (e *Encoder) reflectByteSlice(s []byte) {
+ e.writeStringPrefix(int64(len(s)))
e.write(s)
}
return true
}
-var bigIntType = reflect.TypeOf(big.Int{})
+var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
func (e *Encoder) reflectValue(v reflect.Value) {
-
if e.reflectMarshaler(v) {
return
}
e.reflectValue(v.MapIndex(key))
}
e.writeString("e")
- case reflect.Slice:
- if v.Type().Elem().Kind() == reflect.Uint8 {
- s := v.Bytes()
- e.reflectByteSlice(s)
- break
- }
- if v.IsNil() {
- e.writeString("le")
- break
- }
- fallthrough
- case reflect.Array:
- e.writeString("l")
- for i, n := 0, v.Len(); i < n; i++ {
- e.reflectValue(v.Index(i))
- }
- e.writeString("e")
+ case reflect.Slice, reflect.Array:
+ e.reflectSequence(v)
case reflect.Interface:
e.reflectValue(v.Elem())
case reflect.Ptr:
}
}
+func (e *Encoder) reflectSequence(v reflect.Value) {
+ // Use bencode string-type
+ if v.Type().Elem().Kind() == reflect.Uint8 {
+ if v.Kind() != reflect.Slice {
+ // Can't use []byte optimization
+ if !v.CanAddr() {
+ e.writeStringPrefix(int64(v.Len()))
+ for i := 0; i < v.Len(); i++ {
+ var b [1]byte
+ b[0] = byte(v.Index(i).Uint())
+ e.write(b[:])
+ }
+ return
+ }
+ v = v.Slice(0, v.Len())
+ }
+ s := v.Bytes()
+ e.reflectByteSlice(s)
+ return
+ }
+ if v.IsNil() {
+ e.writeString("le")
+ return
+ }
+ e.writeString("l")
+ for i, n := 0, v.Len(); i < n; i++ {
+ e.reflectValue(v.Index(i))
+ }
+ e.writeString("e")
+}
+
type encodeField struct {
i func(v reflect.Value) reflect.Value
tag string