public void AdvanceSingleBufferSkipsValues()
        {
            SequenceReader <T> reader = new SequenceReader <T>(SequenceFactory.Create(GetInputData(5)));

            Assert.Equal(5, reader.Length);
            Assert.Equal(5, reader.Remaining);
            Assert.Equal(0, reader.Consumed);
            Assert.Equal(0, reader.CurrentSpanIndex);

            // Advance 2 positions
            reader.Advance(2);
            Assert.Equal(5, reader.Length);
            Assert.Equal(3, reader.Remaining);
            Assert.Equal(2, reader.Consumed);
            Assert.Equal(2, reader.CurrentSpanIndex);
            Assert.Equal(InputData[2], reader.CurrentSpan[reader.CurrentSpanIndex]);
            Assert.True(reader.TryPeek(out T value));
            Assert.Equal(InputData[2], value);

            // Advance 2 positions
            reader.Advance(2);
            Assert.Equal(1, reader.Remaining);
            Assert.Equal(4, reader.Consumed);
            Assert.Equal(4, reader.CurrentSpanIndex);
            Assert.Equal(InputData[4], reader.CurrentSpan[reader.CurrentSpanIndex]);
            Assert.True(reader.TryPeek(out value));
            Assert.Equal(InputData[4], value);
        }
Exemple #2
0
        public void Rewind_ByOne()
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { 1, 2 },
                new byte[] { 3, 4 },
                new byte[] { 5, 6, 7, 8 }
            });

            SequenceReader <byte> reader = new SequenceReader <byte>(bytes);

            reader.Advance(1);
            SequenceReader <byte> copy = reader;

            for (int i = 1; i < bytes.Length; i++)
            {
                reader.Advance(i);
                Assert.Equal(i + 1, reader.Consumed);

                for (int j = 0; j < i; j++)
                {
                    reader.Rewind(1);
                    Assert.Equal(i - j, reader.Consumed);
                    Assert.False(reader.End);
                }

                Assert.Equal(copy.Position, reader.Position);
                Assert.Equal(copy.Consumed, reader.Consumed);
                Assert.Equal(copy.CurrentSpanIndex, reader.CurrentSpanIndex);
                Assert.Equal(copy.End, reader.End);
                Assert.True(copy.CurrentSpan.SequenceEqual(reader.CurrentSpan));
            }
        }
Exemple #3
0
        public void TryReadExact_Sequence()
        {
            ReadOnlySequence <int> data = SequenceFactory.Create(new int[][] {
                new int[] { 0 },
                new int[] { 1, 2 },
                new int[] { },
                new int[] { 3, 4 }
            });

            var sequenceReader = new SequenceReader <int>(data);

            Assert.True(sequenceReader.TryReadExact(0, out ReadOnlySequence <int> sequence));
            Assert.Equal(0, sequence.Length);

            for (int i = 0; i < 2; i++)
            {
                Assert.True(sequenceReader.TryReadExact(2, out sequence));
                Assert.Equal(Enumerable.Range(i * 2, 2), sequence.ToArray());
            }

            // There is only 1 item in sequence reader
            Assert.False(sequenceReader.TryReadExact(2, out _));

            // The last 1 item was not advanced so still can be fetched
            Assert.True(sequenceReader.TryReadExact(1, out sequence));
            Assert.Equal(1, sequence.Length);
            Assert.Equal(4, sequence.First.Span[0]);

            Assert.True(sequenceReader.End);
        }
        public void MultiSegmentBytesReaderNumbers()
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { 1, 2 },
                new byte[] { 3, 4 },
                new byte[] { 5, 6, 7, 8 },
                new byte[] { 8, 0 },
                new byte[] { 1, },
                new byte[] { 0, 2, },
                new byte[] { 1, 2, 3, 4 },
                new byte[] { 5, 6 },
                new byte[] { 7, 8, 9, },
                new byte[] { 0, 1, 2, 3 },
                new byte[] { 4, 5 },
                new byte[] { 6, 7, 8, 9 },
                new byte[] { 0, 1, 2, 3 },
                new byte[] { 4 },
            });

            SequenceReader <byte> reader = new SequenceReader <byte>(bytes);

            Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> bytesValue, 2));
            Span <byte> span = bytesValue.ToArray();

            Assert.Equal(0, span[0]);
            Assert.Equal(1, span[1]);

            Assert.True(reader.TryReadTo(out bytesValue, 5));
            span = bytesValue.ToArray();
            Assert.Equal(3, span[0]);
            Assert.Equal(4, span[1]);

            Assert.True(reader.TryReadTo(out bytesValue, new byte[] { 8, 8 }));
            span = bytesValue.ToArray();
            Assert.Equal(6, span[0]);
            Assert.Equal(7, span[1]);

            reader.TryReadExact(4, out _);
            ////Assert.True(reader.TryRead<int>(out int intValue));
            ////Assert.Equal(BitConverter.ToInt32(new byte[] { 0, 1, 0, 2 }, 0), intValue);

            Assert.True(reader.TryReadBigEndian(out int intValue));
            Assert.Equal(0x01020304, intValue);

            Assert.True(reader.TryReadLittleEndian(out long longValue));
            Assert.Equal(0x0201000908070605L, longValue);

            Assert.True(reader.TryReadBigEndian(out longValue));
            Assert.Equal(0x0304050607080900L, longValue);

            Assert.True(reader.TryReadLittleEndian(out short shortValue));
            Assert.Equal(0x0201, shortValue);

            Assert.True(reader.TryReadBigEndian(out shortValue));
            Assert.Equal(0x0304, shortValue);
        }
