You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.2 KiB
Go
62 lines
1.2 KiB
Go
|
2 years ago
|
package network
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"encoding/binary"
|
||
|
|
"errors"
|
||
|
|
)
|
||
|
|
|
||
|
|
type ICodec interface {
|
||
|
2 years ago
|
Decode([]byte) ([]int32, []interface{}, error)
|
||
|
|
Encode(interface{}) []byte
|
||
|
2 years ago
|
}
|
||
|
|
|
||
|
|
type CodecChain func(l int, paloay interface{})
|
||
|
|
|
||
|
|
var ErrRecvLen = errors.New("data is too long")
|
||
|
|
|
||
|
|
type StreamCodec struct {
|
||
|
|
MaxDecode int
|
||
|
|
msglen uint32
|
||
|
|
context bytes.Buffer
|
||
|
|
}
|
||
|
|
|
||
|
|
const STREAM_HEADLEN = 4
|
||
|
|
|
||
|
2 years ago
|
func (s *StreamCodec) Decode(data []byte) ([]int32, []interface{}, error) {
|
||
|
2 years ago
|
s.context.Write(data)
|
||
|
|
|
||
|
|
var ret []interface{} = nil
|
||
|
|
for s.context.Len() >= STREAM_HEADLEN {
|
||
|
|
if s.msglen == 0 {
|
||
|
|
d := s.context.Bytes()
|
||
|
|
s.msglen = binary.BigEndian.Uint32(d[:STREAM_HEADLEN])
|
||
|
|
if s.MaxDecode > 0 && int(s.msglen) > s.MaxDecode {
|
||
|
|
return nil, nil, ErrRecvLen
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if int(s.msglen)+STREAM_HEADLEN > s.context.Len() {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
|
||
|
|
d := make([]byte, s.msglen+STREAM_HEADLEN)
|
||
|
|
n, err := s.context.Read(d)
|
||
|
|
if n != int(s.msglen)+STREAM_HEADLEN || err != nil {
|
||
|
|
s.msglen = 0
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
s.msglen = 0
|
||
|
|
|
||
|
|
each := d[STREAM_HEADLEN:]
|
||
|
|
ret = append(ret, each)
|
||
|
|
}
|
||
|
|
return nil, ret, nil
|
||
|
|
}
|
||
|
|
|
||
|
2 years ago
|
func (s *StreamCodec) Encode(data interface{}) []byte {
|
||
|
2 years ago
|
d := make([]byte, STREAM_HEADLEN)
|
||
|
|
binary.BigEndian.PutUint32(d, uint32(len(data.([]byte))))
|
||
|
|
return append(d, data.([]byte)...)
|
||
|
|
}
|