mirror of
https://github.com/golang/go
synced 2024-11-19 05:54:44 -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:
parent
68ed122bf9
commit
8dc0ba7ae5
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user