[System.Security.SecuritySafeCritical] // auto-generated 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(); // Keep contract validation in sync with WriteAsync(..) if (!_isOpen) { throw Error.GetStreamIsClosed(); } if (!CanWrite) { throw Error.GetWriteNotSupported(); } 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); } if (_buffer == null) { // Check to see whether we are now expanding the stream and must // zero any memory in the middle. if (pos > len) { unsafe { 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 { fixed(byte *pBuffer = buffer) { if (_buffer != null) { long bytesLeft = _capacity - pos; if (bytesLeft < count) { throw new ArgumentException(SR.Arg_BufferTooSmall); } byte *pointer = null; try { _buffer.AcquirePointer(ref pointer); Buffer.MemoryCopy(source: pBuffer + offset, destination: pointer + pos + _offset, destinationSizeInBytes: count, sourceBytesToCopy: count); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } else { Buffer.MemoryCopy(source: pBuffer + offset, destination: _mem + pos, destinationSizeInBytes: count, sourceBytesToCopy: count); } } } Interlocked.Exchange(ref _position, n); return; }
[System.Security.SecuritySafeCritical] // auto-generated public override void WriteByte(byte value) { if (!_isOpen) { throw Error.GetStreamIsClosed(); } if (!CanWrite) { throw Error.GetWriteNotSupported(); } long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition long len = Interlocked.Read(ref _length); long n = pos + 1; if (pos >= len) { // 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. // don't do if created from SafeBuffer if (_buffer == null) { if (pos > len) { unsafe { ZeroMemory(_mem + len, pos - len); } } // set length after zeroing memory to avoid race condition of accessing unzeroed memory Interlocked.Exchange(ref _length, n); } } if (_buffer != null) { unsafe { byte *pointer = null; try { _buffer.AcquirePointer(ref pointer); *(pointer + pos + _offset) = value; } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } } else { unsafe { _mem[pos] = value; } } Interlocked.Exchange(ref _position, n); }
[System.Security.SecuritySafeCritical] // auto-generated public override int Read([In, Out] 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(); // Keep this in sync with contract validation in ReadAsync if (!_isOpen) { throw Error.GetStreamIsClosed(); } if (!CanRead) { throw Error.GetReadNotSupported(); } // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. long pos = Interlocked.Read(ref _position); long len = Interlocked.Read(ref _length); long n = len - pos; if (n > count) { n = count; } if (n <= 0) { return(0); } int nInt = (int)n; // Safe because n <= count, which is an Int32 if (nInt < 0) { return(0); // _position could be beyond EOF } Debug.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1. unsafe { fixed(byte *pBuffer = buffer) { if (_buffer != null) { byte *pointer = null; try { _buffer.AcquirePointer(ref pointer); Buffer.MemoryCopy(source: pointer + pos + _offset, destination: pBuffer + offset, destinationSizeInBytes: nInt, sourceBytesToCopy: nInt); } finally { if (pointer != null) { _buffer.ReleasePointer(); } } } else { Buffer.MemoryCopy(source: _mem + pos, destination: pBuffer + offset, destinationSizeInBytes: nInt, sourceBytesToCopy: nInt); } } } Interlocked.Exchange(ref _position, pos + n); return(nInt); }