From a42a906c420d7bb196cb8541e0ab65264a0b04b0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 12 Dec 2012 23:13:29 +0000 Subject: libgo: Update to current master library sources. From-SVN: r194460 --- libgo/go/bytes/buffer.go | 24 ++++++++++++++++-------- libgo/go/bytes/buffer_test.go | 35 +++++++++++++++++++++++++++++++++++ libgo/go/bytes/reader.go | 2 +- libgo/go/bytes/reader_test.go | 36 ++++++++++++++++++++++++++++++++---- 4 files changed, 84 insertions(+), 13 deletions(-) (limited to 'libgo/go/bytes') 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) + } +} -- cgit v1.2.1