Exemple #5
0
        public void Advance_Exception()
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { 1, 2 },
                new byte[] { 3, 4 },
                new byte[] { 5, 6, 7, 8 }
            });

            Assert.Throws <ArgumentOutOfRangeException>(() => new SequenceReader <byte>(bytes).Advance(-1));
        }
Exemple #6
0
        public void TryReadTo_NotFound_Sequence(bool advancePastDelimiter)
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 1 },
                new byte[] { 2, 3, 255 }
            });

            SequenceReader <byte> reader = new SequenceReader <byte>(bytes);

            reader.Advance(4);
            Assert.False(reader.TryReadTo(out ReadOnlySequence <byte> span, 255, 0, advancePastDelimiter));
        }
Exemple #7
0
        public void TryReadTo_Sequence(bool advancePastDelimiter, bool useEscapeOverload)
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { 1, 2 },
                new byte[] { },
                new byte[] { 3, 4, 5, 6 }
            });

            SequenceReader <byte> reader = new SequenceReader <byte>(bytes);

            // Read to 0-5
            for (byte i = 0; i < bytes.Length - 1; i++)
            {
                SequenceReader <byte> copy = reader;

                // Can read to the first integer (0-5)
                Assert.True(
                    useEscapeOverload
                        ? copy.TryReadTo(out ReadOnlySequence <byte> sequence, i, 255, advancePastDelimiter)
                        : copy.TryReadTo(out sequence, i, advancePastDelimiter));

                // Should never have a null Position object
                Assert.NotNull(copy.Position.GetObject());
                ReadOnlySequence <byte> .Enumerator enumerator = sequence.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    ;
                }

                // Should be able to read to final 6
                Assert.True(
                    useEscapeOverload
                        ? copy.TryReadTo(out sequence, 6, 255, advancePastDelimiter)
                        : copy.TryReadTo(out sequence, 6, advancePastDelimiter));

                Assert.NotNull(copy.Position.GetObject());
                enumerator = sequence.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    ;
                }

                // If we didn't advance, we should still be able to read to 6
                Assert.Equal(!advancePastDelimiter,
                             useEscapeOverload
                        ? copy.TryReadTo(out sequence, 6, 255, advancePastDelimiter)
                        : copy.TryReadTo(out sequence, 6, advancePastDelimiter));
            }
        }
Exemple #8
0
        public void RewindEmptyFirstSpan()
        {
            // This is to hit the "if (memory.Length == 0)" branch in ResetReader.
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[0],
                new byte[] { 1, 2 },
                new byte[] { 3, 4 }
            });

            var reader = new SequenceReader <byte>(bytes);

            reader.Advance(3);
            Assert.True(reader.IsNext(4));
            reader.Rewind(2);
            Assert.Equal(new byte[] { 1, 2 }, reader.CurrentSpan.ToArray());
        }
