public void TryReadToSpan_Sequence(bool advancePastDelimiter) { ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] { new byte[] { 0, 0 }, new byte[] { 1, 1, 2, 2 }, new byte[] { }, new byte[] { 3, 3, 4, 4, 5, 5, 6, 6 } }); SequenceReader <byte> reader = new SequenceReader <byte>(bytes); for (byte i = 0; i < bytes.Length / 2 - 1; i++) { byte[] expected = new byte[i * 2 + 1]; for (int j = 0; j < expected.Length - 1; j++) { expected[j] = (byte)(j / 2); } expected[i * 2] = i; ReadOnlySpan <byte> searchFor = new byte[] { i, (byte)(i + 1) }; SequenceReader <byte> copy = reader; Assert.True(copy.TryReadTo(out ReadOnlySequence <byte> seq, searchFor, advancePastDelimiter)); Assert.True(seq.ToArray().AsSpan().SequenceEqual(expected)); } bytes = SequenceFactory.Create(new byte[][] { new byte[] { 47, 42, 66, 32, 42, 32, 66, 42, 47 } // /*b * b*/ }); reader = new SequenceReader <byte>(bytes); Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> sequence, new byte[] { 42, 47 }, advancePastDelimiter)); // */ Assert.True(sequence.ToArray().AsSpan().SequenceEqual(new byte[] { 47, 42, 66, 32, 42, 32, 66 })); }
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.FirstSpan[0]); Assert.True(sequenceReader.End); }
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); }
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 } }); SequenceReader <byte> 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); }
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); }
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)); } }
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]); Assert.True(SequenceMarshal.TryRead(ref reader, out int intValue)); Assert.Equal(BitConverter.ToInt32(new byte[] { 0, 1, 0, 2 }), intValue); Assert.True(reader.TryReadBigEndian(out intValue)); Assert.Equal(BitConverter.ToInt32(new byte[] { 4, 3, 2, 1 }), intValue); Assert.True(reader.TryReadLittleEndian(out long longValue)); Assert.Equal(BitConverter.ToInt64(new byte[] { 5, 6, 7, 8, 9, 0, 1, 2 }), longValue); Assert.True(reader.TryReadBigEndian(out longValue)); Assert.Equal(BitConverter.ToInt64(new byte[] { 0, 9, 8, 7, 6, 5, 4, 3 }), longValue); Assert.True(reader.TryReadLittleEndian(out short shortValue)); Assert.Equal(BitConverter.ToInt16(new byte[] { 1, 2 }), shortValue); Assert.True(reader.TryReadBigEndian(out shortValue)); Assert.Equal(BitConverter.ToInt16(new byte[] { 4, 3 }), shortValue); }
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)); }
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)); }
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 Assert.Throws <ArgumentOutOfRangeException>(() => new SequenceReader <byte>(bytes).Rewind(1)); }
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)); } }
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()); }
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); }
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); }
public void TryReadTo_SingleDelimiter() { ReadOnlySequence <byte> bytes = SequenceFactory.Create(new byte[][] { new byte[] { 1 }, new byte[] { 2, 3, 4, 5, 6 } }); SequenceReader <byte> reader = new SequenceReader <byte>(bytes); Span <byte> delimiter = new byte[] { 1 }; for (int i = 1; i < 6; i += 1) { // Also check scanning from the start. SequenceReader <byte> resetReader = new SequenceReader <byte>(bytes); delimiter[0] = (byte)i; Assert.True(reader.TryReadTo(out ReadOnlySequence <byte> sequence, delimiter, advancePastDelimiter: true)); Assert.True(resetReader.TryReadTo(out sequence, delimiter, advancePastDelimiter: true)); Assert.True(reader.TryPeek(out byte value)); Assert.Equal(i + 1, value); Assert.True(resetReader.TryPeek(out value)); Assert.Equal(i + 1, value); } }
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])); }
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); }
public void TryReadTo_SkipDelimiter() { byte[] expected = "This is our ^|understanding^|" u8.ToArray(); 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("abc^|de" u8.ToArray(), 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("abc^|de" u8.ToArray(), 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("^|a" u8.ToArray(), 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("^|a" u8.ToArray(), 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("^|a" u8.ToArray(), 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("^|a" u8.ToArray(), sequence.ToArray()); Assert.True(reader.IsNext((byte)'b')); Assert.Equal(4, reader.Consumed); }
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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("abc^^" u8.ToArray(), 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("^^" u8.ToArray(), 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("^^" u8.ToArray(), 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); }