func (m *Message) MethodLen() int {
	return int(m.Buffer[HeaderIndexMethodLen])
}
MethodLen returns method length.
package arpc
import (
	"encoding/binary"
	"errors"
	"fmt"
	"sync"
	"sync/atomic"
	"github.com/lesismal/arpc/codec"
	"github.com/lesismal/arpc/util"
)
const (
	CmdNone byte = 0
	CmdRequest byte = 1
	CmdResponse byte = 2
	CmdNotify byte = 3
)
const (
	HeaderIndexBodyLenBegin = 0
	HeaderIndexBodyLenEnd = 4
	HeaderIndexReserved = 4
	HeaderIndexCmd = 5
	HeaderIndexFlag = 6
	HeaderIndexMethodLen = 7
	HeaderIndexSeqBegin = 8
	HeaderIndexSeqEnd = 16
	HeaderFlagMaskError byte = 0x01
	HeaderFlagMaskAsync byte = 0x02
)
const (
	HeadLen int = 16
	MaxMethodLen int = 127
	DefaultMaxBodyLen int = 1024*1024*64 - 16
)
type Header []byte
func (h Header) BodyLen() int {
	return int(binary.LittleEndian.Uint32(h[HeaderIndexBodyLenBegin:HeaderIndexBodyLenEnd]))
}
func (h Header) message(handler Handler) (*Message, error) {
	bodyLen := h.BodyLen()
	if bodyLen < 0 || bodyLen > handler.MaxBodyLen() {
		return nil, fmt.Errorf("invalid body length: %v", bodyLen)
	}
	msg := messagePool.Get().(*Message)
	msg.handler = handler
	msg.Buffer = handler.Malloc(HeadLen + bodyLen)
	binary.LittleEndian.PutUint32(msg.Buffer[HeaderIndexBodyLenBegin:HeaderIndexBodyLenEnd], uint32(bodyLen))
	return msg, nil
}
var (
	messagePool = sync.Pool{
		New: func() interface{} {
			return &Message{}
		},
	}
	emptyMessage = Message{}
)
type Message struct {
	Buffer []byte
	ref     int32
	handler Handler
	values  map[interface{}]interface{}
}
func (m *Message) Retain() int32 {
	return atomic.AddInt32(&m.ref, 1)
}
func (m *Message) Release() int32 {
	n := atomic.AddInt32(&m.ref, -1)
	if n == -1 {
		if m.handler != nil {
			m.handler.Free(m.Buffer)
		}
		*m = emptyMessage
		messagePool.Put(m)
	}
	return n
}
func (m *Message) ResetAttrs() {
	binary.LittleEndian.PutUint32(m.Buffer[HeaderIndexBodyLenEnd:HeaderIndexSeqBegin], 0)
}
func (m *Message) Payback() {
	*m = emptyMessage
	messagePool.Put(m)
}
func (m *Message) Len() int {
	return len(m.Buffer)
}
func (m *Message) Cmd() byte {
	return m.Buffer[HeaderIndexCmd]
}
func (m *Message) SetCmd(cmd byte) {
	m.Buffer[HeaderIndexCmd] = cmd
}
func (m *Message) IsError() bool {
	return m.Buffer[HeaderIndexFlag]&HeaderFlagMaskError > 0
}
func (m *Message) SetError(isError bool) {
	if isError {
		m.Buffer[HeaderIndexFlag] |= HeaderFlagMaskError
	} else {
		m.Buffer[HeaderIndexFlag] &= ^HeaderFlagMaskError
	}
}
func (m *Message) Error() error {
	if !m.IsError() {
		return nil
	}
	return errors.New(string(m.Buffer[HeadLen+m.MethodLen():]))
}
func (m *Message) IsAsync() bool {
	return m.Buffer[HeaderIndexFlag]&HeaderFlagMaskAsync > 0
}
func (m *Message) SetAsync(isAsync bool) {
	if isAsync {
		m.Buffer[HeaderIndexFlag] |= HeaderFlagMaskAsync
	} else {
		m.Buffer[HeaderIndexFlag] &= ^HeaderFlagMaskAsync
	}
}
func (m *Message) Values() map[interface{}]interface{} {
	return m.values
}
func (m *Message) SetFlagBit(index int, value bool) error {
	switch index {
	case 0, 1, 2, 3, 4, 5, 6, 7:
		if value {
			m.Buffer[HeaderIndexReserved] |= (0x1 << index)
		} else {
			m.Buffer[HeaderIndexReserved] &= (^(0x1 << index))
		}
		return nil
	default:
		break
	}
	return ErrInvalidFlagBitIndex
}
func (m *Message) IsFlagBitSet(index int) bool {
	switch index {
	case 0, 1, 2, 3, 4, 5, 6, 7:
		return (m.Buffer[HeaderIndexReserved] & (0x1 << index)) != 0
	default:
		break
	}
	return false
}