Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MemoryStream.CanWrite to allow read-only #67

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions System.IO.Streams/MemoryStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class MemoryStream : Stream
private readonly bool _expandable;
// Is this stream open or closed?
private bool _isOpen;
// Is the stream writable
private bool _isWritable;

private const int MemStreamMaxLength = 0xFFFF;

Expand All @@ -50,6 +52,7 @@ public MemoryStream()
// Must be 0 for byte[]'s created by MemoryStream
_origin = 0;
_isOpen = true;
_isWritable = true;
}

/// <summary>
Expand All @@ -61,9 +64,6 @@ public MemoryStream()
/// <para>
/// The <see cref="CanRead"/>, <see cref="CanSeek"/>, and <see cref="CanWrite"/> properties are all set to <see langword="true"/>.
/// </para>
/// <para>
/// The capacity of the current stream automatically increases when you use the <see cref="SetLength"/> method to set the length to a value larger than the capacity of the current stream.
/// </para>
/// </remarks>
public MemoryStream(byte[] buffer)
{
Expand All @@ -73,6 +73,24 @@ public MemoryStream(byte[] buffer)
_expandable = false;
_origin = 0;
_isOpen = true;
_isWritable = true;
}

/// <summary>
/// Initializes a new non-resizable instance of the <see cref="MemoryStream"/> class based on the specified byte array with the <see cref="CanWrite"/> property set as specified.
/// </summary>
/// <param name="buffer">The array of unsigned bytes from which to create the current stream.</param>
/// <param name="isWritable">A bool indicating whether the stream should be writable</param>
/// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
public MemoryStream(byte[] buffer, bool isWritable)
{
_buffer = buffer ?? throw new ArgumentNullException();
mizady marked this conversation as resolved.
Show resolved Hide resolved

_length = _capacity = buffer.Length;
_expandable = false;
_origin = 0;
_isOpen = true;
_isWritable = isWritable;
}

/// <summary>
Expand Down Expand Up @@ -115,7 +133,7 @@ public MemoryStream(byte[] buffer)
/// If the stream is closed, this property returns <see langword="false"/>.
/// </para>
/// </remarks>
public override bool CanWrite => _isOpen;
public override bool CanWrite => _isWritable;

/// <inheritdoc/>
protected override void Dispose(bool disposing)
Expand Down Expand Up @@ -335,6 +353,11 @@ public override void SetLength(long value)
{
EnsureOpen();

if(!CanWrite)
mizady marked this conversation as resolved.
Show resolved Hide resolved
{
throw new NotSupportedException();
}

if (value > MemStreamMaxLength || value < 0)
{
throw new ArgumentOutOfRangeException();
Expand Down Expand Up @@ -377,6 +400,11 @@ public override void Write(byte[] buffer, int offset, int count)
{
EnsureOpen();

if (!CanWrite)
{
throw new NotSupportedException();
}

if (buffer == null)
{
throw new ArgumentNullException();
Expand Down Expand Up @@ -417,6 +445,11 @@ public override void WriteByte(byte value)
{
EnsureOpen();

if (!CanWrite)
{
throw new NotSupportedException();
}

if (_position >= _capacity)
{
EnsureCapacity(_position + 1);
Expand Down
14 changes: 14 additions & 0 deletions UnitTests/MemoryStreamUnitTests/CanWrite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,19 @@ public void CanWrite_Byte_Ctor()
OutputHelper.WriteLine($"Unexpected exception {ex}");
}
}

[TestMethod]
public void CanWrite_bool_false_Ctor()
mizady marked this conversation as resolved.
Show resolved Hide resolved
{
// Arrange
byte[] buffer = new byte[1024];

// Act
using MemoryStream fs = new MemoryStream(buffer, false);

// Assert
Assert.IsFalse(fs.CanWrite, "Expected CanWrite == false, but got CanWrite == true");
Assert.ThrowsException(typeof(NotSupportedException), () => fs.WriteByte(0), "Expected exception when attempt to write to a read only stream.");
}
}
}