]> Cypherpunks repositories - gostls13.git/commitdiff
bufio: make Reader.Reset and Writer.Reset work on the zero value
authorJoe Tsai <joetsai@digital-static.net>
Wed, 4 Aug 2021 07:57:07 +0000 (00:57 -0700)
committerJoe Tsai <joetsai@digital-static.net>
Sat, 11 Sep 2021 04:44:12 +0000 (04:44 +0000)
For batch allocation reasons, it would be useful to nest a
bufio.Reader or bufio.Writer in a struct as a value,
rather than a pointer. When the Reset method is called,
have it use the default buffer size if the buffer is nil.

Fixes #45374

Change-Id: I80df18a13575431428a42ed150a1579de1282637
Reviewed-on: https://go-review.googlesource.com/c/go/+/345570
Trust: Joe Tsai <joetsai@digital-static.net>
Run-TryBot: Joe Tsai <joetsai@digital-static.net>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/bufio/bufio.go
src/bufio/bufio_test.go

index ec928e7ad69ed54d213d3a38d9efb011ff32eb82..391ecf46b339e23df728d659d63127734a7fce1a 100644 (file)
@@ -68,7 +68,12 @@ func (b *Reader) Size() int { return len(b.buf) }
 
 // Reset discards any buffered data, resets all state, and switches
 // the buffered reader to read from r.
+// Calling Reset on the zero value of Reader initializes the internal buffer
+// to the default size.
 func (b *Reader) Reset(r io.Reader) {
+       if b.buf == nil {
+               b.buf = make([]byte, defaultBufSize)
+       }
        b.reset(b.buf, r)
 }
 
@@ -590,7 +595,12 @@ func (b *Writer) Size() int { return len(b.buf) }
 
 // Reset discards any unflushed buffered data, clears any error, and
 // resets b to write its output to w.
+// Calling Reset on the zero value of Writer initializes the internal buffer
+// to the default size.
 func (b *Writer) Reset(w io.Writer) {
+       if b.buf == nil {
+               b.buf = make([]byte, defaultBufSize)
+       }
        b.err = nil
        b.n = 0
        b.wr = w
index ebcc711db9d48cdefa44d6ec9bddd2406c13b59d..eb5136c9ea858c7bf6b21a6eefc4bdcb1e9bba20 100644 (file)
@@ -1312,6 +1312,7 @@ func TestReaderReset(t *testing.T) {
        if string(buf) != "foo" {
                t.Errorf("buf = %q; want foo", buf)
        }
+
        r.Reset(strings.NewReader("bar bar"))
        all, err := io.ReadAll(r)
        if err != nil {
@@ -1320,12 +1321,23 @@ func TestReaderReset(t *testing.T) {
        if string(all) != "bar bar" {
                t.Errorf("ReadAll = %q; want bar bar", all)
        }
+
+       *r = Reader{} // zero out the Reader
+       r.Reset(strings.NewReader("bar bar"))
+       all, err = io.ReadAll(r)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if string(all) != "bar bar" {
+               t.Errorf("ReadAll = %q; want bar bar", all)
+       }
 }
 
 func TestWriterReset(t *testing.T) {
-       var buf1, buf2 bytes.Buffer
+       var buf1, buf2, buf3 bytes.Buffer
        w := NewWriter(&buf1)
        w.WriteString("foo")
+
        w.Reset(&buf2) // and not flushed
        w.WriteString("bar")
        w.Flush()
@@ -1335,6 +1347,17 @@ func TestWriterReset(t *testing.T) {
        if buf2.String() != "bar" {
                t.Errorf("buf2 = %q; want bar", buf2.String())
        }
+
+       *w = Writer{}  // zero out the Writer
+       w.Reset(&buf3) // and not flushed
+       w.WriteString("bar")
+       w.Flush()
+       if buf1.String() != "" {
+               t.Errorf("buf1 = %q; want empty", buf1.String())
+       }
+       if buf3.String() != "bar" {
+               t.Errorf("buf3 = %q; want bar", buf3.String())
+       }
 }
 
 func TestReaderDiscard(t *testing.T) {