123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package zmostp_go
- type DFAOutMsg struct {
- RawChannel []byte
- RawPayload []byte
- Checksum []byte
- }
- type DFAState uint8
- const (
- DFAS_IDLE DFAState = iota
- DFAS_HEADER_RECEIVED DFAState = iota
- DFAS_CHNANEL_RECEIVED DFAState = iota
- DFAS_PAYLOAD_RECEIVED DFAState = iota
- )
- func (s DFAState) ToAbbr() string {
- switch s {
- case DFAS_IDLE:
- return "IDLE"
- case DFAS_HEADER_RECEIVED:
- return "HDRC"
- case DFAS_CHNANEL_RECEIVED:
- return "CHRC"
- case DFAS_PAYLOAD_RECEIVED:
- return "PDRC"
- default:
- return "UKNW"
- }
- }
- type DecoderDFA struct {
- outCh chan *DFAOutMsg
- st DFAState
- flh DecodeFailureLogHandler
- chnbuf []byte
- pdbuf []byte
- crcbuf []byte
- }
- func NewDecoderDFA(flh DecodeFailureLogHandler) *DecoderDFA {
- a := &DecoderDFA{
- outCh: make(chan *DFAOutMsg),
- st: DFAS_IDLE,
- flh: flh,
- }
- return a
- }
- func (a *DecoderDFA) GetOutChannel() chan *DFAOutMsg {
- return a.outCh
- }
- func (a *DecoderDFA) Shutdown() {
- close(a.outCh)
- }
- func (a *DecoderDFA) Reset() {
- close(a.outCh)
- a.st = DFAS_IDLE
- a.outCh = make(chan *DFAOutMsg)
- }
- func (a *DecoderDFA) PushByte(b byte) {
- switch a.st {
- default:
- a.flh.DFAInvalidState(a.st)
- a.st = DFAS_IDLE
- case DFAS_IDLE:
- switch b {
- default:
- a.flh.DFAInvalidInput(a.st, b)
- a.st = DFAS_IDLE
- case '{':
- a.chnbuf = make([]byte, 0, 5)
- a.pdbuf = make([]byte, 0)
- a.crcbuf = make([]byte, 0, 5)
- a.st = DFAS_HEADER_RECEIVED
- case '\t', ' ', '\r', '\n':
- // ignore whitespace
- }
- case DFAS_HEADER_RECEIVED:
- switch {
- case b >= '!' && b <= 'u' || b == 'z':
- a.chnbuf = append(a.chnbuf, b)
- case b == '|':
- a.st = DFAS_CHNANEL_RECEIVED
- case b == '\t' || b == ' ' || b == '\r' || b == '\n':
- // ignore whitespace
- default:
- a.flh.DFAInvalidInput(a.st, b)
- a.st = DFAS_IDLE
- }
- case DFAS_CHNANEL_RECEIVED:
- switch {
- case b >= '!' && b <= 'u' || b == 'z':
- a.pdbuf = append(a.pdbuf, b)
- case b == '|':
- a.st = DFAS_PAYLOAD_RECEIVED
- case b == '}':
- go func() {
- a.outCh <- &DFAOutMsg{
- RawChannel: a.chnbuf,
- RawPayload: a.pdbuf,
- Checksum: []byte{},
- }
- }()
- a.st = DFAS_IDLE
- case b == '\t' || b == ' ' || b == '\r' || b == '\n':
- // ignore whitespace
- default:
- a.flh.DFAInvalidInput(a.st, b)
- a.st = DFAS_IDLE
- }
- case DFAS_PAYLOAD_RECEIVED:
- switch {
- case b >= '!' && b <= 'u' || b == 'z':
- a.crcbuf = append(a.crcbuf, b)
- case b == '}':
- go func() {
- a.outCh <- &DFAOutMsg{
- RawChannel: a.chnbuf,
- RawPayload: a.pdbuf,
- Checksum: a.crcbuf,
- }
- }()
- a.st = DFAS_IDLE
- case b == '\t' || b == ' ' || b == '\r' || b == '\n':
- // ignore whitespace
- default:
- a.flh.DFAInvalidInput(a.st, b)
- a.st = DFAS_IDLE
- }
- }
- }
|