StateMachineMessageCutter.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using System;
  2. using System.Linq;
  3. using Edge.Core.Processor.Communicator;
  4. namespace HengShan_Pump_NonIC_Plus
  5. {
  6. public class StateMachineMessageCutter : IMessageCutter<byte[]>
  7. {
  8. public byte[] Message { get; private set; }
  9. public event EventHandler OnMessageCut;
  10. public event EventHandler<MessageCutterInvalidMessageReadEventArg> OnInvalidMessageRead;
  11. static NLog.Logger innerLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("StateMachineMessageCutter");
  12. private string loggerAppendix = "HengShan_Pump_NonIC_Plus msgCutter ";
  13. private readonly SizableWindow<byte> window;
  14. private State nextState = State.Uninitialized;
  15. public StateMachineMessageCutter()
  16. {
  17. this.window = new SizableWindow<byte>();
  18. this.window.OnWindowFull += (data) =>
  19. {
  20. switch (nextState)
  21. {
  22. case State.Uninitialized:
  23. if (data.First() == 0x9F)
  24. {
  25. //前导码(09FH) + 枪号 + 长度(0-20H)
  26. this.window.NewSize = 3;
  27. this.nextState = State.LengthReady;
  28. innerLogger.Debug(this.loggerAppendix + " state is State.Uninitialized and next is 0x9F, switch to LengthReady");
  29. }
  30. else
  31. ReadInvalidMessage();
  32. break;
  33. case State.LengthReady:
  34. int len = this.window.Skip(2).First();
  35. if (len > 0)
  36. {
  37. this.window.NewSize += len;
  38. this.nextState = State.BodyReady;
  39. innerLogger.Debug(this.loggerAppendix + " MsgBodyLen caculated with: " + this.window.NewSize);
  40. }
  41. else
  42. ReadInvalidMessage();
  43. break;
  44. case State.BodyReady:
  45. //innerLogger.Debug(this.loggerAppendix + " Fire OnMessageConstructed with innerQueue: " + this.buffer.ToHexLogString());
  46. this.Message = this.window.ToArray();
  47. var safe = this.OnMessageCut;
  48. safe?.Invoke(this, null);
  49. this.nextState = State.Uninitialized;
  50. this.window.Clear();
  51. break;
  52. default:
  53. throw new ArgumentOutOfRangeException();
  54. }
  55. };
  56. }
  57. private void ReadInvalidMessage()
  58. {
  59. this.nextState = State.Uninitialized;
  60. this.window.Clear();
  61. }
  62. private enum State
  63. {
  64. Uninitialized,
  65. //HeaderSeeking,
  66. HeaderReady,
  67. LengthReady,
  68. BodyReady,
  69. }
  70. public void Feed(byte[] next)
  71. {
  72. //innerLogger.Debug(this.loggerAppendix + " " + next.ToHexLogString() + " is feed in Window in state: " + nextState);
  73. for (int i = 0; i < next.Length; i++)
  74. this.window.Add(next[i]);
  75. }
  76. }
  77. }