Skip to content

Commit 20b7a95

Browse files
committed
Switched MemoryStream to generic type
1 parent 49e504d commit 20b7a95

File tree

9 files changed

+411
-372
lines changed

9 files changed

+411
-372
lines changed

Microsoft.Toolkit.HighPerformance/Extensions/IMemoryOwnerExtensions.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using System.Diagnostics.Contracts;
77
using System.IO;
88
using System.Runtime.CompilerServices;
9-
using Microsoft.Toolkit.HighPerformance.Streams;
9+
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;
1010

1111
namespace Microsoft.Toolkit.HighPerformance.Extensions
1212
{
@@ -18,17 +18,17 @@ public static class IMemoryOwnerExtensions
1818
/// <summary>
1919
/// Returns a <see cref="Stream"/> wrapping the contents of the given <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.
2020
/// </summary>
21-
/// <param name="memory">The input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.</param>
22-
/// <returns>A <see cref="Stream"/> wrapping the data within <paramref name="memory"/>.</returns>
21+
/// <param name="memoryOwner">The input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.</param>
22+
/// <returns>A <see cref="Stream"/> wrapping the data within <paramref name="memoryOwner"/>.</returns>
2323
/// <remarks>
2424
/// The caller does not need to track the lifetime of the input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/>
2525
/// instance, as the returned <see cref="Stream"/> will take care of disposing that buffer when it is closed.
2626
/// </remarks>
2727
[Pure]
2828
[MethodImpl(MethodImplOptions.AggressiveInlining)]
29-
public static Stream AsStream(this IMemoryOwner<byte> memory)
29+
public static Stream AsStream(this IMemoryOwner<byte> memoryOwner)
3030
{
31-
return new IMemoryOwnerStream(memory);
31+
return MemoryStream.Create(memoryOwner);
3232
}
3333
}
3434
}

Microsoft.Toolkit.HighPerformance/Extensions/MemoryExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static class MemoryExtensions
3030
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3131
public static Stream AsStream(this Memory<byte> memory)
3232
{
33-
return new MemoryStream(memory);
33+
return MemoryStream.Create(memory, true);
3434
}
3535
}
3636
}

Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlyMemoryExtensions.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System;
66
using System.Diagnostics.Contracts;
77
using System.IO;
8-
using System.Runtime.CompilerServices;
98
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;
109

1110
namespace Microsoft.Toolkit.HighPerformance.Extensions
@@ -27,10 +26,9 @@ public static class ReadOnlyMemoryExtensions
2726
/// as the returned <see cref="Stream"/> is in use, to avoid unexpected issues.
2827
/// </remarks>
2928
[Pure]
30-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3129
public static Stream AsStream(this ReadOnlyMemory<byte> memory)
3230
{
33-
return new MemoryStream(memory);
31+
return MemoryStream.Create(memory, false);
3432
}
3533
}
3634
}

Microsoft.Toolkit.HighPerformance/Streams/IMemoryOwnerStream.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System;
56
using System.Buffers;
67
using System.IO;
78

@@ -10,29 +11,33 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
1011
/// <summary>
1112
/// A <see cref="Stream"/> implementation wrapping an <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.
1213
/// </summary>
13-
internal sealed class IMemoryOwnerStream : MemoryStream
14+
/// <typeparam name="TSource">The type of source to use for the underlying data.</typeparam>
15+
internal sealed class IMemoryOwnerStream<TSource> : MemoryStream<TSource>
16+
where TSource : struct, ISpanOwner
1417
{
1518
/// <summary>
16-
/// The <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance currently in use.
19+
/// The <see cref="IDisposable"/> instance currently in use.
1720
/// </summary>
18-
private readonly IMemoryOwner<byte> memory;
21+
private readonly IDisposable disposable;
1922

2023
/// <summary>
21-
/// Initializes a new instance of the <see cref="IMemoryOwnerStream"/> class.
24+
/// Initializes a new instance of the <see cref="IMemoryOwnerStream{TSource}"/> class.
2225
/// </summary>
23-
/// <param name="memory">The input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance to use.</param>
24-
public IMemoryOwnerStream(IMemoryOwner<byte> memory)
25-
: base(memory.Memory)
26+
/// <param name="source">The input <typeparamref name="TSource"/> instance to use.</param>
27+
/// <param name="isReadOnly">Indicates whether <paramref name="source"/> can be written to.</param>
28+
/// <param name="disposable">The <see cref="IDisposable"/> instance currently in use.</param>
29+
public IMemoryOwnerStream(TSource source, bool isReadOnly, IDisposable disposable)
30+
: base(source, isReadOnly)
2631
{
27-
this.memory = memory;
32+
this.disposable = disposable;
2833
}
2934

3035
/// <inheritdoc/>
3136
protected override void Dispose(bool disposing)
3237
{
3338
base.Dispose(disposing);
3439

35-
this.memory.Dispose();
40+
this.disposable.Dispose();
3641
}
3742
}
3843
}
Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,49 @@
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-
// See the LICENSE file in the project root for more information.
4-
5-
using System;
1+
using System;
62
using System.IO;
7-
using System.Runtime.CompilerServices;
83

