package proto

import (
	
	
	

	
)

const (
	ErrorReply  = '-'
	StatusReply = '+'
	IntReply    = ':'
	StringReply = '$'
	ArrayReply  = '*'
)
------------------------------------------------------------------------------

const Nil = RedisError("redis: nil")

type RedisError string

func ( RedisError) () string { return string() }

func (RedisError) () {}
------------------------------------------------------------------------------

type MultiBulkParse func(*Reader, int64) (interface{}, error)

type Reader struct {
	rd   *bufio.Reader
	_buf []byte
}

func ( io.Reader) *Reader {
	return &Reader{
		rd:   bufio.NewReader(),
		_buf: make([]byte, 64),
	}
}

func ( *Reader) () int {
	return .rd.Buffered()
}

func ( *Reader) ( int) ([]byte, error) {
	return .rd.Peek()
}

func ( *Reader) ( io.Reader) {
	.rd.Reset()
}

func ( *Reader) () ([]byte, error) {
	,  := .readLine()
	if  != nil {
		return nil, 
	}
	if isNilReply() {
		return nil, Nil
	}
	return , nil
}
readLine that returns an error if: - there is a pending read error; - or line does not end with \r\n.
func ( *Reader) () ([]byte, error) {
	,  := .rd.ReadSlice('\n')
	if  != nil {
		return nil, 
	}
	if len() <= 2 || [len()-1] != '\n' || [len()-2] != '\r' {
		return nil, fmt.Errorf("redis: invalid reply: %q", )
	}
	 = [:len()-2]
	return , nil
}

func ( *Reader) ( MultiBulkParse) (interface{}, error) {
	,  := .ReadLine()
	if  != nil {
		return nil, 
	}

	switch [0] {
	case ErrorReply:
		return nil, ParseErrorReply()
	case StatusReply:
		return string([1:]), nil
	case IntReply:
		return util.ParseInt([1:], 10, 64)
	case StringReply:
		return .readStringReply()
	case ArrayReply:
		,  := parseArrayLen()
		if  != nil {
			return nil, 
		}
		if  == nil {
			 := fmt.Errorf("redis: got %.100q, but multi bulk parser is nil", )
			return nil, 
		}
		return (, )
	}
	return nil, fmt.Errorf("redis: can't parse %.100q", )
}

func ( *Reader) () (int64, error) {
	,  := .ReadLine()
	if  != nil {
		return 0, 
	}
	switch [0] {
	case ErrorReply:
		return 0, ParseErrorReply()
	case IntReply:
		return util.ParseInt([1:], 10, 64)
	default:
		return 0, fmt.Errorf("redis: can't parse int reply: %.100q", )
	}
}

func ( *Reader) () (string, error) {
	,  := .ReadLine()
	if  != nil {
		return "", 
	}
	switch [0] {
	case ErrorReply:
		return "", ParseErrorReply()
	case StringReply:
		return .readStringReply()
	case StatusReply:
		return string([1:]), nil
	case IntReply:
		return string([1:]), nil
	default:
		return "", fmt.Errorf("redis: can't parse reply=%.100q reading string", )
	}
}

func ( *Reader) ( []byte) (string, error) {
	if isNilReply() {
		return "", Nil
	}

	,  := util.Atoi([1:])
	if  != nil {
		return "", 
	}

	 := make([]byte, +2)
	_,  = io.ReadFull(.rd, )
	if  != nil {
		return "", 
	}

	return util.BytesToString([:]), nil
}

func ( *Reader) ( MultiBulkParse) (interface{}, error) {
	,  := .ReadLine()
	if  != nil {
		return nil, 
	}
	switch [0] {
	case ErrorReply:
		return nil, ParseErrorReply()
	case ArrayReply:
		,  := parseArrayLen()
		if  != nil {
			return nil, 
		}
		return (, )
	default:
		return nil, fmt.Errorf("redis: can't parse array reply: %.100q", )
	}
}

func ( *Reader) () (int64, error) {
	,  := .ReadLine()
	if  != nil {
		return 0, 
	}
	switch [0] {
	case ErrorReply:
		return 0, ParseErrorReply()
	case ArrayReply:
		return parseArrayLen()
	default:
		return 0, fmt.Errorf("redis: can't parse array reply: %.100q", )
	}
}

func ( *Reader) () ([]string, uint64, error) {
	,  := .ReadArrayLen()
	if  != nil {
		return nil, 0, 
	}
	if  != 2 {
		return nil, 0, fmt.Errorf("redis: got %d elements in scan reply, expected 2", )
	}

	,  := .ReadUint()
	if  != nil {
		return nil, 0, 
	}

	,  = .ReadArrayLen()
	if  != nil {
		return nil, 0, 
	}

	 := make([]string, )
	for  := int64(0);  < ; ++ {
		,  := .ReadString()
		if  != nil {
			return nil, 0, 
		}
		[] = 
	}

	return , , 
}

func ( *Reader) () (int64, error) {
	,  := .readTmpBytesReply()
	if  != nil {
		return 0, 
	}
	return util.ParseInt(, 10, 64)
}

func ( *Reader) () (uint64, error) {
	,  := .readTmpBytesReply()
	if  != nil {
		return 0, 
	}
	return util.ParseUint(, 10, 64)
}

func ( *Reader) () (float64, error) {
	,  := .readTmpBytesReply()
	if  != nil {
		return 0, 
	}
	return util.ParseFloat(, 64)
}

func ( *Reader) () ([]byte, error) {
	,  := .ReadLine()
	if  != nil {
		return nil, 
	}
	switch [0] {
	case ErrorReply:
		return nil, ParseErrorReply()
	case StringReply:
		return ._readTmpBytesReply()
	case StatusReply:
		return [1:], nil
	default:
		return nil, fmt.Errorf("redis: can't parse string reply: %.100q", )
	}
}

func ( *Reader) ( []byte) ([]byte, error) {
	if isNilReply() {
		return nil, Nil
	}

	,  := util.Atoi([1:])
	if  != nil {
		return nil, 
	}

	 := .buf( + 2)
	_,  = io.ReadFull(.rd, )
	if  != nil {
		return nil, 
	}

	return [:], nil
}

func ( *Reader) ( int) []byte {
	if  <= cap(._buf) {
		return ._buf[:]
	}
	 :=  - cap(._buf)
	._buf = append(._buf, make([]byte, )...)
	return ._buf
}

func ( []byte) bool {
	return len() == 3 &&
		([0] == StringReply || [0] == ArrayReply) &&
		[1] == '-' && [2] == '1'
}

func ( []byte) error {
	return RedisError(string([1:]))
}

func ( []byte) (int64, error) {
	if isNilReply() {
		return 0, Nil
	}
	return util.ParseInt([1:], 10, 64)