func (b *buffer) takeCompleteBuffer() []byte {
	if b.length > 0 {
		return nil
	}
	return b.buf
}
takeCompleteBuffer returns the complete existing buffer.
This can be used if the necessary buffer size is unknown.
Only one buffer (total) can be used at a time.
package mysql
import (
	"io"
	"net"
	"time"
)
const defaultBufSize = 4096
type buffer struct {
	buf     []byte
	nc      net.Conn
	idx     int
	length  int
	timeout time.Duration
}
func newBuffer(nc net.Conn) buffer {
	var b [defaultBufSize]byte
	return buffer{
		buf: b[:],
		nc:  nc,
	}
}
func (b *buffer) fill(need int) error {
	n := b.length
	if n > 0 && b.idx > 0 {
		copy(b.buf[0:n], b.buf[b.idx:])
	}
	if need > len(b.buf) {
		newBuf := make([]byte, ((need/defaultBufSize)+1)*defaultBufSize)
		copy(newBuf, b.buf)
		b.buf = newBuf
	}
	b.idx = 0
	for {
		if b.timeout > 0 {
			if err := b.nc.SetReadDeadline(time.Now().Add(b.timeout)); err != nil {
				return err
			}
		}
		nn, err := b.nc.Read(b.buf[n:])
		n += nn
		switch err {
		case nil:
			if n < need {
				continue
			}
			b.length = n
			return nil
		case io.EOF:
			if n >= need {
				b.length = n
				return nil
			}
			return io.ErrUnexpectedEOF
		default:
			return err
		}
	}
}
func (b *buffer) readNext(need int) ([]byte, error) {
	if b.length < need {
		if err := b.fill(need); err != nil {
			return nil, err
		}
	}
	offset := b.idx
	b.idx += need
	b.length -= need
	return b.buf[offset:b.idx], nil
}
func (b *buffer) takeBuffer(length int) []byte {
	if b.length > 0 {
		return nil
	}
	if length <= defaultBufSize || length <= cap(b.buf) {
		return b.buf[:length]
	}
	if length < maxPacketSize {
		b.buf = make([]byte, length)
		return b.buf
	}
	return make([]byte, length)
}
func (b *buffer) takeSmallBuffer(length int) []byte {
	if b.length > 0 {
		return nil
	}
	return b.buf[:length]
}