Exemple #9
0
        public void IsNext_Value()
        {
            ReadOnlySequence <char> chars = SequenceFactory.Create(new char[][] {
                new char[] { 'A' },
                new char[] { 'B', 'C' },
            });

            var reader = new SequenceReader <char>(chars);

            Assert.False(reader.IsNext('Z', advancePast: false));
            Assert.False(reader.IsNext('B', advancePast: false));
            Assert.True(reader.IsNext('A', advancePast: false));
            Assert.True(reader.IsNext('A', advancePast: true));
            Assert.True(reader.IsNext('B', advancePast: true));
            Assert.True(reader.IsNext('C', advancePast: true));
            Assert.False(reader.IsNext('C', advancePast: true));
            Assert.True(reader.End);
        }
Exemple #10
0
        public void PastEmptySegments()
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { },
                new byte[] { },
                new byte[] { }
            });

            SequenceReader <byte> reader = new SequenceReader <byte>(bytes);

            reader.Advance(1);
            Assert.Equal(0, reader.CurrentSpanIndex);
            Assert.Equal(0, reader.CurrentSpan.Length);
            Assert.False(reader.TryPeek(out byte value));
            ReadOnlySequence <byte> sequence = reader.Sequence.Slice(reader.Position);

            Assert.Equal(0, sequence.Length);
        }
Exemple #11
0
        public void Basic(bool singleSegment)
        {
            byte[] buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            ReadOnlySequence <byte> bytes = singleSegment
                ? new ReadOnlySequence <byte>(buffer)
                : SequenceFactory.CreateSplit(buffer, 2, 4);

            SequenceReader <byte> skipReader = new SequenceReader <byte>(bytes);

            Assert.False(skipReader.TryAdvanceTo(10));
            Assert.True(skipReader.TryAdvanceTo(4, advancePastDelimiter: false));
            Assert.True(skipReader.TryRead(out byte value));
            Assert.Equal(4, value);

            Assert.True(skipReader.TryAdvanceToAny(new byte[] { 3, 12, 7 }, advancePastDelimiter: false));
            Assert.True(skipReader.TryRead(out value));
            Assert.Equal(7, value);
            Assert.Equal(1, skipReader.AdvancePast(8));
            Assert.True(skipReader.TryRead(out value));
            Assert.Equal(9, value);

            skipReader = new SequenceReader <byte>(bytes);
            Assert.Equal(0, skipReader.AdvancePast(2));
            Assert.Equal(3, skipReader.AdvancePastAny(new byte[] { 2, 3, 1 }));
            Assert.True(skipReader.TryRead(out value));
            Assert.Equal(4, value);
            skipReader.Rewind(skipReader.Consumed);
            Assert.Equal(0, skipReader.AdvancePast(2));
            Assert.Equal(3, skipReader.AdvancePastAny(2, 3, 1));
            Assert.True(skipReader.TryRead(out value));
            Assert.Equal(4, value);
            skipReader.Rewind(skipReader.Consumed);
            Assert.Equal(0, skipReader.AdvancePast(2));
            Assert.Equal(3, skipReader.AdvancePastAny(2, 3, 1, 7));
            Assert.True(skipReader.TryRead(out value));
            Assert.Equal(4, value);
            skipReader.Rewind(skipReader.Consumed - 1);
            Assert.Equal(0, skipReader.AdvancePast(1));
            Assert.Equal(2, skipReader.AdvancePastAny(2, 3));
            Assert.True(skipReader.TryRead(out value));
            Assert.Equal(4, value);
        }
Exemple #12
0
        public void TryCopyTo_Multisegment()
        {
            ReadOnlySequence <char> chars = SequenceFactory.Create(new char[][] {
                new char[] { 'A' },
                new char[] { 'B', 'C' },
                new char[] { 'D', 'E', 'F' }
            });

            ReadOnlySpan <char> linear = new char[] { 'A', 'B', 'C', 'D', 'E', 'F' };

            var reader = new SequenceReader <char>(chars);

            // Something to nothing is always possible
            Assert.True(reader.TryCopyTo(Span <char> .Empty));
            Span <char> buffer;

            // Read out ABCDEF, ABCDE, etc.
            for (int i = linear.Length; i > 0; i--)
            {
                buffer = new char[i];
                Assert.True(reader.TryCopyTo(buffer));
                Assert.True(buffer.SequenceEqual(linear.Slice(0, i)));
            }

            buffer = new char[1];

            // Read out one at a time and move through
            for (int i = 0; i < linear.Length; i++)
            {
                Assert.True(reader.TryCopyTo(buffer));
                Assert.True(reader.TryRead(out char value));
                Assert.Equal(buffer[0], value);
            }

            // Trying to get more data than there is will fail
            Assert.False(reader.TryCopyTo(new char[reader.Remaining + 1]));
        }
