dfa.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package zmostp_go
  2. type DFAOutMsg struct {
  3. RawChannel []byte
  4. RawPayload []byte
  5. Checksum []byte
  6. }
  7. type DFAState uint8
  8. const (
  9. DFAS_IDLE DFAState = iota
  10. DFAS_HEADER_RECEIVED DFAState = iota
  11. DFAS_CHNANEL_RECEIVED DFAState = iota
  12. DFAS_PAYLOAD_RECEIVED DFAState = iota
  13. )
  14. func (s DFAState) ToAbbr() string {
  15. switch s {
  16. case DFAS_IDLE:
  17. return "IDLE"
  18. case DFAS_HEADER_RECEIVED:
  19. return "HDRC"
  20. case DFAS_CHNANEL_RECEIVED:
  21. return "CHRC"
  22. case DFAS_PAYLOAD_RECEIVED:
  23. return "PDRC"
  24. default:
  25. return "UKNW"
  26. }
  27. }
  28. type DecoderDFA struct {
  29. outCh chan *DFAOutMsg
  30. st DFAState
  31. flh DecodeFailureLogHandler
  32. chnbuf []byte
  33. pdbuf []byte
  34. crcbuf []byte
  35. }
  36. func NewDecoderDFA(flh DecodeFailureLogHandler) *DecoderDFA {
  37. a := &DecoderDFA{
  38. outCh: make(chan *DFAOutMsg),
  39. st: DFAS_IDLE,
  40. flh: flh,
  41. }
  42. return a
  43. }
  44. func (a *DecoderDFA) GetOutChannel() chan *DFAOutMsg {
  45. return a.outCh
  46. }
  47. func (a *DecoderDFA) Shutdown() {
  48. close(a.outCh)
  49. }
  50. func (a *DecoderDFA) Reset() {
  51. close(a.outCh)
  52. a.st = DFAS_IDLE
  53. a.outCh = make(chan *DFAOutMsg)
  54. }
  55. func (a *DecoderDFA) PushByte(b byte) {
  56. switch a.st {
  57. default:
  58. a.flh.DFAInvalidState(a.st)
  59. a.st = DFAS_IDLE
  60. case DFAS_IDLE:
  61. switch b {
  62. default:
  63. a.flh.DFAInvalidInput(a.st, b)
  64. a.st = DFAS_IDLE
  65. case '{':
  66. a.chnbuf = make([]byte, 0, 5)
  67. a.pdbuf = make([]byte, 0)
  68. a.crcbuf = make([]byte, 0, 5)
  69. a.st = DFAS_HEADER_RECEIVED
  70. case '\t', ' ', '\r', '\n':
  71. // ignore whitespace
  72. }
  73. case DFAS_HEADER_RECEIVED:
  74. switch {
  75. case b >= '!' && b <= 'u' || b == 'z':
  76. a.chnbuf = append(a.chnbuf, b)
  77. case b == '|':
  78. a.st = DFAS_CHNANEL_RECEIVED
  79. case b == '\t' || b == ' ' || b == '\r' || b == '\n':
  80. // ignore whitespace
  81. default:
  82. a.flh.DFAInvalidInput(a.st, b)
  83. a.st = DFAS_IDLE
  84. }
  85. case DFAS_CHNANEL_RECEIVED:
  86. switch {
  87. case b >= '!' && b <= 'u' || b == 'z':
  88. a.pdbuf = append(a.pdbuf, b)
  89. case b == '|':
  90. a.st = DFAS_PAYLOAD_RECEIVED
  91. case b == '}':
  92. go func() {
  93. a.outCh <- &DFAOutMsg{
  94. RawChannel: a.chnbuf,
  95. RawPayload: a.pdbuf,
  96. Checksum: []byte{},
  97. }
  98. }()
  99. a.st = DFAS_IDLE
  100. case b == '\t' || b == ' ' || b == '\r' || b == '\n':
  101. // ignore whitespace
  102. default:
  103. a.flh.DFAInvalidInput(a.st, b)
  104. a.st = DFAS_IDLE
  105. }
  106. case DFAS_PAYLOAD_RECEIVED:
  107. switch {
  108. case b >= '!' && b <= 'u' || b == 'z':
  109. a.crcbuf = append(a.crcbuf, b)
  110. case b == '}':
  111. go func() {
  112. a.outCh <- &DFAOutMsg{
  113. RawChannel: a.chnbuf,
  114. RawPayload: a.pdbuf,
  115. Checksum: a.crcbuf,
  116. }
  117. }()
  118. a.st = DFAS_IDLE
  119. case b == '\t' || b == ' ' || b == '\r' || b == '\n':
  120. // ignore whitespace
  121. default:
  122. a.flh.DFAInvalidInput(a.st, b)
  123. a.st = DFAS_IDLE
  124. }
  125. }
  126. }