Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,21 @@ public static void Write(this Stream stream, ReadOnlySpan<byte> buffer)
/// <typeparam name="T">The type of value to read.</typeparam>
/// <param name="stream">The source <see cref="Stream"/> instance to read from.</param>
/// <returns>The <typeparamref name="T"/> value read from <paramref name="stream"/>.</returns>
/// <exception cref="InvalidOperationException">Thrown if <paramref name="stream"/> reaches the end.</exception>
/// <exception cref="EndOfStreamException">Thrown if <paramref name="stream"/> reaches the end.</exception>
#if NETSTANDARD2_1_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
public static unsafe T Read<T>(this Stream stream)
where T : unmanaged
{
#if NETSTANDARD2_1_OR_GREATER
T result = default;
#if NET7_0_OR_GREATER
T result;

stream.ReadExactly(new Span<byte>(&result, sizeof(T)));

return result;
#elif NETSTANDARD2_1_OR_GREATER
T result;
int bytesOffset = 0;

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

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

if (bytesRead == 0)
{
ThrowInvalidOperationExceptionForEndOfStream();
ThrowEndOfStreamException();
}

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

#if !NET7_0_OR_GREATER
/// <summary>
/// Throws an <see cref="InvalidOperationException"/> when <see cref="Read{T}"/> fails.
/// Throws an <see cref="EndOfStreamException"/> when <see cref="Read{T}"/> fails.
/// </summary>
private static void ThrowInvalidOperationExceptionForEndOfStream()
private static void ThrowEndOfStreamException()
{
throw new InvalidOperationException("The stream didn't contain enough data to read the requested item.");
throw new EndOfStreamException("The stream didn't contain enough data to read the requested item.");
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void Test_StreamExtensions_ReadWrite()
Assert.AreEqual(3.14f, stream.Read<float>());
Assert.AreEqual(unchecked(uint.MaxValue * 324823489204ul), stream.Read<ulong>());

_ = Assert.ThrowsException<InvalidOperationException>(() => stream.Read<long>());
_ = Assert.ThrowsException<EndOfStreamException>(() => stream.Read<long>());
}

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

_ = Assert.ThrowsException<InvalidOperationException>(() => stream.Read<long>());
_ = Assert.ThrowsException<EndOfStreamException>(() => stream.Read<long>());
}

private sealed class BufferedStream : MemoryStream
Expand Down