func (b *Buffer) BuildBytes(reuse ...[]byte) []byte {
	if len(b.bufs) == 0 {
		ret := b.Buf
		b.toPool = nil
		b.Buf = nil
		return ret
	}
	var ret []byte
	size := b.Size()
	if len(reuse) == 1 && cap(reuse[0]) >= size {
		ret = reuse[0][:0]
	} else {
		ret = make([]byte, 0, size)
	}
	for _, buf := range b.bufs {
		ret = append(ret, buf...)
		putBuf(buf)
	}
	ret = append(ret, b.Buf...)
	putBuf(b.toPool)
	b.bufs = nil
	b.toPool = nil
	b.Buf = nil
	return ret
}
BuildBytes creates a single byte slice with all the contents of the buffer. Data is
copied if it does not fit in a single chunk. You can optionally provide one byte
slice as argument that it will try to reuse.
package buffer
import (
	"io"
	"net"
	"sync"
)
type PoolConfig struct {
	StartSize  int  
	PooledSize int  
	MaxSize    int  
}
var config = PoolConfig{
	StartSize:  128,
	PooledSize: 512,
	MaxSize:    32768,
}
var buffers = map[int]*sync.Pool{}
func initBuffers() {
	for l := config.PooledSize; l <= config.MaxSize; l *= 2 {
		buffers[l] = new(sync.Pool)
	}
}
func init() {
	initBuffers()
}
func Init(cfg PoolConfig) {
	config = cfg
	initBuffers()
}
func putBuf(buf []byte) {
	size := cap(buf)
	if size < config.PooledSize {
		return
	}
	if c := buffers[size]; c != nil {
		c.Put(buf[:0])
	}
}
func getBuf(size int) []byte {
	if size >= config.PooledSize {
		if c := buffers[size]; c != nil {
			v := c.Get()
			if v != nil {
				return v.([]byte)
			}
		}
	}
	return make([]byte, 0, size)
}
type Buffer struct {
	Buf []byte
	toPool []byte
	bufs   [][]byte
}
func (b *Buffer) EnsureSpace(s int) {
	if cap(b.Buf)-len(b.Buf) < s {
		b.ensureSpaceSlow(s)
	}
}
func (b *Buffer) ensureSpaceSlow(s int) {
	l := len(b.Buf)
	if l > 0 {
		if cap(b.toPool) != cap(b.Buf) {
			putBuf(b.toPool)
		}
		if cap(b.bufs) == 0 {
			b.bufs = make([][]byte, 0, 8)
		}
		b.bufs = append(b.bufs, b.Buf)
		l = cap(b.toPool) * 2
	} else {
		l = config.StartSize
	}
	if l > config.MaxSize {
		l = config.MaxSize
	}
	b.Buf = getBuf(l)
	b.toPool = b.Buf
}
func (b *Buffer) AppendByte(data byte) {
	b.EnsureSpace(1)
	b.Buf = append(b.Buf, data)
}
func (b *Buffer) AppendBytes(data []byte) {
	if len(data) <= cap(b.Buf)-len(b.Buf) {
		b.Buf = append(b.Buf, data...)  
	} else {
		b.appendBytesSlow(data)
	}
}
func (b *Buffer) appendBytesSlow(data []byte) {
	for len(data) > 0 {
		b.EnsureSpace(1)
		sz := cap(b.Buf) - len(b.Buf)
		if sz > len(data) {
			sz = len(data)
		}
		b.Buf = append(b.Buf, data[:sz]...)
		data = data[sz:]
	}
}
func (b *Buffer) AppendString(data string) {
	if len(data) <= cap(b.Buf)-len(b.Buf) {
		b.Buf = append(b.Buf, data...)  
	} else {
		b.appendStringSlow(data)
	}
}
func (b *Buffer) appendStringSlow(data string) {
	for len(data) > 0 {
		b.EnsureSpace(1)
		sz := cap(b.Buf) - len(b.Buf)
		if sz > len(data) {
			sz = len(data)
		}
		b.Buf = append(b.Buf, data[:sz]...)
		data = data[sz:]
	}
}
func (b *Buffer) Size() int {
	size := len(b.Buf)
	for _, buf := range b.bufs {
		size += len(buf)
	}
	return size
}
func (b *Buffer) DumpTo(w io.Writer) (written int, err error) {
	bufs := net.Buffers(b.bufs)
	if len(b.Buf) > 0 {
		bufs = append(bufs, b.Buf)
	}
	n, err := bufs.WriteTo(w)
	for _, buf := range b.bufs {
		putBuf(buf)
	}
	putBuf(b.toPool)
	b.bufs = nil
	b.Buf = nil
	b.toPool = nil
	return int(n), err
}