propper buffering in place

This commit is contained in:
JanEggers
2017-09-10 18:20:25 +02:00
parent 644bcfba27
commit 9cde49f5f8
14 changed files with 227 additions and 131 deletions
+10 -11
View File
@@ -49,13 +49,13 @@ namespace MQTTnet.Core.Serializer
return ReadBytes(_header.BodyLength - (int)BaseStream.Position);
}
public static async Task<MqttPacketHeader> ReadHeaderFromSourceAsync(IMqttCommunicationChannel source)
public static async Task<MqttPacketHeader> ReadHeaderFromSourceAsync(IMqttCommunicationChannel source, byte[] buffer)
{
var fixedHeader = await ReadStreamByteAsync(source).ConfigureAwait(false);
var fixedHeader = await ReadStreamByteAsync(source, buffer).ConfigureAwait(false);
var byteReader = new ByteReader(fixedHeader);
byteReader.Read(4);
var controlPacketType = (MqttControlPacketType)byteReader.Read(4);
var bodyLength = await ReadBodyLengthFromSourceAsync(source).ConfigureAwait(false);
var bodyLength = await ReadBodyLengthFromSourceAsync(source, buffer).ConfigureAwait(false);
return new MqttPacketHeader()
{
@@ -65,18 +65,17 @@ namespace MQTTnet.Core.Serializer
};
}
private static async Task<byte> ReadStreamByteAsync(IMqttCommunicationChannel source)
private static async Task<byte> ReadStreamByteAsync(IMqttCommunicationChannel source, byte[] readBuffer)
{
var buffer = new byte[1];
await ReadFromSourceAsync(source, buffer).ConfigureAwait(false);
return buffer[0];
var result = await ReadFromSourceAsync(source, 1, readBuffer).ConfigureAwait(false);
return result.Array[result.Offset];
}
public static async Task ReadFromSourceAsync(IMqttCommunicationChannel source, byte[] buffer)
public static async Task<ArraySegment<byte>> ReadFromSourceAsync(IMqttCommunicationChannel source, int length, byte[] buffer)
{
try
{
await source.ReadAsync(buffer);
return await source.ReadAsync(length, buffer);
}
catch (Exception exception)
{
@@ -84,7 +83,7 @@ namespace MQTTnet.Core.Serializer
}
}
private static async Task<int> ReadBodyLengthFromSourceAsync(IMqttCommunicationChannel source)
private static async Task<int> ReadBodyLengthFromSourceAsync(IMqttCommunicationChannel source, byte[] buffer)
{
// Alorithm taken from http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html.
var multiplier = 1;
@@ -92,7 +91,7 @@ namespace MQTTnet.Core.Serializer
byte encodedByte;
do
{
encodedByte = await ReadStreamByteAsync(source).ConfigureAwait(false);
encodedByte = await ReadStreamByteAsync(source, buffer).ConfigureAwait(false);
value += (encodedByte & 127) * multiplier;
multiplier *= 128;
if (multiplier > 128 * 128 * 128)
@@ -17,6 +17,7 @@ namespace MQTTnet.Core.Serializer
private static byte[] ProtocolVersionV310Name { get; } = Encoding.UTF8.GetBytes("MQIs");
public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311;
private byte[] _readBuffer = new byte[BufferConstants.Size];
public async Task SerializeAsync(MqttBasePacket packet, IMqttCommunicationChannel destination)
{
@@ -115,17 +116,13 @@ namespace MQTTnet.Core.Serializer
public async Task<MqttBasePacket> DeserializeAsync(IMqttCommunicationChannel source)
{
if (source == null) throw new ArgumentNullException(nameof(source));
var header = await MqttPacketReader.ReadHeaderFromSourceAsync(source).ConfigureAwait(false);
var body = new byte[header.BodyLength];
if (header.BodyLength > 0)
var header = await MqttPacketReader.ReadHeaderFromSourceAsync(source, _readBuffer).ConfigureAwait(false);
var body = await GetBody(source, header).ConfigureAwait(false);
using (var mqttPacketReader = new MqttPacketReader(body, header))
{
await MqttPacketReader.ReadFromSourceAsync(source, body).ConfigureAwait(false);
}
using (var mqttPacketReader = new MqttPacketReader(new MemoryStream(body), header))
{
switch (header.ControlPacketType)
{
case MqttControlPacketType.Connect:
@@ -221,6 +218,17 @@ namespace MQTTnet.Core.Serializer
}
}
private async Task<MemoryStream> GetBody(IMqttCommunicationChannel source, MqttPacketHeader header)
{
if (header.BodyLength > 0)
{
var segment = await MqttPacketReader.ReadFromSourceAsync(source, header.BodyLength, _readBuffer).ConfigureAwait(false);
return new MemoryStream(segment.Array, segment.Offset, segment.Count);
}
return new MemoryStream();
}
private static MqttBasePacket DeserializeUnsubscribe(MqttPacketReader reader)
{
var packet = new MqttUnsubscribePacket