Simplify QuicStreamSendBuffer::SaveStreamData(). This method is called at two places in production: QuicCryptoStream::WriteCryptoData() and QuicStream::WriteOrBufferDataAtLevel(), both times with an iovec created locally from an absl::string_view. In order to reduce complexity, this CL changes SaveStreamData() to take an absl::string_view directly instead of an iovec. PiperOrigin-RevId: 432178898
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index 311cf1f..a629827 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -341,14 +341,12 @@ } QuicConsumedData SendStreamData(QuicStream* stream) { - struct iovec iov; if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(), stream->id()) && connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) { this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); } - MakeIOVector("not empty", &iov); - QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9); + QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty"); QuicConsumedData consumed = WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, GetEncryptionLevelToSendApplicationData());
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index fc4df23..84f0bce 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -230,16 +230,15 @@ } QuicConsumedData SaveAndSendStreamData(QuicStreamId id, - const struct iovec* iov, int iov_count, - size_t total_length, + absl::string_view data, QuicStreamOffset offset, StreamSendingState state) { ScopedPacketFlusher flusher(this); - producer_.SaveStreamData(id, iov, iov_count, 0u, total_length); + producer_.SaveStreamData(id, data); if (notifier_ != nullptr) { - return notifier_->WriteOrBufferData(id, total_length, state); + return notifier_->WriteOrBufferData(id, data.length(), state); } - return QuicConnection::SendStreamData(id, total_length, offset, state); + return QuicConnection::SendStreamData(id, data.length(), offset, state); } QuicConsumedData SendStreamDataWithString(QuicStreamId id, @@ -257,9 +256,7 @@ QuicConnectionPeer::SetAddressValidated(this); } } - struct iovec iov; - MakeIOVector(data, &iov); - return SaveAndSendStreamData(id, &iov, 1, data.length(), offset, state); + return SaveAndSendStreamData(id, data, offset, state); } QuicConsumedData SendApplicationDataAtLevel(EncryptionLevel encryption_level, @@ -271,9 +268,7 @@ QUICHE_DCHECK(encryption_level >= ENCRYPTION_ZERO_RTT); SetEncrypter(encryption_level, std::make_unique<TaggingEncrypter>(0x01)); SetDefaultEncryptionLevel(encryption_level); - struct iovec iov; - MakeIOVector(data, &iov); - return SaveAndSendStreamData(id, &iov, 1, data.length(), offset, state); + return SaveAndSendStreamData(id, data, offset, state); } QuicConsumedData SendStreamData3() { @@ -3707,19 +3702,11 @@ TEST_P(QuicConnectionTest, FramePackingSendv) { connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - // Send data in 1 packet by writing multiple blocks in a single iovector - // using writev. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); - char data[] = "ABCDEF"; - struct iovec iov[2]; - iov[0].iov_base = data; - iov[0].iov_len = 4; - iov[1].iov_base = data + 4; - iov[1].iov_len = 2; QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( connection_.transport_version(), Perspective::IS_CLIENT); - connection_.SaveAndSendStreamData(stream_id, iov, 2, 6, 0, NO_FIN); + connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN); EXPECT_EQ(0u, connection_.NumQueuedPackets()); EXPECT_FALSE(connection_.HasQueuedData()); @@ -3737,19 +3724,12 @@ TEST_P(QuicConnectionTest, FramePackingSendvQueued) { connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - // Try to send two stream frames in 1 packet by using writev. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); BlockOnNextWrite(); - char data[] = "ABCDEF"; - struct iovec iov[2]; - iov[0].iov_base = data; - iov[0].iov_len = 4; - iov[1].iov_base = data + 4; - iov[1].iov_len = 2; QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( connection_.transport_version(), Perspective::IS_CLIENT); - connection_.SaveAndSendStreamData(stream_id, iov, 2, 6, 0, NO_FIN); + connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN); EXPECT_EQ(1u, connection_.NumQueuedPackets()); EXPECT_TRUE(connection_.HasQueuedData()); @@ -3763,7 +3743,10 @@ EXPECT_EQ(1u, writer_->frame_count()); EXPECT_EQ(1u, writer_->stream_frames().size()); EXPECT_EQ(0u, writer_->padding_frames().size()); - EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id); + QuicStreamFrame* frame = writer_->stream_frames()[0].get(); + EXPECT_EQ(stream_id, frame->stream_id); + EXPECT_EQ("ABCDEF", + absl::string_view(frame->data_buffer, frame->data_length)); } TEST_P(QuicConnectionTest, SendingZeroBytes) { @@ -3772,7 +3755,7 @@ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( connection_.transport_version(), Perspective::IS_CLIENT); - connection_.SaveAndSendStreamData(stream_id, nullptr, 0, 0, 0, FIN); + connection_.SaveAndSendStreamData(stream_id, {}, 0, FIN); EXPECT_EQ(0u, connection_.NumQueuedPackets()); EXPECT_FALSE(connection_.HasQueuedData()); @@ -3805,16 +3788,11 @@ // Send data and ensure the ack is bundled. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9); - size_t len = 10000; - std::unique_ptr<char[]> data_array(new char[len]); - memset(data_array.get(), '?', len); - struct iovec iov; - iov.iov_base = data_array.get(); - iov.iov_len = len; + const std::string data(10000, '?'); QuicConsumedData consumed = connection_.SaveAndSendStreamData( - GetNthClientInitiatedStreamId(0, connection_.transport_version()), &iov, - 1, len, 0, FIN); - EXPECT_EQ(len, consumed.bytes_consumed); + GetNthClientInitiatedStreamId(0, connection_.transport_version()), data, + 0, FIN); + EXPECT_EQ(data.length(), consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_EQ(0u, connection_.NumQueuedPackets()); EXPECT_FALSE(connection_.HasQueuedData()); @@ -7409,9 +7387,7 @@ EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)) .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame)); - struct iovec iov; - MakeIOVector("", &iov); - EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, &iov, 1, 0, 0, FIN), + EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, {}, 0, FIN), "Cannot send stream data with level: ENCRYPTION_INITIAL"); EXPECT_FALSE(connection_.connected()); EXPECT_EQ(1, connection_close_frame_count_); @@ -12292,11 +12268,8 @@ .WillOnce(Invoke([=](const QuicStreamFrame& frame) { // Send some data on the stream. The STREAM_FRAME should be built into // one packet together with the latter PATH_RESPONSE and PATH_CHALLENGE. - std::string data{"response body"}; - struct iovec iov; - MakeIOVector(data, &iov); - connection_.producer()->SaveStreamData(frame.stream_id, &iov, 1, 0u, - data.length()); + const std::string data{"response body"}; + connection_.producer()->SaveStreamData(frame.stream_id, data); return notifier_.WriteOrBufferData(frame.stream_id, data.length(), NO_FIN); })); @@ -12365,11 +12338,8 @@ .WillOnce(Invoke([=](const QuicStreamFrame& frame) { // Send some data on the stream. The STREAM_FRAME should be built into a // new packet but throttled by anti-amplifciation limit. - std::string data{"response body"}; - struct iovec iov; - MakeIOVector(data, &iov); - connection_.producer()->SaveStreamData(frame.stream_id, &iov, 1, 0u, - data.length()); + const std::string data{"response body"}; + connection_.producer()->SaveStreamData(frame.stream_id, data); return notifier_.WriteOrBufferData(frame.stream_id, data.length(), NO_FIN); })); @@ -12409,11 +12379,8 @@ .WillRepeatedly(Invoke([=](const QuicStreamFrame& frame) { // Send some data on the stream. The STREAM_FRAME should be built into // one packet together with the latter PATH_RESPONSE. - std::string data{"response body"}; - struct iovec iov; - MakeIOVector(data, &iov); - connection_.producer()->SaveStreamData(frame.stream_id, &iov, 1, 0u, - data.length()); + const std::string data{"response body"}; + connection_.producer()->SaveStreamData(frame.stream_id, data); return notifier_.WriteOrBufferData(frame.stream_id, data.length(), NO_FIN); }));
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc index b579ff5..5690743 100644 --- a/quic/core/quic_crypto_stream.cc +++ b/quic/core/quic_crypto_stream.cc
@@ -140,11 +140,9 @@ } const bool had_buffered_data = HasBufferedCryptoFrames(); // Append |data| to the send buffer for this encryption level. - struct iovec iov(QuicUtils::MakeIovec(data)); QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer; QuicStreamOffset offset = send_buffer->stream_offset(); - send_buffer->SaveStreamData(&iov, /*iov_count=*/1, /*iov_offset=*/0, - data.length()); + send_buffer->SaveStreamData(data); if (kMaxStreamLength - offset < data.length()) { QUIC_BUG(quic_bug_10322_2) << "Writing too much crypto handshake data"; // TODO(nharper): Switch this to an IETF QUIC error code, possibly
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc index 3b56f82..f038e33 100644 --- a/quic/core/quic_packet_creator_test.cc +++ b/quic/core/quic_packet_creator_test.cc
@@ -104,24 +104,18 @@ producer_(producer), version_(framer->version()) {} - bool ConsumeDataToFillCurrentPacket(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t total_length, - size_t iov_offset, - QuicStreamOffset offset, - bool fin, + bool ConsumeDataToFillCurrentPacket(QuicStreamId id, absl::string_view data, + QuicStreamOffset offset, bool fin, bool needs_full_padding, TransmissionType transmission_type, QuicFrame* frame) { // Save data before data is consumed. - QuicByteCount data_length = total_length - iov_offset; - if (data_length > 0) { - producer_->SaveStreamData(id, iov, iov_count, iov_offset, data_length); + if (!data.empty()) { + producer_->SaveStreamData(id, data); } return QuicPacketCreator::ConsumeDataToFillCurrentPacket( - id, data_length - iov_offset, offset, fin, needs_full_padding, - transmission_type, frame); + id, data.length(), offset, fin, needs_full_padding, transmission_type, + frame); } void StopSendingVersion() { @@ -283,7 +277,6 @@ StrictMock<MockFramerVisitor> framer_visitor_; StrictMock<MockPacketCreatorDelegate> delegate_; std::string data_; - struct iovec iov_; TestPacketCreator creator_; std::unique_ptr<SerializedPacket> serialized_packet_; SimpleDataProducer producer_; @@ -384,12 +377,11 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataToFillCurrentPacket) { creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); QuicFrame frame; - MakeIOVector("test", &iov_); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); + const std::string data("test"); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, - NOT_RETRANSMISSION, &frame)); + stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame)); size_t consumed = frame.stream_frame.data_length; EXPECT_EQ(4u, consumed); CheckStreamFrame(frame, stream_id, "test", 0u, false); @@ -399,12 +391,11 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataFin) { creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); QuicFrame frame; - MakeIOVector("test", &iov_); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); + const std::string data("test"); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, true, false, - NOT_RETRANSMISSION, &frame)); + stream_id, data, 0u, true, false, NOT_RETRANSMISSION, &frame)); size_t consumed = frame.stream_frame.data_length; EXPECT_EQ(4u, consumed); CheckStreamFrame(frame, stream_id, "test", 0u, true); @@ -417,8 +408,7 @@ QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, nullptr, 0u, 0u, 0u, 0u, true, false, NOT_RETRANSMISSION, - &frame)); + stream_id, {}, 0u, true, false, NOT_RETRANSMISSION, &frame)); size_t consumed = frame.stream_frame.data_length; EXPECT_EQ(0u, consumed); CheckStreamFrame(frame, stream_id, std::string(), 0u, true); @@ -445,13 +435,13 @@ kOffset, /* data_size=*/0xffff)); if (should_have_room) { QuicFrame frame; - MakeIOVector("testdata", &iov_); + const std::string data("testdata"); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly(Invoke( this, &QuicPacketCreatorTest::ClearSerializedPacketForTests)); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, - kOffset, false, false, NOT_RETRANSMISSION, &frame)); + GetNthClientInitiatedStreamId(1), data, kOffset, false, false, + NOT_RETRANSMISSION, &frame)); size_t bytes_consumed = frame.stream_frame.data_length; EXPECT_LT(0u, bytes_consumed); creator_.FlushCurrentPacket(); @@ -472,10 +462,9 @@ std::string data(capacity + delta, 'A'); size_t bytes_free = delta > 0 ? 0 : 0 - delta; QuicFrame frame; - MakeIOVector(data, &iov_); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, kOffset, - false, false, NOT_RETRANSMISSION, &frame)); + GetNthClientInitiatedStreamId(1), data, kOffset, false, false, + NOT_RETRANSMISSION, &frame)); // BytesFree() returns bytes available for the next frame, which will // be two bytes smaller since the stream frame would need to be grown. @@ -513,7 +502,6 @@ size_t bytes_free = delta > 0 ? 0 : 0 - delta; QuicFrame frame; - MakeIOVector(data, &iov_); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); @@ -524,8 +512,7 @@ if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), - &iov_, 1u, iov_.iov_len, 0u, kOffset, false, true, NOT_RETRANSMISSION, - &frame)); + data, kOffset, false, true, NOT_RETRANSMISSION, &frame)); size_t bytes_consumed = frame.stream_frame.data_length; EXPECT_LT(0u, bytes_consumed); } else { @@ -569,12 +556,11 @@ size_t bytes_free = delta > 0 ? 0 : 0 - delta; QuicFrame frame; - MakeIOVector(data, &iov_); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, kOffset, - false, false, NOT_RETRANSMISSION, &frame)); + GetNthClientInitiatedStreamId(1), data, kOffset, false, false, + NOT_RETRANSMISSION, &frame)); size_t bytes_consumed = frame.stream_frame.data_length; EXPECT_LT(0u, bytes_consumed); creator_.FlushCurrentPacket(); @@ -1398,14 +1384,13 @@ QuicFrame frame; size_t payload_length = creator_.max_packet_length(); const std::string too_long_payload(payload_length, 'a'); - MakeIOVector(too_long_payload, &iov_); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, true, false, - NOT_RETRANSMISSION, &frame)); + stream_id, too_long_payload, 0u, true, false, NOT_RETRANSMISSION, + &frame)); size_t consumed = frame.stream_frame.data_length; // The entire payload could not be consumed. EXPECT_GT(payload_length, consumed); @@ -1450,11 +1435,10 @@ EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id)); QuicFrame frame; - MakeIOVector("test", &iov_); + const std::string data("test"); EXPECT_CALL(debug, OnFrameAddedToPacket(_)); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, - NOT_RETRANSMISSION, &frame)); + stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame)); size_t consumed = frame.stream_frame.data_length; EXPECT_EQ(4u, consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -1504,9 +1488,8 @@ } EXPECT_FALSE(creator_.HasPendingFrames()); - MakeIOVector("test", &iov_); - producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u, - iov_.iov_len); + const std::string data("test"); + producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); size_t num_bytes_consumed; @@ -1514,7 +1497,7 @@ creator_.set_debug_delegate(&debug); EXPECT_CALL(debug, OnFrameAddedToPacket(_)); creator_.CreateAndSerializeStreamFrame( - GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true, + GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true, NOT_RETRANSMISSION, &num_bytes_consumed); EXPECT_EQ(4u, num_bytes_consumed); @@ -1541,14 +1524,13 @@ EXPECT_FALSE(creator_.HasPendingFrames()); // Send one byte of stream data. - MakeIOVector("a", &iov_); - producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u, - iov_.iov_len); + const std::string data("a"); + producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); size_t num_bytes_consumed; creator_.CreateAndSerializeStreamFrame( - GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true, + GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true, NOT_RETRANSMISSION, &num_bytes_consumed); EXPECT_EQ(1u, num_bytes_consumed); @@ -1621,16 +1603,13 @@ std::unique_ptr<QuicData> message_data; message_data = framer.ConstructHandshakeMessage(message); - struct iovec iov; - MakeIOVector(absl::string_view(message_data->data(), message_data->length()), - &iov); QuicFrame frame; EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _)); EXPECT_QUIC_BUG( creator_.ConsumeDataToFillCurrentPacket( QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), - &iov, 1u, iov.iov_len, 0u, 0u, false, false, NOT_RETRANSMISSION, - &frame), + absl::string_view(message_data->data(), message_data->length()), 0u, + false, false, NOT_RETRANSMISSION, &frame), "Client hello won't fit in a single packet."); } @@ -1665,11 +1644,11 @@ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); creator_.AddPendingPadding(kMaxNumRandomPaddingBytes); QuicFrame frame; - MakeIOVector("test", &iov_); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); + const std::string data("test"); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, + stream_id, data, 0u, false, /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame)); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); @@ -1700,18 +1679,16 @@ .WillRepeatedly( Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); // Send stream frame of size kStreamFramePayloadSize. - MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); - creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, - 0u, 0u, false, false, - NOT_RETRANSMISSION, &frame); + creator_.ConsumeDataToFillCurrentPacket( + stream_id, absl::string_view(buf, kStreamFramePayloadSize), 0u, false, + false, NOT_RETRANSMISSION, &frame); creator_.FlushCurrentPacket(); // 1 byte padding is sent. EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes()); // Send stream frame of size kStreamFramePayloadSize + 1. - MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize + 1), &iov_); - creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, - 0u, kStreamFramePayloadSize, false, - false, NOT_RETRANSMISSION, &frame); + creator_.ConsumeDataToFillCurrentPacket( + stream_id, absl::string_view(buf, kStreamFramePayloadSize + 1), + kStreamFramePayloadSize, false, false, NOT_RETRANSMISSION, &frame); // No padding is sent. creator_.FlushCurrentPacket(); EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes()); @@ -1730,11 +1707,11 @@ EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(external_buffer)); QuicFrame frame; - MakeIOVector("test", &iov_); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); + const std::string data("test"); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, + stream_id, data, 0u, false, /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame)); EXPECT_CALL(delegate_, OnSerializedPacket(_)) @@ -1792,12 +1769,11 @@ creator_.FlushCurrentPacket(); QuicFrame frame; - MakeIOVector("test", &iov_); QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( client_framer_.transport_version(), Perspective::IS_CLIENT); + const std::string data("test"); EXPECT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, - NOT_RETRANSMISSION, &frame)); + stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame)); QuicMessageFrame* frame4 = new QuicMessageFrame(4, MemSliceFromString("message")); EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame4), NOT_RETRANSMISSION)); @@ -2062,43 +2038,38 @@ StrictMock<MockDebugDelegate> debug; creator_.set_debug_delegate(&debug); - MakeIOVector("test", &iov_); QuicFrame frame; + const std::string data1("test"); EXPECT_CALL(debug, OnFrameAddedToPacket(_)); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id1, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, - NOT_RETRANSMISSION, &frame)); + stream_id1, data1, 0u, false, false, NOT_RETRANSMISSION, &frame)); EXPECT_TRUE(creator_.HasPendingFrames()); EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id1)); - MakeIOVector("coalesce", &iov_); + const std::string data2("coalesce"); // frame will be coalesced with the first frame. const auto previous_size = creator_.PacketSize(); - QuicStreamFrame target(stream_id1, true, 0, 12); + QuicStreamFrame target(stream_id1, true, 0, data1.length() + data2.length()); EXPECT_CALL(debug, OnStreamFrameCoalesced(target)); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id1, &iov_, 1u, iov_.iov_len, 0u, 4u, true, false, - NOT_RETRANSMISSION, &frame)); + stream_id1, data2, 4u, true, false, NOT_RETRANSMISSION, &frame)); EXPECT_EQ(frame.stream_frame.data_length, creator_.PacketSize() - previous_size); // frame is for another stream, so it won't be coalesced. const auto length = creator_.BytesFree() - 10u; - std::string large_data(length, 'x'); - MakeIOVector(large_data, &iov_); + const std::string data3(length, 'x'); EXPECT_CALL(debug, OnFrameAddedToPacket(_)); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id2, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, - NOT_RETRANSMISSION, &frame)); + stream_id2, data3, 0u, false, false, NOT_RETRANSMISSION, &frame)); EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id2)); // The packet doesn't have enough free bytes for all data, but will still be // able to consume and coalesce part of them. EXPECT_CALL(debug, OnStreamFrameCoalesced(_)); - MakeIOVector("somerandomdata", &iov_); + const std::string data4("somerandomdata"); ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - stream_id2, &iov_, 1u, iov_.iov_len, 0u, length, false, false, - NOT_RETRANSMISSION, &frame)); + stream_id2, data4, length, false, false, NOT_RETRANSMISSION, &frame)); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); @@ -2254,14 +2225,12 @@ // restored. creator_.SetSoftMaxPacketLength(overhead); EXPECT_EQ(overhead, creator_.max_packet_length()); - std::string data = "crypto data"; - MakeIOVector(data, &iov_); + const std::string data = "crypto data"; QuicFrame frame; if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( - QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), &iov_, - 1u, iov_.iov_len, 0u, kOffset, false, true, NOT_RETRANSMISSION, - &frame)); + QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), data, + kOffset, false, true, NOT_RETRANSMISSION, &frame)); size_t bytes_consumed = frame.stream_frame.data_length; EXPECT_LT(0u, bytes_consumed); } else { @@ -2417,34 +2386,28 @@ } QuicConsumedData ConsumeDataFastPath(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t total_length, - QuicStreamOffset offset, - bool fin) { + absl::string_view data) { // Save data before data is consumed. - if (total_length > 0) { - producer_->SaveStreamData(id, iov, iov_count, 0, total_length); + if (!data.empty()) { + producer_->SaveStreamData(id, data); } - return QuicPacketCreator::ConsumeDataFastPath(id, total_length, offset, fin, - 0); + return QuicPacketCreator::ConsumeDataFastPath(id, data.length(), + /* offset = */ 0, + /* fin = */ true, 0); } - QuicConsumedData ConsumeData(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t total_length, + QuicConsumedData ConsumeData(QuicStreamId id, absl::string_view data, QuicStreamOffset offset, StreamSendingState state) { // Save data before data is consumed. - if (total_length > 0) { - producer_->SaveStreamData(id, iov, iov_count, 0, total_length); + if (!data.empty()) { + producer_->SaveStreamData(id, data); } if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) { EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); } - return QuicPacketCreator::ConsumeData(id, total_length, offset, state); + return QuicPacketCreator::ConsumeData(id, data.length(), offset, state); } MessageStatus AddMessageFrame(QuicMessageId message_id, @@ -2591,13 +2554,6 @@ } } - void CreateData(size_t len) { - data_array_.reset(new char[len]); - memset(data_array_.get(), '?', len); - iov_.iov_base = data_array_.get(); - iov_.iov_len = len; - } - QuicFramer framer_; MockRandom random_creator_; StrictMock<MockDelegate> delegate_; @@ -2630,14 +2586,13 @@ WrongEncryptionLevelForStreamDataFastPath) { creator_.set_encryption_level(ENCRYPTION_HANDSHAKE); delegate_.SetCanWriteAnything(); - // Create a 10000 byte IOVector. - CreateData(10000); + const std::string data(10000, '?'); EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0); EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); EXPECT_QUIC_BUG(creator_.ConsumeDataFastPath( QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, true), + data), ""); } @@ -2734,11 +2689,10 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) { delegate_.SetCanNotWrite(); - MakeIOVector("foo", &iov_); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "foo", 0, FIN); EXPECT_EQ(0u, consumed.bytes_consumed); EXPECT_FALSE(consumed.fin_consumed); EXPECT_FALSE(creator_.HasPendingFrames()); @@ -2749,11 +2703,10 @@ ConsumeData_WritableAndShouldNotFlush) { delegate_.SetCanWriteAnything(); - MakeIOVector("foo", &iov_); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "foo", 0, FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -2767,11 +2720,10 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector("foo", &iov_); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "foo", 0, FIN); creator_.Flush(); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); @@ -2792,8 +2744,7 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - std::string data = "foo bar"; - MakeIOVector(data, &iov_); + const std::string data = "foo bar"; size_t consumed_bytes = 0; if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { consumed_bytes = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); @@ -2801,8 +2752,8 @@ consumed_bytes = creator_ .ConsumeData( - QuicUtils::GetCryptoStreamId(framer_.transport_version()), - &iov_, 1u, iov_.iov_len, 0, NO_FIN) + QuicUtils::GetCryptoStreamId(framer_.transport_version()), data, + 0, NO_FIN) .bytes_consumed; } EXPECT_EQ(7u, consumed_bytes); @@ -2834,8 +2785,7 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - std::string data = "foo"; - MakeIOVector(data, &iov_); + const std::string data = "foo"; size_t bytes_consumed = 0; if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { bytes_consumed = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); @@ -2843,8 +2793,8 @@ bytes_consumed = creator_ .ConsumeData( - QuicUtils::GetCryptoStreamId(framer_.transport_version()), - &iov_, 1u, iov_.iov_len, 0, NO_FIN) + QuicUtils::GetCryptoStreamId(framer_.transport_version()), data, + 0, NO_FIN) .bytes_consumed; } EXPECT_EQ(3u, bytes_consumed); @@ -2882,7 +2832,7 @@ EXPECT_QUIC_BUG(creator_.ConsumeData( QuicUtils::QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT), - nullptr, 0, 0, 0, NO_FIN), + {}, 0, NO_FIN), "Attempt to consume empty data without FIN."); } @@ -2890,13 +2840,10 @@ ConsumeDataMultipleTimes_WritableAndShouldNotFlush) { delegate_.SetCanWriteAnything(); - MakeIOVector("foo", &iov_); creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - MakeIOVector("quux", &iov_); - QuicConsumedData consumed = - creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 3, NO_FIN); + "foo", 0, FIN); + QuicConsumedData consumed = creator_.ConsumeData(3, "quux", 3, NO_FIN); EXPECT_EQ(4u, consumed.bytes_consumed); EXPECT_FALSE(consumed.fin_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -2906,15 +2853,13 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_BatchOperations) { delegate_.SetCanWriteAnything(); - MakeIOVector("foo", &iov_); creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); - MakeIOVector("quux", &iov_); + "foo", 0, NO_FIN); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 3, FIN); + "quux", 3, FIN); EXPECT_EQ(4u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -2969,11 +2914,10 @@ } // Queue enough data to prevent a stream frame with a non-zero offset from // fitting. - MakeIOVector("foo", &iov_); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); + "foo", 0, NO_FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_FALSE(consumed.fin_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -2981,11 +2925,10 @@ // This frame will not fit with the existing frame, causing the queued frame // to be serialized, and it will be added to a new open packet. - MakeIOVector("bar", &iov_); consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 3, FIN); + "bar", 3, FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -3005,15 +2948,14 @@ delegate_.SetCanWriteAnything(); creator_.SetTransmissionType(LOSS_RETRANSMISSION); - // Create a 10000 byte IOVector. - CreateData(10000); + const std::string data(10000, '?'); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); QuicConsumedData consumed = creator_.ConsumeDataFastPath( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, true); + data); EXPECT_EQ(10000u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_FALSE(creator_.HasPendingFrames()); @@ -3035,15 +2977,14 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLarge) { delegate_.SetCanWriteAnything(); - // Create a 10000 byte IOVector. - CreateData(10000); + const std::string data(10000, '?'); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + data, 0, FIN); EXPECT_EQ(10000u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); EXPECT_FALSE(creator_.HasPendingFrames()); @@ -3077,8 +3018,7 @@ creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), /*bundle_ack=*/false); - // Create a 10000 byte IOVector. - CreateData(10000); + const std::string data(10000, '?'); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); @@ -3087,7 +3027,7 @@ QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + data, 0, FIN); creator_.Flush(); EXPECT_EQ(10000u, consumed.bytes_consumed); @@ -3108,15 +3048,14 @@ delegate_.SetCanNotWrite(); delegate_.SetCanWriteAnything(); - // Create a 10000 byte IOVector. - CreateData(10000); + const std::string data(10000, '?'); EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + data, 0, FIN); creator_.Flush(); EXPECT_EQ(10000u, consumed.bytes_consumed); @@ -3151,8 +3090,7 @@ creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), /*bundle_ack=*/false)); // Send some data and a control frame - MakeIOVector("quux", &iov_); - creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, NO_FIN); + creator_.ConsumeData(3, "quux", 0, NO_FIN); if (!VersionHasIetfQuicFrames(framer_.transport_version())) { creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()), /*bundle_ack=*/false); @@ -3209,9 +3147,8 @@ /*bundle_ack=*/false)); // Send enough data to exceed one packet size_t data_len = kDefaultMaxPacketSize + 100; - CreateData(data_len); - QuicConsumedData consumed = - creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, FIN); + const std::string data(data_len, '?'); + QuicConsumedData consumed = creator_.ConsumeData(3, data, 0, FIN); EXPECT_EQ(data_len, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); if (!VersionHasIetfQuicFrames(framer_.transport_version())) { @@ -3250,11 +3187,10 @@ creator_.SetTransmissionType(LOSS_RETRANSMISSION); size_t data_len = 1224; - CreateData(data_len); + const std::string data(data_len, '?'); QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT); - QuicConsumedData consumed = - creator_.ConsumeData(stream1_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN); + QuicConsumedData consumed = creator_.ConsumeData(stream1_id, data, 0, NO_FIN); EXPECT_EQ(data_len, consumed.bytes_consumed); ASSERT_EQ(0u, creator_.BytesFree()) << "Test setup failed: Please increase data_len to " @@ -3269,8 +3205,7 @@ QuicStreamId stream2_id = stream1_id + 4; - consumed = - creator_.ConsumeData(stream2_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN); + consumed = creator_.ConsumeData(stream2_id, data, 0, NO_FIN); EXPECT_EQ(data_len, consumed.bytes_consumed); // Ensure the packet is successfully created. @@ -3319,11 +3254,11 @@ .Times(3) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - CreateData(data_len); + const std::string data(data_len, '?'); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, + data, /*offset=*/0, FIN); EXPECT_EQ(data_len, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); @@ -3358,11 +3293,11 @@ Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); // Send two packets before packet size change. - CreateData(data_len); + const std::string data(data_len, '?'); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, + data, /*offset=*/0, NO_FIN); creator_.Flush(); EXPECT_EQ(data_len, consumed.bytes_consumed); @@ -3378,12 +3313,11 @@ EXPECT_EQ(packet_len, creator_.max_packet_length()); // Send a packet after packet size change. - CreateData(data_len); creator_.AttachPacketFlusher(); consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, data_len, FIN); + data, data_len, FIN); creator_.Flush(); EXPECT_EQ(data_len, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); @@ -3411,11 +3345,11 @@ // First send half of the packet worth of data. We are in the batch mode, so // should not cause packet serialization. - CreateData(first_write_len); + const std::string first_write(first_write_len, '?'); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, + first_write, /*offset=*/0, NO_FIN); EXPECT_EQ(first_write_len, consumed.bytes_consumed); EXPECT_FALSE(consumed.fin_consumed); @@ -3447,11 +3381,11 @@ // Send a more than a packet worth of data to the same stream. This should // trigger serialization of one packet, and queue another one. - CreateData(second_write_len); + const std::string second_write(second_write_len, '?'); consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, + second_write, /*offset=*/first_write_len, FIN); EXPECT_EQ(second_write_len, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); @@ -3541,11 +3475,11 @@ Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); // Send data before the MTU probe. - CreateData(data_len); + const std::string data(data_len, '?'); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, + data, /*offset=*/0, NO_FIN); creator_.Flush(); EXPECT_EQ(data_len, consumed.bytes_consumed); @@ -3559,12 +3493,11 @@ EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); // Send data after the MTU probe. - CreateData(data_len); creator_.AttachPacketFlusher(); consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, + data, /*offset=*/data_len, FIN); creator_.Flush(); EXPECT_EQ(data_len, consumed.bytes_consumed); @@ -3655,9 +3588,9 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); QuicConsumedData consumed = creator_.ConsumeData( - kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); + kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 0, + FIN_AND_PADDING); creator_.Flush(); EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); EXPECT_FALSE(creator_.HasPendingFrames()); @@ -3698,9 +3631,9 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); QuicConsumedData consumed = creator_.ConsumeData( - kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); + kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 0, + FIN_AND_PADDING); creator_.Flush(); EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); EXPECT_FALSE(creator_.HasPendingFrames()); @@ -3753,13 +3686,13 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); QuicConsumedData consumed = creator_.ConsumeData( - kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); + kDataStreamId1, absl::string_view(buf, kStreamFramePayloadSize), 0, + FIN_AND_PADDING); EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); - MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); - consumed = creator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 0, - FIN_AND_PADDING); + consumed = creator_.ConsumeData( + kDataStreamId2, absl::string_view(buf, kStreamFramePayloadSize), 0, + FIN_AND_PADDING); EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); creator_.Flush(); EXPECT_FALSE(creator_.HasPendingFrames()); @@ -3796,10 +3729,9 @@ .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector("foo", &iov_); creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "foo", 0, FIN); EXPECT_EQ(MESSAGE_STATUS_SUCCESS, creator_.AddMessageFrame(1, MemSliceFromString("message"))); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -3841,10 +3773,9 @@ EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector("a", &iov_); creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( framer_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "a", 0, FIN); creator_.Flush(); ASSERT_FALSE(packets_[0].nonretransmittable_frames.empty()); QuicFrame padding = packets_[0].nonretransmittable_frames[0]; @@ -3861,13 +3792,12 @@ creator_.SetClientConnectionId(client_connection_id); creator_.SetServerConnectionId(server_connection_id); // Send some stream data. - MakeIOVector("foo", &iov_); EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _)) .WillRepeatedly(Return(true)); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); + "foo", 0, NO_FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); { @@ -3882,7 +3812,7 @@ QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "foo", 0, FIN); EXPECT_EQ(3u, consumed.bytes_consumed); } // After exiting the scope, the last queued frame should be flushed. @@ -3902,13 +3832,12 @@ QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345); creator_.SetDefaultPeerAddress(peer_addr); // Send some stream data. - MakeIOVector("foo", &iov_); EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _)) .WillRepeatedly(Return(true)); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); + "foo", 0, NO_FIN); EXPECT_EQ(3u, consumed.bytes_consumed); QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346); @@ -3938,7 +3867,7 @@ QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); + "foo", 0, FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); } @@ -3959,13 +3888,12 @@ ASSERT_EQ(server_connection_id1, creator_.GetServerConnectionId()); // Send some stream data. - MakeIOVector("foo", &iov_); EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _)) .WillRepeatedly(Return(true)); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); + "foo", 0, NO_FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -3984,13 +3912,12 @@ /*update_connection_id=*/true); ASSERT_EQ(client_connection_id2, creator_.GetClientConnectionId()); ASSERT_EQ(server_connection_id2, creator_.GetServerConnectionId()); - MakeIOVector("foo", &iov_); EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _)) .WillRepeatedly(Return(true)); QuicConsumedData consumed = creator_.ConsumeData( QuicUtils::GetFirstBidirectionalStreamId( creator_.transport_version(), Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); + "foo", 0, NO_FIN); EXPECT_EQ(3u, consumed.bytes_consumed); EXPECT_TRUE(creator_.HasPendingFrames()); // This should trigger another OnSerializedPacket() with the 2nd
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc index 68ae9f9..4d5eed5 100644 --- a/quic/core/quic_session_test.cc +++ b/quic/core/quic_session_test.cc
@@ -352,14 +352,12 @@ } QuicConsumedData SendStreamData(QuicStream* stream) { - struct iovec iov; if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(), stream->id()) && this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) { this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); } - MakeIOVector("not empty", &iov); - QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9); + QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty"); QuicConsumedData consumed = WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, GetEncryptionLevelToSendApplicationData());
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc index f8e00b4..8737044 100644 --- a/quic/core/quic_stream.cc +++ b/quic/core/quic_stream.cc
@@ -688,7 +688,6 @@ // Do not respect buffered data upper limit as WriteOrBufferData guarantees // all data to be consumed. if (data.length() > 0) { - struct iovec iov(QuicUtils::MakeIovec(data)); QuicStreamOffset offset = send_buffer_.stream_offset(); if (kMaxStreamLength - offset < data.length()) { QUIC_BUG(quic_bug_10586_4) << "Write too many data via stream " << id_; @@ -697,7 +696,7 @@ absl::StrCat("Write too many data via stream ", id_)); return; } - send_buffer_.SaveStreamData(&iov, 1, 0, data.length()); + send_buffer_.SaveStreamData(data); OnDataBuffered(offset, data.length(), ack_listener); } if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
diff --git a/quic/core/quic_stream_send_buffer.cc b/quic/core/quic_stream_send_buffer.cc index aa58ead..6017768 100644 --- a/quic/core/quic_stream_send_buffer.cc +++ b/quic/core/quic_stream_send_buffer.cc
@@ -58,22 +58,19 @@ QuicStreamSendBuffer::~QuicStreamSendBuffer() {} -void QuicStreamSendBuffer::SaveStreamData(const struct iovec* iov, - int iov_count, - size_t iov_offset, - QuicByteCount data_length) { - QUICHE_DCHECK_LT(0u, data_length); +void QuicStreamSendBuffer::SaveStreamData(absl::string_view data) { + QUICHE_DCHECK(!data.empty()); + // Latch the maximum data slice size. const QuicByteCount max_data_slice_size = GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size); - while (data_length > 0) { - size_t slice_len = std::min(data_length, max_data_slice_size); - quiche::QuicheBuffer buffer(allocator_, slice_len); - QuicUtils::CopyToBuffer(iov, iov_count, iov_offset, slice_len, - buffer.data()); + while (!data.empty()) { + size_t slice_len = std::min(data.length(), max_data_slice_size); + auto buffer = + quiche::QuicheBuffer::Copy(allocator_, data.substr(0, slice_len)); SaveMemSlice(quiche::QuicheMemSlice(std::move(buffer))); - data_length -= slice_len; - iov_offset += slice_len; + + data = data.substr(slice_len); } }
diff --git a/quic/core/quic_stream_send_buffer.h b/quic/core/quic_stream_send_buffer.h index 6fe7b75..cf3fa13 100644 --- a/quic/core/quic_stream_send_buffer.h +++ b/quic/core/quic_stream_send_buffer.h
@@ -69,11 +69,8 @@ QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete; ~QuicStreamSendBuffer(); - // Save |data_length| of data starts at |iov_offset| in |iov| to send buffer. - void SaveStreamData(const struct iovec* iov, - int iov_count, - size_t iov_offset, - QuicByteCount data_length); + // Save |data| to send buffer. + void SaveStreamData(absl::string_view data); // Save |slice| to send buffer. void SaveMemSlice(quiche::QuicheMemSlice slice);
diff --git a/quic/core/quic_stream_send_buffer_test.cc b/quic/core/quic_stream_send_buffer_test.cc index 2e0f9dc..599ebf4 100644 --- a/quic/core/quic_stream_send_buffer_test.cc +++ b/quic/core/quic_stream_send_buffer_test.cc
@@ -20,46 +20,41 @@ namespace test { namespace { -struct iovec MakeIovec(absl::string_view data) { - struct iovec iov = {const_cast<char*>(data.data()), - static_cast<size_t>(data.size())}; - return iov; -} - class QuicStreamSendBufferTest : public QuicTest { public: QuicStreamSendBufferTest() : send_buffer_(&allocator_) { EXPECT_EQ(0u, send_buffer_.size()); EXPECT_EQ(0u, send_buffer_.stream_bytes_written()); EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding()); - std::string data1(1536, 'a'); - std::string data2 = std::string(256, 'b') + std::string(256, 'c'); - struct iovec iov[2]; - iov[0] = MakeIovec(absl::string_view(data1)); - iov[1] = MakeIovec(absl::string_view(data2)); + // The stream offset should be 0 since nothing is written. + EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_)); + + std::string data1 = absl::StrCat( + std::string(1536, 'a'), std::string(256, 'b'), std::string(256, 'c')); quiche::QuicheBuffer buffer1(&allocator_, 1024); memset(buffer1.data(), 'c', buffer1.size()); quiche::QuicheMemSlice slice1(std::move(buffer1)); + quiche::QuicheBuffer buffer2(&allocator_, 768); memset(buffer2.data(), 'd', buffer2.size()); quiche::QuicheMemSlice slice2(std::move(buffer2)); - // The stream offset should be 0 since nothing is written. - EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_)); - - // Save all data. + // `data` will be split into two BufferedSlices. SetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size, 1024); - send_buffer_.SaveStreamData(iov, 2, 0, 2048); + send_buffer_.SaveStreamData(data1); + send_buffer_.SaveMemSlice(std::move(slice1)); EXPECT_TRUE(slice1.empty()); send_buffer_.SaveMemSlice(std::move(slice2)); EXPECT_TRUE(slice2.empty()); EXPECT_EQ(4u, send_buffer_.size()); - // At this point, the whole buffer looks like: - // | a * 1536 |b * 256| c * 1280 | d * 768 | - // | slice1 | slice2 | slice3 | slice4 | + // At this point, `send_buffer_.interval_deque_` looks like this: + // BufferedSlice1: 'a' * 1024 + // BufferedSlice2: 'a' * 512 + 'b' * 256 + 'c' * 256 + // BufferedSlice3: 'c' * 1024 + // BufferedSlice4: 'd' * 768 } void WriteAllData() {
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc index caffd7f..aa8f59e 100644 --- a/quic/core/quic_utils.cc +++ b/quic/core/quic_utils.cc
@@ -290,13 +290,6 @@ } // static -struct iovec QuicUtils::MakeIovec(absl::string_view data) { - struct iovec iov = {const_cast<char*>(data.data()), - static_cast<size_t>(data.size())}; - return iov; -} - -// static bool QuicUtils::IsAckable(SentPacketState state) { return state != NEVER_SENT && state != ACKED && state != UNACKABLE; }
diff --git a/quic/core/quic_utils.h b/quic/core/quic_utils.h index 43e6470..085f532 100644 --- a/quic/core/quic_utils.h +++ b/quic/core/quic_utils.h
@@ -81,9 +81,6 @@ size_t buffer_length, char* buffer); - // Creates an iovec pointing to the same data as |data|. - static struct iovec MakeIovec(absl::string_view data); - // Returns the opposite Perspective of the |perspective| passed in. static constexpr Perspective InvertPerspective(Perspective perspective) { return perspective == Perspective::IS_CLIENT ? Perspective::IS_SERVER
diff --git a/quic/test_tools/simple_data_producer.cc b/quic/test_tools/simple_data_producer.cc index aaab1d1..64c0a2c 100644 --- a/quic/test_tools/simple_data_producer.cc +++ b/quic/test_tools/simple_data_producer.cc
@@ -20,17 +20,14 @@ SimpleDataProducer::~SimpleDataProducer() {} void SimpleDataProducer::SaveStreamData(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t iov_offset, - QuicByteCount data_length) { - if (data_length == 0) { + absl::string_view data) { + if (data.empty()) { return; } if (!send_buffer_map_.contains(id)) { send_buffer_map_[id] = std::make_unique<QuicStreamSendBuffer>(&allocator_); } - send_buffer_map_[id]->SaveStreamData(iov, iov_count, iov_offset, data_length); + send_buffer_map_[id]->SaveStreamData(data); } void SimpleDataProducer::SaveCryptoData(EncryptionLevel level,
diff --git a/quic/test_tools/simple_data_producer.h b/quic/test_tools/simple_data_producer.h index e8dd4e4..9564f86 100644 --- a/quic/test_tools/simple_data_producer.h +++ b/quic/test_tools/simple_data_producer.h
@@ -23,17 +23,10 @@ SimpleDataProducer(); ~SimpleDataProducer() override; - // Saves data to be provided when WriteStreamData is called. Data of length - // |data_length| is buffered to be provided for stream |id|. Multiple calls to - // SaveStreamData for the same stream ID append to the buffer for that stream. - // The data to be buffered is provided in |iov_count| iovec structs, with - // |iov| pointing to the first, and |iov_offset| indicating how many bytes - // into the iovec structs the data starts. - void SaveStreamData(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t iov_offset, - QuicByteCount data_length); + // Saves `data` to be provided when WriteStreamData() is called. Multiple + // calls to SaveStreamData() for the same stream ID append to the buffer for + // that stream. + void SaveStreamData(QuicStreamId id, absl::string_view data); void SaveCryptoData(EncryptionLevel level, QuicStreamOffset offset,