]> Cypherpunks repositories - gostls13.git/commitdiff
io: fixes for Read with n > 0, os.EOF
authorRobert Hencke <robert.hencke@gmail.com>
Fri, 8 Apr 2011 17:45:56 +0000 (13:45 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 8 Apr 2011 17:45:56 +0000 (13:45 -0400)
R=rsc
CC=golang-dev
https://golang.org/cl/4271080

src/pkg/io/io.go
src/pkg/io/io_test.go
src/pkg/io/multi.go

index 3b8791897988399a7c9a7ec7db0373ef105a59a2..c0bc54d0d4e8c37f264942d233d6476055b13d56 100644 (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
index 4fcd85e693e9f4fe8514c8398494c7dc1bf0e5ae..bc4f354af40ed7b8cc54bbc81b0cd4f66b1dffb4 100644 (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)
        }
index 88e4f1b769886620b2a0eb3c3920fb784fd4b210..d702d46c725717f34a709b48dba5f0736a1f1bb0 100644 (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