From 9c3c9b1fcfb2b557fecb6b1c9e9b3c4d219d20f9 Mon Sep 17 00:00:00 2001 From: Linus Hamlin Date: Fri, 3 Jul 2026 15:14:02 +0200 Subject: [PATCH 1/7] Add SequenceReaderExtensions.TryPeek* --- .../System.Memory/ref/System.Memory.cs | 6 + .../SequenceReaderExtensions.Binary.cs | 158 ++++++++++++++++++ 2 files changed, 164 insertions(+) diff --git a/src/libraries/System.Memory/ref/System.Memory.cs b/src/libraries/System.Memory/ref/System.Memory.cs index f373f41d19195f..c4621756268e3b 100644 --- a/src/libraries/System.Memory/ref/System.Memory.cs +++ b/src/libraries/System.Memory/ref/System.Memory.cs @@ -111,6 +111,12 @@ public partial struct Enumerator } public static partial class SequenceReaderExtensions { + public static bool TryPeekBigEndian(this ref System.Buffers.SequenceReader reader, out short value) { throw null; } + public static bool TryPeekBigEndian(this ref System.Buffers.SequenceReader reader, out int value) { throw null; } + public static bool TryPeekBigEndian(this ref System.Buffers.SequenceReader reader, out long value) { throw null; } + public static bool TryPeekLittleEndian(this ref System.Buffers.SequenceReader reader, out short value) { throw null; } + public static bool TryPeekLittleEndian(this ref System.Buffers.SequenceReader reader, out int value) { throw null; } + public static bool TryPeekLittleEndian(this ref System.Buffers.SequenceReader reader, out long value) { throw null; } public static bool TryReadBigEndian(this ref System.Buffers.SequenceReader reader, out short value) { throw null; } public static bool TryReadBigEndian(this ref System.Buffers.SequenceReader reader, out int value) { throw null; } public static bool TryReadBigEndian(this ref System.Buffers.SequenceReader reader, out long value) { throw null; } diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs index 3e739afec755b2..028b19a736c2f0 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs @@ -169,5 +169,163 @@ private static bool TryReadReverseEndianness(ref SequenceReader reader, ou return false; } + + /// + /// Try to peek the given type out of the buffer if possible. Warning: this is dangerous to use with arbitrary + /// structs- see remarks for full details. + /// + /// + /// IMPORTANT: The read is a straight copy of bits. If a struct depends on specific state of it's members to + /// behave correctly this can lead to exceptions, etc. If reading endian specific integers, use the explicit + /// overloads such as + /// + /// + /// True if successful. will be default if failed. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static unsafe bool TryPeek(ref this SequenceReader reader, out T value) where T : unmanaged + { + ReadOnlySpan span = reader.UnreadSpan; + if (span.Length < sizeof(T)) + return TryPeekMultisegment(ref reader, out value); + + value = MemoryMarshal.Read(span); + return true; + } + + private static unsafe bool TryPeekMultisegment(ref SequenceReader reader, out T value) where T : unmanaged + { + Debug.Assert(reader.UnreadSpan.Length < sizeof(T)); + + // Not enough data in the current segment, try to peek for the data we need. + T buffer = default; + Span tempSpan = new Span(&buffer, sizeof(T)); + + if (!reader.TryCopyTo(tempSpan)) + { + value = default; + return false; + } + + value = MemoryMarshal.Read(tempSpan); + return true; + } + + /// + /// Reads an as little endian. + /// + /// False if there wasn't enough data for an . + public static bool TryPeekLittleEndian(ref this SequenceReader reader, out short value) + { + if (BitConverter.IsLittleEndian) + { + return reader.TryPeek(out value); + } + + return TryPeekReverseEndianness(ref reader, out value); + } + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryPeekBigEndian(ref this SequenceReader reader, out short value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryPeek(out value); + } + + return TryPeekReverseEndianness(ref reader, out value); + } + + private static bool TryPeekReverseEndianness(ref SequenceReader reader, out short value) + { + if (reader.TryPeek(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + + /// + /// Reads an as little endian. + /// + /// False if there wasn't enough data for an . + public static bool TryPeekLittleEndian(ref this SequenceReader reader, out int value) + { + if (BitConverter.IsLittleEndian) + { + return reader.TryPeek(out value); + } + + return TryPeekReverseEndianness(ref reader, out value); + } + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryPeekBigEndian(ref this SequenceReader reader, out int value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryPeek(out value); + } + + return TryPeekReverseEndianness(ref reader, out value); + } + + private static bool TryPeekReverseEndianness(ref SequenceReader reader, out int value) + { + if (reader.TryPeek(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } + + /// + /// Reads an as little endian. + /// + /// False if there wasn't enough data for an . + public static bool TryPeekLittleEndian(ref this SequenceReader reader, out long value) + { + if (BitConverter.IsLittleEndian) + { + return reader.TryPeek(out value); + } + + return TryPeekReverseEndianness(ref reader, out value); + } + + /// + /// Reads an as big endian. + /// + /// False if there wasn't enough data for an . + public static bool TryPeekBigEndian(ref this SequenceReader reader, out long value) + { + if (!BitConverter.IsLittleEndian) + { + return reader.TryPeek(out value); + } + + return TryPeekReverseEndianness(ref reader, out value); + } + + private static bool TryPeekReverseEndianness(ref SequenceReader reader, out long value) + { + if (reader.TryPeek(out value)) + { + value = BinaryPrimitives.ReverseEndianness(value); + return true; + } + + return false; + } } } From 8f054fd3574c13a447b8d89c14805e58f5b9b596 Mon Sep 17 00:00:00 2001 From: Linus Hamlin Date: Fri, 3 Jul 2026 15:14:06 +0200 Subject: [PATCH 2/7] Add tests --- .../tests/SequenceReader/BinaryExtensions.cs | 93 ++++++++++++++++++- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Memory/tests/SequenceReader/BinaryExtensions.cs b/src/libraries/System.Memory/tests/SequenceReader/BinaryExtensions.cs index 5785bb5ca13a4d..576fa750e50d5e 100644 --- a/src/libraries/System.Memory/tests/SequenceReader/BinaryExtensions.cs +++ b/src/libraries/System.Memory/tests/SequenceReader/BinaryExtensions.cs @@ -20,6 +20,7 @@ public void MultiSegmentBytesReaderNumbers() new byte[] { 8, 0 }, new byte[] { 1, }, new byte[] { 0, 2, }, + new byte[] { 6, 7, 8, 9 }, new byte[] { 1, 2, 3, 4 }, new byte[] { 5, 6 }, new byte[] { 7, 8, 9, }, @@ -27,7 +28,7 @@ public void MultiSegmentBytesReaderNumbers() new byte[] { 4, 5 }, new byte[] { 6, 7, 8, 9 }, new byte[] { 0, 1, 2, 3 }, - new byte[] { 4 }, + new byte[] { 4, 6 }, }); SequenceReader reader = new SequenceReader(bytes); @@ -36,34 +37,120 @@ public void MultiSegmentBytesReaderNumbers() Span span = bytesValue.ToArray(); Assert.Equal(0, span[0]); Assert.Equal(1, span[1]); + Assert.Equal(2, span.Length); + Assert.Equal(3, reader.Consumed); Assert.True(reader.TryReadTo(out bytesValue, 5)); span = bytesValue.ToArray(); Assert.Equal(3, span[0]); Assert.Equal(4, span[1]); + Assert.Equal(2, span.Length); + Assert.Equal(6, reader.Consumed); Assert.True(reader.TryReadTo(out bytesValue, new byte[] { 8, 8 })); span = bytesValue.ToArray(); Assert.Equal(6, span[0]); Assert.Equal(7, span[1]); + Assert.Equal(2, span.Length); + Assert.Equal(10, reader.Consumed); Assert.True(SequenceMarshal.TryRead(ref reader, out int intValue)); Assert.Equal(BitConverter.ToInt32(new byte[] { 0, 1, 0, 2 }), intValue); + Assert.Equal(14, reader.Consumed); + + Assert.True(reader.TryPeekLittleEndian(out intValue)); + Assert.Equal(0x09080706, intValue); + Assert.Equal(14, reader.Consumed); + + Assert.True(reader.TryReadLittleEndian(out intValue)); + Assert.Equal(0x09080706, intValue); + Assert.Equal(18, reader.Consumed); + + Assert.True(reader.TryPeekBigEndian(out intValue)); + Assert.Equal(0x01020304, intValue); + Assert.Equal(18, reader.Consumed); Assert.True(reader.TryReadBigEndian(out intValue)); Assert.Equal(0x01020304, intValue); + Assert.Equal(22, reader.Consumed); + + Assert.True(reader.TryPeekLittleEndian(out long longValue)); + Assert.Equal(0x0201000908070605L, longValue); + Assert.Equal(22, reader.Consumed); - Assert.True(reader.TryReadLittleEndian(out long longValue)); + Assert.True(reader.TryReadLittleEndian(out longValue)); Assert.Equal(0x0201000908070605L, longValue); + Assert.Equal(30, reader.Consumed); + + Assert.True(reader.TryPeekBigEndian(out longValue)); + Assert.Equal(0x0304050607080900L, longValue); + Assert.Equal(30, reader.Consumed); Assert.True(reader.TryReadBigEndian(out longValue)); Assert.Equal(0x0304050607080900L, longValue); + Assert.Equal(38, reader.Consumed); + + Assert.True(reader.TryPeekLittleEndian(out short shortValue)); + Assert.Equal(0x0201, shortValue); + Assert.Equal(38, reader.Consumed); - Assert.True(reader.TryReadLittleEndian(out short shortValue)); + Assert.True(reader.TryReadLittleEndian(out shortValue)); Assert.Equal(0x0201, shortValue); + Assert.Equal(40, reader.Consumed); + + Assert.True(reader.TryPeekBigEndian(out shortValue)); + Assert.Equal(0x0304, shortValue); + Assert.Equal(40, reader.Consumed); Assert.True(reader.TryReadBigEndian(out shortValue)); Assert.Equal(0x0304, shortValue); + Assert.Equal(42, reader.Consumed); + + // There is only one byte left, all Try* methods should return false + + Assert.False(SequenceMarshal.TryRead(ref reader, out intValue)); + Assert.Equal(0, intValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryPeekBigEndian(out intValue)); + Assert.Equal(0, intValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryReadBigEndian(out intValue)); + Assert.Equal(0, intValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryPeekLittleEndian(out longValue)); + Assert.Equal(0, longValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryReadLittleEndian(out longValue)); + Assert.Equal(0, longValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryPeekBigEndian(out longValue)); + Assert.Equal(0, longValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryReadBigEndian(out longValue)); + Assert.Equal(0, longValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryPeekLittleEndian(out shortValue)); + Assert.Equal(0, shortValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryReadLittleEndian(out shortValue)); + Assert.Equal(0, shortValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryPeekBigEndian(out shortValue)); + Assert.Equal(0, shortValue); + Assert.Equal(42, reader.Consumed); + + Assert.False(reader.TryReadBigEndian(out shortValue)); + Assert.Equal(0, shortValue); + Assert.Equal(42, reader.Consumed); } } } From dbc0ba0bc91e7c60cc73149b943174245e180f76 Mon Sep 17 00:00:00 2001 From: Linus Hamlin Date: Fri, 3 Jul 2026 15:23:26 +0200 Subject: [PATCH 3/7] Fix xml comments --- .../Buffers/SequenceReaderExtensions.Binary.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs index 028b19a736c2f0..559653160a02bc 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs @@ -146,7 +146,7 @@ public static bool TryReadLittleEndian(ref this SequenceReader reader, out } /// - /// Reads an as big endian. + /// Reads an as big endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryReadBigEndian(ref this SequenceReader reader, out long value) @@ -212,7 +212,7 @@ private static unsafe bool TryPeekMultisegment(ref SequenceReader reade } /// - /// Reads an as little endian. + /// Try peek at an as little endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekLittleEndian(ref this SequenceReader reader, out short value) @@ -226,7 +226,7 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out } /// - /// Reads an as big endian. + /// Try peek at an as big endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekBigEndian(ref this SequenceReader reader, out short value) @@ -251,7 +251,7 @@ private static bool TryPeekReverseEndianness(ref SequenceReader reader, ou } /// - /// Reads an as little endian. + /// Try peek at an as little endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekLittleEndian(ref this SequenceReader reader, out int value) @@ -265,7 +265,7 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out } /// - /// Reads an as big endian. + /// Try peek at an as big endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekBigEndian(ref this SequenceReader reader, out int value) @@ -290,7 +290,7 @@ private static bool TryPeekReverseEndianness(ref SequenceReader reader, ou } /// - /// Reads an as little endian. + /// Try peek at an as little endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekLittleEndian(ref this SequenceReader reader, out long value) @@ -304,7 +304,7 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out } /// - /// Reads an as big endian. + /// Try peek at an as big endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekBigEndian(ref this SequenceReader reader, out long value) From 311b058c7c734ec66795a982d3712fda8028e0b6 Mon Sep 17 00:00:00 2001 From: Linus Schwartz Hamlin <78953007+lilinus@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:07:39 +0200 Subject: [PATCH 4/7] Fix mistake --- .../src/System/Buffers/SequenceReaderExtensions.Binary.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs index 559653160a02bc..144796c635e807 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs @@ -146,7 +146,7 @@ public static bool TryReadLittleEndian(ref this SequenceReader reader, out } /// - /// Reads an as big endian without advancing the reader. + /// Reads an as big endian. /// /// False if there wasn't enough data for an . public static bool TryReadBigEndian(ref this SequenceReader reader, out long value) From 7883a16a9af569dd253d221e101a8b990c787d39 Mon Sep 17 00:00:00 2001 From: Linus Hamlin Date: Tue, 7 Jul 2026 09:30:46 +0200 Subject: [PATCH 5/7] Address feedback --- .../src/System/Buffers/SequenceReaderExtensions.Binary.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs index 144796c635e807..964f5c239e46e4 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs @@ -198,16 +198,15 @@ private static unsafe bool TryPeekMultisegment(ref SequenceReader reade Debug.Assert(reader.UnreadSpan.Length < sizeof(T)); // Not enough data in the current segment, try to peek for the data we need. - T buffer = default; - Span tempSpan = new Span(&buffer, sizeof(T)); + Span tempSpan = [default]; - if (!reader.TryCopyTo(tempSpan)) + if (!reader.TryCopyTo(MemoryMarshal.AsBytes(tempSpan))) { value = default; return false; } - value = MemoryMarshal.Read(tempSpan); + value = tempSpan[0]; return true; } From 7c5852825604ef6cfe124baa188ad9c11088ed69 Mon Sep 17 00:00:00 2001 From: Linus Hamlin Date: Tue, 18 Aug 2026 14:01:55 +0200 Subject: [PATCH 6/7] Switch from unsafe MemoryMarshal to safe BinaryPrimitives methods --- .../SequenceReaderExtensions.Binary.cs | 145 ++++++------------ 1 file changed, 48 insertions(+), 97 deletions(-) diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs index 964f5c239e46e4..d9b4526272a640 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs @@ -170,58 +170,22 @@ private static bool TryReadReverseEndianness(ref SequenceReader reader, ou return false; } - /// - /// Try to peek the given type out of the buffer if possible. Warning: this is dangerous to use with arbitrary - /// structs- see remarks for full details. - /// - /// - /// IMPORTANT: The read is a straight copy of bits. If a struct depends on specific state of it's members to - /// behave correctly this can lead to exceptions, etc. If reading endian specific integers, use the explicit - /// overloads such as - /// - /// - /// True if successful. will be default if failed. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe bool TryPeek(ref this SequenceReader reader, out T value) where T : unmanaged - { - ReadOnlySpan span = reader.UnreadSpan; - if (span.Length < sizeof(T)) - return TryPeekMultisegment(ref reader, out value); - - value = MemoryMarshal.Read(span); - return true; - } - - private static unsafe bool TryPeekMultisegment(ref SequenceReader reader, out T value) where T : unmanaged - { - Debug.Assert(reader.UnreadSpan.Length < sizeof(T)); - - // Not enough data in the current segment, try to peek for the data we need. - Span tempSpan = [default]; - - if (!reader.TryCopyTo(MemoryMarshal.AsBytes(tempSpan))) - { - value = default; - return false; - } - - value = tempSpan[0]; - return true; - } - /// /// Try peek at an as little endian without advancing the reader. /// /// False if there wasn't enough data for an . public static bool TryPeekLittleEndian(ref this SequenceReader reader, out short value) { - if (BitConverter.IsLittleEndian) + if (!BinaryPrimitives.TryReadInt16LittleEndian(reader.UnreadSpan, out value)) { - return reader.TryPeek(out value); + Span tmpSpan = [0, 0]; + if (!reader.TryCopyTo(tmpSpan)) + { + return false; + } + value = BinaryPrimitives.ReadInt16LittleEndian(tmpSpan); } - - return TryPeekReverseEndianness(ref reader, out value); + return true; } /// @@ -230,23 +194,16 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out /// False if there wasn't enough data for an . public static bool TryPeekBigEndian(ref this SequenceReader reader, out short value) { - if (!BitConverter.IsLittleEndian) + if (!BinaryPrimitives.TryReadInt16BigEndian(reader.UnreadSpan, out value)) { - return reader.TryPeek(out value); + Span tmpSpan = [0, 0]; + if (!reader.TryCopyTo(tmpSpan)) + { + return false; + } + value = BinaryPrimitives.ReadInt16BigEndian(tmpSpan); } - - return TryPeekReverseEndianness(ref reader, out value); - } - - private static bool TryPeekReverseEndianness(ref SequenceReader reader, out short value) - { - if (reader.TryPeek(out value)) - { - value = BinaryPrimitives.ReverseEndianness(value); - return true; - } - - return false; + return true; } /// @@ -255,12 +212,16 @@ private static bool TryPeekReverseEndianness(ref SequenceReader reader, ou /// False if there wasn't enough data for an . public static bool TryPeekLittleEndian(ref this SequenceReader reader, out int value) { - if (BitConverter.IsLittleEndian) + if (!BinaryPrimitives.TryReadInt32LittleEndian(reader.UnreadSpan, out value)) { - return reader.TryPeek(out value); + Span tmpSpan = [0, 0, 0, 0]; + if (!reader.TryCopyTo(tmpSpan)) + { + return false; + } + value = BinaryPrimitives.ReadInt32LittleEndian(tmpSpan); } - - return TryPeekReverseEndianness(ref reader, out value); + return true; } /// @@ -269,23 +230,16 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out /// False if there wasn't enough data for an . public static bool TryPeekBigEndian(ref this SequenceReader reader, out int value) { - if (!BitConverter.IsLittleEndian) + if (!BinaryPrimitives.TryReadInt32BigEndian(reader.UnreadSpan, out value)) { - return reader.TryPeek(out value); - } - - return TryPeekReverseEndianness(ref reader, out value); - } - - private static bool TryPeekReverseEndianness(ref SequenceReader reader, out int value) - { - if (reader.TryPeek(out value)) - { - value = BinaryPrimitives.ReverseEndianness(value); - return true; + Span tmpSpan = [0, 0, 0, 0]; + if (!reader.TryCopyTo(tmpSpan)) + { + return false; + } + value = BinaryPrimitives.ReadInt32BigEndian(tmpSpan); } - - return false; + return true; } /// @@ -294,12 +248,16 @@ private static bool TryPeekReverseEndianness(ref SequenceReader reader, ou /// False if there wasn't enough data for an . public static bool TryPeekLittleEndian(ref this SequenceReader reader, out long value) { - if (BitConverter.IsLittleEndian) + if (!BinaryPrimitives.TryReadInt64LittleEndian(reader.UnreadSpan, out value)) { - return reader.TryPeek(out value); + Span tmpSpan = [0, 0, 0, 0, 0, 0, 0, 0]; + if (!reader.TryCopyTo(tmpSpan)) + { + return false; + } + value = BinaryPrimitives.ReadInt64LittleEndian(tmpSpan); } - - return TryPeekReverseEndianness(ref reader, out value); + return true; } /// @@ -308,23 +266,16 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out /// False if there wasn't enough data for an . public static bool TryPeekBigEndian(ref this SequenceReader reader, out long value) { - if (!BitConverter.IsLittleEndian) + if (!BinaryPrimitives.TryReadInt64BigEndian(reader.UnreadSpan, out value)) { - return reader.TryPeek(out value); + Span tmpSpan = [0, 0, 0, 0, 0, 0, 0, 0]; + if (!reader.TryCopyTo(tmpSpan)) + { + return false; + } + value = BinaryPrimitives.ReadInt64BigEndian(tmpSpan); } - - return TryPeekReverseEndianness(ref reader, out value); - } - - private static bool TryPeekReverseEndianness(ref SequenceReader reader, out long value) - { - if (reader.TryPeek(out value)) - { - value = BinaryPrimitives.ReverseEndianness(value); - return true; - } - - return false; + return true; } } } From 983abbca90fcf07df8df3bd04b325555107b9cd5 Mon Sep 17 00:00:00 2001 From: Linus Hamlin Date: Thu, 20 Aug 2026 10:18:44 +0200 Subject: [PATCH 7/7] Fix xml docs --- .../SequenceReaderExtensions.Binary.cs | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs index d9b4526272a640..793fec2e8ea8b6 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReaderExtensions.Binary.cs @@ -171,9 +171,13 @@ private static bool TryReadReverseEndianness(ref SequenceReader reader, ou } /// - /// Try peek at an as little endian without advancing the reader. + /// Tries to peek at an as little endian without advancing the reader. /// - /// False if there wasn't enough data for an . + /// The byte sequence reader instance from which the value is to be peeked. + /// When the method returns, the value peeked out of the byte sequence reader, as little endian. + /// + /// if the peek operation is successful; if there isn't enough data for an . + /// public static bool TryPeekLittleEndian(ref this SequenceReader reader, out short value) { if (!BinaryPrimitives.TryReadInt16LittleEndian(reader.UnreadSpan, out value)) @@ -189,9 +193,13 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out } /// - /// Try peek at an as big endian without advancing the reader. + /// Tries to peek at an as big endian without advancing the reader. /// - /// False if there wasn't enough data for an . + /// The byte sequence reader instance from which the value is to be peeked. + /// When the method returns, the value peeked out of the byte sequence reader, as big endian. + /// + /// if the peek operation is successful; if there isn't enough data for an . + /// public static bool TryPeekBigEndian(ref this SequenceReader reader, out short value) { if (!BinaryPrimitives.TryReadInt16BigEndian(reader.UnreadSpan, out value)) @@ -207,9 +215,13 @@ public static bool TryPeekBigEndian(ref this SequenceReader reader, out sh } /// - /// Try peek at an as little endian without advancing the reader. + /// Tries to peek at an as little endian without advancing the reader. /// - /// False if there wasn't enough data for an . + /// The byte sequence reader instance from which the value is to be peeked. + /// When the method returns, the value peeked out of the byte sequence reader, as little endian. + /// + /// if the peek operation is successful; if there isn't enough data for an . + /// public static bool TryPeekLittleEndian(ref this SequenceReader reader, out int value) { if (!BinaryPrimitives.TryReadInt32LittleEndian(reader.UnreadSpan, out value)) @@ -225,9 +237,13 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out } /// - /// Try peek at an as big endian without advancing the reader. + /// Tries to peek at an as big endian without advancing the reader. /// - /// False if there wasn't enough data for an . + /// The byte sequence reader instance from which the value is to be peeked. + /// When the method returns, the value peeked out of the byte sequence reader, as big endian. + /// + /// if the peek operation is successful; if there isn't enough data for an . + /// public static bool TryPeekBigEndian(ref this SequenceReader reader, out int value) { if (!BinaryPrimitives.TryReadInt32BigEndian(reader.UnreadSpan, out value)) @@ -243,9 +259,13 @@ public static bool TryPeekBigEndian(ref this SequenceReader reader, out in } /// - /// Try peek at an as little endian without advancing the reader. + /// Tries to peek at an as little endian without advancing the reader. /// - /// False if there wasn't enough data for an . + /// The byte sequence reader instance from which the value is to be peeked. + /// When the method returns, the value peeked out of the byte sequence reader, as little endian. + /// + /// if the peek operation is successful; if there isn't enough data for an . + /// public static bool TryPeekLittleEndian(ref this SequenceReader reader, out long value) { if (!BinaryPrimitives.TryReadInt64LittleEndian(reader.UnreadSpan, out value)) @@ -261,9 +281,13 @@ public static bool TryPeekLittleEndian(ref this SequenceReader reader, out } /// - /// Try peek at an as big endian without advancing the reader. + /// Tries to peek at an as big endian without advancing the reader. /// - /// False if there wasn't enough data for an . + /// The byte sequence reader instance from which the value is to be peeked. + /// When the method returns, the value peeked out of the byte sequence reader, as big endian. + /// + /// if the peek operation is successful; if there isn't enough data for an . + /// public static bool TryPeekBigEndian(ref this SequenceReader reader, out long value) { if (!BinaryPrimitives.TryReadInt64BigEndian(reader.UnreadSpan, out value))