summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/IO/MemoryStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/IO/MemoryStream.cs')
-rw-r--r--src/mscorlib/src/System/IO/MemoryStream.cs112
1 files changed, 60 insertions, 52 deletions
diff --git a/src/mscorlib/src/System/IO/MemoryStream.cs b/src/mscorlib/src/System/IO/MemoryStream.cs
index edb583b9b5..bdddc83818 100644
--- a/src/mscorlib/src/System/IO/MemoryStream.cs
+++ b/src/mscorlib/src/System/IO/MemoryStream.cs
@@ -19,6 +19,7 @@ using System;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
@@ -61,7 +62,7 @@ namespace System.IO {
public MemoryStream(int capacity) {
if (capacity < 0) {
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
}
Contract.EndContractBlock();
@@ -79,7 +80,7 @@ namespace System.IO {
}
public MemoryStream(byte[] buffer, bool writable) {
- if (buffer == null) throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ if (buffer == null) throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
Contract.EndContractBlock();
_buffer = buffer;
_length = _capacity = buffer.Length;
@@ -99,11 +100,11 @@ namespace System.IO {
public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), 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 - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -180,7 +181,6 @@ namespace System.IO {
public override void Flush() {
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task FlushAsync(CancellationToken cancellationToken) {
@@ -259,7 +259,7 @@ namespace System.IO {
if (n > count) n = count;
if (n < 0) n = 0;
- Contract.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
+ Debug.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
_position += n;
return n;
}
@@ -276,7 +276,7 @@ namespace System.IO {
set {
// Only update the capacity if the MS is expandable and the value is different than the current capacity.
// Special behavior if the MS isn't expandable: we don't throw if value is the same as the current capacity
- if (value < Length) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ if (value < Length) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
Contract.Ensures(_capacity - _origin == value);
Contract.EndContractBlock();
@@ -312,25 +312,25 @@ namespace System.IO {
}
set {
if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.Ensures(Position == value);
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
if (value > MemStreamMaxLength)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
_position = _origin + (int)value;
}
}
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();
@@ -342,7 +342,7 @@ namespace System.IO {
if (n <= 0)
return 0;
- Contract.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
+ Debug.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
if (n <= 8)
{
@@ -357,16 +357,15 @@ namespace System.IO {
return n;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task<int> ReadAsync(Byte[] buffer, int offset, int 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(...)
@@ -379,7 +378,7 @@ namespace System.IO {
{
int n = Read(buffer, offset, count);
var t = _lastReadTask;
- Contract.Assert(t == null || t.Status == TaskStatus.RanToCompletion,
+ Debug.Assert(t == null || t.Status == TaskStatus.RanToCompletion,
"Expected that a stored last task completed successfully");
return (t != null && t.Result == n) ? t : (_lastReadTask = Task.FromResult<int>(n));
}
@@ -402,36 +401,46 @@ namespace System.IO {
return _buffer[_position++];
}
+ public override void CopyTo(Stream destination, int bufferSize)
+ {
+ // Since we did not originally override this method, validate the arguments
+ // the same way Stream does for back-compat.
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
- public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) {
-
- // This implementation offers beter performance compared to the base class version.
-
- // The parameter checks must be in sync with the base version:
- if (destination == null)
- throw new ArgumentNullException("destination");
+ // If we have been inherited into a subclass, the following implementation could be incorrect
+ // since it does not call through to Read() which a subclass might have overridden.
+ // To be safe we will only use this implementation in cases where we know it is safe to do so,
+ // and delegate to our base class (which will call into Read) when we are not sure.
+ if (GetType() != typeof(MemoryStream))
+ {
+ base.CopyTo(destination, bufferSize);
+ return;
+ }
- if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ int originalPosition = _position;
- if (!CanRead && !CanWrite)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ // Seek to the end of the MemoryStream.
+ int remaining = InternalEmulateRead(_length - originalPosition);
- if (!destination.CanRead && !destination.CanWrite)
- throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ // If we were already at or past the end, there's no copying to do so just quit.
+ if (remaining > 0)
+ {
+ // Call Write() on the other Stream, using our internal buffer and avoiding any
+ // intermediary allocations.
+ destination.Write(_buffer, originalPosition, remaining);
+ }
+ }
- if (!CanRead)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
+ public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) {
- if (!destination.CanWrite)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
+ // This implementation offers beter performance compared to the base class version.
- Contract.EndContractBlock();
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
// If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Read() or Write() which a subclass might have overriden.
+ // since it does not call through to ReadAsync() which a subclass might have overridden.
// To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Read/Write) when we are not sure.
+ // and delegate to our base class (which will call into ReadAsync) when we are not sure.
if (this.GetType() != typeof(MemoryStream))
return base.CopyToAsync(destination, bufferSize, cancellationToken);
@@ -467,7 +476,7 @@ namespace System.IO {
if (!_isOpen) __Error.StreamIsClosed();
if (offset > MemStreamMaxLength)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
switch(loc) {
case SeekOrigin.Begin: {
int tempPosition = unchecked(_origin + (int)offset);
@@ -494,7 +503,7 @@ namespace System.IO {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin"));
}
- Contract.Assert(_position >= 0, "_position >= 0");
+ Debug.Assert(_position >= 0, "_position >= 0");
return _position;
}
@@ -510,16 +519,16 @@ namespace System.IO {
//
public override void SetLength(long value) {
if (value < 0 || value > Int32.MaxValue) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
}
Contract.Ensures(_length - _origin == value);
Contract.EndContractBlock();
EnsureWriteable();
// Origin wasn't publicly exposed above.
- Contract.Assert(MemStreamMaxLength == Int32.MaxValue); // Check parameter validation logic in this method if this fails.
+ Debug.Assert(MemStreamMaxLength == Int32.MaxValue); // Check parameter validation logic in this method if this fails.
if (value > (Int32.MaxValue - _origin)) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
}
int newLength = _origin + (int)value;
@@ -540,11 +549,11 @@ namespace System.IO {
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();
@@ -580,16 +589,15 @@ namespace System.IO {
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(Byte[] buffer, int offset, int 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(...)
@@ -636,7 +644,7 @@ namespace System.IO {
// Writes this MemoryStream to another stream.
public virtual void WriteTo(Stream stream) {
if (stream==null)
- throw new ArgumentNullException("stream", Environment.GetResourceString("ArgumentNull_Stream"));
+ throw new ArgumentNullException(nameof(stream), Environment.GetResourceString("ArgumentNull_Stream"));
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();