QuicFrame parseFrame()

in quic/codec/Decode.cpp [711:817]


QuicFrame parseFrame(
    BufQueue& queue,
    const PacketHeader& header,
    const CodecParameters& params) {
  folly::io::Cursor cursor(queue.front());
  auto frameTypeInt = decodeQuicInteger(cursor);
  if (!frameTypeInt) {
    throw QuicTransportException(
        "Invalid frame-type field", TransportErrorCode::FRAME_ENCODING_ERROR);
  }
  queue.trimStart(cursor - queue.front());
  bool consumedQueue = false;
  bool error = false;
  SCOPE_EXIT {
    if (consumedQueue || error) {
      return;
    }
    queue.trimStart(cursor - queue.front());
  };
  cursor.reset(queue.front());
  FrameType frameType = static_cast<FrameType>(frameTypeInt->first);
  try {
    switch (frameType) {
      case FrameType::PADDING:
        return QuicFrame(decodePaddingFrame(cursor));
      case FrameType::PING:
        return QuicFrame(decodePingFrame(cursor));
      case FrameType::ACK:
        return QuicFrame(decodeAckFrame(cursor, header, params));
      case FrameType::ACK_ECN:
        return QuicFrame(decodeAckFrameWithECN(cursor, header, params));
      case FrameType::RST_STREAM:
        return QuicFrame(decodeRstStreamFrame(cursor));
      case FrameType::STOP_SENDING:
        return QuicFrame(decodeStopSendingFrame(cursor));
      case FrameType::CRYPTO_FRAME:
        return QuicFrame(decodeCryptoFrame(cursor));
      case FrameType::NEW_TOKEN:
        return QuicFrame(decodeNewTokenFrame(cursor));
      case FrameType::STREAM:
      case FrameType::STREAM_FIN:
      case FrameType::STREAM_LEN:
      case FrameType::STREAM_LEN_FIN:
      case FrameType::STREAM_OFF:
      case FrameType::STREAM_OFF_FIN:
      case FrameType::STREAM_OFF_LEN:
      case FrameType::STREAM_OFF_LEN_FIN:
        consumedQueue = true;
        return QuicFrame(
            decodeStreamFrame(queue, StreamTypeField(frameTypeInt->first)));
      case FrameType::MAX_DATA:
        return QuicFrame(decodeMaxDataFrame(cursor));
      case FrameType::MAX_STREAM_DATA:
        return QuicFrame(decodeMaxStreamDataFrame(cursor));
      case FrameType::MAX_STREAMS_BIDI:
        return QuicFrame(decodeBiDiMaxStreamsFrame(cursor));
      case FrameType::MAX_STREAMS_UNI:
        return QuicFrame(decodeUniMaxStreamsFrame(cursor));
      case FrameType::DATA_BLOCKED:
        return QuicFrame(decodeDataBlockedFrame(cursor));
      case FrameType::STREAM_DATA_BLOCKED:
        return QuicFrame(decodeStreamDataBlockedFrame(cursor));
      case FrameType::STREAMS_BLOCKED_BIDI:
        return QuicFrame(decodeBiDiStreamsBlockedFrame(cursor));
      case FrameType::STREAMS_BLOCKED_UNI:
        return QuicFrame(decodeUniStreamsBlockedFrame(cursor));
      case FrameType::NEW_CONNECTION_ID:
        return QuicFrame(decodeNewConnectionIdFrame(cursor));
      case FrameType::RETIRE_CONNECTION_ID:
        return QuicFrame(decodeRetireConnectionIdFrame(cursor));
      case FrameType::PATH_CHALLENGE:
        return QuicFrame(decodePathChallengeFrame(cursor));
      case FrameType::PATH_RESPONSE:
        return QuicFrame(decodePathResponseFrame(cursor));
      case FrameType::CONNECTION_CLOSE:
        return QuicFrame(decodeConnectionCloseFrame(cursor));
      case FrameType::CONNECTION_CLOSE_APP_ERR:
        return QuicFrame(decodeApplicationClose(cursor));
      case FrameType::HANDSHAKE_DONE:
        return QuicFrame(decodeHandshakeDoneFrame(cursor));
      case FrameType::DATAGRAM: {
        consumedQueue = true;
        return QuicFrame(decodeDatagramFrame(queue, false /* hasLen */));
      }
      case FrameType::DATAGRAM_LEN: {
        consumedQueue = true;
        return QuicFrame(decodeDatagramFrame(queue, true /* hasLen */));
      }
      case FrameType::KNOB:
        return QuicFrame(decodeKnobFrame(cursor));
      case FrameType::ACK_FREQUENCY:
        return QuicFrame(decodeAckFrequencyFrame(cursor));
    }
  } catch (const std::exception&) {
    error = true;
    throw QuicTransportException(
        folly::to<std::string>(
            "Frame format invalid, type=", frameTypeInt->first),
        TransportErrorCode::FRAME_ENCODING_ERROR,
        frameType);
  }
  error = true;
  throw QuicTransportException(
      folly::to<std::string>("Unknown frame, type=", frameTypeInt->first),
      TransportErrorCode::FRAME_ENCODING_ERROR,
      frameType);
}