LineBasedFrameBuilder.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using System;
  2. using System.Text;
  3. using MECF.Framework.Common.Communications.Tcp.Socket.Framing.Base;
  4. namespace MECF.Framework.Common.Communications.Tcp.Socket.Framing
  5. {
  6. public class LineDelimiter : IEquatable<LineDelimiter>
  7. {
  8. public static readonly LineDelimiter CRLF = new LineDelimiter("\r\n");
  9. public static readonly LineDelimiter UNIX = new LineDelimiter("\n");
  10. public static readonly LineDelimiter MAC = new LineDelimiter("\r");
  11. public static readonly LineDelimiter WINDOWS = CRLF;
  12. public LineDelimiter(string delimiter)
  13. {
  14. this.DelimiterString = delimiter;
  15. this.DelimiterChars = this.DelimiterString.ToCharArray();
  16. this.DelimiterBytes = Encoding.UTF8.GetBytes(this.DelimiterChars);
  17. }
  18. public string DelimiterString { get; private set; }
  19. public char[] DelimiterChars { get; private set; }
  20. public byte[] DelimiterBytes { get; private set; }
  21. public bool Equals(LineDelimiter other)
  22. {
  23. if (Object.ReferenceEquals(other, null)) return false;
  24. if (Object.ReferenceEquals(this, other)) return true;
  25. return (StringComparer.OrdinalIgnoreCase.Compare(this.DelimiterString, other.DelimiterString) == 0);
  26. }
  27. public override bool Equals(object obj)
  28. {
  29. return this.Equals(obj as LineDelimiter);
  30. }
  31. public override int GetHashCode()
  32. {
  33. return this.DelimiterString.GetHashCode();
  34. }
  35. public override string ToString()
  36. {
  37. return this.DelimiterString;
  38. }
  39. }
  40. public sealed class LineBasedFrameBuilder : FrameBuilder
  41. {
  42. public LineBasedFrameBuilder()
  43. : this(new LineBasedFrameEncoder(), new LineBasedFrameDecoder())
  44. {
  45. }
  46. public LineBasedFrameBuilder(LineDelimiter delimiter)
  47. : this(new LineBasedFrameEncoder(delimiter), new LineBasedFrameDecoder(delimiter))
  48. {
  49. }
  50. public LineBasedFrameBuilder(LineBasedFrameEncoder encoder, LineBasedFrameDecoder decoder)
  51. : base(encoder, decoder)
  52. {
  53. }
  54. }
  55. public sealed class LineBasedFrameEncoder : IFrameEncoder
  56. {
  57. private readonly LineDelimiter _delimiter;
  58. public LineBasedFrameEncoder()
  59. : this(LineDelimiter.CRLF)
  60. {
  61. }
  62. public LineBasedFrameEncoder(LineDelimiter delimiter)
  63. {
  64. if (delimiter == null)
  65. throw new ArgumentNullException("delimiter");
  66. _delimiter = delimiter;
  67. }
  68. public LineDelimiter LineDelimiter { get { return _delimiter; } }
  69. public void EncodeFrame(byte[] payload, int offset, int count, out byte[] frameBuffer, out int frameBufferOffset, out int frameBufferLength)
  70. {
  71. var buffer = new byte[count + _delimiter.DelimiterBytes.Length];
  72. Array.Copy(payload, offset, buffer, 0, count);
  73. Array.Copy(_delimiter.DelimiterBytes, 0, buffer, count, _delimiter.DelimiterBytes.Length);
  74. frameBuffer = buffer;
  75. frameBufferOffset = 0;
  76. frameBufferLength = buffer.Length;
  77. }
  78. }
  79. public sealed class LineBasedFrameDecoder : IFrameDecoder
  80. {
  81. private readonly LineDelimiter _delimiter;
  82. public LineBasedFrameDecoder()
  83. : this(LineDelimiter.CRLF)
  84. {
  85. }
  86. public LineBasedFrameDecoder(LineDelimiter delimiter)
  87. {
  88. if (delimiter == null)
  89. throw new ArgumentNullException("delimiter");
  90. _delimiter = delimiter;
  91. }
  92. public LineDelimiter LineDelimiter { get { return _delimiter; } }
  93. public bool TryDecodeFrame(byte[] buffer, int offset, int count, out int frameLength, out byte[] payload, out int payloadOffset, out int payloadCount)
  94. {
  95. frameLength = 0;
  96. payload = null;
  97. payloadOffset = 0;
  98. payloadCount = 0;
  99. if (count < _delimiter.DelimiterBytes.Length)
  100. return false;
  101. var delimiter = _delimiter.DelimiterBytes;
  102. bool matched = false;
  103. for (int i = 0; i < count; i++)
  104. {
  105. for (int j = 0; j < delimiter.Length; j++)
  106. {
  107. if (i + j < count && buffer[offset + i + j] == delimiter[j])
  108. {
  109. matched = true;
  110. }
  111. else
  112. {
  113. matched = false;
  114. break;
  115. }
  116. }
  117. if (matched)
  118. {
  119. frameLength = i + delimiter.Length;
  120. payload = buffer;
  121. payloadOffset = offset;
  122. payloadCount = i;
  123. return true;
  124. }
  125. }
  126. return false;
  127. }
  128. }
  129. }