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 } }); ByteBufferReader reader = new ByteBufferReader(bytes); reader.Advance(1); ByteBufferReader 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 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); ByteBufferReader skipReader = new ByteBufferReader(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 ByteBufferReader(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); }
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 ByteBufferReader(bytes).Rewind(-1)); // Can't pull more than we consumed ByteBufferReader reader = new ByteBufferReader(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 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 ByteBufferReader(bytes); reader.Advance(3); Assert.True(reader.IsNext(4)); reader.Rewind(2); Assert.Equal(new byte[] { 1, 2 }, reader.CurrentSpan.ToArray()); }
public void TryReadTo_SkipDelimiter_Runs() { ReadOnlySequence <byte> bytes = SequenceFactory.CreateUtf8("abc^^|def"); ByteBufferReader reader = new ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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); }
public void TryReadTo_SkipDelimiter() { byte[] expected = Encoding.UTF8.GetBytes("This is our ^|understanding^|"); ReadOnlySequence <byte> bytes = SequenceFactory.CreateUtf8("This is our ^|understanding^|| you see."); ByteBufferReader reader = new ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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 ByteBufferReader(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); }