1
0
mirror of https://github.com/golang/go synced 2024-11-19 08:24:41 -07:00

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

R=rsc
CC=golang-dev
https://golang.org/cl/4271080
This commit is contained in:
Robert Hencke 2011-04-08 13:45:56 -04:00 committed by Russ Cox
parent 68ed122bf9
commit 8dc0ba7ae5
3 changed files with 40 additions and 19 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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