Exemplo n.º 1
0
        public void TestSeekIteratorLimitWithinSameBlock(string input, char seek, char limitAfter, int expectedReturnValue)
        {
            ReadOnlyBuffer <byte> originalBuffer = Factory.CreateWithContent(input);

            SequencePosition      scan1  = originalBuffer.Start;
            ReadOnlyBuffer <byte> buffer = originalBuffer;

            // Act
            SequencePosition?end = originalBuffer.PositionOf((byte)limitAfter);

            if (end.HasValue)
            {
                buffer = originalBuffer.Slice(buffer.Start, buffer.GetPosition(end.Value, 1));
            }

            SequencePosition?returnValue1 = buffer.PositionOf((byte)seek);

            // Assert
            Assert.Equal(input.Contains(limitAfter), end.HasValue);

            if (expectedReturnValue != -1)
            {
                int expectedEndIndex = input.IndexOf(seek);

                Assert.NotNull(returnValue1);
                Assert.Equal(Encoding.ASCII.GetBytes(input.Substring(expectedEndIndex)), originalBuffer.Slice(returnValue1.Value).ToArray());
            }
        }
Exemplo n.º 2
0
        public void TestSeekByteLimitWithinSameBlock(string input, char seek, int limit, int expectedBytesScanned, int expectedReturnValue)
        {
            // Arrange
            ReadOnlyBuffer <byte> originalBuffer = Factory.CreateWithContent(input);

            // Act
            ReadOnlyBuffer <byte> buffer = limit > input.Length ? originalBuffer : originalBuffer.Slice(0, limit);

            SequencePosition?result = buffer.PositionOf((byte)seek);

            // Assert
            if (expectedReturnValue == -1)
            {
                Assert.Null(result);
            }
            else
            {
                Assert.NotNull(result);
            }

            if (expectedReturnValue != -1)
            {
                Assert.Equal(Encoding.ASCII.GetBytes(input.Substring(expectedBytesScanned - 1)), originalBuffer.Slice(result.Value).ToArray());
            }
        }
Exemplo n.º 3
0
        public void MemorySeek(string raw, char searchFor, int expectIndex)
        {
            ReadOnlyBuffer <byte> cursors = Factory.CreateWithContent(raw);
            SequencePosition?     result  = cursors.PositionOf((byte)searchFor);

            Assert.NotNull(result);
            Assert.Equal(cursors.Slice(result.Value).ToArray(), Encoding.ASCII.GetBytes(raw.Substring(expectIndex)));
        }
Exemplo n.º 4
0
            private void ParseExtension(ReadOnlyBuffer <byte> buffer, out SequencePosition consumed, out SequencePosition examined)
            {
                // Chunk-extensions not currently parsed
                // Just drain the data
                consumed = buffer.Start;
                examined = buffer.Start;

                do
                {
                    SequencePosition?extensionCursorPosition = buffer.PositionOf(ByteCR);
                    if (extensionCursorPosition == null)
                    {
                        // End marker not found yet
                        consumed = buffer.End;
                        examined = buffer.End;
                        AddAndCheckConsumedBytes(buffer.Length);
                        return;
                    }
                    ;

                    var extensionCursor        = extensionCursorPosition.Value;
                    var charsToByteCRExclusive = buffer.Slice(0, extensionCursor).Length;

                    var sufixBuffer = buffer.Slice(extensionCursor);
                    if (sufixBuffer.Length < 2)
                    {
                        consumed = extensionCursor;
                        examined = buffer.End;
                        AddAndCheckConsumedBytes(charsToByteCRExclusive);
                        return;
                    }

                    sufixBuffer = sufixBuffer.Slice(0, 2);
                    var sufixSpan = sufixBuffer.ToSpan();

                    if (sufixSpan[1] == '\n')
                    {
                        // We consumed the \r\n at the end of the extension, so switch modes.
                        _mode = _inputLength > 0 ? Mode.Data : Mode.Trailer;

                        consumed = sufixBuffer.End;
                        examined = sufixBuffer.End;
                        AddAndCheckConsumedBytes(charsToByteCRExclusive + 2);
                    }
                    else
                    {
                        // Don't consume suffixSpan[1] in case it is also a \r.
                        buffer   = buffer.Slice(charsToByteCRExclusive + 1);
                        consumed = extensionCursor;
                        AddAndCheckConsumedBytes(charsToByteCRExclusive + 1);
                    }
                } while (_mode == Mode.Extension);
            }
        public void SequencePositionOfMultiSegment()
        {
            var(first, last) = BufferList.Create(
                new byte[] { 1, 2 },
                new byte[] { 3, 4 }
                );
            var bytes = new ReadOnlyBuffer <byte>(first, 0, last, last.Memory.Length);

            Assert.Equal(4, bytes.Length);

            // Static method call to avoid calling instance methods
            Assert.False(Sequence.PositionOf(bytes, 0).HasValue);

            for (int i = 0; i < bytes.Length; i++)
            {
                var value = (byte)(i + 1);

                var listPosition = MemoryListExtensions.PositionOf(first, value).GetValueOrDefault();
                var(node, index) = listPosition.Get <IMemoryList <byte> >();

                if (listPosition != default)
                {
                    Assert.Equal(value, node.Memory.Span[index]);
                }

                var robPosition         = bytes.PositionOf(value);
                var robSequencePosition = Sequence.PositionOf(bytes, value);

                Assert.Equal(listPosition, robPosition);
                Assert.Equal(listPosition, robSequencePosition);

                var robSlice = bytes.Slice(1);
                robPosition         = robSlice.PositionOf(value);
                robSequencePosition = Sequence.PositionOf(robSlice, value);

                if (i > 0)
                {
                    Assert.Equal(listPosition, robPosition);
                    Assert.Equal(listPosition, robSequencePosition);
                }
                else
                {
                    Assert.False(robPosition.HasValue);
                    Assert.False(robSequencePosition.HasValue);
                }

                if (listPosition != default)
                {
                    robSlice = bytes.Slice(listPosition);
                    Assert.Equal(value, robSlice.First.Span[0]);
                }
            }
        }
