Skip to content

Commit

Permalink
all: use strings.Builder instead of bytes.Buffer where appropriate
Browse files Browse the repository at this point in the history
I grepped for "bytes.Buffer" and "buf.String" and mostly ignored test
files. I skipped a few on purpose and probably missed a few others,
but otherwise I think this should be most of them.

Updates #18990

Change-Id: I5a6ae4296b87b416d8da02d7bfaf981d8cc14774
Reviewed-on: https://go-review.googlesource.com/102479
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
  • Loading branch information
bradfitz committed Mar 26, 2018
1 parent f0eca37 commit 48db2c0
Show file tree
Hide file tree
Showing 16 changed files with 56 additions and 86 deletions.
3 changes: 1 addition & 2 deletions src/archive/tar/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package tar

import (
"bytes"
"fmt"
"io"
"path"
Expand Down Expand Up @@ -176,7 +175,7 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
sort.Strings(keys)

// Write each record to a buffer.
var buf bytes.Buffer
var buf strings.Builder
for _, k := range keys {
rec, err := formatPAXRecord(k, paxHdrs[k])
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/cover/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"math"
"os"
"path/filepath"
"strings"
)

// htmlOutput reads the profile data from profile and generates an HTML
Expand All @@ -41,7 +42,7 @@ func htmlOutput(profile, outfile string) error {
if err != nil {
return fmt.Errorf("can't read %q: %v", fn, err)
}
var buf bytes.Buffer
var buf strings.Builder
err = htmlGen(&buf, src, profile.Boundaries(src))
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions src/expvar/expvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
package expvar

import (
"bytes"
"encoding/json"
"fmt"
"log"
Expand All @@ -32,6 +31,7 @@ import (
"runtime"
"sort"
"strconv"
"strings"
"sync"
"sync/atomic"
)
Expand Down Expand Up @@ -111,7 +111,7 @@ type KeyValue struct {
}

func (v *Map) String() string {
var b bytes.Buffer
var b strings.Builder
fmt.Fprintf(&b, "{")
first := true
v.Do(func(kv KeyValue) {
Expand Down
4 changes: 2 additions & 2 deletions src/go/types/methodset.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
package types

import (
"bytes"
"fmt"
"sort"
"strings"
)

// A MethodSet is an ordered set of concrete or abstract (interface) methods;
Expand All @@ -24,7 +24,7 @@ func (s *MethodSet) String() string {
return "MethodSet {}"
}

var buf bytes.Buffer
var buf strings.Builder
fmt.Fprintln(&buf, "MethodSet {")
for _, f := range s.list {
fmt.Fprintf(&buf, "\t%s\n", f)
Expand Down
56 changes: 17 additions & 39 deletions src/mime/encodedword.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"fmt"
"io"
"strings"
"sync"
"unicode"
"unicode/utf8"
)
Expand Down Expand Up @@ -51,16 +50,15 @@ func needsEncoding(s string) bool {

// encodeWord encodes a string into an encoded-word.
func (e WordEncoder) encodeWord(charset, s string) string {
buf := getBuffer()
defer putBuffer(buf)
var buf strings.Builder

e.openWord(buf, charset)
e.openWord(&buf, charset)
if e == BEncoding {
e.bEncode(buf, charset, s)
e.bEncode(&buf, charset, s)
} else {
e.qEncode(buf, charset, s)
e.qEncode(&buf, charset, s)
}
closeWord(buf)
closeWord(&buf)

return buf.String()
}
Expand All @@ -77,7 +75,7 @@ const (
var maxBase64Len = base64.StdEncoding.DecodedLen(maxContentLen)

// bEncode encodes s using base64 encoding and writes it to buf.
func (e WordEncoder) bEncode(buf *bytes.Buffer, charset, s string) {
func (e WordEncoder) bEncode(buf *strings.Builder, charset, s string) {
w := base64.NewEncoder(base64.StdEncoding, buf)
// If the charset is not UTF-8 or if the content is short, do not bother
// splitting the encoded-word.
Expand Down Expand Up @@ -109,7 +107,7 @@ func (e WordEncoder) bEncode(buf *bytes.Buffer, charset, s string) {

// qEncode encodes s using Q encoding and writes it to buf. It splits the
// encoded-words when necessary.
func (e WordEncoder) qEncode(buf *bytes.Buffer, charset, s string) {
func (e WordEncoder) qEncode(buf *strings.Builder, charset, s string) {
// We only split encoded-words when the charset is UTF-8.
if !isUTF8(charset) {
writeQString(buf, s)
Expand Down Expand Up @@ -139,7 +137,7 @@ func (e WordEncoder) qEncode(buf *bytes.Buffer, charset, s string) {
}

// writeQString encodes s using Q encoding and writes it to buf.
func writeQString(buf *bytes.Buffer, s string) {
func writeQString(buf *strings.Builder, s string) {
for i := 0; i < len(s); i++ {
switch b := s[i]; {
case b == ' ':
Expand All @@ -155,7 +153,7 @@ func writeQString(buf *bytes.Buffer, s string) {
}

// openWord writes the beginning of an encoded-word into buf.
func (e WordEncoder) openWord(buf *bytes.Buffer, charset string) {
func (e WordEncoder) openWord(buf *strings.Builder, charset string) {
buf.WriteString("=?")
buf.WriteString(charset)
buf.WriteByte('?')
Expand All @@ -164,12 +162,12 @@ func (e WordEncoder) openWord(buf *bytes.Buffer, charset string) {
}

// closeWord writes the end of an encoded-word into buf.
func closeWord(buf *bytes.Buffer) {
func closeWord(buf *strings.Builder) {
buf.WriteString("?=")
}

// splitWord closes the current encoded-word and opens a new one.
func (e WordEncoder) splitWord(buf *bytes.Buffer, charset string) {
func (e WordEncoder) splitWord(buf *strings.Builder, charset string) {
closeWord(buf)
buf.WriteByte(' ')
e.openWord(buf, charset)
Expand Down Expand Up @@ -224,10 +222,9 @@ func (d *WordDecoder) Decode(word string) (string, error) {
return "", err
}

buf := getBuffer()
defer putBuffer(buf)
var buf strings.Builder

if err := d.convert(buf, charset, content); err != nil {
if err := d.convert(&buf, charset, content); err != nil {
return "", err
}

Expand All @@ -243,8 +240,7 @@ func (d *WordDecoder) DecodeHeader(header string) (string, error) {
return header, nil
}

buf := getBuffer()
defer putBuffer(buf)
var buf strings.Builder

buf.WriteString(header[:i])
header = header[i:]
Expand Down Expand Up @@ -296,7 +292,7 @@ func (d *WordDecoder) DecodeHeader(header string) (string, error) {
buf.WriteString(header[:start])
}

if err := d.convert(buf, charset, content); err != nil {
if err := d.convert(&buf, charset, content); err != nil {
return "", err
}

Expand All @@ -322,7 +318,7 @@ func decode(encoding byte, text string) ([]byte, error) {
}
}

func (d *WordDecoder) convert(buf *bytes.Buffer, charset string, content []byte) error {
func (d *WordDecoder) convert(buf *strings.Builder, charset string, content []byte) error {
switch {
case strings.EqualFold("utf-8", charset):
buf.Write(content)
Expand All @@ -346,7 +342,7 @@ func (d *WordDecoder) convert(buf *bytes.Buffer, charset string, content []byte)
if err != nil {
return err
}
if _, err = buf.ReadFrom(r); err != nil {
if _, err = io.Copy(buf, r); err != nil {
return err
}
}
Expand Down Expand Up @@ -422,21 +418,3 @@ func fromHex(b byte) (byte, error) {
}
return 0, fmt.Errorf("mime: invalid hex byte %#02x", b)
}

var bufPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}

func getBuffer() *bytes.Buffer {
return bufPool.Get().(*bytes.Buffer)
}

func putBuffer(buf *bytes.Buffer) {
if buf.Len() > 1024 {
return
}
buf.Reset()
bufPool.Put(buf)
}
7 changes: 3 additions & 4 deletions src/mime/mediatype.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package mime

import (
"bytes"
"errors"
"fmt"
"sort"
Expand All @@ -19,7 +18,7 @@ import (
// When any of the arguments result in a standard violation then
// FormatMediaType returns the empty string.
func FormatMediaType(t string, param map[string]string) string {
var b bytes.Buffer
var b strings.Builder
if slash := strings.Index(t, "/"); slash == -1 {
if !isToken(t) {
return ""
Expand Down Expand Up @@ -167,7 +166,7 @@ func ParseMediaType(v string) (mediatype string, params map[string]string, err e

// Stitch together any continuations or things with stars
// (i.e. RFC 2231 things with stars: "foo*0" or "foo*")
var buf bytes.Buffer
var buf strings.Builder
for key, pieceMap := range continuation {
singlePartKey := key + "*"
if v, ok := pieceMap[singlePartKey]; ok {
Expand Down Expand Up @@ -265,7 +264,7 @@ func consumeValue(v string) (value, rest string) {
}

// parse a quoted-string
buffer := new(bytes.Buffer)
buffer := new(strings.Builder)
for i := 1; i < len(v); i++ {
r := v[i]
if r == '"' {
Expand Down
12 changes: 4 additions & 8 deletions src/net/http/cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package http

import (
"bytes"
"log"
"net"
"strconv"
Expand Down Expand Up @@ -143,7 +142,7 @@ func (c *Cookie) String() string {
if c == nil || !isCookieNameValid(c.Name) {
return ""
}
var b bytes.Buffer
var b strings.Builder
b.WriteString(sanitizeCookieName(c.Name))
b.WriteRune('=')
b.WriteString(sanitizeCookieValue(c.Value))
Expand All @@ -168,17 +167,14 @@ func (c *Cookie) String() string {
log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute", c.Domain)
}
}
var buf [len(TimeFormat)]byte
if validCookieExpires(c.Expires) {
b.WriteString("; Expires=")
b2 := b.Bytes()
b.Reset()
b.Write(c.Expires.UTC().AppendFormat(b2, TimeFormat))
b.Write(c.Expires.UTC().AppendFormat(buf[:0], TimeFormat))
}
if c.MaxAge > 0 {
b.WriteString("; Max-Age=")
b2 := b.Bytes()
b.Reset()
b.Write(strconv.AppendInt(b2, int64(c.MaxAge), 10))
b.Write(strconv.AppendInt(buf[:0], int64(c.MaxAge), 10))
} else if c.MaxAge < 0 {
b.WriteString("; Max-Age=0")
}
Expand Down
4 changes: 2 additions & 2 deletions src/net/http/httptest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package httptest

import (
"bytes"
"crypto/tls"
"crypto/x509"
"flag"
Expand All @@ -17,6 +16,7 @@ import (
"net/http"
"net/http/internal"
"os"
"strings"
"sync"
"time"
)
Expand Down Expand Up @@ -224,7 +224,7 @@ func (s *Server) Close() {
func (s *Server) logCloseHangDebugInfo() {
s.mu.Lock()
defer s.mu.Unlock()
var buf bytes.Buffer
var buf strings.Builder
buf.WriteString("httptest.Server blocked in Close after 5 seconds, waiting for connections:\n")
for c, st := range s.conns {
fmt.Fprintf(&buf, " %T %p %v in state %v\n", c, c, c.RemoteAddr(), st)
Expand Down
3 changes: 1 addition & 2 deletions src/net/mail/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package mail

import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -735,7 +734,7 @@ func isQtext(r rune) bool {

// quoteString renders a string as an RFC 5322 quoted-string.
func quoteString(s string) string {
var buf bytes.Buffer
var buf strings.Builder
buf.WriteByte('"')
for _, r := range s {
if isQtext(r) || isWSP(r) {
Expand Down
10 changes: 5 additions & 5 deletions src/net/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ package url
// contain references to issue numbers with details.

import (
"bytes"
"errors"
"fmt"
"sort"
Expand Down Expand Up @@ -737,7 +736,7 @@ func validOptionalPort(port string) bool {
// - if u.RawQuery is empty, ?query is omitted.
// - if u.Fragment is empty, #fragment is omitted.
func (u *URL) String() string {
var buf bytes.Buffer
var buf strings.Builder
if u.Scheme != "" {
buf.WriteString(u.Scheme)
buf.WriteByte(':')
Expand Down Expand Up @@ -878,20 +877,21 @@ func (v Values) Encode() string {
if v == nil {
return ""
}
var buf bytes.Buffer
var buf strings.Builder
keys := make([]string, 0, len(v))
for k := range v {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
vs := v[k]
prefix := QueryEscape(k) + "="
keyEscaped := QueryEscape(k)
for _, v := range vs {
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(prefix)
buf.WriteString(keyEscaped)
buf.WriteByte('=')
buf.WriteString(QueryEscape(v))
}
}
Expand Down
Loading

0 comments on commit 48db2c0

Please sign in to comment.