Skip to content

Commit b533ef0

Browse files
authored
Add ReadOnlySpan and Span overloads (#87)
1 parent 1146d14 commit b533ef0

29 files changed

Lines changed: 782 additions & 438 deletions

System.IO.Streams/MemoryStream.cs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ public MemoryStream(byte[] buffer) : this(buffer, true) { }
7272
/// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
7373
public MemoryStream(byte[] buffer, bool isWritable)
7474
{
75-
_buffer = buffer ?? throw new ArgumentNullException();
75+
ArgumentNullException.ThrowIfNull(buffer);
7676

77+
_buffer = buffer;
7778
_length = _capacity = buffer.Length;
7879
_expandable = false;
7980
_origin = 0;
@@ -181,7 +182,7 @@ public override long Position
181182
{
182183
EnsureOpen();
183184

184-
if (value < 0 || value > MemStreamMaxLength)
185+
if (value is < 0 or > MemStreamMaxLength)
185186
{
186187
throw new ArgumentOutOfRangeException();
187188
}
@@ -196,7 +197,7 @@ public override int Read(Span<byte> buffer)
196197
{
197198
EnsureOpen();
198199

199-
var bytesToRead = _length - _position;
200+
int bytesToRead = _length - _position;
200201

201202
if (bytesToRead > buffer.Length)
202203
{
@@ -209,7 +210,6 @@ public override int Read(Span<byte> buffer)
209210
}
210211

211212
new Span<byte>(_buffer, _position, bytesToRead).CopyTo(buffer);
212-
213213
_position += bytesToRead;
214214

215215
return bytesToRead;
@@ -384,10 +384,7 @@ public override void Write(byte[] buffer, int offset, int count)
384384
EnsureOpen();
385385
EnsureWritable();
386386

387-
if (buffer == null)
388-
{
389-
throw new ArgumentNullException();
390-
}
387+
ArgumentNullException.ThrowIfNull(buffer);
391388

392389
if (offset < 0 || count < 0)
393390
{
@@ -399,44 +396,59 @@ public override void Write(byte[] buffer, int offset, int count)
399396
throw new ArgumentException();
400397
}
401398

402-
int i = _position + count;
399+
int newPosition = _position + count;
403400

404401
// check for overflow
405-
if (i > _length)
402+
if (newPosition > _length)
406403
{
407-
if (i > _capacity)
404+
if (newPosition > _capacity)
408405
{
409-
EnsureCapacity(i);
406+
EnsureCapacity(newPosition);
410407
}
411408

412-
_length = i;
409+
_length = newPosition;
413410
}
414411

415-
Array.Copy(buffer, offset, _buffer, _position, count);
416-
_position = i;
412+
new Span<byte>(buffer, offset, count).CopyTo(new Span<byte>(_buffer, _position, count));
413+
_position = newPosition;
417414
}
418415

419-
/// <inheritdoc/>
420-
/// <exception cref="ObjectDisposedException"></exception>
416+
/// <summary>
417+
/// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
418+
/// </summary>
419+
/// <param name="buffer">A region of memory. This method copies the contents of this region to the current stream.</param>
420+
/// <exception cref="ObjectDisposedException">The current stream instance is closed.</exception>
421421
/// <exception cref="NotSupportedException">The stream buffer does not have the capacity to hold the
422422
/// data and is not expandable, and/or the stream is not writable.</exception>
423-
/// <exception cref="ArgumentOutOfRangeException">The MemoryStream max size was exceeded</exception>
424-
public override void WriteByte(byte value)
423+
/// <exception cref="ArgumentOutOfRangeException">The MemoryStream max size was exceeded.</exception>
424+
/// <remarks>
425+
/// Use the <see cref="CanWrite"/> property to determine whether the current instance supports writing.
426+
/// If the write operation is successful, the position within the stream advances by the number of bytes written.
427+
/// If an exception occurs, the position within the stream remains unchanged.
428+
/// </remarks>
429+
public override void Write(ReadOnlySpan<byte> buffer)
425430
{
426431
EnsureOpen();
427432
EnsureWritable();
428433

429-
if (_position >= _capacity)
434+
int count = buffer.Length;
435+
int newPosition = _position + count;
436+
437+
// check for overflow
438+
if (newPosition > _length)
430439
{
431-
EnsureCapacity(_position + 1);
440+
if (newPosition > _capacity)
441+
{
442+
EnsureCapacity(newPosition);
443+
}
444+
445+
_length = newPosition;
432446
}
433447

434-
_buffer[_position++] = value;
448+
// Copy ReadOnlySpan to buffer
449+
buffer.CopyTo(new Span<byte>(_buffer, _position, count));
435450

436-
if (_position > _length)
437-
{
438-
_length = _position;
439-
}
451+
_position = newPosition;
440452
}
441453

442454
/// <summary>

System.IO.Streams/Properties/AssemblyInfo.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using System.Reflection;
2-
using System.Runtime.CompilerServices;
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Reflection;
36
using System.Runtime.InteropServices;
47

58
// General Information about an assembly is controlled through the following
@@ -15,3 +18,6 @@
1518
// COM, set the ComVisible attribute to true on that type.
1619
[assembly: ComVisible(false)]
1720

21+
// Mark the assembly as CLS compliant
22+
[assembly: CLSCompliant(true)]
23+

System.IO.Streams/SeekOrigin.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,44 @@
1-
//
2-
// Copyright (c) .NET Foundation and Contributors
3-
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
4-
// See LICENSE file in the project root for full license information.
5-
//
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
63

74
namespace System.IO
85
{
96
/// <summary>
107
/// Specifies the position in a stream to use for seeking.
118
/// </summary>
12-
/// <remarks>These constants match Win32's FILE_BEGIN, FILE_CURRENT, and FILE_END</remarks>
9+
/// <remarks>
10+
/// <para>
11+
/// <see cref="SeekOrigin"/> is used by the Seek methods of <see cref="Stream"/>, <see cref="MemoryStream"/>, and other streams.
12+
/// </para>
13+
/// <para>
14+
/// These constants match Win32's FILE_BEGIN, FILE_CURRENT, and FILE_END values.
15+
/// </para>
16+
/// </remarks>
1317
[Serializable]
1418
public enum SeekOrigin
1519
{
1620
/// <summary>
1721
/// Specifies the beginning of a stream.
1822
/// </summary>
23+
/// <remarks>
24+
/// Seeking to the beginning of a stream sets the position to zero.
25+
/// </remarks>
1926
Begin = 0,
2027

2128
/// <summary>
2229
/// Specifies the current position within a stream.
2330
/// </summary>
31+
/// <remarks>
32+
/// Seeking relative to the current position allows you to move forward or backward from the current position by specifying a positive or negative offset.
33+
/// </remarks>
2434
Current = 1,
2535

2636
/// <summary>
2737
/// Specifies the end of a stream.
2838
/// </summary>
39+
/// <remarks>
40+
/// Seeking relative to the end of a stream allows you to position at or before the end by specifying a zero or negative offset.
41+
/// </remarks>
2942
End = 2,
3043
}
3144
}

0 commit comments

Comments
 (0)