StateMachineMessageCutter.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using Common;
  2. using Communicator;
  3. using log4net;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace HengShan_Pump_NonIC
  11. {
  12. public class StateMachineMessageCutter : IMessageCutter<byte[]>
  13. {
  14. public byte[] Message { get; private set; }
  15. public event EventHandler OnMessageCut;
  16. static ILog innerLogger = log4net.LogManager.GetLogger("StateMachine");
  17. private string loggerAppendix = "HengShan_Pump_NonIC msgCutter ";
  18. private readonly SizableWindow<byte> window;
  19. private State nextState = State.Uninitialized;
  20. /// <summary>
  21. ///
  22. /// </summary>
  23. public StateMachineMessageCutter()
  24. {
  25. //this.initWindowSize = initWindowSize;
  26. this.window = new SizableWindow<byte>();
  27. this.window.OnWindowFull += (data) =>
  28. {
  29. switch (nextState)
  30. {
  31. case State.Uninitialized:
  32. if (data.First() == 0xFF)
  33. {
  34. //前导码(0FFH) +长度(0-20H)
  35. this.window.NewSize = 2;
  36. this.nextState = State.LengthReady;
  37. innerLogger.Debug(this.loggerAppendix + " state is State.Uninitialized and next is 0xFF, switch to LengthReady");
  38. }
  39. else
  40. this.window.Clear();
  41. break;
  42. case State.LengthReady:
  43. //this.DumpWindowToQueue();
  44. this.window.NewSize = this.window.Skip(1).First() + 2;
  45. this.nextState = State.BodyReady;
  46. innerLogger.Debug(this.loggerAppendix + " MsgBodyLen caculated with: " + this.window.NewSize);
  47. break;
  48. case State.BodyReady:
  49. //innerLogger.Debug(this.loggerAppendix + " Fire OnMessageConstructed with innerQueue: " + this.buffer.ToHexLogString());
  50. this.Message = this.window.ToArray();
  51. var safe = this.OnMessageCut;
  52. safe?.Invoke(this, null);
  53. this.nextState = State.Uninitialized;
  54. this.window.Clear();
  55. //this.window.NewSize = this.initWindowSize;
  56. break;
  57. default:
  58. throw new ArgumentOutOfRangeException();
  59. }
  60. };
  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. }