summaryrefslogtreecommitdiff
path: root/libgo/go/bufio
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2015-10-31 00:59:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-10-31 00:59:47 +0000
commitaf146490bb04205107cb23e301ec7a8ff927b5fc (patch)
tree13beeaed3698c61903fe93fb1ce70bd9b18d4e7f /libgo/go/bufio
parent725e1be3406315d9bcc8195d7eef0a7082b3c7cc (diff)
downloadgcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.gz
runtime: Remove now unnecessary pad field from ParFor.
It is not needed due to the removal of the ctx field. Reviewed-on: https://go-review.googlesource.com/16525 From-SVN: r229616
Diffstat (limited to 'libgo/go/bufio')
-rw-r--r--libgo/go/bufio/bufio.go34
-rw-r--r--libgo/go/bufio/bufio_test.go146
-rw-r--r--libgo/go/bufio/scan.go2
3 files changed, 180 insertions, 2 deletions
diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go
index d3c68fe6fe5..3bbb933df35 100644
--- a/libgo/go/bufio/bufio.go
+++ b/libgo/go/bufio/bufio.go
@@ -144,6 +144,39 @@ func (b *Reader) Peek(n int) ([]byte, error) {
return b.buf[b.r : b.r+n], err
}
+// Discard skips the next n bytes, returning the number of bytes discarded.
+//
+// If Discard skips fewer than n bytes, it also returns an error.
+// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
+// reading from the underlying io.Reader.
+func (b *Reader) Discard(n int) (discarded int, err error) {
+ if n < 0 {
+ return 0, ErrNegativeCount
+ }
+ if n == 0 {
+ return
+ }
+ remain := n
+ for {
+ skip := b.Buffered()
+ if skip == 0 {
+ b.fill()
+ skip = b.Buffered()
+ }
+ if skip > remain {
+ skip = remain
+ }
+ b.r += skip
+ remain -= skip
+ if remain == 0 {
+ return n, nil
+ }
+ if b.err != nil {
+ return n - remain, b.readErr()
+ }
+ }
+}
+
// Read reads data into p.
// It returns the number of bytes read into p.
// It calls Read at most once on the underlying Reader,
@@ -367,7 +400,6 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err error) {
// accumulating full buffers.
var frag []byte
var full [][]byte
- err = nil
for {
var e error
diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go
index 550dac9173f..666c44e15a9 100644
--- a/libgo/go/bufio/bufio_test.go
+++ b/libgo/go/bufio/bufio_test.go
@@ -1268,6 +1268,135 @@ func TestWriterReset(t *testing.T) {
}
}
+func TestReaderDiscard(t *testing.T) {
+ tests := []struct {
+ name string
+ r io.Reader
+ bufSize int // 0 means 16
+ peekSize int
+
+ n int // input to Discard
+
+ want int // from Discard
+ wantErr error // from Discard
+
+ wantBuffered int
+ }{
+ {
+ name: "normal case",
+ r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+ peekSize: 16,
+ n: 6,
+ want: 6,
+ wantBuffered: 10,
+ },
+ {
+ name: "discard causing read",
+ r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+ n: 6,
+ want: 6,
+ wantBuffered: 10,
+ },
+ {
+ name: "discard all without peek",
+ r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+ n: 26,
+ want: 26,
+ wantBuffered: 0,
+ },
+ {
+ name: "discard more than end",
+ r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
+ n: 27,
+ want: 26,
+ wantErr: io.EOF,
+ wantBuffered: 0,
+ },
+ // Any error from filling shouldn't show up until we
+ // get past the valid bytes. Here we return we return 5 valid bytes at the same time
+ // as an error, but test that we don't see the error from Discard.
+ {
+ name: "fill error, discard less",
+ r: newScriptedReader(func(p []byte) (n int, err error) {
+ if len(p) < 5 {
+ panic("unexpected small read")
+ }
+ return 5, errors.New("5-then-error")
+ }),
+ n: 4,
+ want: 4,
+ wantErr: nil,
+ wantBuffered: 1,
+ },
+ {
+ name: "fill error, discard equal",
+ r: newScriptedReader(func(p []byte) (n int, err error) {
+ if len(p) < 5 {
+ panic("unexpected small read")
+ }
+ return 5, errors.New("5-then-error")
+ }),
+ n: 5,
+ want: 5,
+ wantErr: nil,
+ wantBuffered: 0,
+ },
+ {
+ name: "fill error, discard more",
+ r: newScriptedReader(func(p []byte) (n int, err error) {
+ if len(p) < 5 {
+ panic("unexpected small read")
+ }
+ return 5, errors.New("5-then-error")
+ }),
+ n: 6,
+ want: 5,
+ wantErr: errors.New("5-then-error"),
+ wantBuffered: 0,
+ },
+ // Discard of 0 shouldn't cause a read:
+ {
+ name: "discard zero",
+ r: newScriptedReader(), // will panic on Read
+ n: 0,
+ want: 0,
+ wantErr: nil,
+ wantBuffered: 0,
+ },
+ {
+ name: "discard negative",
+ r: newScriptedReader(), // will panic on Read
+ n: -1,
+ want: 0,
+ wantErr: ErrNegativeCount,
+ wantBuffered: 0,
+ },
+ }
+ for _, tt := range tests {
+ br := NewReaderSize(tt.r, tt.bufSize)
+ if tt.peekSize > 0 {
+ peekBuf, err := br.Peek(tt.peekSize)
+ if err != nil {
+ t.Errorf("%s: Peek(%d): %v", tt.name, tt.peekSize, err)
+ continue
+ }
+ if len(peekBuf) != tt.peekSize {
+ t.Errorf("%s: len(Peek(%d)) = %v; want %v", tt.name, tt.peekSize, len(peekBuf), tt.peekSize)
+ continue
+ }
+ }
+ discarded, err := br.Discard(tt.n)
+ if ge, we := fmt.Sprint(err), fmt.Sprint(tt.wantErr); discarded != tt.want || ge != we {
+ t.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt.name, tt.n, discarded, ge, tt.want, we)
+ continue
+ }
+ if bn := br.Buffered(); bn != tt.wantBuffered {
+ t.Errorf("%s: after Discard, Buffered = %d; want %d", tt.name, bn, tt.wantBuffered)
+ }
+ }
+
+}
+
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
type onlyReader struct {
io.Reader
@@ -1278,6 +1407,23 @@ type onlyWriter struct {
io.Writer
}
+// A scriptedReader is an io.Reader that executes its steps sequentially.
+type scriptedReader []func(p []byte) (n int, err error)
+
+func (sr *scriptedReader) Read(p []byte) (n int, err error) {
+ if len(*sr) == 0 {
+ panic("too many Read calls on scripted Reader. No steps remain.")
+ }
+ step := (*sr)[0]
+ *sr = (*sr)[1:]
+ return step(p)
+}
+
+func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
+ sr := scriptedReader(steps)
+ return &sr
+}
+
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/scan.go b/libgo/go/bufio/scan.go
index 364d1596139..7a349fa8fab 100644
--- a/libgo/go/bufio/scan.go
+++ b/libgo/go/bufio/scan.go
@@ -109,7 +109,7 @@ func (s *Scanner) Text() string {
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
-// Split panics if the split function returns 100 empty tokens without
+// Scan panics if the split function returns 100 empty tokens without
// advancing the input. This is a common error mode for scanners.
func (s *Scanner) Scan() bool {
// Loop until we have a token.