aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/bufio
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/bufio')
-rw-r--r--libgo/go/bufio/bufio.go3
-rw-r--r--libgo/go/bufio/bufio_test.go54
-rw-r--r--libgo/go/bufio/example_test.go16
-rw-r--r--libgo/go/bufio/scan.go2
4 files changed, 74 insertions, 1 deletions
diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go
index 0125d72..0f05d3b 100644
--- a/libgo/go/bufio/bufio.go
+++ b/libgo/go/bufio/bufio.go
@@ -197,6 +197,9 @@ func (b *Reader) Discard(n int) (discarded int, err error) {
func (b *Reader) Read(p []byte) (n int, err error) {
n = len(p)
if n == 0 {
+ if b.Buffered() > 0 {
+ return 0, nil
+ }
return 0, b.readErr()
}
if b.r == b.w {
diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go
index f7a0682..782ca21 100644
--- a/libgo/go/bufio/bufio_test.go
+++ b/libgo/go/bufio/bufio_test.go
@@ -1481,6 +1481,60 @@ func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
return &sr
}
+// eofReader returns the number of bytes read and io.EOF for the read that consumes the last of the content.
+type eofReader struct {
+ buf []byte
+}
+
+func (r *eofReader) Read(p []byte) (int, error) {
+ read := copy(p, r.buf)
+ r.buf = r.buf[read:]
+
+ switch read {
+ case 0, len(r.buf):
+ // As allowed in the documentation, this will return io.EOF
+ // in the same call that consumes the last of the data.
+ // https://godoc.org/io#Reader
+ return read, io.EOF
+ }
+
+ return read, nil
+}
+
+func TestPartialReadEOF(t *testing.T) {
+ src := make([]byte, 10)
+ eofR := &eofReader{buf: src}
+ r := NewReader(eofR)
+
+ // Start by reading 5 of the 10 available bytes.
+ dest := make([]byte, 5)
+ read, err := r.Read(dest)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if n := len(dest); read != n {
+ t.Fatalf("read %d bytes; wanted %d bytes", read, n)
+ }
+
+ // The Reader should have buffered all the content from the io.Reader.
+ if n := len(eofR.buf); n != 0 {
+ t.Fatalf("got %d bytes left in bufio.Reader source; want 0 bytes", n)
+ }
+ // To prove the point, check that there are still 5 bytes available to read.
+ if n := r.Buffered(); n != 5 {
+ t.Fatalf("got %d bytes buffered in bufio.Reader; want 5 bytes", n)
+ }
+
+ // This is the second read of 0 bytes.
+ read, err = r.Read([]byte{})
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if read != 0 {
+ t.Fatalf("read %d bytes; want 0 bytes", read)
+ }
+}
+
func BenchmarkReaderCopyOptimal(b *testing.B) {
// Optimal case is where the underlying reader implements io.WriterTo
srcBuf := bytes.NewBuffer(make([]byte, 8192))
diff --git a/libgo/go/bufio/example_test.go b/libgo/go/bufio/example_test.go
index 4666e6d..8885d40 100644
--- a/libgo/go/bufio/example_test.go
+++ b/libgo/go/bufio/example_test.go
@@ -31,6 +31,19 @@ func ExampleScanner_lines() {
}
}
+// Return the most recent call to Scan as a []byte.
+func ExampleScanner_Bytes() {
+ scanner := bufio.NewScanner(strings.NewReader("gopher"))
+ for scanner.Scan() {
+ fmt.Println(len(scanner.Bytes()) == 6)
+ }
+ if err := scanner.Err(); err != nil {
+ fmt.Fprintln(os.Stderr, "shouldn't see an error scanning a string")
+ }
+ // Output:
+ // true
+}
+
// Use a Scanner to implement a simple word-count utility by scanning the
// input as a sequence of space-delimited tokens.
func ExampleScanner_words() {
@@ -94,6 +107,9 @@ func ExampleScanner_emptyFinalToken() {
return i + 1, data[:i], nil
}
}
+ if !atEOF {
+ return 0, nil, nil
+ }
// There is one final token to be delivered, which may be the empty string.
// Returning bufio.ErrFinalToken here tells Scan there are no more tokens after this
// but does not trigger an error to be returned from Scan itself.
diff --git a/libgo/go/bufio/scan.go b/libgo/go/bufio/scan.go
index cefd261..4e787c4 100644
--- a/libgo/go/bufio/scan.go
+++ b/libgo/go/bufio/scan.go
@@ -73,7 +73,7 @@ var (
const (
// MaxScanTokenSize is the maximum size used to buffer a token
- // unless the user provides an explicit buffer with Scan.Buffer.
+ // unless the user provides an explicit buffer with Scanner.Buffer.
// The actual maximum token size may be smaller as the buffer
// may need to include, for instance, a newline.
MaxScanTokenSize = 64 * 1024