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);
        }
Example #2
0
        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());
        }
Example #3
0
        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());
        }
Example #4
0
        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);
            }
        }
Example #8
0
        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);
            }
        }
Example #9
0
    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);
        }
Example #11
0
        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);
        }
Example #12
0
        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));
        }
Example #14
0
        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;
                }
            }
        }