func ReadMessage(src io.ReadWriteCloser, dst *bytes.Buffer) (*Header, error) {
	header, err := readHeader(src)
	if err != nil {
		return nil, err
	}
	length := int64(header.MessageLength)
	nr, err := io.CopyN(dst, src, length)
	if err != nil {
		return nil, err
	}
	if nr != length {
		return nil, fmt.Errorf("byte count mismatch")
	}
	return header, nil
}
ReadMessage reads the whole message from src into the given bytes.Buffer.
Header can be used to determine message. Then you can pick an appropriate message
type and decode it.
package protocol
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"strings"
	"github.com/buraksezer/olric/internal/bufpool"
	"github.com/pkg/errors"
)
var Version1 uint8 = 1
var pool = bufpool.New()
type MagicCode uint8
type EncodeDecoder interface {
	Encode() error
	Decode() error
	SetStatus(StatusCode)
	Status() StatusCode
	SetValue([]byte)
	Value() []byte
	OpCode() OpCode
	SetBuffer(*bytes.Buffer)
	Buffer() *bytes.Buffer
	SetExtra(interface{})
	Extra() interface{}
	Response(*bytes.Buffer) EncodeDecoder
}
const HeaderLength int64 = 6
type Header struct {
	Magic         MagicCode  
	Version       uint8      
	MessageLength uint32     
}
func checkProtocolVersion(header *Header) error {
	switch header.Version {
	case Version1:
		return nil
	default:
		return fmt.Errorf("unsupported protocol version: %d", header.Version)
	}
}
func readHeader(conn io.ReadWriteCloser) (*Header, error) {
	buf := pool.Get()
	defer pool.Put(buf)
	var header Header
	_, err := io.CopyN(buf, conn, HeaderLength)
	if err != nil {
		return nil, filterNetworkErrors(err)
	}
	err = binary.Read(buf, binary.BigEndian, &header)
	if err != nil {
		return nil, err
	}
	if err := checkProtocolVersion(&header); err != nil {
		return nil, err
	}
	return &header, nil
}