TlvPackLayer.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. namespace TLVProtocal;
  2. internal class TlvPackLayer(bool ConvertToBigEnd) : BaseFilter
  3. {
  4. private readonly ConcurrentDictionary<Connection, List<byte>> _buffer = [];
  5. public override bool Receive(Data data)
  6. {
  7. if (data.RawData is null || data.RawData.Length == 0)
  8. return false;
  9. List<byte> bytes;
  10. lock (_buffer)
  11. if (!this._buffer.TryGetValue(data.Connection, out bytes) || bytes is null)
  12. {
  13. bytes = [];
  14. this._buffer[data.Connection] = bytes;
  15. }
  16. lock (bytes)
  17. bytes.AddRange(data.RawData);
  18. for (ushort length; bytes.Count > 2;)
  19. {
  20. byte[] message = [.. bytes];
  21. if (ConvertToBigEnd)
  22. {
  23. byte[] lengthByte = new byte[2];
  24. Array.Copy(message, lengthByte, 2);
  25. Array.Reverse(lengthByte);
  26. length = BitConverter.ToUInt16(lengthByte, 0);
  27. }
  28. else
  29. length = BitConverter.ToUInt16(message, 0);
  30. if (message.Length < length + 2)
  31. return true;
  32. byte[] dataBytes = new byte[length];
  33. bytes.CopyTo(2, dataBytes, 0, length);
  34. bytes.RemoveRange(0, length + 2);
  35. Data dataRecived = new(dataBytes, data.Connection, data.DateTime);
  36. base.Receive(dataRecived);
  37. }
  38. return true;
  39. }
  40. public override bool Send(Data data)
  41. {
  42. if (data.RawData is null || data.RawData.Length < 2)
  43. return false;
  44. ushort length = (ushort)data.RawData.Length;
  45. byte[] lengthByte = BitConverter.GetBytes(length);
  46. if (ConvertToBigEnd)
  47. Array.Reverse(lengthByte);
  48. List<byte> bytes = [];
  49. bytes.AddRange(lengthByte);
  50. bytes.AddRange(data.RawData);
  51. Data sendData = new([.. bytes], data.Connection, data.DateTime);
  52. return base.Send(sendData);
  53. }
  54. public override void Disconnected(Connection connection)
  55. {
  56. this._buffer.TryRemove(connection, out _);
  57. base.Disconnected(connection);
  58. }
  59. public override void Connected(Connection connection)
  60. {
  61. lock (_buffer)
  62. if (!this._buffer.TryGetValue(connection, out List<byte> bytes) || bytes is null)
  63. {
  64. bytes = [];
  65. this._buffer[connection] = bytes;
  66. }
  67. base.Connected(connection);
  68. }
  69. }