diff options
| author | Michael Stapelberg <stapelberg@debian.org> | 2013-03-04 21:27:43 +0100 |
|---|---|---|
| committer | Michael Stapelberg <michael@stapelberg.de> | 2013-03-04 21:27:43 +0100 |
| commit | ad47422646a18ffcb47cec916ef7393c923f2e76 (patch) | |
| tree | 7c7861fb3d9539d61c1dcfd5b8dadee974c25760 /src/pkg/io/io.go | |
| parent | 2c8d5d584a79781ca41bb6f4b396893fbbac5b97 (diff) | |
| parent | 04b08da9af0c450d645ab7389d1467308cfc2db8 (diff) | |
| download | golang-ad47422646a18ffcb47cec916ef7393c923f2e76.tar.gz | |
Merge tag 'upstream/1.1_hg20130304' into debian-sid
Upstream version 1.1~hg20130304
Diffstat (limited to 'src/pkg/io/io.go')
| -rw-r--r-- | src/pkg/io/io.go | 81 |
1 files changed, 37 insertions, 44 deletions
diff --git a/src/pkg/io/io.go b/src/pkg/io/io.go index 54bf159eb..23d05e575 100644 --- a/src/pkg/io/io.go +++ b/src/pkg/io/io.go @@ -130,11 +130,23 @@ type ReadWriteSeeker interface { } // ReaderFrom is the interface that wraps the ReadFrom method. +// +// ReadFrom reads data from r until EOF or error. +// The return value n is the number of bytes read. +// Any error except io.EOF encountered during the read is also returned. +// +// The Copy function uses ReaderFrom if available. type ReaderFrom interface { ReadFrom(r Reader) (n int64, err error) } // WriterTo is the interface that wraps the WriteTo method. +// +// WriteTo writes data to w until there's no more data to write or +// when an error occurs. The return value n is the number of bytes +// written. Any error encountered during the write is also returned. +// +// The Copy function uses WriterTo if available. type WriterTo interface { WriteTo(w Writer) (n int64, err error) } @@ -204,6 +216,11 @@ type ByteScanner interface { UnreadByte() error } +// ByteWriter is the interface that wraps the WriteByte method. +type ByteWriter interface { + WriteByte(c byte) error +} + // RuneReader is the interface that wraps the ReadRune method. // // ReadRune reads a single UTF-8 encoded Unicode character @@ -245,6 +262,7 @@ func WriteString(w Writer, s string) (n int, err error) { // If an EOF happens after reading fewer than min bytes, // ReadAtLeast returns ErrUnexpectedEOF. // If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer. +// On return, n >= min if and only if err == nil. func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) { if len(buf) < min { return 0, ErrShortBuffer @@ -254,12 +272,10 @@ func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) { nn, err = r.Read(buf[n:]) n += nn } - if err == EOF { - if n >= min { - err = nil - } else if n > 0 { - err = ErrUnexpectedEOF - } + if n >= min { + err = nil + } else if n > 0 && err == EOF { + err = ErrUnexpectedEOF } return } @@ -269,56 +285,28 @@ func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) { // The error is EOF only if no bytes were read. // If an EOF happens after reading some but not all the bytes, // ReadFull returns ErrUnexpectedEOF. +// On return, n == len(buf) if and only if err == nil. func ReadFull(r Reader, buf []byte) (n int, err error) { return ReadAtLeast(r, buf, len(buf)) } // CopyN copies n bytes (or until an error) from src to dst. // It returns the number of bytes copied and the earliest -// error encountered while copying. Because Read can -// return the full amount requested as well as an error -// (including EOF), so can CopyN. +// error encountered while copying. +// On return, written == n if and only if err == nil. // // If dst implements the ReaderFrom interface, // the copy is implemented using it. func CopyN(dst Writer, src Reader, n int64) (written int64, err error) { - // If the writer has a ReadFrom method, use it to do the copy. - // Avoids a buffer allocation and a copy. - if rt, ok := dst.(ReaderFrom); ok { - written, err = rt.ReadFrom(LimitReader(src, n)) - if written < n && err == nil { - // rt stopped early; must have been EOF. - err = EOF - } - return + written, err = Copy(dst, LimitReader(src, n)) + if written == n { + return n, nil } - buf := make([]byte, 32*1024) - for written < n { - l := len(buf) - if d := n - written; d < int64(l) { - l = int(d) - } - nr, er := src.Read(buf[0:l]) - if nr > 0 { - nw, ew := dst.Write(buf[0:nr]) - if nw > 0 { - written += int64(nw) - } - if ew != nil { - err = ew - break - } - if nr != nw { - err = ErrShortWrite - break - } - } - if er != nil { - err = er - break - } + if written < n && err == nil { + // src stopped early; must have been EOF. + err = EOF } - return written, err + return } // Copy copies from src to dst until either EOF is reached @@ -451,6 +439,11 @@ func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) { off += s.base if max := s.limit - off; int64(len(p)) > max { p = p[0:max] + n, err = s.r.ReadAt(p, off) + if err == nil { + err = EOF + } + return n, err } return s.r.ReadAt(p, off) } |
