From 3b8f1c943548bd2612794b42c715f8a53b7bd3a7 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Thu, 5 Dec 2019 22:50:08 +0100 Subject: [PATCH] Implement SequenceReader.TryPeek(long offset, out T value) (#346) * address PR feedback * Update src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs Co-Authored-By: Ahson Khan * address PR feedback --- .../System.Memory/src/System/Buffers/SequenceReader.cs | 14 ++++++++++---- .../System.Memory/tests/SequenceReader/BasicTests.cs | 1 - 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs index 18d75cd..b3ca47a 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs @@ -124,8 +124,8 @@ namespace System.Buffers /// Peeks at the next value at specific offset without advancing the reader. /// /// The offset from current position. - /// The next value or default if at the end. - /// False if at the end of the reader. + /// The next value, or the default value if at the end of the reader. + /// true if the reader is not at its end and the peek operation succeeded; false if at the end of the reader. public readonly bool TryPeek(long offset, out T value) { if (offset < 0) @@ -138,9 +138,15 @@ namespace System.Buffers return false; } + // Sum CurrentSpanIndex + offset could overflow as is but the value of offset should be very large + // because we check Remaining <= offset above so to overflow we should have a ReadOnlySequence close to 8 exabytes + Debug.Assert(CurrentSpanIndex + offset >= 0); + // If offset doesn't fall inside current segment move to next until we find correct one if ((CurrentSpanIndex + offset) <= CurrentSpan.Length - 1) { + Debug.Assert(offset <= int.MaxValue); + value = CurrentSpan[CurrentSpanIndex + (int)offset]; return true; } @@ -150,12 +156,12 @@ namespace System.Buffers SequencePosition nextPosition = _nextPosition; ReadOnlyMemory currentMemory = default; - while (Sequence.TryGet(ref nextPosition, out currentMemory, true)) + while (Sequence.TryGet(ref nextPosition, out currentMemory, advance: true)) { // Skip empty segment if (currentMemory.Length > 0) { - if (remainingOffset > currentMemory.Length - 1) + if (remainingOffset >= currentMemory.Length) { // Subtract current non consumed data remainingOffset -= currentMemory.Length; diff --git a/src/libraries/System.Memory/tests/SequenceReader/BasicTests.cs b/src/libraries/System.Memory/tests/SequenceReader/BasicTests.cs index e5c0625..75cfde3 100644 --- a/src/libraries/System.Memory/tests/SequenceReader/BasicTests.cs +++ b/src/libraries/System.Memory/tests/SequenceReader/BasicTests.cs @@ -241,7 +241,6 @@ namespace System.Memory.Tests.SequenceReader Assert.Equal(default, defaultValue); } - [Fact] public void TryPeekOffset_MultiSegment_StarAhead() { -- 2.7.4