protected byte[] ReadBinaryBuffer(int length)
{
if (length == 0) return ArrayUtils.EmptyBytes;
byte[] peek = readBuffers.Peek().AsBytes(_ctx.StringEncoding);
Debug.Assert(peek.Length >= readPosition);
if (peek.Length - readPosition >= length)
{
// Great! We can just take a sub-data.
byte[] data = new byte[length];
Array.Copy(peek, readPosition, data, 0, length);
readPosition += length;
if (peek.Length == readPosition)
{
// We just consumed the entire string. Dequeue it.
DropReadBuffer();
}
return data;
}
else
{
// Start building the data from the remainder in the buffer.
int buffered = this.ReadBufferLength;
if (buffered < length) length = buffered;
byte[] data = new byte[length];
int copied = peek.Length - readPosition;
Array.Copy(peek, readPosition, data, 0, copied); readPosition += copied;
length -= copied;
// We just consumed the entire data. Dequeue it.
DropReadBuffer();
while (length > 0)
{
peek = readBuffers.Peek().AsBytes(_ctx.StringEncoding);
if (peek.Length > length)
{
// This data is long enough. It is the last one.
Array.Copy(peek, 0, data, copied, length);
readPosition = length;
length = 0;
break;
}
else
{
// Append just another whole buffer to the array.
Array.Copy(peek, 0, data, copied, peek.Length);
length -= peek.Length;
copied += peek.Length;
DropReadBuffer();
// When this is the last buffer (it's probably an EOF), return.
if (readBuffers.Count == 0)
break;
}
} // while
Debug.Assert(copied > 0);
if (copied < length)
{
byte[] sub = new byte[copied];
Array.Copy(data, 0, sub, 0, copied);
return sub;
}
return data;
} // else
}