Skip to content

Commit 98aff98

Browse files
authored
Merge pull request #535 from CommunityToolkit/dev/stream-read-exactly
Use Stream.ReadExactly on .NET 7
2 parents 4600382 + cf451e8 commit 98aff98

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

src/CommunityToolkit.HighPerformance/Extensions/StreamExtensions.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,21 @@ public static void Write(this Stream stream, ReadOnlySpan<byte> buffer)
198198
/// <typeparam name="T">The type of value to read.</typeparam>
199199
/// <param name="stream">The source <see cref="Stream"/> instance to read from.</param>
200200
/// <returns>The <typeparamref name="T"/> value read from <paramref name="stream"/>.</returns>
201-
/// <exception cref="InvalidOperationException">Thrown if <paramref name="stream"/> reaches the end.</exception>
201+
/// <exception cref="EndOfStreamException">Thrown if <paramref name="stream"/> reaches the end.</exception>
202202
#if NETSTANDARD2_1_OR_GREATER
203203
[MethodImpl(MethodImplOptions.AggressiveInlining)]
204204
#endif
205205
public static unsafe T Read<T>(this Stream stream)
206206
where T : unmanaged
207207
{
208-
#if NETSTANDARD2_1_OR_GREATER
209-
T result = default;
208+
#if NET7_0_OR_GREATER
209+
T result;
210+
211+
stream.ReadExactly(new Span<byte>(&result, sizeof(T)));
212+
213+
return result;
214+
#elif NETSTANDARD2_1_OR_GREATER
215+
T result;
210216
int bytesOffset = 0;
211217

212218
// As per Stream.Read's documentation:
@@ -220,7 +226,7 @@ public static unsafe T Read<T>(this Stream stream)
220226
// A return value of 0 indicates that the end of the stream has been reached
221227
if (bytesRead == 0)
222228
{
223-
ThrowInvalidOperationExceptionForEndOfStream();
229+
ThrowEndOfStreamException();
224230
}
225231

226232
bytesOffset += bytesRead;
@@ -240,7 +246,7 @@ public static unsafe T Read<T>(this Stream stream)
240246

241247
if (bytesRead == 0)
242248
{
243-
ThrowInvalidOperationExceptionForEndOfStream();
249+
ThrowEndOfStreamException();
244250
}
245251

246252
bytesOffset += bytesRead;
@@ -293,11 +299,13 @@ public static unsafe void Write<T>(this Stream stream, in T value)
293299
#endif
294300
}
295301

302+
#if !NET7_0_OR_GREATER
296303
/// <summary>
297-
/// Throws an <see cref="InvalidOperationException"/> when <see cref="Read{T}"/> fails.
304+
/// Throws an <see cref="EndOfStreamException"/> when <see cref="Read{T}"/> fails.
298305
/// </summary>
299-
private static void ThrowInvalidOperationExceptionForEndOfStream()
306+
private static void ThrowEndOfStreamException()
300307
{
301-
throw new InvalidOperationException("The stream didn't contain enough data to read the requested item.");
308+
throw new EndOfStreamException("The stream didn't contain enough data to read the requested item.");
302309
}
310+
#endif
303311
}

tests/CommunityToolkit.HighPerformance.UnitTests/Extensions/Test_StreamExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void Test_StreamExtensions_ReadWrite()
3434
Assert.AreEqual(3.14f, stream.Read<float>());
3535
Assert.AreEqual(unchecked(uint.MaxValue * 324823489204ul), stream.Read<ulong>());
3636

37-
_ = Assert.ThrowsException<InvalidOperationException>(() => stream.Read<long>());
37+
_ = Assert.ThrowsException<EndOfStreamException>(() => stream.Read<long>());
3838
}
3939

4040
// See https://github.com/CommunityToolkit/dotnet/issues/513
@@ -55,7 +55,7 @@ public void Test_StreamExtensions_ReadWrite_WithBufferedStream()
5555
Assert.AreEqual(3.14f, stream.Read<float>());
5656
Assert.AreEqual(unchecked(uint.MaxValue * 324823489204ul), stream.Read<ulong>());
5757

58-
_ = Assert.ThrowsException<InvalidOperationException>(() => stream.Read<long>());
58+
_ = Assert.ThrowsException<EndOfStreamException>(() => stream.Read<long>());
5959
}
6060

6161
private sealed class BufferedStream : MemoryStream

0 commit comments

Comments
 (0)