Exemplo n.º 6
0
        private static void FindAllNewLines(ReadOnlyBuffer buffer)
        {
            while (true)
            {
                var position = buffer.PositionOf((byte)'\n');
                if (position == null)
                {
                    break;
                }

                buffer = buffer.Slice(position.Value).Slice(1);
            }
        }
Exemplo n.º 7
0
        public static bool TryParseMessage(ReadOnlyBuffer <byte> buffer, out NegotiationMessage negotiationMessage, out SequencePosition consumed, out SequencePosition examined)
        {
            var separator = buffer.PositionOf(TextMessageFormatter.RecordSeparator);

            if (separator == null)
            {
                // Haven't seen the entire negotiate message so bail
                consumed           = buffer.Start;
                examined           = buffer.End;
                negotiationMessage = null;
                return(false);
            }
            else
            {
                consumed = buffer.GetPosition(separator.Value, 1);
                examined = consumed;
            }

            var memory = buffer.IsSingleSegment ? buffer.First : buffer.ToArray();

            return(TryParseMessage(memory.Span, out negotiationMessage));
        }
        public ParseResult ParseMessage(ReadOnlyBuffer <byte> buffer, out SequencePosition consumed, out SequencePosition examined, out byte[] message)
        {
            consumed = buffer.Start;
            examined = buffer.End;
            message  = null;

            var start = consumed;
            var end   = examined;

            while (buffer.Length > 0)
            {
                if (!(buffer.PositionOf(ByteLF) is SequencePosition lineEnd))
                {
                    // For the case of  data: Foo\r\n\r\<Anytine except \n>
                    if (_internalParserState == InternalParseState.ReadEndOfMessage)
                    {
                        if (ConvertBufferToSpan(buffer.Slice(start, buffer.End)).Length > 1)
                        {
                            throw new FormatException("Expected a \\r\\n frame ending");
                        }
                    }

                    // Partial message. We need to read more.
                    return(ParseResult.Incomplete);
                }

                lineEnd = buffer.GetPosition(lineEnd, 1);
                var line = ConvertBufferToSpan(buffer.Slice(start, lineEnd));
                buffer = buffer.Slice(line.Length);

                if (line.Length <= 1)
                {
                    throw new FormatException("There was an error in the frame format");
                }

                // Skip comments
                if (line[0] == ByteColon)
                {
                    start    = lineEnd;
                    consumed = lineEnd;
                    continue;
                }

                if (IsMessageEnd(line))
                {
                    _internalParserState = InternalParseState.ReadEndOfMessage;
                }

                // To ensure that the \n was preceded by a \r
                // since messages can't contain \n.
                // data: foo\n\bar should be encoded as
                // data: foo\r\n
                // data: bar\r\n
                else if (line[line.Length - _sseLineEnding.Length] != ByteCR)
                {
                    throw new FormatException("Unexpected '\n' in message. A '\n' character can only be used as part of the newline sequence '\r\n'");
                }
                else
                {
                    EnsureStartsWithDataPrefix(line);
                }

                var payload = Array.Empty <byte>();
                switch (_internalParserState)
                {
                case InternalParseState.ReadMessagePayload:
                    EnsureStartsWithDataPrefix(line);

                    // Slice away the 'data: '
                    var payloadLength = line.Length - (_dataPrefix.Length + _sseLineEnding.Length);
                    var newData       = line.Slice(_dataPrefix.Length, payloadLength).ToArray();
                    _data.Add(newData);

                    start    = lineEnd;
                    consumed = lineEnd;
                    break;

                case InternalParseState.ReadEndOfMessage:
                    if (_data.Count == 1)
                    {
                        payload = _data[0];
                    }
                    else if (_data.Count > 1)
                    {
                        // Find the final size of the payload
                        var payloadSize = 0;
                        foreach (var dataLine in _data)
                        {
                            payloadSize += dataLine.Length;
                        }

                        payloadSize += _newLine.Length * _data.Count;

                        // Allocate space in the payload buffer for the data and the new lines.
                        // Subtract newLine length because we don't want a trailing newline.
                        payload = new byte[payloadSize - _newLine.Length];

                        var offset = 0;
                        foreach (var dataLine in _data)
                        {
                            dataLine.CopyTo(payload, offset);
                            offset += dataLine.Length;
                            if (offset < payload.Length)
                            {
                                _newLine.CopyTo(payload, offset);
                                offset += _newLine.Length;
                            }
                        }
                    }

                    message  = payload;
                    consumed = lineEnd;
                    examined = consumed;
                    return(ParseResult.Completed);
                }

                if (buffer.Length > 0 && buffer.First.Span[0] == ByteCR)
                {
                    _internalParserState = InternalParseState.ReadEndOfMessage;
                }
            }
            return(ParseResult.Incomplete);
        }