Exemple #13
0
        public void IsNext_Span()
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { 1, 2 },
                new byte[] { 3, 4 },
                new byte[] { 5, 6, 7, 8 }
            });

            var reader = new SequenceReader <byte>(bytes);

            Assert.True(reader.IsNext(ReadOnlySpan <byte> .Empty, advancePast: false));
            Assert.True(reader.IsNext(ReadOnlySpan <byte> .Empty, advancePast: true));
            Assert.True(reader.IsNext(new byte[] { 0 }, advancePast: false));
            Assert.False(reader.IsNext(new byte[] { 0, 2 }, advancePast: false));
            Assert.False(reader.IsNext(new byte[] { 0, 2 }, advancePast: true));
            Assert.True(reader.IsNext(new byte[] { 0, 1 }, advancePast: false));
            Assert.False(reader.IsNext(new byte[] { 0, 1, 3 }, advancePast: false));
            Assert.True(reader.IsNext(new byte[] { 0, 1, 2 }, advancePast: false));
            Assert.False(reader.IsNext(new byte[] { 0, 1, 2, 4 }, advancePast: false));
            Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3 }, advancePast: false));
            Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3, 4 }, advancePast: false));
            Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5 }, advancePast: false));
            Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, advancePast: false));
            Assert.False(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, advancePast: false));
            Assert.False(reader.IsNext(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, advancePast: true));
            Assert.Equal(0, reader.Consumed);

            Assert.True(reader.IsNext(new byte[] { 0, 1, 2, 3 }, advancePast: true));
            Assert.True(reader.IsNext(new byte[] { 4, 5, 6 }, advancePast: true));
            Assert.True(reader.TryPeek(out byte value));
            Assert.Equal(7, value);

            Assert.True(reader.IsNext(new byte[] { 7, 8 }, advancePast: true));
            Assert.True(reader.End);
        }
Exemple #14
0
        public void Rewind_Exception()
        {
            ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] {
                new byte[] { 0 },
                new byte[] { 1, 2 }
            });

            // Can't go negative
            Assert.Throws <ArgumentOutOfRangeException>(() => new SequenceReader <byte>(bytes).Rewind(-1));

            // Can't pull more than we consumed
            SequenceReader <byte> reader = new SequenceReader <byte>(bytes);

            try
            {
                reader.Rewind(1);
                Assert.True(false, "no exception thrown");
            }
            catch (ArgumentOutOfRangeException)
            {
                // Expected
            }
            Assert.Equal(0, reader.Consumed);

            reader.Advance(1);
            try
            {
                reader.Rewind(2);
                Assert.True(false, "no exception thrown");
            }
            catch (ArgumentOutOfRangeException)
            {
                // Expected
            }
            Assert.Equal(1, reader.Consumed);
        }
