Skip to content

Commit

Permalink
Read whole frame before touching the buffer
Browse files Browse the repository at this point in the history
References #30
  • Loading branch information
andreashuber-lawo committed Nov 30, 2016
1 parent 42687c4 commit 0fe0115
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions Lawo.EmberPlusSharp/S101/DeframingStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,27 @@ internal sealed class DeframingStream : BufferStream
public sealed override async Task<int> ReadAsync(
byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (this.state == State.AfterFrame)
if (this.state != State.AfterFrame)
{
return 0;
// We're reading the full frame before touching the passed buffer, so that we have a chance to silently
// throw away data if it turns out to be invalid. This is necessary so that we can correctly
// communicate with consumers and providers which mix Ember+ data with other data. For example,
// vsmStudio often sends a first Ember message followed by an Ember+ message.
var readBuffer = this.ReadBuffer;

while (((readBuffer.Index < readBuffer.Count) || await readBuffer.ReadAsync(cancellationToken)) &&
this.ReadByte(readBuffer))
{
}
}

var readBuffer = this.ReadBuffer;
var index = offset;
var pastEnd = offset + count;

while ((index < pastEnd) && ((readBuffer.Index < readBuffer.Count) ||
await readBuffer.ReadAsync(cancellationToken)) && this.ReadByte(readBuffer, buffer, ref index))
// The last 2 bytes are the CRC
while ((index < pastEnd) && (this.decodedQueue.Count > 2))
{
buffer[index++] = this.decodedQueue.Dequeue();
}

return index - offset;
Expand All @@ -52,7 +61,7 @@ internal DeframingStream(ReadBuffer readBuffer, Action<byte> outOfFrameByteRecei

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

private readonly Queue<byte> decodedQueue = new Queue<byte>();
private readonly Queue<byte> decodedQueue = new Queue<byte>(64);
private readonly Action<byte> outOfFrameByteReceived;
private State state;
private ushort crc = 0xFFFF;
Expand All @@ -73,7 +82,7 @@ private enum State
AfterFrame
}

private bool ReadByte(ReadBuffer readBuffer, byte[] buffer, ref int index)
private bool ReadByte(ReadBuffer readBuffer)
{
var currentByte = readBuffer[readBuffer.Index++];

Expand Down Expand Up @@ -133,11 +142,6 @@ private bool ReadByte(ReadBuffer readBuffer, byte[] buffer, ref int index)
break;
}

if (this.decodedQueue.Count == 3)
{
buffer[index++] = this.decodedQueue.Dequeue();
}

return true;
}
}
Expand Down

0 comments on commit 0fe0115

Please sign in to comment.