func (b *Bounded) String() string {
	return string(b.Bytes())
}
String consumes all readable data on the ring buffer and returns it
as a string.
package ringio
import (
	"sync"
	"github.com/antifuchs/o"
)
type Bounded struct {
	sync.Mutex
	r         o.Ring
	buf       []byte
	overwrite bool
}
type byteSlice []byte
func (bs byteSlice) Len() int {
	return len(bs)
}
func New(cap uint, overwrite bool) *Bounded {
	buf := make([]byte, cap)
	ring := o.NewRingForSlice(byteSlice(buf))
	return &Bounded{r: ring, buf: buf, overwrite: overwrite}
}
func (b *Bounded) Write(p []byte) (n int, err error) {
	b.Lock()
	defer b.Unlock()
	n = len(p)
	reserve := uint(len(p))
	remaining := b.r.Capacity() - b.r.Size()
	if remaining < uint(len(p)) {
		if !b.overwrite {
			return 0, o.ErrFull
		}
		p = p[reserve-b.r.Capacity():]
		for i := uint(0); i <= b.r.Size(); i++ {
			_, _ = b.r.Shift()
		}
		reserve = uint(len(p))
	}
	first, second, _ := b.r.PushN(reserve)
	copy(b.buf[first.Start:first.End], p[0:first.Length()])
	copy(b.buf[second.Start:second.End], p[first.Length():])
	return
}
func (b *Bounded) Read(p []byte) (n int, err error) {
	b.Lock()
	defer b.Unlock()
	if b.r.Empty() {
		return 0, nil
	}
	n = int(b.r.Size())
	if n > len(p) {
		n = len(p)
	}
	var first, second o.Range
	first, second, err = b.r.ShiftN(uint(n))
	copy(p[0:first.Length()], b.buf[first.Start:first.End])
	copy(p[first.Length():], b.buf[second.Start:second.End])
	return
}
func (b *Bounded) reset() {
	b.r = o.NewRingForSlice(byteSlice(b.buf))
}
func (b *Bounded) Reset() {
	b.Lock()
	defer b.Unlock()
	b.reset()
}
func (b *Bounded) Bytes() []byte {
	b.Lock()
	defer b.Unlock()
	first, second := b.r.Consume()
	val := make([]byte, first.Length()+second.Length())
	copy(val, b.buf[first.Start:first.End])
	copy(val[first.End:], b.buf[second.Start:second.End])
	return val
}