diff --git a/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs b/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs index 2b118f7..58edcf8 100644 --- a/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs +++ b/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs @@ -9,6 +9,7 @@ namespace MQTTnet.AspNetCore public class SpanBasedMqttPacketBodyReader : IMqttPacketBodyReader { private ReadOnlyMemory _buffer; + private int _offset; public void SetBuffer(ReadOnlyMemory buffer) @@ -17,11 +18,11 @@ namespace MQTTnet.AspNetCore _offset = 0; } - public ulong Length => (ulong)_buffer.Length; + public int Length => _buffer.Length; public bool EndOfStream => _buffer.Length.Equals(_offset); - public ulong Offset => (ulong)_offset; + public int Offset => _offset; public byte ReadByte() { @@ -116,9 +117,9 @@ namespace MQTTnet.AspNetCore throw new MqttProtocolViolationException("Boolean values can be 0 or 1 only."); } - public void Seek(ulong position) + public void Seek(int position) { - _offset = (int)position; + _offset = position; } } } diff --git a/Source/MQTTnet/Formatter/IMqttPacketBodyReader.cs b/Source/MQTTnet/Formatter/IMqttPacketBodyReader.cs index 632c493..2e0f8f0 100644 --- a/Source/MQTTnet/Formatter/IMqttPacketBodyReader.cs +++ b/Source/MQTTnet/Formatter/IMqttPacketBodyReader.cs @@ -4,9 +4,9 @@ namespace MQTTnet.Formatter { public interface IMqttPacketBodyReader { - ulong Length { get; } + int Length { get; } - ulong Offset { get; } + int Offset { get; } bool EndOfStream { get; } @@ -26,6 +26,6 @@ namespace MQTTnet.Formatter bool ReadBoolean(); - void Seek(ulong position); + void Seek(int position); } } diff --git a/Source/MQTTnet/Formatter/MqttPacketBodyReader.cs b/Source/MQTTnet/Formatter/MqttPacketBodyReader.cs index c45fb3d..dece6f3 100644 --- a/Source/MQTTnet/Formatter/MqttPacketBodyReader.cs +++ b/Source/MQTTnet/Formatter/MqttPacketBodyReader.cs @@ -9,52 +9,54 @@ namespace MQTTnet.Formatter public class MqttPacketBodyReader : IMqttPacketBodyReader { private readonly byte[] _buffer; - private readonly ulong _initialOffset; - private readonly ulong _length; + private readonly int _initialOffset; + private readonly int _length; - public MqttPacketBodyReader(byte[] buffer, int offset, int length) - : this(buffer, (ulong)offset, (ulong)length) - { - } + private int _offset; - public MqttPacketBodyReader(byte[] buffer, ulong offset, ulong length) + public MqttPacketBodyReader(byte[] buffer, int offset, int length) { _buffer = buffer; _initialOffset = offset; - Offset = offset; + _offset = offset; _length = length; } - public ulong Offset { get; private set; } + public int Offset + { + get => _offset; + } - public ulong Length => _length - Offset; + public int Length => _length - _offset; - public bool EndOfStream => Offset == _length; + public bool EndOfStream => _offset == _length; - public void Seek(ulong position) + public void Seek(int position) { - Offset = _initialOffset + position; + _offset = _initialOffset + position; } - public ArraySegment Read(uint length) + public ArraySegment Read(int length) { ValidateReceiveBuffer(length); - var buffer = new ArraySegment(_buffer, (int)Offset, (int)length); - Offset += length; + var buffer = new ArraySegment(_buffer, (int)_offset, (int)length); + _offset += length; return buffer; } public byte ReadByte() { ValidateReceiveBuffer(1); - return _buffer[Offset++]; + + return _buffer[_offset++]; } public bool ReadBoolean() { ValidateReceiveBuffer(1); - var buffer = _buffer[Offset++]; + + var buffer = _buffer[_offset++]; if (buffer == 0) { @@ -71,15 +73,15 @@ namespace MQTTnet.Formatter public byte[] ReadRemainingData() { - return new ArraySegment(_buffer, (int)Offset, (int)(_length - Offset)).ToArray(); + return new ArraySegment(_buffer, (int)_offset, (int)(_length - _offset)).ToArray(); } public ushort ReadTwoByteInteger() { ValidateReceiveBuffer(2); - var msb = _buffer[Offset++]; - var lsb = _buffer[Offset++]; + var msb = _buffer[_offset++]; + var lsb = _buffer[_offset++]; return (ushort)(msb << 8 | lsb); } @@ -88,31 +90,14 @@ namespace MQTTnet.Formatter { ValidateReceiveBuffer(4); - var byte0 = _buffer[Offset++]; - var byte1 = _buffer[Offset++]; - var byte2 = _buffer[Offset++]; - var byte3 = _buffer[Offset++]; + var byte0 = _buffer[_offset++]; + var byte1 = _buffer[_offset++]; + var byte2 = _buffer[_offset++]; + var byte3 = _buffer[_offset++]; return (uint)(byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3); } - public byte[] ReadWithLengthPrefix() - { - return ReadSegmentWithLengthPrefix().ToArray(); - } - - private ArraySegment ReadSegmentWithLengthPrefix() - { - var length = ReadTwoByteInteger(); - - ValidateReceiveBuffer(length); - - var result = new ArraySegment(_buffer, (int)Offset, length); - Offset += length; - - return result; - } - public uint ReadVariableLengthInteger() { var multiplier = 1; @@ -134,13 +119,30 @@ namespace MQTTnet.Formatter return value; } + + public byte[] ReadWithLengthPrefix() + { + return ReadSegmentWithLengthPrefix().ToArray(); + } + + private ArraySegment ReadSegmentWithLengthPrefix() + { + var length = ReadTwoByteInteger(); + + ValidateReceiveBuffer(length); + + var result = new ArraySegment(_buffer, (int)_offset, length); + _offset += length; + + return result; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ValidateReceiveBuffer(uint length) + private void ValidateReceiveBuffer(int length) { - if (_length < Offset + length) + if (_length < _offset + length) { - throw new ArgumentOutOfRangeException(nameof(_buffer), $"Expected at least {Offset + length} bytes but there are only {_length} bytes"); + throw new ArgumentOutOfRangeException(nameof(_buffer), $"Expected at least {_offset + length} bytes but there are only {_length} bytes"); } } diff --git a/Source/MQTTnet/Formatter/V5/MqttV500PropertiesReader.cs b/Source/MQTTnet/Formatter/V5/MqttV500PropertiesReader.cs index df323ae..443cf17 100644 --- a/Source/MQTTnet/Formatter/V5/MqttV500PropertiesReader.cs +++ b/Source/MQTTnet/Formatter/V5/MqttV500PropertiesReader.cs @@ -9,8 +9,8 @@ namespace MQTTnet.Formatter.V5 public class MqttV500PropertiesReader { private readonly IMqttPacketBodyReader _body; - private readonly uint _length; - private readonly ulong _targetOffset; + private readonly int _length; + private readonly int _targetOffset; public MqttV500PropertiesReader(IMqttPacketBodyReader body) { @@ -18,7 +18,7 @@ namespace MQTTnet.Formatter.V5 if (!body.EndOfStream) { - _length = body.ReadVariableLengthInteger(); + _length = (int)body.ReadVariableLengthInteger(); } _targetOffset = body.Offset + _length; diff --git a/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs b/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs index 7fbb552..51e7ecb 100644 --- a/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs +++ b/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs @@ -57,7 +57,7 @@ namespace MQTTnet.Benchmarks var receivedPacket = new ReceivedMqttPacket( header.Flags, - new MqttPacketBodyReader(_serializedPacket.Array, (ulong)(_serializedPacket.Count - header.RemainingLength), (ulong)_serializedPacket.Array.Length), 0); + new MqttPacketBodyReader(_serializedPacket.Array, _serializedPacket.Count - header.RemainingLength, _serializedPacket.Array.Length), 0); _serializer.Decode(receivedPacket); } diff --git a/Tests/MQTTnet.Core.Tests/Protocol_Tests.cs b/Tests/MQTTnet.Core.Tests/Protocol_Tests.cs new file mode 100644 index 0000000..41cd1fa --- /dev/null +++ b/Tests/MQTTnet.Core.Tests/Protocol_Tests.cs @@ -0,0 +1,23 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.Formatter; + +namespace MQTTnet.Tests +{ + [TestClass] + public class Protocol_Tests + { + [TestMethod] + public void Encode_Four_Byte_Integer() + { + for (uint i = 0; i < 268435455; i++) + { + var buffer = MqttPacketWriter.EncodeVariableLengthInteger(i); + var reader = new MqttPacketBodyReader(buffer.Array, buffer.Offset, buffer.Count); + + var checkValue = reader.ReadVariableLengthInteger(); + + Assert.AreEqual(i, checkValue); + } + } + } +}