public override void Write(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed);
if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream);
long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition
long len = Interlocked.Read(ref _length);
long n = pos + count;
// Check for overflow
if (n < 0)
throw new IOException(SR.IO_StreamTooLong);
if (n > _capacity)
{
throw new NotSupportedException(SR.IO_FixedCapacity);
}
// Check to see whether we are now expanding the stream and must
// zero any memory in the middle.
if (pos > len)
{
unsafe
{
Helpers.ZeroMemory(_mem + len, pos - len);
}
}
// set length after zeroing memory to avoid race condition of accessing unzeroed memory
if (n > len)
{
Interlocked.Exchange(ref _length, n);
}
unsafe
{
Marshal.Copy(buffer, offset, (IntPtr)(_mem + pos), count);
}
Interlocked.Exchange(ref _position, n);
return;
}