private async Task ReadSegmentAsync(int size)
{
if(_disposed)
throw new ObjectDisposedException("FrameReader");
if(_remainingInBuffer + _unreadFromStream < size)
throw new IOException("Trying to read beyond frame length!");
if(size > _buffer.Length)
{
//size does not fit in current buffer. Get a larger one
var buf = MemoryPool.Instance.Take(size);
//copy already read bytes
Buffer.BlockCopy(_buffer, _position, buf, 0, _remainingInBuffer);
//return old buffer, replace it with new
MemoryPool.Instance.Return(_buffer);
_buffer = buf;
_position = 0;
}
//shift remaining buffer content to start if necessary
if(_position + size > _buffer.Length)
{
Buffer.BlockCopy(_buffer, _position, _buffer, 0, _remainingInBuffer);
_position = 0;
}
while(!TryGetSegmentFromBuffer(size))
{
//fill up the buffer with more data
int offset = _position + _remainingInBuffer;
//read
int extra = await ReadAsync(_buffer, offset, _buffer.Length - offset).AutoConfigureAwait();
if(extra == 0)
throw new IOException("Unexpected end of stream reached");
_remainingInBuffer += extra;
}
}