internal/proto: use strict ReadLine

This commit is contained in:
Vladimir Mihailenco 2019-08-14 11:09:02 +03:00
parent 61e0d1d527
commit e269de20cf
1 changed files with 25 additions and 10 deletions

View File

@ -44,27 +44,40 @@ func (r *Reader) Buffered() int {
return r.rd.Buffered() return r.rd.Buffered()
} }
func (r *Reader) Peek(n int) ([]byte, error) {
return r.rd.Peek(n)
}
func (r *Reader) Reset(rd io.Reader) { func (r *Reader) Reset(rd io.Reader) {
r.rd.Reset(rd) r.rd.Reset(rd)
} }
func (r *Reader) ReadLine() ([]byte, error) { func (r *Reader) ReadLine() ([]byte, error) {
line, isPrefix, err := r.rd.ReadLine() line, err := r.readLine()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if isPrefix {
return nil, bufio.ErrBufferFull
}
if len(line) == 0 {
return nil, fmt.Errorf("redis: reply is empty")
}
if isNilReply(line) { if isNilReply(line) {
return nil, Nil return nil, Nil
} }
return line, nil return line, nil
} }
// readLine that returns an error if:
// - there is a pending read error;
// - or line does not end with \r\n.
func (r *Reader) readLine() ([]byte, error) {
b, err := r.rd.ReadSlice('\n')
if err != nil {
return nil, err
}
if len(b) <= 2 || b[len(b)-1] != '\n' || b[len(b)-2] != '\r' {
return nil, fmt.Errorf("redis: invalid reply: %q", b)
}
b = b[:len(b)-2]
return b, nil
}
func (r *Reader) ReadReply(m MultiBulkParse) (interface{}, error) { func (r *Reader) ReadReply(m MultiBulkParse) (interface{}, error) {
line, err := r.ReadLine() line, err := r.ReadLine()
if err != nil { if err != nil {
@ -273,11 +286,13 @@ func (r *Reader) _readTmpBytesReply(line []byte) ([]byte, error) {
} }
func (r *Reader) buf(n int) []byte { func (r *Reader) buf(n int) []byte {
if d := n - cap(r._buf); d > 0 { if n <= cap(r._buf) {
r._buf = append(r._buf, make([]byte, d)...)
}
return r._buf[:n] return r._buf[:n]
} }
d := n - cap(r._buf)
r._buf = append(r._buf, make([]byte, d)...)
return r._buf
}
func isNilReply(b []byte) bool { func isNilReply(b []byte) bool {
return len(b) == 3 && return len(b) == 3 &&