From: Matt Joiner Date: Mon, 23 Jul 2018 00:50:18 +0000 (+1000) Subject: bencode.Marshal: Get rid of the intermediate buffer X-Git-Tag: v1.0.0~64 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=2eb98189ff7a313bac8c4fbbddd6b082d3b47917;p=btrtrc.git bencode.Marshal: Get rid of the intermediate buffer --- diff --git a/bencode/api.go b/bencode/api.go index 6c311e11..15687a8c 100644 --- a/bencode/api.go +++ b/bencode/api.go @@ -1,7 +1,6 @@ package bencode import ( - "bufio" "bytes" "fmt" "io" @@ -111,11 +110,11 @@ type Unmarshaler interface { UnmarshalBencode([]byte) error } -// Marshal the value 'v' to the bencode form, return the result as []byte and an -// error if any. +// Marshal the value 'v' to the bencode form, return the result as []byte and +// an error if any. func Marshal(v interface{}) ([]byte, error) { var buf bytes.Buffer - e := Encoder{w: bufio.NewWriter(&buf)} + e := Encoder{w: &buf} err := e.Encode(v) if err != nil { return nil, err @@ -154,5 +153,5 @@ func NewDecoder(r io.Reader) *Decoder { } func NewEncoder(w io.Writer) *Encoder { - return &Encoder{w: bufio.NewWriter(w)} + return &Encoder{w: w} } diff --git a/bencode/encode.go b/bencode/encode.go index d6b6334f..2bbf0bad 100644 --- a/bencode/encode.go +++ b/bencode/encode.go @@ -17,11 +17,7 @@ func isEmptyValue(v reflect.Value) bool { } type Encoder struct { - w interface { - Flush() error - io.Writer - WriteString(string) (int, error) - } + w io.Writer scratch [64]byte } @@ -42,7 +38,7 @@ func (e *Encoder) Encode(v interface{}) (err error) { } }() e.reflectValue(reflect.ValueOf(v)) - return e.w.Flush() + return nil } type string_values []reflect.Value @@ -60,9 +56,10 @@ func (e *Encoder) write(s []byte) { } func (e *Encoder) writeString(s string) { - _, err := e.w.WriteString(s) - if err != nil { - panic(err) + for s != "" { + n := copy(e.scratch[:], s) + s = s[n:] + e.write(e.scratch[:n]) } } @@ -129,13 +126,13 @@ func (e *Encoder) reflectValue(v reflect.Value) { e.writeString("i0e") } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) e.writeString("i") + b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) e.write(b) e.writeString("e") case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) e.writeString("i") + b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) e.write(b) e.writeString("e") case reflect.String: