func New(buf []byte) (*PipeReader, *PipeWriter) {
	p := &pipe{
		buf:  bytes.NewBuffer(buf),
		cond: sync.NewCond(new(sync.Mutex)),
	}
	return &PipeReader{
			pipe: p,
		}, &PipeWriter{
			pipe: p,
		}
}
New creates a synchronous pipe using buf as its initial contents. It can be
used to connect code expecting an io.Reader with code expecting an io.Writer.

Unlike io.Pipe, writes never block because the internal buffer has variable
size. Reads block only when the buffer is empty.

It is safe to call Read and Write in parallel with each other or with Close.
Parallel calls to Read and parallel calls to Write are also safe: the
individual calls will be gated sequentially.

The new pipe takes ownership of buf, and the caller should not use buf after
this call. New is intended to prepare a PipeReader to read existing data. It
can also be used to set the initial size of the internal buffer for writing.
To do that, buf should have the desired capacity but a length of zero.
package bufpipe
import (
	"bytes"
	"errors"
	"io"
	"sync"
)
var ErrClosedPipe = errors.New("bufpipe: read/write on closed pipe")
type pipe struct {
	cond       *sync.Cond
	buf        *bytes.Buffer
	rerr, werr error
}
type PipeReader struct {
	*pipe
}
type PipeWriter struct {
	*pipe
}