您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

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