Commit 8dc0ba7a authored by Robert Hencke's avatar Robert Hencke Committed by Russ Cox

io: fixes for Read with n > 0, os.EOF

R=rsc
CC=golang-dev
https://golang.org/cl/4271080
parent 68ed122b
......@@ -182,16 +182,16 @@ func ReadAtLeast(r Reader, buf []byte, min int) (n int, err os.Error) {
if len(buf) < min {
return 0, ErrShortBuffer
}
for n < min {
nn, e := r.Read(buf[n:])
if nn > 0 {
n += nn
}
if e != nil {
if e == os.EOF && n > 0 {
e = ErrUnexpectedEOF
}
return n, e
for n < min && err == nil {
var nn int
nn, err = r.Read(buf[n:])
n += nn
}
if err == os.EOF {
if n >= min {
err = nil
} else if n > 0 {
err = ErrUnexpectedEOF
}
}
return
......
......@@ -118,27 +118,50 @@ func TestCopynEOF(t *testing.T) {
func TestReadAtLeast(t *testing.T) {
var rb bytes.Buffer
testReadAtLeast(t, &rb)
}
// A version of bytes.Buffer that returns n > 0, os.EOF on Read
// when the input is exhausted.
type dataAndEOFBuffer struct {
bytes.Buffer
}
func (r *dataAndEOFBuffer) Read(p []byte) (n int, err os.Error) {
n, err = r.Buffer.Read(p)
if n > 0 && r.Buffer.Len() == 0 && err == nil {
err = os.EOF
}
return
}
func TestReadAtLeastWithDataAndEOF(t *testing.T) {
var rb dataAndEOFBuffer
testReadAtLeast(t, &rb)
}
func testReadAtLeast(t *testing.T, rb ReadWriter) {
rb.Write([]byte("0123"))
buf := make([]byte, 2)
n, err := ReadAtLeast(&rb, buf, 2)
n, err := ReadAtLeast(rb, buf, 2)
if err != nil {
t.Error(err)
}
n, err = ReadAtLeast(&rb, buf, 4)
n, err = ReadAtLeast(rb, buf, 4)
if err != ErrShortBuffer {
t.Errorf("expected ErrShortBuffer got %v", err)
}
if n != 0 {
t.Errorf("expected to have read 0 bytes, got %v", n)
}
n, err = ReadAtLeast(&rb, buf, 1)
n, err = ReadAtLeast(rb, buf, 1)
if err != nil {
t.Error(err)
}
if n != 2 {
t.Errorf("expected to have read 2 bytes, got %v", n)
}
n, err = ReadAtLeast(&rb, buf, 2)
n, err = ReadAtLeast(rb, buf, 2)
if err != os.EOF {
t.Errorf("expected EOF, got %v", err)
}
......@@ -146,7 +169,7 @@ func TestReadAtLeast(t *testing.T) {
t.Errorf("expected to have read 0 bytes, got %v", n)
}
rb.Write([]byte("4"))
n, err = ReadAtLeast(&rb, buf, 2)
n, err = ReadAtLeast(rb, buf, 2)
if err != ErrUnexpectedEOF {
t.Errorf("expected ErrUnexpectedEOF, got %v", err)
}
......
......@@ -15,10 +15,8 @@ func (mr *multiReader) Read(p []byte) (n int, err os.Error) {
n, err = mr.readers[0].Read(p)
if n > 0 || err != os.EOF {
if err == os.EOF {
// This shouldn't happen.
// Well-behaved Readers should never
// return non-zero bytes read with an
// EOF. But if so, we clean it.
// Don't return EOF yet. There may be more bytes
// in the remaining readers.
err = nil
}
return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment