mirror of
https://github.com/golang/go
synced 2024-11-26 04:47:57 -07:00
bytes, strings: add (*Reader).WriteTo
Fixes #4031. R=golang-dev, bradfitz, remyoudompheng, r, dave CC=golang-dev https://golang.org/cl/6632046
This commit is contained in:
parent
06d42690b6
commit
eae25d430d
@ -251,10 +251,10 @@ func TestReadFrom(t *testing.T) {
|
|||||||
func TestWriteTo(t *testing.T) {
|
func TestWriteTo(t *testing.T) {
|
||||||
var buf Buffer
|
var buf Buffer
|
||||||
for i := 3; i < 30; i += 3 {
|
for i := 3; i < 30; i += 3 {
|
||||||
s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
|
s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
|
||||||
var b Buffer
|
var b Buffer
|
||||||
buf.WriteTo(&b)
|
buf.WriteTo(&b)
|
||||||
empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
|
empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Reader implements the io.Reader, io.ReaderAt, io.Seeker,
|
// A Reader implements the io.Reader, io.ReaderAt, io.WriterTo, io.Seeker,
|
||||||
// io.ByteScanner, and io.RuneScanner interfaces by reading from
|
// io.ByteScanner, and io.RuneScanner interfaces by reading from
|
||||||
// a byte slice.
|
// a byte slice.
|
||||||
// Unlike a Buffer, a Reader is read-only and supports seeking.
|
// Unlike a Buffer, a Reader is read-only and supports seeking.
|
||||||
@ -121,5 +121,24 @@ func (r *Reader) Seek(offset int64, whence int) (int64, error) {
|
|||||||
return abs, nil
|
return abs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteTo implements the io.WriterTo interface.
|
||||||
|
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
r.prevRune = -1
|
||||||
|
if r.i >= len(r.s) {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
b := r.s[r.i:]
|
||||||
|
m, err := w.Write(b)
|
||||||
|
if m > len(b) {
|
||||||
|
panic("bytes.Reader.WriteTo: invalid Write count")
|
||||||
|
}
|
||||||
|
r.i += m
|
||||||
|
n = int64(m)
|
||||||
|
if m != len(b) && err == nil {
|
||||||
|
err = io.ErrShortWrite
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 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} }
|
||||||
|
@ -86,3 +86,24 @@ func TestReaderAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReaderWriteTo(t *testing.T) {
|
||||||
|
for i := 3; i < 30; i += 3 {
|
||||||
|
s := data[:len(data)/i]
|
||||||
|
r := NewReader(testBytes[:len(testBytes)/i])
|
||||||
|
var b Buffer
|
||||||
|
n, err := r.WriteTo(&b)
|
||||||
|
if expect := int64(len(s)); n != expect {
|
||||||
|
t.Errorf("got %v; want %v", n, expect)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("got error = %v; want nil", err)
|
||||||
|
}
|
||||||
|
if b.String() != s {
|
||||||
|
t.Errorf("got string %q; want %q", b.String(), s)
|
||||||
|
}
|
||||||
|
if r.Len() != 0 {
|
||||||
|
t.Errorf("reader contains %v bytes; want 0", r.Len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Reader implements the io.Reader, io.ReaderAt, io.Seeker,
|
// A Reader implements the io.Reader, io.ReaderAt, io.Seeker, io.WriterTo,
|
||||||
// io.ByteScanner, and io.RuneScanner interfaces by reading
|
// io.ByteScanner, and io.RuneScanner interfaces by reading
|
||||||
// from a string.
|
// from a string.
|
||||||
type Reader struct {
|
type Reader struct {
|
||||||
@ -120,6 +120,25 @@ func (r *Reader) Seek(offset int64, whence int) (int64, error) {
|
|||||||
return abs, nil
|
return abs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteTo implements the io.WriterTo interface.
|
||||||
|
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
r.prevRune = -1
|
||||||
|
if r.i >= len(r.s) {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
s := r.s[r.i:]
|
||||||
|
m, err := io.WriteString(w, s)
|
||||||
|
if m > len(s) {
|
||||||
|
panic("strings.Reader.WriteTo: invalid WriteString count")
|
||||||
|
}
|
||||||
|
r.i += m
|
||||||
|
n = int64(m)
|
||||||
|
if m != len(s) && err == nil {
|
||||||
|
err = io.ErrShortWrite
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 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} }
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package strings_test
|
package strings_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -86,3 +87,25 @@ func TestReaderAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteTo(t *testing.T) {
|
||||||
|
const str = "0123456789"
|
||||||
|
for i := 0; i < len(str); i++ {
|
||||||
|
s := str[i:]
|
||||||
|
r := strings.NewReader(s)
|
||||||
|
var b bytes.Buffer
|
||||||
|
n, err := r.WriteTo(&b)
|
||||||
|
if expect := int64(len(s)); n != expect {
|
||||||
|
t.Errorf("got %v; want %v", n, expect)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("got error = %v; want nil", err)
|
||||||
|
}
|
||||||
|
if b.String() != s {
|
||||||
|
t.Errorf("got string %q; want %q", b.String(), s)
|
||||||
|
}
|
||||||
|
if r.Len() != 0 {
|
||||||
|
t.Errorf("reader contains %v bytes; want 0", r.Len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user