func (s *reader) NextMsgLen() (int, error) {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.nextMsgLen()
}
NextMsgLen reads the length of the next msg into s.lbuf, and returns it.
WARNING: like Read, NextMsgLen is destructive. It reads from the internal
reader.
package msgio
import (
	"errors"
	"io"
	"sync"
	mpool "github.com/jbenet/go-msgio/mpool"
)
var ErrMsgTooLarge = errors.New("message too large")
const (
	lengthSize     = 4
	defaultMaxSize = 8 * 1024 * 1024  
)
type Writer interface {
	Write([]byte) (int, error)
	WriteMsg([]byte) error
}
type WriteCloser interface {
	Writer
	io.Closer
}
type Reader interface {
	Read([]byte) (int, error)
	ReadMsg() ([]byte, error)
	ReleaseMsg([]byte)
	NextMsgLen() (int, error)
}
type ReadCloser interface {
	Reader
	io.Closer
}
type ReadWriter interface {
	Reader
	Writer
}
type ReadWriteCloser interface {
	Reader
	Writer
	io.Closer
}
type writer struct {
	W io.Writer
	lock sync.Locker
}
func NewWriter(w io.Writer) WriteCloser {
	return &writer{W: w, lock: new(sync.Mutex)}
}
func (s *writer) Write(msg []byte) (int, error) {
	err := s.WriteMsg(msg)
	if err != nil {
		return 0, err
	}
	return len(msg), nil
}
func (s *writer) WriteMsg(msg []byte) (err error) {
	s.lock.Lock()
	defer s.lock.Unlock()
	if err := WriteLen(s.W, len(msg)); err != nil {
		return err
	}
	_, err = s.W.Write(msg)
	return err
}
func (s *writer) Close() error {
	s.lock.Lock()
	defer s.lock.Unlock()
	if c, ok := s.W.(io.Closer); ok {
		return c.Close()
	}
	return nil
}
type reader struct {
	R io.Reader
	lbuf []byte
	next int
	pool *mpool.Pool
	lock sync.Locker
	max  int  
}
func NewReader(r io.Reader) ReadCloser {
	return NewReaderWithPool(r, &mpool.ByteSlicePool)
}
func NewReaderWithPool(r io.Reader, p *mpool.Pool) ReadCloser {
	if p == nil {
		panic("nil pool")
	}
	return &reader{
		R:    r,
		lbuf: make([]byte, lengthSize),
		next: -1,
		pool: p,
		lock: new(sync.Mutex),
		max:  defaultMaxSize,
	}
}