3 Star 0 Fork 0

Admin/legacy-syrsa-parser

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
framer.go 2.92 KB
一键复制 编辑 原始数据 按行查看 历史
钟林峰 提交于 2020-08-18 15:54 +08:00 . initial commit
package main
import "fmt"
// FramerResult framer result
type FramerResult interface {
Frames() [][]byte
Remains() []byte
}
// Framer framer interface
type Framer interface {
Frame(bs []byte) FramerResult
}
type frameResult struct {
frames [][]byte
remains []byte
}
func (r *frameResult) Frames() [][]byte {
return r.frames
}
func (r *frameResult) Remains() []byte {
return r.remains
}
type packetFramer struct{}
func (*packetFramer) Frame(bs []byte) FramerResult {
f := frameResult{
frames: [][]byte{bs},
remains: []byte{},
}
return &f
}
// NewPacketFramer create packet framer
func NewPacketFramer() (Framer, error) {
return &packetFramer{}, nil
}
// FramerConfig framer config
type FramerConfig struct {
STX []byte `json:"stx,omitempty" yaml:"stx" mapstructure:"stx"`
ETX []byte `json:"etx,omitempty" yaml:"etx" mapstructure:"etx"`
MaxBytes int `json:"max_bytes,omitempty" yaml:"max_bytes" mapstructure:"max_bytes"`
}
// NewFramer create new framer
func NewFramer(config FramerConfig) (Framer, error) {
if len(config.ETX) == 0 && config.MaxBytes == 0 {
return nil, fmt.Errorf("byte sequence with no ending must define maximum length")
}
return &delimiterFramer{
stxCh: config.STX,
endCh: config.ETX,
maxBytes: config.MaxBytes,
}, nil
}
type delimiterFramer struct {
stxCh []byte
endCh []byte
maxBytes int
}
const (
idle = iota
stxing
packeting
)
func (f *delimiterFramer) Frame(bs []byte) FramerResult {
state := idle
current := []byte{}
stxIndex := 0
endIndex := 0
frame := frameResult{
frames: [][]byte{},
remains: []byte{},
}
for _, b := range bs {
switch state {
case idle:
{
if len(f.stxCh) > 0 {
if b == f.stxCh[stxIndex] {
stxIndex++
if stxIndex == len(f.stxCh) {
// stx match
state = packeting
stxIndex = 0
}
} else {
stxIndex = 0
}
} else {
// no stx
stxIndex = 0
current = append(current, b)
state = packeting
}
break
}
case packeting:
{
current = append(current, b)
if len(f.endCh) > 0 {
if b == f.endCh[endIndex] {
endIndex++
if endIndex == len(f.endCh) {
// packet complete
packet := join(f.stxCh, current)
current = []byte{}
endIndex = 0
frame.frames = append(frame.frames, packet)
state = idle
}
} else {
// reset
endIndex = 0
}
}
if f.maxBytes > 0 && len(current) == f.maxBytes {
// packet complete
packet := join(f.stxCh, current)
current = []byte{}
endIndex = 0
state = idle
stxIndex = 0
frame.frames = append(frame.frames, packet)
}
break
}
default:
{
state = idle
}
}
}
if state == packeting {
remains := join(f.stxCh, current)
frame.remains = remains
}
return &frame
}
func join(parts ...[]byte) []byte {
all := []byte{}
for _, part := range parts {
all = append(all, part...)
}
return all
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/shipnet_masterclock/legacy-syrsa-parser.git
git@gitee.com:shipnet_masterclock/legacy-syrsa-parser.git
shipnet_masterclock
legacy-syrsa-parser
legacy-syrsa-parser
master

搜索帮助