Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

126 lignes
3.1 KiB

  1. using MQTTnet.Exceptions;
  2. using MQTTnet.Formatter;
  3. using System;
  4. using System.Buffers.Binary;
  5. using System.Text;
  6. namespace MQTTnet.AspNetCore
  7. {
  8. public class SpanBasedMqttPacketBodyReader : IMqttPacketBodyReader
  9. {
  10. private ReadOnlyMemory<byte> _buffer;
  11. private int _offset;
  12. public void SetBuffer(ReadOnlyMemory<byte> buffer)
  13. {
  14. _buffer = buffer;
  15. _offset = 0;
  16. }
  17. public int Length => _buffer.Length;
  18. public bool EndOfStream => _buffer.Length.Equals(_offset);
  19. public int Offset => _offset;
  20. public byte ReadByte()
  21. {
  22. return _buffer.Span[_offset++];
  23. }
  24. public byte[] ReadRemainingData()
  25. {
  26. return _buffer.Slice(_offset).ToArray();
  27. }
  28. public byte[] ReadWithLengthPrefix()
  29. {
  30. return ReadSegmentWithLengthPrefix().ToArray();
  31. }
  32. private ReadOnlySpan<byte> ReadSegmentWithLengthPrefix()
  33. {
  34. var span = _buffer.Span;
  35. var length = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(_offset));
  36. var result = span.Slice(_offset+2, length);
  37. _offset += 2 + length;
  38. return result;
  39. }
  40. public unsafe string ReadStringWithLengthPrefix()
  41. {
  42. var buffer = ReadSegmentWithLengthPrefix();
  43. if (buffer.Length == 0)
  44. {
  45. return string.Empty;
  46. }
  47. fixed (byte* bytes = &buffer.GetPinnableReference())
  48. {
  49. var result = Encoding.UTF8.GetString(bytes, buffer.Length);
  50. return result;
  51. }
  52. }
  53. public ushort ReadTwoByteInteger()
  54. {
  55. var result = BinaryPrimitives.ReadUInt16BigEndian(_buffer.Span.Slice(_offset));
  56. _offset += 2;
  57. return result;
  58. }
  59. public uint ReadFourByteInteger()
  60. {
  61. var result = BinaryPrimitives.ReadUInt32BigEndian(_buffer.Span.Slice(_offset));
  62. _offset += 4;
  63. return result;
  64. }
  65. public uint ReadVariableLengthInteger()
  66. {
  67. var multiplier = 1;
  68. var value = 0U;
  69. byte encodedByte;
  70. do
  71. {
  72. encodedByte = ReadByte();
  73. value += (uint)((encodedByte & 127) * multiplier);
  74. if (multiplier > 2097152)
  75. {
  76. throw new MqttProtocolViolationException("Variable length integer is invalid.");
  77. }
  78. multiplier *= 128;
  79. } while ((encodedByte & 128) != 0);
  80. return value;
  81. }
  82. public bool ReadBoolean()
  83. {
  84. var buffer = ReadByte();
  85. if (buffer == 0)
  86. {
  87. return false;
  88. }
  89. if (buffer == 1)
  90. {
  91. return true;
  92. }
  93. throw new MqttProtocolViolationException("Boolean values can be 0 or 1 only.");
  94. }
  95. public void Seek(int position)
  96. {
  97. _offset = position;
  98. }
  99. }
  100. }