summaryrefslogtreecommitdiff
path: root/libgo/go/bytes
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-12-12 23:13:29 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-12-12 23:13:29 +0000
commita42a906c420d7bb196cb8541e0ab65264a0b04b0 (patch)
tree8c441679e35147b1e9bec048f733fc394fb0c161 /libgo/go/bytes
parentbc77608b97abcc4bb3171f08a71e34ae342e9f8d (diff)
downloadgcc-a42a906c420d7bb196cb8541e0ab65264a0b04b0.tar.gz
libgo: Update to current master library sources.
From-SVN: r194460
Diffstat (limited to 'libgo/go/bytes')
-rw-r--r--libgo/go/bytes/buffer.go24
-rw-r--r--libgo/go/bytes/buffer_test.go35
-rw-r--r--libgo/go/bytes/reader.go2
-rw-r--r--libgo/go/bytes/reader_test.go36
4 files changed, 84 insertions, 13 deletions
diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go
index efb9798ee01..3ae930384f6 100644
--- a/libgo/go/bytes/buffer.go
+++ b/libgo/go/bytes/buffer.go
@@ -360,16 +360,24 @@ func (b *Buffer) UnreadByte() error {
// ReadBytes returns err != nil if and only if the returned data does not end in
// delim.
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
+ slice, err := b.readSlice(delim)
+ // return a copy of slice. The buffer's backing array may
+ // be overwritten by later calls.
+ line = append(line, slice...)
+ return
+}
+
+// readSlice is like readBytes but returns a reference to internal buffer data.
+func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
i := IndexByte(b.buf[b.off:], delim)
- size := i + 1
+ end := b.off + i + 1
if i < 0 {
- size = len(b.buf) - b.off
+ end = len(b.buf)
err = io.EOF
}
- line = make([]byte, size)
- copy(line, b.buf[b.off:])
- b.off += size
- return
+ line = b.buf[b.off:end]
+ b.off = end
+ return line, err
}
// ReadString reads until the first occurrence of delim in the input,
@@ -379,8 +387,8 @@ func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
// ReadString returns err != nil if and only if the returned data does not end
// in delim.
func (b *Buffer) ReadString(delim byte) (line string, err error) {
- bytes, err := b.ReadBytes(delim)
- return string(bytes), err
+ slice, err := b.readSlice(delim)
+ return string(slice), err
}
// NewBuffer creates and initializes a new Buffer using buf as its initial
diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go
index 92e29146b32..c53544a74a0 100644
--- a/libgo/go/bytes/buffer_test.go
+++ b/libgo/go/bytes/buffer_test.go
@@ -375,6 +375,41 @@ func TestReadBytes(t *testing.T) {
}
}
+func TestReadString(t *testing.T) {
+ for _, test := range readBytesTests {
+ buf := NewBufferString(test.buffer)
+ var err error
+ for _, expected := range test.expected {
+ var s string
+ s, err = buf.ReadString(test.delim)
+ if s != expected {
+ t.Errorf("expected %q, got %q", expected, s)
+ }
+ if err != nil {
+ break
+ }
+ }
+ if err != test.err {
+ t.Errorf("expected error %v, got %v", test.err, err)
+ }
+ }
+}
+
+func BenchmarkReadString(b *testing.B) {
+ const n = 32 << 10
+
+ data := make([]byte, n)
+ data[n-1] = 'x'
+ b.SetBytes(int64(n))
+ for i := 0; i < b.N; i++ {
+ buf := NewBuffer(data)
+ _, err := buf.ReadString('x')
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
+
func TestGrow(t *testing.T) {
x := []byte{'x'}
y := []byte{'y'}
diff --git a/libgo/go/bytes/reader.go b/libgo/go/bytes/reader.go
index b34dfc11bff..77511b94555 100644
--- a/libgo/go/bytes/reader.go
+++ b/libgo/go/bytes/reader.go
@@ -125,7 +125,7 @@ func (r *Reader) Seek(offset int64, whence int) (int64, error) {
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
r.prevRune = -1
if r.i >= len(r.s) {
- return 0, io.EOF
+ return 0, nil
}
b := r.s[r.i:]
m, err := w.Write(b)
diff --git a/libgo/go/bytes/reader_test.go b/libgo/go/bytes/reader_test.go
index 66688188676..f0a3e26c4a7 100644
--- a/libgo/go/bytes/reader_test.go
+++ b/libgo/go/bytes/reader_test.go
@@ -8,6 +8,7 @@ import (
. "bytes"
"fmt"
"io"
+ "io/ioutil"
"os"
"testing"
)
@@ -88,16 +89,20 @@ 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])
+ for i := 0; i < 30; i += 3 {
+ var l int
+ if i > 0 {
+ l = len(data) / i
+ }
+ s := data[:l]
+ r := NewReader(testBytes[:l])
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)
+ t.Errorf("for length %d: got error = %v; want nil", l, err)
}
if b.String() != s {
t.Errorf("got string %q; want %q", b.String(), s)
@@ -107,3 +112,26 @@ func TestReaderWriteTo(t *testing.T) {
}
}
}
+
+// verify that copying from an empty reader always has the same results,
+// regardless of the presence of a WriteTo method.
+func TestReaderCopyNothing(t *testing.T) {
+ type nErr struct {
+ n int64
+ err error
+ }
+ type justReader struct {
+ io.Reader
+ }
+ type justWriter struct {
+ io.Writer
+ }
+ discard := justWriter{ioutil.Discard} // hide ReadFrom
+
+ var with, withOut nErr
+ with.n, with.err = io.Copy(discard, NewReader(nil))
+ withOut.n, withOut.err = io.Copy(discard, justReader{NewReader(nil)})
+ if with != withOut {
+ t.Errorf("behavior differs: with = %#v; without: %#v", with, withOut)
+ }
+}