public override void Write(byte[] buffer, int offset, int count)
{
this.CheckDisposed();
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", offset, "Offset must be in the range of 0 - buffer.Length-1");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", count, "count must be non-negative");
}
if (count + offset > buffer.Length)
{
throw new ArgumentException("count must be greater than buffer.Length - offset");
}
int blockSize = this.memoryManager.BlockSize;
long end = (long)this.position + count;
// Check for overflow
if (end > MaxStreamLength)
{
throw new IOException("Maximum capacity exceeded");
}
long requiredBuffers = (end + blockSize - 1) / blockSize;
if (requiredBuffers * blockSize > MaxStreamLength)
{
throw new IOException("Maximum capacity exceeded");
}
this.EnsureCapacity((int)end);
if (this.largeBuffer == null)
{
int bytesRemaining = count;
int bytesWritten = 0;
var blockAndOffset = this.GetBlockAndRelativeOffset(this.position);
while (bytesRemaining > 0)
{
byte[] currentBlock = this.blocks[blockAndOffset.Block];
int remainingInBlock = blockSize - blockAndOffset.Offset;
int amountToWriteInBlock = Math.Min(remainingInBlock, bytesRemaining);
Buffer.BlockCopy(buffer, offset + bytesWritten, currentBlock, blockAndOffset.Offset, amountToWriteInBlock);
bytesRemaining -= amountToWriteInBlock;
bytesWritten += amountToWriteInBlock;
++blockAndOffset.Block;
blockAndOffset.Offset = 0;
}
}
else
{
Buffer.BlockCopy(buffer, offset, this.largeBuffer, this.position, count);
}
this.position = (int)end;
this.length = Math.Max(this.position, this.length);
}