89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package netlib
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"sync/atomic"
|
|
)
|
|
|
|
var (
|
|
DefaultProtocoDecoderName = "default-protocol-decoder"
|
|
protocolDecoders = make(map[string]ProtocolDecoder)
|
|
ErrRcvBufCannotGet = errors.New("Session rcvbuf get failed")
|
|
)
|
|
|
|
type ProtocolDecoder interface {
|
|
Decode(s *Session, r io.Reader) (packetid int, logicNo uint32, packet interface{}, err error, raw []byte)
|
|
FinishDecode(s *Session)
|
|
}
|
|
|
|
type DefaultProtocolDecoder struct {
|
|
}
|
|
|
|
func (pdi *DefaultProtocolDecoder) Decode(s *Session, r io.Reader) (packetid int, logicNo uint32, packet interface{}, err error, raw []byte) {
|
|
if s.rcvbuf == nil {
|
|
s.rcvbuf = AllocRWBuf()
|
|
}
|
|
rdbuf := s.rcvbuf
|
|
if rdbuf == nil {
|
|
err = ErrRcvBufCannotGet
|
|
return
|
|
}
|
|
err = binary.Read(r, binary.LittleEndian, &rdbuf.pheader)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if int(rdbuf.pheader.Len) > MaxPacketSize {
|
|
err = fmt.Errorf("PacketHeader len exceed MaxPacket. get %v limit %v", rdbuf.pheader.Len, MaxPacketSize)
|
|
return
|
|
}
|
|
if rdbuf.pheader.Seq != rdbuf.seq+1 {
|
|
err = fmt.Errorf("PacketHeader sno not matched. get %v want %v", rdbuf.pheader.Seq, rdbuf.seq+1)
|
|
return
|
|
}
|
|
rdbuf.seq++
|
|
logicNo = rdbuf.pheader.LogicNo
|
|
_, err = io.ReadFull(r, rdbuf.buf[0:rdbuf.pheader.Len])
|
|
if err != nil {
|
|
return
|
|
}
|
|
raw = rdbuf.buf[0:rdbuf.pheader.Len]
|
|
packetid, packet, err = UnmarshalPacket(rdbuf.buf[0:rdbuf.pheader.Len])
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
atomic.AddInt64(&s.recvedBytes, int64(int(rdbuf.pheader.Len)+LenOfProtoHeader))
|
|
atomic.AddInt64(&s.recvedPack, 1)
|
|
return
|
|
}
|
|
|
|
func (pdi *DefaultProtocolDecoder) FinishDecode(s *Session) {
|
|
if s.rcvbuf != nil {
|
|
FreeRWBuf(s.rcvbuf)
|
|
s.rcvbuf = nil
|
|
}
|
|
}
|
|
|
|
func RegisteProtocolDecoder(name string, dec ProtocolDecoder) {
|
|
if _, exist := protocolDecoders[name]; exist {
|
|
panic("repeated registe protocol decoder:" + name)
|
|
}
|
|
protocolDecoders[name] = dec
|
|
}
|
|
|
|
func GetProtocolDecoder(name string) ProtocolDecoder {
|
|
if dec, exist := protocolDecoders[name]; exist {
|
|
return dec
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func init() {
|
|
RegisteProtocolDecoder(DefaultProtocoDecoderName, &DefaultProtocolDecoder{})
|
|
}
|