Skip to content

Commit 256a099

Browse files
committed
(*Reader).ReadFull/ReadAtLeast, UnderlyingReader
1 parent b4635b1 commit 256a099

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

bufiox/bufio.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,40 @@ func Seek(b *bufio.Reader, offset int64, whence int) (int64, error) {
9595
return 0, ErrSeekUnsupported
9696
}
9797

98+
// ReadAtLeast reads from r into buf until it has read at least min bytes.
99+
// It returns the number of bytes copied and an error if fewer bytes were read.
100+
// The error is EOF only if no bytes were read.
101+
// If an EOF happens after reading fewer than min bytes,
102+
// ReadAtLeast returns ErrUnexpectedEOF.
103+
// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
104+
// On return, n >= min if and only if err == nil.
105+
// If r returns an error having read at least min bytes, the error is dropped.
106+
func ReadAtLeast(r *bufio.Reader, buf []byte, min int) (n int, err error) {
107+
if len(buf) < min {
108+
return 0, io.ErrShortBuffer
109+
}
110+
for n < min && err == nil {
111+
var nn int
112+
nn, err = r.Read(buf[n:])
113+
n += nn
114+
}
115+
if n >= min {
116+
err = nil
117+
} else if n > 0 && err == io.EOF {
118+
err = io.ErrUnexpectedEOF
119+
}
120+
return
121+
}
122+
123+
// ReadFull reads exactly len(buf) bytes from r into buf.
124+
// It returns the number of bytes copied and an error if fewer bytes were read.
125+
// The error is EOF only if no bytes were read.
126+
// If an EOF happens after reading some but not all the bytes,
127+
// ReadFull returns ErrUnexpectedEOF.
128+
// On return, n == len(buf) if and only if err == nil.
129+
// If r returns an error having read at least len(buf) bytes, the error is dropped.
130+
func ReadFull(r *bufio.Reader, buf []byte) (n int, err error) {
131+
return ReadAtLeast(r, buf, len(buf))
132+
}
133+
98134
// -----------------------------------------------------------------------------

bufiox/seek.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,45 @@ func NewReaderSize(rd io.ReadSeeker, size int) *Reader {
4040
// relative to the end. Seek returns the new offset relative to the start
4141
// of the file and an error, if any.
4242
//
43-
func (p *Reader) Seek(offset int64, whence int) (int64, error) {
44-
return Seek(&p.Reader, offset, whence)
43+
func (r *Reader) Seek(offset int64, whence int) (int64, error) {
44+
return Seek(&r.Reader, offset, whence)
45+
}
46+
47+
// ReadAtLeast reads from r into buf until it has read at least min bytes.
48+
// It returns the number of bytes copied and an error if fewer bytes were read.
49+
// The error is EOF only if no bytes were read.
50+
// If an EOF happens after reading fewer than min bytes,
51+
// ReadAtLeast returns ErrUnexpectedEOF.
52+
// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
53+
// On return, n >= min if and only if err == nil.
54+
// If r returns an error having read at least min bytes, the error is dropped.
55+
func (r *Reader) ReadAtLeast(buf []byte, min int) (n int, err error) {
56+
return ReadAtLeast(&r.Reader, buf, min)
57+
}
58+
59+
// ReadFull reads exactly len(buf) bytes from r into buf.
60+
// It returns the number of bytes copied and an error if fewer bytes were read.
61+
// The error is EOF only if no bytes were read.
62+
// If an EOF happens after reading some but not all the bytes,
63+
// ReadFull returns ErrUnexpectedEOF.
64+
// On return, n == len(buf) if and only if err == nil.
65+
// If r returns an error having read at least len(buf) bytes, the error is dropped.
66+
func (r *Reader) ReadFull(buf []byte) (n int, err error) {
67+
return ReadAtLeast(&r.Reader, buf, len(buf))
68+
}
69+
70+
// -----------------------------------------------------------------------------
71+
72+
// UnderlyingReader returns the underlying reader.
73+
func UnderlyingReader(b interface{}) io.Reader {
74+
switch v := b.(type) {
75+
case *Reader:
76+
return getUnderlyingReader(&v.Reader)
77+
case *bufio.Reader:
78+
return getUnderlyingReader(v)
79+
default:
80+
panic("can only to get the underlying reader of *bufiox.Reader or *bufio.Reader")
81+
}
4582
}
4683

4784
// -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)