Skip to content

Commit

Permalink
(*Reader).ReadFull/ReadAtLeast, UnderlyingReader
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Apr 12, 2020
1 parent b4635b1 commit 256a099
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
36 changes: 36 additions & 0 deletions bufiox/bufio.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,40 @@ func Seek(b *bufio.Reader, offset int64, whence int) (int64, error) {
return 0, ErrSeekUnsupported
}

// ReadAtLeast reads from r into buf until it has read at least min bytes.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is EOF only if no bytes were read.
// 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.
// If r returns an error having read at least min bytes, the error is dropped.
func ReadAtLeast(r *bufio.Reader, buf []byte, min int) (n int, err error) {
if len(buf) < min {
return 0, io.ErrShortBuffer
}
for n < min && err == nil {
var nn int
nn, err = r.Read(buf[n:])
n += nn
}
if n >= min {
err = nil
} else if n > 0 && err == io.EOF {
err = io.ErrUnexpectedEOF
}
return
}

// ReadFull reads exactly len(buf) bytes from r into buf.
// It returns the number of bytes copied and an error if fewer bytes were read.
// 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.
// If r returns an error having read at least len(buf) bytes, the error is dropped.
func ReadFull(r *bufio.Reader, buf []byte) (n int, err error) {
return ReadAtLeast(r, buf, len(buf))
}

// -----------------------------------------------------------------------------
41 changes: 39 additions & 2 deletions bufiox/seek.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,45 @@ func NewReaderSize(rd io.ReadSeeker, size int) *Reader {
// relative to the end. Seek returns the new offset relative to the start
// of the file and an error, if any.
//
func (p *Reader) Seek(offset int64, whence int) (int64, error) {
return Seek(&p.Reader, offset, whence)
func (r *Reader) Seek(offset int64, whence int) (int64, error) {
return Seek(&r.Reader, offset, whence)
}

// ReadAtLeast reads from r into buf until it has read at least min bytes.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is EOF only if no bytes were read.
// 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.
// If r returns an error having read at least min bytes, the error is dropped.
func (r *Reader) ReadAtLeast(buf []byte, min int) (n int, err error) {
return ReadAtLeast(&r.Reader, buf, min)
}

// ReadFull reads exactly len(buf) bytes from r into buf.
// It returns the number of bytes copied and an error if fewer bytes were read.
// 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.
// If r returns an error having read at least len(buf) bytes, the error is dropped.
func (r *Reader) ReadFull(buf []byte) (n int, err error) {
return ReadAtLeast(&r.Reader, buf, len(buf))
}

// -----------------------------------------------------------------------------

// UnderlyingReader returns the underlying reader.
func UnderlyingReader(b interface{}) io.Reader {
switch v := b.(type) {
case *Reader:
return getUnderlyingReader(&v.Reader)
case *bufio.Reader:
return getUnderlyingReader(v)
default:
panic("can only to get the underlying reader of *bufiox.Reader or *bufio.Reader")
}
}

// -----------------------------------------------------------------------------

0 comments on commit 256a099

Please sign in to comment.