public void SkipToEndThenPeekReturnsMinusOne() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 1, 2, 3, 4, 5 }, 0, 5)); reader.Skip(5); Assert.True(reader.End); Assert.Equal(-1, reader.Peek()); Assert.True(reader.Cursor.IsEnd); }
public void EmptySegmentsAreSkippedOnMoveNext() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1 }, new byte[] { }, new byte[] { }, new byte[] { 2 } }); var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Peek()); reader.Skip(1); Assert.Equal(2, reader.Peek()); }
public void SkipTraversesSegments() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2, 3 }); var reader = new ReadableBufferReader(buffer); reader.Skip(2); Assert.Equal(3, reader.Span[reader.Index]); Assert.Equal(3, reader.Take()); }
public void EmptySegmentsAreSkippedOnMoveNext() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2 }); var reader = new ReadableBufferReader(buffer); Assert.Equal(1, reader.Peek()); reader.Skip(1); Assert.Equal(2, reader.Peek()); }
public void SkipTraversesSegments() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1 }, new byte[] { 2 }, new byte[] { 3 } }); var reader = new ReadableBufferReader(buffer); reader.Skip(2); Assert.Equal(0, reader.Index); Assert.Equal(3, reader.Span[reader.Index]); Assert.Equal(3, reader.Take()); }
public void SkippingPastLengthThrows() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 1, 2, 3, 4, 5 }, 0, 5)); try { reader.Skip(6); Assert.True(false); } catch (Exception ex) { Assert.True(ex is ArgumentOutOfRangeException); } }
public void SkipThrowsPastLengthMultipleSegments() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1 }, new byte[] { 2 }, new byte[] { 3 } }); var reader = new ReadableBufferReader(buffer); try { reader.Skip(4); Assert.True(false); } catch (Exception ex) { Assert.True(ex is ArgumentOutOfRangeException); } }
public void SkipThrowsPastLengthMultipleSegments() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2, 3 }); var reader = new ReadableBufferReader(buffer); try { reader.Skip(4); Assert.True(false); } catch (Exception ex) { Assert.True(ex is ArgumentOutOfRangeException); } }
static void ParseInt32ReadableBufferReader() { foreach (var iteration in Benchmark.Iterations) { var buffer = ReadableBuffer.Create(s_data); var reader = new ReadableBufferReader(buffer); using (iteration.StartMeasurement()) { while (Utf8Parser.TryParse(reader.Span.Slice(reader.ConsumedBytes), out int value, out int consumed)) { reader.Skip(consumed + 1); } } } }
public void ReaderIndexIsCorrect() { var buffer = BufferUtilities.CreateBuffer(new[] { new byte[] { 1, 2, 3, 4 }, new byte[] { 5, 6, 7 }, new byte[] { 8, 9, 10 } }); var reader = new ReadableBufferReader(buffer); var counter = 1; while (!reader.End) { var span = reader.Span; for (int i = reader.Index; i < span.Length; i++) { Assert.Equal(counter++, reader.Span[i]); } reader.Skip(span.Length); } Assert.Equal(buffer.Length, reader.ConsumedBytes); }
public void ReaderIndexIsCorrect() { var buffer = Factory.CreateWithContent(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); var reader = new ReadableBufferReader(buffer); var counter = 1; while (!reader.End) { var span = reader.Span; for (int i = reader.Index; i < span.Length; i++) { Assert.Equal(counter++, reader.Span[i]); } reader.Skip(span.Length); } Assert.Equal(buffer.Length, reader.ConsumedBytes); }
private static void FindAllNewLinesReadableBufferReader(ReadableBuffer buffer) { var reader = new ReadableBufferReader(buffer); var end = buffer.End; while (!reader.End) { var span = reader.Span; // Trim the start if we have an index if (reader.Index > 0) { span = span.Slice(reader.Index); } while (span.Length > 0) { var length = span.IndexOf((byte)'\n'); var skip = length; if (length == -1) { var current = reader.Cursor; if (ReadCursorOperations.Seek(current, end, out var found, (byte)'\n') == -1) { // We're done return; } length = span.Length; skip = (int)buffer.Slice(current, found).Length + 1; } else { length += 1; skip = length; } span = span.Slice(length); reader.Skip(skip); } } }
public void SkippingPastLengthThrows() { var reader = new ReadableBufferReader(ReadableBuffer.Create(new byte[] { 1, 2, 3, 4, 5 }, 0, 5)); Assert.Throws <ArgumentOutOfRangeException>(() => reader.Skip(6)); }
public unsafe bool ParseHeaders <T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler { consumed = buffer.Start; examined = buffer.End; consumedBytes = 0; var bufferEnd = buffer.End; var reader = new ReadableBufferReader(buffer); var start = default(ReadableBufferReader); var done = false; try { while (!reader.End) { var span = reader.Span; var remaining = span.Length - reader.Index; fixed(byte *pBuffer = &span.DangerousGetPinnableReference()) { while (remaining > 0) { var index = reader.Index; int ch1; int ch2; // Fast path, we're still looking at the same span if (remaining >= 2) { ch1 = pBuffer[index]; ch2 = pBuffer[index + 1]; } else { // Store the reader before we look ahead 2 bytes (probably straddling // spans) start = reader; // Possibly split across spans ch1 = reader.Take(); ch2 = reader.Take(); } if (ch1 == ByteCR) { // Check for final CRLF. if (ch2 == -1) { // Reset the reader so we don't consume anything reader = start; return(false); } else if (ch2 == ByteLF) { // If we got 2 bytes from the span directly so skip ahead 2 so that // the reader's state matches what we expect if (index == reader.Index) { reader.Skip(2); } done = true; return(true); } // Headers don't end in CRLF line. RejectRequest(RequestRejectionReason.InvalidRequestHeadersNoCRLF); } // We moved the reader so look ahead 2 bytes so reset both the reader // and the index if (index != reader.Index) { reader = start; index = reader.Index; } var endIndex = new ReadOnlySpan <byte>(pBuffer + index, remaining).IndexOf(ByteLF); var length = 0; if (endIndex != -1) { length = endIndex + 1; var pHeader = pBuffer + index; TakeSingleHeader(pHeader, length, handler); } else { var current = reader.Cursor; // Split buffers if (ReadCursorOperations.Seek(current, bufferEnd, out var lineEnd, ByteLF) == -1) { // Not there return(false); } // Make sure LF is included in lineEnd lineEnd = buffer.Move(lineEnd, 1); var headerSpan = buffer.Slice(current, lineEnd).ToSpan(); length = headerSpan.Length; fixed(byte *pHeader = &headerSpan.DangerousGetPinnableReference()) { TakeSingleHeader(pHeader, length, handler); } // We're going to the next span after this since we know we crossed spans here // so mark the remaining as equal to the headerSpan so that we end up at 0 // on the next iteration remaining = length; } // Skip the reader forward past the header line reader.Skip(length); remaining -= length; } } } return(false); } finally { consumed = reader.Cursor; consumedBytes = reader.ConsumedBytes; if (done) { examined = consumed; } } }