Implement SequenceReader.TryPeek(long offset, out T value) (#346)
authorMarco Rossignoli <marco.rossignoli@gmail.com>
Thu, 5 Dec 2019 21:50:08 +0000 (22:50 +0100)
committerAhson Khan <ahson_ahmedk@yahoo.com>
Thu, 5 Dec 2019 21:50:08 +0000 (13:50 -0800)
* address PR feedback

* Update src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs

Co-Authored-By: Ahson Khan <ahkha@microsoft.com>
* address PR feedback

src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs
src/libraries/System.Memory/tests/SequenceReader/BasicTests.cs

index 18d75cd..b3ca47a 100644 (file)
@@ -124,8 +124,8 @@ namespace System.Buffers
         /// Peeks at the next value at specific offset without advancing the reader.
         /// </summary>
         /// <param name="offset">The offset from current position.</param>
-        /// <param name="value">The next value or default if at the end.</param>
-        /// <returns>False if at the end of the reader.</returns>
+        /// <param name="value">The next value, or the default value if at the end of the reader.</param>
+        /// <returns><c>true</c> if the reader is not at its end and the peek operation succeeded; <c>false</c> if at the end of the reader.</returns>
         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<T> 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;
index e5c0625..75cfde3 100644 (file)
@@ -241,7 +241,6 @@ namespace System.Memory.Tests.SequenceReader
             Assert.Equal(default, defaultValue);
         }
 
-
         [Fact]
         public void TryPeekOffset_MultiSegment_StarAhead()
         {