summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs')
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs187
1 files changed, 89 insertions, 98 deletions
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
index 6b506ea5b1..d78632639b 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
@@ -19,6 +19,7 @@ using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading.Tasks;
@@ -43,7 +44,7 @@ namespace System.IO {
*
* It may become necessary to add in some sort of
* DeallocationMode enum, specifying whether we unmap a section of memory,
- * call free, run a user-provided delegate to free the memory, etc etc.
+ * call free, run a user-provided delegate to free the memory, etc.
* We'll suggest user write a subclass of UnmanagedMemoryStream that uses
* a SafeHandle subclass to hold onto the memory.
* Check for problems when using this in the negative parts of a
@@ -76,7 +77,7 @@ namespace System.IO {
* a. a race condition in WriteX that could have allowed a thread to
* read from unzeroed memory was fixed
* b. memory region cannot be expanded beyond _capacity; in other
- * words, a UMS creator is saying a writeable UMS is safe to
+ * words, a UMS creator is saying a writable UMS is safe to
* write to anywhere in the memory range up to _capacity, specified
* in the ctor. Even if the caller doesn't specify a capacity, then
* length is used as the capacity.
@@ -85,22 +86,19 @@ namespace System.IO {
{
private const long UnmanagedMemStreamMaxLength = Int64.MaxValue;
- [System.Security.SecurityCritical] // auto-generated
private SafeBuffer _buffer;
- [SecurityCritical]
private unsafe byte* _mem;
private long _length;
private long _capacity;
private long _position;
private long _offset;
private FileAccess _access;
- internal bool _isOpen;
+ internal bool _isOpen;
[NonSerialized]
private Task<Int32> _lastReadTask; // The last successful task returned from ReadAsync
// Needed for subclasses that need to map a file, etc.
- [System.Security.SecuritySafeCritical] // auto-generated
protected UnmanagedMemoryStream()
{
unsafe {
@@ -109,12 +107,10 @@ namespace System.IO {
_isOpen = false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length) {
Initialize(buffer, offset, length, FileAccess.Read, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access) {
Initialize(buffer, offset, length, access, false);
}
@@ -122,32 +118,29 @@ namespace System.IO {
// We must create one of these without doing a security check. This
// class is created while security is trying to start up. Plus, doing
// a Demand from Assembly.GetManifestResourceStream isn't useful.
- [System.Security.SecurityCritical] // auto-generated
internal UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) {
Initialize(buffer, offset, length, access, skipSecurityCheck);
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access) {
Initialize(buffer, offset, length, access, false);
}
- [System.Security.SecurityCritical] // auto-generated
internal void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) {
if (buffer == null) {
- throw new ArgumentNullException("buffer");
+ throw new ArgumentNullException(nameof(buffer));
}
if (offset < 0) {
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (length < 0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (buffer.ByteLength < (ulong)(offset + length)) {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen"));
}
if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
- throw new ArgumentOutOfRangeException("access");
+ throw new ArgumentOutOfRangeException(nameof(access));
}
Contract.EndContractBlock();
@@ -185,14 +178,12 @@ namespace System.IO {
_isOpen = true;
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe UnmanagedMemoryStream(byte* pointer, long length)
{
Initialize(pointer, length, length, FileAccess.Read, false);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access)
{
@@ -202,41 +193,39 @@ namespace System.IO {
// We must create one of these without doing a security check. This
// class is created while security is trying to start up. Plus, doing
// a Demand from Assembly.GetManifestResourceStream isn't useful.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck)
{
Initialize(pointer, length, capacity, access, skipSecurityCheck);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access)
{
Initialize(pointer, length, capacity, access, false);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck)
{
if (pointer == null)
- throw new ArgumentNullException("pointer");
+ throw new ArgumentNullException(nameof(pointer));
if (length < 0 || capacity < 0)
- throw new ArgumentOutOfRangeException((length < 0) ? "length" : "capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((length < 0) ? nameof(length) : nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (length > capacity)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
Contract.EndContractBlock();
// Check for wraparound.
if (((byte*) ((long)pointer + capacity)) < pointer)
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
if (access < FileAccess.Read || access > FileAccess.ReadWrite)
- throw new ArgumentOutOfRangeException("access", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(access), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
if (_isOpen)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
- if (!skipSecurityCheck)
+ if (!skipSecurityCheck) {
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
+ }
_mem = pointer;
_offset = 0;
@@ -261,7 +250,6 @@ namespace System.IO {
get { return _isOpen && (_access & FileAccess.Write) != 0; }
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected override void Dispose(bool disposing)
{
_isOpen = false;
@@ -277,7 +265,6 @@ namespace System.IO {
if (!_isOpen) __Error.StreamIsClosed();
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task FlushAsync(CancellationToken cancellationToken) {
@@ -316,10 +303,9 @@ namespace System.IO {
Contract.EndContractBlock();
return Interlocked.Read(ref _position);
}
- [System.Security.SecuritySafeCritical] // auto-generated
set {
if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (!CanSeek) __Error.StreamIsClosed();
@@ -327,7 +313,7 @@ namespace System.IO {
unsafe {
// On 32 bit machines, ensure we don't wrap around.
if (value > (long) Int32.MaxValue || _mem + value < _mem)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
}
#endif
Interlocked.Exchange(ref _position, value);
@@ -336,7 +322,6 @@ namespace System.IO {
[CLSCompliant(false)]
public unsafe byte* PositionPointer {
- [System.Security.SecurityCritical] // auto-generated_required
get {
if (_buffer != null) {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
@@ -350,7 +335,6 @@ namespace System.IO {
if (!_isOpen) __Error.StreamIsClosed();
return ptr;
}
- [System.Security.SecurityCritical] // auto-generated_required
set {
if (_buffer != null)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
@@ -368,7 +352,6 @@ namespace System.IO {
}
internal unsafe byte* Pointer {
- [System.Security.SecurityCritical] // auto-generated
get {
if (_buffer != null)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
@@ -377,14 +360,13 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override int Read([In, Out] byte[] buffer, int offset, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // Keep this in sync with contract validation in ReadAsync
@@ -404,42 +386,49 @@ namespace System.IO {
int nInt = (int) n; // Safe because n <= count, which is an Int32
if (nInt < 0)
- nInt = 0; // _position could be beyond EOF
- Contract.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.
-
- if (_buffer != null) {
- unsafe {
- byte* pointer = null;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- _buffer.AcquirePointer(ref pointer);
- Buffer.Memcpy(buffer, offset, pointer + pos + _offset, 0, nInt);
- }
- finally {
- if (pointer != null) {
- _buffer.ReleasePointer();
+ 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;
+
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ _buffer.AcquirePointer(ref pointer);
+ Buffer.Memcpy(pBuffer + offset, pointer + pos + _offset, nInt);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
+ _buffer.ReleasePointer();
+ }
}
}
- }
- }
- else {
- unsafe {
- Buffer.Memcpy(buffer, offset, _mem + pos, 0, nInt);
+ else
+ {
+ Buffer.Memcpy(pBuffer + offset, _mem + pos, nInt);
+ }
}
}
Interlocked.Exchange(ref _position, pos + n);
return nInt;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // contract validation copied from Read(...)
@@ -455,12 +444,11 @@ namespace System.IO {
} catch (Exception ex) {
- Contract.Assert(! (ex is OperationCanceledException));
+ Debug.Assert(! (ex is OperationCanceledException));
return Task.FromException<Int32>(ex);
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override int ReadByte() {
if (!_isOpen) __Error.StreamIsClosed();
if (!CanRead) __Error.ReadNotSupported();
@@ -497,7 +485,7 @@ namespace System.IO {
public override long Seek(long offset, SeekOrigin loc) {
if (!_isOpen) __Error.StreamIsClosed();
if (offset > UnmanagedMemStreamMaxLength)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength"));
switch(loc) {
case SeekOrigin.Begin:
if (offset < 0)
@@ -524,11 +512,10 @@ namespace System.IO {
}
long finalPos = Interlocked.Read(ref _position);
- Contract.Assert(finalPos >= 0, "_position >= 0");
+ Debug.Assert(finalPos >= 0, "_position >= 0");
return finalPos;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void SetLength(long value) {
if (value < 0)
throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
@@ -554,14 +541,13 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void Write(byte[] buffer, int offset, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // Keep contract validation in sync with WriteAsync(..)
@@ -595,46 +581,52 @@ namespace System.IO {
}
}
- if (_buffer != null) {
-
- long bytesLeft = _capacity - pos;
- if (bytesLeft < count) {
- throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
- }
+ unsafe
+ {
+ fixed (byte* pBuffer = buffer)
+ {
+ if (_buffer != null)
+ {
+ long bytesLeft = _capacity - pos;
+ if (bytesLeft < count)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
+ }
- unsafe {
- byte* pointer = null;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- _buffer.AcquirePointer(ref pointer);
- Buffer.Memcpy(pointer + pos + _offset, 0, buffer, offset, count);
- }
- finally {
- if (pointer != null) {
- _buffer.ReleasePointer();
+ byte* pointer = null;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ _buffer.AcquirePointer(ref pointer);
+ Buffer.Memcpy(pointer + pos + _offset, pBuffer + offset, count);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
+ _buffer.ReleasePointer();
+ }
}
}
- }
- }
- else {
- unsafe {
- Buffer.Memcpy(_mem + pos, 0, buffer, offset, count);
+ else
+ {
+ Buffer.Memcpy(_mem + pos, pBuffer + offset, count);
+ }
}
}
Interlocked.Exchange(ref _position, n);
return;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // contract validation copied from Write(..)
@@ -649,13 +641,12 @@ namespace System.IO {
} catch (Exception ex) {
- Contract.Assert(! (ex is OperationCanceledException));
+ Debug.Assert(! (ex is OperationCanceledException));
return Task.FromException<Int32>(ex);
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void WriteByte(byte value) {
if (!_isOpen) __Error.StreamIsClosed();
if (!CanWrite) __Error.WriteNotSupported();
@@ -674,7 +665,7 @@ namespace System.IO {
// 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 (_buffer == null) {
if (pos > len) {
unsafe {
Buffer.ZeroMemory(_mem+len, pos-len);