You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

106 rivejä
2.8 KiB

  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. using MQTTnet.Core.Channel;
  6. using MQTTnet.Core.Protocol;
  7. namespace MQTTnet.Core.Serializer
  8. {
  9. public sealed class MqttPacketWriter : IDisposable
  10. {
  11. private readonly MemoryStream _buffer = new MemoryStream(1024);
  12. public void InjectFixedHeader(MqttControlPacketType packetType, byte flags = 0)
  13. {
  14. var fixedHeader = (int)packetType << 4;
  15. fixedHeader |= flags;
  16. InjectFixedHeader((byte)fixedHeader);
  17. }
  18. public void Write(byte value)
  19. {
  20. _buffer.WriteByte(value);
  21. }
  22. public void Write(ushort value)
  23. {
  24. var buffer = BitConverter.GetBytes(value);
  25. _buffer.WriteByte(buffer[1]);
  26. _buffer.WriteByte(buffer[0]);
  27. }
  28. public void Write(ByteWriter value)
  29. {
  30. if (value == null) throw new ArgumentNullException(nameof(value));
  31. _buffer.WriteByte(value.Value);
  32. }
  33. public void Write(params byte[] value)
  34. {
  35. if (value == null) throw new ArgumentNullException(nameof(value));
  36. _buffer.Write(value, 0, value.Length);
  37. }
  38. public void WriteWithLengthPrefix(string value)
  39. {
  40. WriteWithLengthPrefix(Encoding.UTF8.GetBytes(value ?? string.Empty));
  41. }
  42. public void WriteWithLengthPrefix(byte[] value)
  43. {
  44. var length = (ushort)value.Length;
  45. Write(length);
  46. Write(value);
  47. }
  48. public Task WriteToAsync(IMqttCommunicationChannel destination)
  49. {
  50. if (destination == null) throw new ArgumentNullException(nameof(destination));
  51. return destination.WriteAsync(_buffer.ToArray());
  52. }
  53. public void Dispose()
  54. {
  55. _buffer?.Dispose();
  56. }
  57. private void InjectFixedHeader(byte fixedHeader)
  58. {
  59. if (_buffer.Length == 0)
  60. {
  61. Write(fixedHeader);
  62. Write(0);
  63. return;
  64. }
  65. var backupBuffer = _buffer.ToArray();
  66. var remainingLength = (int)_buffer.Length;
  67. _buffer.SetLength(0);
  68. _buffer.WriteByte(fixedHeader);
  69. // Alorithm taken from http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html.
  70. var x = remainingLength;
  71. do
  72. {
  73. var encodedByte = x % 128;
  74. x = x / 128;
  75. if (x > 0)
  76. {
  77. encodedByte = encodedByte | 128;
  78. }
  79. _buffer.WriteByte((byte)encodedByte);
  80. } while (x > 0);
  81. _buffer.Write(backupBuffer, 0, backupBuffer.Length);
  82. }
  83. }
  84. }