public static bool TryParse(ReadOnlyMemory <byte> bytes, out NewConnectionIdFrame result, out ReadOnlyMemory <byte> remainings)
        {
            result     = new NewConnectionIdFrame();
            remainings = ReadOnlyMemory <byte> .Empty;

            var type = FrameType.Parse(bytes, out var afterTypeBytes);

            if (!type.IsNewConnectionId())
            {
                return(false);
            }

            var sequenceNumber                   = VariableLengthEncoding.Decode32(afterTypeBytes.Span, out var decodedLength);
            var afterSequenceNumberBytes         = afterTypeBytes.Slice(decodedLength);
            var sequenceNumberToRetire           = VariableLengthEncoding.Decode32(afterSequenceNumberBytes.Span, out decodedLength);
            var afterSequenceNumberToRetiryBytes = afterSequenceNumberBytes.Slice(decodedLength);

            if (sequenceNumberToRetire > sequenceNumber)
            {
                throw new EncodingException();
            }

            var connectionId = PacketConnectionId.Parse(afterSequenceNumberToRetiryBytes, out var afterConnectionIdBytes);
            var resetToken   = ParseResetToken(afterConnectionIdBytes, out var afterTokenBytes);

            result     = new NewConnectionIdFrame(sequenceNumber, sequenceNumberToRetire, connectionId, resetToken);
            remainings = afterTokenBytes;

            return(true);
        }
        private static int ParseOffset(ReadOnlyMemory <byte> bytes, FrameType type, out ReadOnlyMemory <byte> remainings)
        {
            remainings = bytes;

            if (!type.HasOffset())
            {
                return(0);
            }

            var offset = VariableLengthEncoding.Decode32(bytes.Span, out var decodedLength);

            remainings = bytes.Slice(decodedLength);

            return(offset);
        }
        public static ReasonPhrase Parse(ReadOnlyMemory <byte> bytes, out ReadOnlyMemory <byte> remainings)
        {
            remainings = ReadOnlyMemory <byte> .Empty;

            var length           = VariableLengthEncoding.Decode32(bytes.Span, out var decodedLength);
            var afterLengthBytes = bytes.Slice(decodedLength);

            if (afterLengthBytes.Length < length)
            {
                throw new EncodingException();
            }

            var reasonPhraseBytes = afterLengthBytes.Slice(0, length);

            remainings = afterLengthBytes.Slice(length);

            return(new ReasonPhrase(reasonPhraseBytes));
        }
        public static bool TryParse(ReadOnlyMemory <byte> bytes, out DataBlockedFrame result, out ReadOnlyMemory <byte> remainings)
        {
            result     = new DataBlockedFrame();
            remainings = ReadOnlyMemory <byte> .Empty;

            var type = FrameType.Parse(bytes, out var afterTypeBytes);

            if (!type.IsDataBlocked())
            {
                return(false);
            }

            var dataLimit = VariableLengthEncoding.Decode32(afterTypeBytes.Span, out var decodedLength);

            result     = new DataBlockedFrame(dataLimit);
            remainings = afterTypeBytes.Slice(decodedLength);

            return(true);
        }
        public static bool TryParse(ReadOnlyMemory <byte> bytes, out StreamsBlockedFrame result, out ReadOnlyMemory <byte> remainings)
        {
            result     = new StreamsBlockedFrame();
            remainings = ReadOnlyMemory <byte> .Empty;

            var type = FrameType.Parse(bytes, out var afterTypeBytes);

            if (!type.IsStreamsBlocked())
            {
                return(false);
            }

            var streamLimit = VariableLengthEncoding.Decode32(afterTypeBytes.Span, out var decodedLength);

            result     = new StreamsBlockedFrame(streamLimit, type.ForBidirectional(), type.ForUnidirectional());
            remainings = afterTypeBytes.Slice(decodedLength);

            return(true);
        }
        public static bool TryParse(ReadOnlyMemory <byte> bytes, out MaxStreamDataFrame result, out ReadOnlyMemory <byte> remainings)
        {
            result     = new MaxStreamDataFrame();
            remainings = ReadOnlyMemory <byte> .Empty;

            var type = FrameType.Parse(bytes, out var afterTypeBytes);

            if (!type.IsMaxStreamData())
            {
                return(false);
            }

            var streamId      = StreamId.Parse(afterTypeBytes, out var afterStreamIdBytes);
            var maxDataLength = VariableLengthEncoding.Decode32(afterStreamIdBytes.Span, out var decodedLength);

            result     = new MaxStreamDataFrame(streamId, maxDataLength);
            remainings = afterStreamIdBytes.Slice(decodedLength);

            return(true);
        }
        public static bool TryParse(ReadOnlyMemory <byte> bytes, out RetireConnectionIdFrame result, out ReadOnlyMemory <byte> remainings)
        {
            result     = new RetireConnectionIdFrame();
            remainings = ReadOnlyMemory <byte> .Empty;

            var type = FrameType.Parse(bytes, out var afterTypeBytes);

            if (!type.IsRetireConnectionId())
            {
                return(false);
            }

            var sequenceNumber           = VariableLengthEncoding.Decode32(afterTypeBytes.Span, out var decodedLength);
            var afterSequenceNumberBytes = afterTypeBytes.Slice(decodedLength);

            result     = new RetireConnectionIdFrame(sequenceNumber);
            remainings = afterSequenceNumberBytes;

            return(true);
        }
        private static ReadOnlyMemory <byte> ParseData(ReadOnlyMemory <byte> bytes, FrameType type, out ReadOnlyMemory <byte> remainings)
        {
            remainings = ReadOnlyMemory <byte> .Empty;

            if (!type.HasLength())
            {
                return(bytes);
            }

            var length           = VariableLengthEncoding.Decode32(bytes.Span, out var decodedLength);
            var afterLengthBytes = bytes.Slice(decodedLength);

            if (afterLengthBytes.Length < length)
            {
                throw new EncodingException();
            }

            remainings = afterLengthBytes.Slice(length);

            return(afterLengthBytes.Slice(0, length));
        }
        public static bool TryParse(ReadOnlyMemory <byte> bytes, out ResetStreamFrame result, out ReadOnlyMemory <byte> remainings)
        {
            result     = new ResetStreamFrame();
            remainings = ReadOnlyMemory <byte> .Empty;

            var type = FrameType.Parse(bytes, out var afterTypeRemainings);

            if (!type.IsResetStream())
            {
                return(false);
            }

            var streamId  = StreamId.Parse(afterTypeRemainings, out var afterStreamIdBytes);
            var error     = Error.ParseApplication(afterStreamIdBytes, out var afterApplicationErrorBytes);
            var finalSize = VariableLengthEncoding.Decode32(afterApplicationErrorBytes.Span, out var decodedLength);

            result     = new ResetStreamFrame(streamId, error, finalSize);
            remainings = afterApplicationErrorBytes.Slice(decodedLength);

            return(true);
        }