Exemple #15
0
        public void TryReadTo_SkipDelimiter_Runs()
        {
            ReadOnlySequence <byte> bytes  = SequenceFactory.CreateUtf8("abc^^|def");
            SequenceReader <byte>   reader = new SequenceReader <byte>(bytes);

            Assert.True(reader.TryReadTo(out ReadOnlySpan <byte> span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(5, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(5, reader.Consumed);

            // Split after escape char
            bytes  = SequenceFactory.CreateUtf8("abc^^", "|def");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(5, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(5, reader.Consumed);

            // Split before and after escape char
            bytes  = SequenceFactory.CreateUtf8("abc^", "^", "|def");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(5, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(5, reader.Consumed);

            // Check advance past delimiter
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), span.ToArray());
            Assert.True(reader.IsNext((byte)'d'));
            Assert.Equal(6, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^^"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'d'));
            Assert.Equal(6, reader.Consumed);

            // Leading run of 2
            bytes  = SequenceFactory.CreateUtf8("^^|abc");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("^^"), span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(2, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(Encoding.UTF8.GetBytes("^^"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(2, reader.Consumed);

            // Leading run of 3
            bytes  = SequenceFactory.CreateUtf8("^^^|abc");
            reader = new SequenceReader <byte>(bytes);
            Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.True(reader.IsNext((byte)'^'));
            Assert.Equal(0, reader.Consumed);
            Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.True(reader.IsNext((byte)'^'));
            Assert.Equal(0, reader.Consumed);

            // Trailing run of 3
            bytes  = SequenceFactory.CreateUtf8("abc^^^|");
            reader = new SequenceReader <byte>(bytes);
            Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.True(reader.IsNext((byte)'a'));
            Assert.Equal(0, reader.Consumed);
            Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.True(reader.IsNext((byte)'a'));
            Assert.Equal(0, reader.Consumed);

            // Trailing run of 3, split
            bytes  = SequenceFactory.CreateUtf8("abc^^^", "|");
            reader = new SequenceReader <byte>(bytes);
            Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.True(reader.IsNext((byte)'a'));
            Assert.Equal(0, reader.Consumed);
            Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.True(reader.IsNext((byte)'a'));
            Assert.Equal(0, reader.Consumed);
        }
Exemple #16
0
        public void TryReadTo_SkipDelimiter()
        {
            byte[] expected = Encoding.UTF8.GetBytes("This is our ^|understanding^|");
            ReadOnlySequence <byte> bytes  = SequenceFactory.CreateUtf8("This is our ^|understanding^|| you see.");
            SequenceReader <byte>   reader = new SequenceReader <byte>(bytes);

            Assert.True(reader.TryReadTo(out ReadOnlySpan <byte> span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)' '));
            Assert.Equal(30, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)' '));
            Assert.Equal(30, reader.Consumed);

            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);

            // Put the skip delimiter in another segment
            bytes  = SequenceFactory.CreateUtf8("This is our ^|understanding", "^|| you see.");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)' '));
            Assert.Equal(30, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)' '));
            Assert.Equal(30, reader.Consumed);

            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);

            // Put the skip delimiter at the end of the segment
            bytes  = SequenceFactory.CreateUtf8("This is our ^|understanding^", "|| you see.");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)' '));
            Assert.Equal(30, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)' '));
            Assert.Equal(30, reader.Consumed);

            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);

            // No trailing data
            bytes  = SequenceFactory.CreateUtf8("This is our ^|understanding^||");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.IsNext((byte)'|'));
            Assert.Equal(29, reader.Consumed);

            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, span.ToArray());
            Assert.True(reader.End);
            Assert.Equal(30, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(expected, sequence.ToArray());
            Assert.True(reader.End);
            Assert.Equal(30, reader.Consumed);

            // All delimiters skipped
            bytes  = SequenceFactory.CreateUtf8("This is our ^|understanding^|");
            reader = new SequenceReader <byte>(bytes);
            Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(0, reader.Consumed);
            Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: false));
            Assert.Equal(0, reader.Consumed);

            reader = new SequenceReader <byte>(bytes);
            Assert.False(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(0, reader.Consumed);
            Assert.False(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(0, reader.Consumed);

            bytes  = SequenceFactory.CreateUtf8("abc^|de|");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^|de"), span.ToArray());
            Assert.True(reader.End);
            Assert.Equal(8, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("abc^|de"), sequence.ToArray());
            Assert.True(reader.End);
            Assert.Equal(8, reader.Consumed);

            // Escape leads
            bytes  = SequenceFactory.CreateUtf8("^|a|b");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("^|a"), span.ToArray());
            Assert.True(reader.IsNext((byte)'b'));
            Assert.Equal(4, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("^|a"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'b'));
            Assert.Equal(4, reader.Consumed);

            // Delimiter starts second segment.
            bytes  = SequenceFactory.CreateUtf8("^", "|a|b");
            reader = new SequenceReader <byte>(bytes);
            Assert.True(reader.TryReadTo(out span, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("^|a"), span.ToArray());
            Assert.True(reader.IsNext((byte)'b'));
            Assert.Equal(4, reader.Consumed);
            reader.Rewind(reader.Consumed);
            Assert.True(reader.TryReadTo(out sequence, (byte)'|', (byte)'^', advancePastDelimiter: true));
            Assert.Equal(Encoding.UTF8.GetBytes("^|a"), sequence.ToArray());
            Assert.True(reader.IsNext((byte)'b'));
            Assert.Equal(4, reader.Consumed);
        }