func (cc *Reader) ReadLine() ([]byte, error) {
	for {
		nlidx := bytes.IndexByte(cc.buf[cc.searchFrom:cc.end], '\n')
		if nlidx != -1 {
			line := cc.buf[cc.start : cc.searchFrom+nlidx]
			cc.start = cc.searchFrom + nlidx + 1
			cc.searchFrom = cc.start
			if 0 < len(line) && line[len(line)-1] == '\r' {
				line = line[:len(line)-1]
			}
			return line, nil
		}
		if cc.start == 0 && cc.end == len(cc.buf) && len(cc.buf) == cc.maxSize {
			return nil, ErrReadQ
		}
		if cc.eof {
			return nil, io.EOF
		}
		if len(cc.buf) < cc.maxSize && (len(cc.buf)-(cc.end-cc.start) < cc.initialSize/2) {
			newLen := roundUpToPowerOfTwo(len(cc.buf) + 1)
			if newLen > cc.maxSize {
				newLen = cc.maxSize
			} else if newLen < cc.initialSize {
				newLen = cc.initialSize
			}
			newBuf := make([]byte, newLen)
			copy(newBuf, cc.buf[cc.start:cc.end])
			cc.buf = newBuf
		} else if cc.start != 0 {
			copy(cc.buf, cc.buf[cc.start:cc.end])
		}
		cc.end = cc.end - cc.start
		cc.start = 0
		cc.searchFrom = cc.end
		n, err := cc.conn.Read(cc.buf[cc.end:])
		cc.end += n
		if n != 0 && err == io.EOF {
			cc.eof = true
		} else if err != nil {
			return nil, err
		}
	}
}
Blocks until a full IRC line is read, then returns it. Accepts either \n
or \r\n as the line terminator (but not \r in isolation). Passes through
errors from the underlying connection. Returns ErrReadQ if the buffer limit
was exceeded without a terminating \n.
package ircreader
import (
	"bytes"
	"errors"
	"io"
)
var (
	ErrReadQ = errors.New("readQ exceeded (read too many bytes without terminating newline)")
)
type Reader struct {
	conn io.Reader
	initialSize int
	maxSize     int
	buf        []byte
	start      int  
	end        int  
	searchFrom int  
	eof        bool
}
func NewIRCReader(conn io.Reader) *Reader {
	var reader Reader
	reader.Initialize(conn, 512, 8192+1024)
	return &reader
}
func (cc *Reader) Initialize(conn io.Reader, initialSize, maxSize int) {
	*cc = Reader{}
	cc.conn = conn
	cc.initialSize = initialSize
	cc.maxSize = maxSize
}