1
0
mirror of https://github.com/golang/go synced 2024-11-19 04:54:41 -07:00

bytes, string: add Reset method to Reader

Currently, there is no easy allocation-free way to turn a
[]byte or string into an io.Reader. Thus, we add a Reset method
to bytes.Reader and strings.Reader to allow the reuse of these
Readers with another []byte or string.

This is consistent with the fact that many standard library io.Readers
already support a Reset method of some type:
	bufio.Reader
	flate.Reader
	gzip.Reader
	zlib.Reader
	debug/dwarf.LineReader
	bytes.Buffer
	crypto/rc4.Cipher

Fixes #15033

Change-Id: I456fd1af77af6ef0b4ac6228b058ac1458ff3d19
Reviewed-on: https://go-review.googlesource.com/21386
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Joe Tsai 2016-03-31 16:05:23 -07:00 committed by Brad Fitzpatrick
parent e6f36f0cd5
commit e88f89028a
4 changed files with 46 additions and 0 deletions

View File

@ -146,5 +146,8 @@ func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
// Reset resets the Reader to be reading from b.
func (r *Reader) Reset(b []byte) { *r = Reader{b, 0, -1} }
// NewReader returns a new Reader reading from b. // NewReader returns a new Reader reading from b.
func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} } func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }

View File

@ -256,3 +256,23 @@ func TestReaderLenSize(t *testing.T) {
t.Errorf("Size = %d; want 3", r.Size()) t.Errorf("Size = %d; want 3", r.Size())
} }
} }
func TestReaderReset(t *testing.T) {
r := NewReader([]byte("世界"))
if _, _, err := r.ReadRune(); err != nil {
t.Errorf("ReadRune: unexpected error: %v", err)
}
const want = "abcdef"
r.Reset([]byte(want))
if err := r.UnreadRune(); err == nil {
t.Errorf("UnreadRune: expected error, got nil")
}
buf, err := ioutil.ReadAll(r)
if err != nil {
t.Errorf("ReadAll: unexpected error: %v", err)
}
if got := string(buf); got != want {
t.Errorf("ReadAll: got %q, want %q", got, want)
}
}

View File

@ -145,6 +145,9 @@ func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
// Reset resets the Reader to be reading from s.
func (r *Reader) Reset(s string) { *r = Reader{s, 0, -1} }
// NewReader returns a new Reader reading from s. // NewReader returns a new Reader reading from s.
// It is similar to bytes.NewBufferString but more efficient and read-only. // It is similar to bytes.NewBufferString but more efficient and read-only.
func NewReader(s string) *Reader { return &Reader{s, 0, -1} } func NewReader(s string) *Reader { return &Reader{s, 0, -1} }

View File

@ -170,3 +170,23 @@ func TestReaderLenSize(t *testing.T) {
t.Errorf("Size = %d; want 3", r.Size()) t.Errorf("Size = %d; want 3", r.Size())
} }
} }
func TestReaderReset(t *testing.T) {
r := strings.NewReader("世界")
if _, _, err := r.ReadRune(); err != nil {
t.Errorf("ReadRune: unexpected error: %v", err)
}
const want = "abcdef"
r.Reset(want)
if err := r.UnreadRune(); err == nil {
t.Errorf("UnreadRune: expected error, got nil")
}
buf, err := ioutil.ReadAll(r)
if err != nil {
t.Errorf("ReadAll: unexpected error: %v", err)
}
if got := string(buf); got != want {
t.Errorf("ReadAll: got %q, want %q", got, want)
}
}