94
namespace Microsoft.Toolkit.HighPerformance.Streams
105
{
116
/// <summary>
12-
/// A <see cref="Stream"/> implementation wrapping a <see cref="Memory{T}"/> or <see cref="ReadOnlyMemory{T}"/> instance.
7+
/// A factory class to produce <see cref="MemoryStream{TSource}"/> instances.
138
/// </summary>
14-
internal partial class MemoryStream
9+
internal static partial class MemoryStream
1510
{
11+
/// <summary>
12+
/// Throws an <see cref="ArgumentException"/> when trying to write too many bytes to the target stream.
13+
/// </summary>
14+
public static void ThrowArgumentExceptionForEndOfStreamOnWrite()
15+
{
16+
throw new ArgumentException("The current stream can't contain the requested input data.");
17+
}
18+
19+
/// <summary>
20+
/// Throws a <see cref="NotSupportedException"/> when trying to set the length of the stream.
21+
/// </summary>
22+
public static void ThrowNotSupportedExceptionForSetLength()
23+
{
24+
throw new NotSupportedException("Setting the length is not supported for this stream.");
25+
}
26+
27+
/// <summary>
28+
/// Throws an <see cref="ArgumentException"/> when using an invalid seek mode.
29+
/// </summary>
30+
/// <returns>Nothing, as this method throws unconditionally.</returns>
31+
public static long ThrowArgumentExceptionForSeekOrigin()
32+
{
33+
throw new ArgumentException("The input seek mode is not valid.", "origin");
34+
}
35+
1636
/// <summary>
1737
/// Throws an <see cref="ArgumentOutOfRangeException"/> when setting the <see cref="Stream.Position"/> property.
1838
/// </summary>
19-
[MethodImpl(MethodImplOptions.NoInlining)]
2039
private static void ThrowArgumentOutOfRangeExceptionForPosition()
2140
{
22-
throw new ArgumentOutOfRangeException(nameof(Position), "The value for the property was not in the valid range.");
41+
throw new ArgumentOutOfRangeException(nameof(Stream.Position), "The value for the property was not in the valid range.");
2342
}
2443

2544
/// <summary>
2645
/// Throws an <see cref="ArgumentNullException"/> when an input buffer is <see langword="null"/>.
2746
/// </summary>
28-
[MethodImpl(MethodImplOptions.NoInlining)]
2947
private static void ThrowArgumentNullExceptionForBuffer()
3048
{
3149
throw new ArgumentNullException("buffer", "The buffer is null.");
@@ -34,7 +52,6 @@ private static void ThrowArgumentNullExceptionForBuffer()
3452
/// <summary>
3553
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the input count is negative.
3654
/// </summary>
37-
[MethodImpl(MethodImplOptions.NoInlining)]
3855
private static void ThrowArgumentOutOfRangeExceptionForOffset()
3956
{
4057
throw new ArgumentOutOfRangeException("offset", "Offset can't be negative.");
@@ -43,7 +60,6 @@ private static void ThrowArgumentOutOfRangeExceptionForOffset()
4360
/// <summary>
4461
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the input count is negative.
4562
/// </summary>
46-
[MethodImpl(MethodImplOptions.NoInlining)]
4763
private static void ThrowArgumentOutOfRangeExceptionForCount()
4864
{
4965
throw new ArgumentOutOfRangeException("count", "Count can't be negative.");
@@ -52,7 +68,6 @@ private static void ThrowArgumentOutOfRangeExceptionForCount()
5268
/// <summary>
5369
/// Throws an <see cref="ArgumentException"/> when the sum of offset and count exceeds the length of the target buffer.
5470
/// </summary>
55-
[MethodImpl(MethodImplOptions.NoInlining)]
5671
private static void ThrowArgumentExceptionForLength()
5772
{
5873
throw new ArgumentException("The sum of offset and count can't be larger than the buffer length.", "buffer");
@@ -61,47 +76,17 @@ private static void ThrowArgumentExceptionForLength()
6176
/// <summary>
6277
/// Throws a <see cref="NotSupportedException"/> when trying to write on a readonly stream.
6378
/// </summary>
64-
[MethodImpl(MethodImplOptions.NoInlining)]
6579
private static void ThrowNotSupportedExceptionForCanWrite()
6680
{
6781
throw new NotSupportedException("The current stream doesn't support writing.");
6882
}
6983

70-
/// <summary>
71-
/// Throws an <see cref="ArgumentException"/> when trying to write too many bytes to the target stream.
72-
/// </summary>
73-
[MethodImpl(MethodImplOptions.NoInlining)]
74-
private static void ThrowArgumentExceptionForEndOfStreamOnWrite()
75-
{
76-
throw new ArgumentException("The current stream can't contain the requested input data.");
77-
}
78-
79-
/// <summary>
80-
/// Throws a <see cref="NotSupportedException"/> when trying to set the length of the stream.
81-
/// </summary>
82-
[MethodImpl(MethodImplOptions.NoInlining)]
83-
private static void ThrowNotSupportedExceptionForSetLength()
84-
{
85-
throw new NotSupportedException("Setting the length is not supported for this stream.");
86-
}
87-
88-
/// <summary>
89-
/// Throws an <see cref="ArgumentException"/> when using an invalid seek mode.
90-
/// </summary>
91-
/// <returns>Nothing, as this method throws unconditionally.</returns>
92-
[MethodImpl(MethodImplOptions.NoInlining)]
93-
private static long ThrowArgumentExceptionForSeekOrigin()
94-
{
95-
throw new ArgumentException("The input seek mode is not valid.", "origin");
96-
}
97-
9884
/// <summary>
9985
/// Throws an <see cref="ObjectDisposedException"/> when using a disposed <see cref="Stream"/> instance.
10086
/// </summary>
101-
[MethodImpl(MethodImplOptions.NoInlining)]
10287
private static void ThrowObjectDisposedException()
10388
{
104-
throw new ObjectDisposedException(nameof(memory), "The current stream has already been disposed");
89+
throw new ObjectDisposedException("source", "The current stream has already been disposed");
10590
}
10691
}
10792
}

Microsoft.Toolkit.HighPerformance/Streams/MemoryStream.Validate.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
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-
// See the LICENSE file in the project root for more information.
4-
5-
using System.IO;
1+
using System.IO;
62
using System.Runtime.CompilerServices;
73

84
namespace Microsoft.Toolkit.HighPerformance.Streams
95
{
106
/// <summary>
11-
/// A <see cref="Stream"/> implementation wrapping a <see cref="System.Memory{T}"/> or <see cref="System.ReadOnlyMemory{T}"/> instance.
7+
/// A factory class to produce <see cref="MemoryStream{TSource}"/> instances.
128
/// </summary>
13-
internal partial class MemoryStream
9+
internal static partial class MemoryStream
1410
{
1511
/// <summary>
1612
/// Validates the <see cref="Stream.Position"/> argument.
1713
/// </summary>
1814
/// <param name="position">The new <see cref="Stream.Position"/> value being set.</param>
1915
/// <param name="length">The maximum length of the target <see cref="Stream"/>.</param>
2016
[MethodImpl(MethodImplOptions.AggressiveInlining)]
21-
private static void ValidatePosition(long position, int length)
17+
public static void ValidatePosition(long position, int length)
2218
{
2319
if ((ulong)position >= (ulong)length)
2420
{
@@ -33,7 +29,7 @@ private static void ValidatePosition(long position, int length)
3329
/// <param name="offset">The offset within <paramref name="buffer"/>.</param>
3430
/// <param name="count">The number of elements to process within <paramref name="buffer"/>.</param>
3531
[MethodImpl(MethodImplOptions.AggressiveInlining)]
36-
private static void ValidateBuffer(byte[]? buffer, int offset, int count)
32+
public static void ValidateBuffer(byte[]? buffer, int offset, int count)
3733
{
3834
if (buffer is null)
3935
{
@@ -57,24 +53,24 @@ private static void ValidateBuffer(byte[]? buffer, int offset, int count)
5753
}
5854

5955
/// <summary>
60-
/// Validates the <see cref="CanWrite"/> property.
56+
/// Validates the <see cref="MemoryStream{TSource}.CanWrite"/> property.
6157
/// </summary>
6258
[MethodImpl(MethodImplOptions.AggressiveInlining)]
63-
private void ValidateCanWrite()
59+
public static void ValidateCanWrite(bool canWrite)
6460
{
65-
if (!CanWrite)
61+
if (!canWrite)
6662
{
6763
ThrowNotSupportedExceptionForCanWrite();
6864
}
6965
}
7066

7167
/// <summary>
72-
/// Validates that the current instance hasn't been disposed.
68+
/// Validates that a given <see cref="Stream"/> instance hasn't been disposed.
7369
/// </summary>
7470
[MethodImpl(MethodImplOptions.AggressiveInlining)]
75-
private void ValidateDisposed()
71+
public static void ValidateDisposed(bool disposed)
7672
{
77-
if (this.disposed)
73+
if (disposed)
7874
{
7975
ThrowObjectDisposedException();
8076
}

0 commit comments

Comments
 (0)