Simplify QpackEncoderStreamSender API.

Instead of each Send*() method returning the number of bytes encoded, return the
total number of bytes written from Flush().

This is a follow-up to cr/273553497.

gfe-relnote: n/a, change to QUIC v99-only code.  Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 273775165
Change-Id: Ifaf1b55d6d0ab26cc3ab23686bcb7427e3c9627f
diff --git a/quic/core/qpack/qpack_encoder.cc b/quic/core/qpack/qpack_encoder.cc
index eac158b..b1f7fbe 100644
--- a/quic/core/qpack/qpack_encoder.cc
+++ b/quic/core/qpack/qpack_encoder.cc
@@ -93,7 +93,6 @@
     QuicByteCount* encoder_stream_sent_byte_count) {
   Instructions instructions;
   instructions.reserve(header_list.size());
-  QuicByteCount sent_byte_count = 0;
 
   // The index of the oldest entry that must not be evicted.
   uint64_t smallest_blocking_index =
@@ -157,7 +156,7 @@
             dynamic_table_insertion_blocked = true;
           } else {
             // If allowed, duplicate entry and refer to it.
-            sent_byte_count += encoder_stream_sender_.SendDuplicate(
+            encoder_stream_sender_.SendDuplicate(
                 QpackAbsoluteIndexToEncoderStreamRelativeIndex(
                     index, header_table_.inserted_entry_count()));
             auto entry = header_table_.InsertEntry(name, value);
@@ -187,9 +186,8 @@
                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
                       smallest_blocking_index)) {
             // If allowed, insert entry into dynamic table and refer to it.
-            sent_byte_count +=
-                encoder_stream_sender_.SendInsertWithNameReference(
-                    is_static, index, value);
+            encoder_stream_sender_.SendInsertWithNameReference(is_static, index,
+                                                               value);
             auto entry = header_table_.InsertEntry(name, value);
             instructions.push_back(EncodeIndexedHeaderField(
                 /* is_static = */ false, entry->InsertionIndex(),
@@ -215,7 +213,7 @@
           dynamic_table_insertion_blocked = true;
         } else {
           // If allowed, insert entry with name reference and refer to it.
-          sent_byte_count += encoder_stream_sender_.SendInsertWithNameReference(
+          encoder_stream_sender_.SendInsertWithNameReference(
               is_static,
               QpackAbsoluteIndexToEncoderStreamRelativeIndex(
                   index, header_table_.inserted_entry_count()),
@@ -258,9 +256,7 @@
                        smallest_blocking_index)) {
           dynamic_table_insertion_blocked = true;
         } else {
-          sent_byte_count +=
-              encoder_stream_sender_.SendInsertWithoutNameReference(name,
-                                                                    value);
+          encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
           auto entry = header_table_.InsertEntry(name, value);
           instructions.push_back(EncodeIndexedHeaderField(
               /* is_static = */ false, entry->InsertionIndex(),
@@ -281,10 +277,7 @@
     }
   }
 
-  encoder_stream_sender_.Flush();
-
-  // Use local |sent_byte_count| variable to avoid branching and dereferencing
-  // each time encoder stream data is sent.
+  const QuicByteCount sent_byte_count = encoder_stream_sender_.Flush();
   if (encoder_stream_sent_byte_count) {
     *encoder_stream_sent_byte_count = sent_byte_count;
   }
diff --git a/quic/core/qpack/qpack_encoder_stream_sender.cc b/quic/core/qpack/qpack_encoder_stream_sender.cc
index 8df0b03..4a7f12c 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender.cc
+++ b/quic/core/qpack/qpack_encoder_stream_sender.cc
@@ -15,7 +15,7 @@
 
 QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
 
-QuicByteCount QpackEncoderStreamSender::SendInsertWithNameReference(
+void QpackEncoderStreamSender::SendInsertWithNameReference(
     bool is_static,
     uint64_t name_index,
     QuicStringPiece value) {
@@ -23,45 +23,42 @@
   values_.varint = name_index;
   values_.value = value;
 
-  return Encode(InsertWithNameReferenceInstruction());
+  instruction_encoder_.Encode(InsertWithNameReferenceInstruction(), values_,
+                              &buffer_);
 }
 
-QuicByteCount QpackEncoderStreamSender::SendInsertWithoutNameReference(
+void QpackEncoderStreamSender::SendInsertWithoutNameReference(
     QuicStringPiece name,
     QuicStringPiece value) {
   values_.name = name;
   values_.value = value;
 
-  return Encode(InsertWithoutNameReferenceInstruction());
+  instruction_encoder_.Encode(InsertWithoutNameReferenceInstruction(), values_,
+                              &buffer_);
 }
 
-QuicByteCount QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
+void QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
   values_.varint = index;
 
-  return Encode(DuplicateInstruction());
+  instruction_encoder_.Encode(DuplicateInstruction(), values_, &buffer_);
 }
 
-QuicByteCount QpackEncoderStreamSender::SendSetDynamicTableCapacity(
-    uint64_t capacity) {
+void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
   values_.varint = capacity;
 
-  return Encode(SetDynamicTableCapacityInstruction());
+  instruction_encoder_.Encode(SetDynamicTableCapacityInstruction(), values_,
+                              &buffer_);
 }
 
-void QpackEncoderStreamSender::Flush() {
+QuicByteCount QpackEncoderStreamSender::Flush() {
   if (buffer_.empty()) {
-    return;
+    return 0;
   }
 
   delegate_->WriteStreamData(buffer_);
+  const QuicByteCount bytes_written = buffer_.size();
   buffer_.clear();
-}
-
-QuicByteCount QpackEncoderStreamSender::Encode(
-    const QpackInstruction* instruction) {
-  const size_t old_buffer_size = buffer_.size();
-  instruction_encoder_.Encode(instruction, values_, &buffer_);
-  return buffer_.size() - old_buffer_size;
+  return bytes_written;
 }
 
 }  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder_stream_sender.h b/quic/core/qpack/qpack_encoder_stream_sender.h
index 5c4af7d..efbfbc6 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender.h
+++ b/quic/core/qpack/qpack_encoder_stream_sender.h
@@ -27,19 +27,20 @@
   // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
 
   // 5.2.1. Insert With Name Reference
-  QuicByteCount SendInsertWithNameReference(bool is_static,
-                                            uint64_t name_index,
-                                            QuicStringPiece value);
+  void SendInsertWithNameReference(bool is_static,
+                                   uint64_t name_index,
+                                   QuicStringPiece value);
   // 5.2.2. Insert Without Name Reference
-  QuicByteCount SendInsertWithoutNameReference(QuicStringPiece name,
-                                               QuicStringPiece value);
+  void SendInsertWithoutNameReference(QuicStringPiece name,
+                                      QuicStringPiece value);
   // 5.2.3. Duplicate
-  QuicByteCount SendDuplicate(uint64_t index);
+  void SendDuplicate(uint64_t index);
   // 5.2.4. Set Dynamic Table Capacity
-  QuicByteCount SendSetDynamicTableCapacity(uint64_t capacity);
+  void SendSetDynamicTableCapacity(uint64_t capacity);
 
   // Writes all buffered instructions on the encoder stream.
-  void Flush();
+  // Returns the number of bytes written.
+  QuicByteCount Flush();
 
   // delegate must be set if dynamic table capacity is not zero.
   void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
@@ -47,10 +48,6 @@
   }
 
  private:
-  // Encodes |instruction| with |values_| using |instruction_encoder_| into
-  // |buffer_|.  Returns number of bytes encoded.
-  QuicByteCount Encode(const QpackInstruction* instruction);
-
   QpackStreamSenderDelegate* delegate_;
   QpackInstructionEncoder instruction_encoder_;
   QpackInstructionEncoder::Values values_;
diff --git a/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
index b1ddd97..80a6ed3 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender_test.cc
+++ b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
@@ -30,23 +30,20 @@
   // Static, index fits in prefix, empty value.
   std::string expected_encoded_data = QuicTextUtils::HexDecode("c500");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithNameReference(true, 5, ""));
-  stream_.Flush();
+  stream_.SendInsertWithNameReference(true, 5, "");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Static, index fits in prefix, Huffman encoded value.
   expected_encoded_data = QuicTextUtils::HexDecode("c28294e7");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithNameReference(true, 2, "foo"));
-  stream_.Flush();
+  stream_.SendInsertWithNameReference(true, 2, "foo");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Not static, index does not fit in prefix, not Huffman encoded value.
   expected_encoded_data = QuicTextUtils::HexDecode("bf4a03626172");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithNameReference(false, 137, "bar"));
-  stream_.Flush();
+  stream_.SendInsertWithNameReference(false, 137, "bar");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Value length does not fit in prefix.
   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
@@ -56,33 +53,28 @@
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(
-      expected_encoded_data.size(),
-      stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z')));
-  stream_.Flush();
+  stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 }
 
 TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
   // Empty name and value.
   std::string expected_encoded_data = QuicTextUtils::HexDecode("4000");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithoutNameReference("", ""));
-  stream_.Flush();
+  stream_.SendInsertWithoutNameReference("", "");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Huffman encoded short strings.
   expected_encoded_data = QuicTextUtils::HexDecode("6294e78294e7");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithoutNameReference("foo", "foo"));
-  stream_.Flush();
+  stream_.SendInsertWithoutNameReference("foo", "foo");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Not Huffman encoded short strings.
   expected_encoded_data = QuicTextUtils::HexDecode("4362617203626172");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithoutNameReference("bar", "bar"));
-  stream_.Flush();
+  stream_.SendInsertWithoutNameReference("bar", "bar");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Not Huffman encoded long strings; length does not fit on prefix.
   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
@@ -93,74 +85,67 @@
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
-                                                   std::string(127, 'Z')));
-  stream_.Flush();
+  stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
+                                         std::string(127, 'Z'));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 }
 
 TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
   // Small index fits in prefix.
   std::string expected_encoded_data = QuicTextUtils::HexDecode("11");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(), stream_.SendDuplicate(17));
-  stream_.Flush();
+  stream_.SendDuplicate(17);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Large index requires two extension bytes.
   expected_encoded_data = QuicTextUtils::HexDecode("1fd503");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(), stream_.SendDuplicate(500));
-  stream_.Flush();
+  stream_.SendDuplicate(500);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 }
 
 TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
   // Small capacity fits in prefix.
   std::string expected_encoded_data = QuicTextUtils::HexDecode("31");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendSetDynamicTableCapacity(17));
-  stream_.Flush();
+  stream_.SendSetDynamicTableCapacity(17);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 
   // Large capacity requires two extension bytes.
   expected_encoded_data = QuicTextUtils::HexDecode("3fd503");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(),
-            stream_.SendSetDynamicTableCapacity(500));
-  stream_.Flush();
+  stream_.SendSetDynamicTableCapacity(500);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 }
 
 // No writes should happen until Flush is called.
 TEST_F(QpackEncoderStreamSenderTest, Coalesce) {
   // Insert entry with static name reference, empty value.
-  std::string expected_encoded_data1 = QuicTextUtils::HexDecode("c500");
-  EXPECT_EQ(expected_encoded_data1.size(),
-            stream_.SendInsertWithNameReference(true, 5, ""));
+  stream_.SendInsertWithNameReference(true, 5, "");
 
   // Insert entry with static name reference, Huffman encoded value.
-  std::string expected_encoded_data2 = QuicTextUtils::HexDecode("c28294e7");
-  EXPECT_EQ(expected_encoded_data2.size(),
-            stream_.SendInsertWithNameReference(true, 2, "foo"));
+  stream_.SendInsertWithNameReference(true, 2, "foo");
 
   // Insert literal entry, Huffman encoded short strings.
-  std::string expected_encoded_data3 = QuicTextUtils::HexDecode("6294e78294e7");
-  EXPECT_EQ(expected_encoded_data3.size(),
-            stream_.SendInsertWithoutNameReference("foo", "foo"));
+  stream_.SendInsertWithoutNameReference("foo", "foo");
 
   // Duplicate entry.
-  std::string expected_encoded_data4 = QuicTextUtils::HexDecode("11");
-  EXPECT_EQ(expected_encoded_data4.size(), stream_.SendDuplicate(17));
+  stream_.SendDuplicate(17);
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(QuicStrCat(
-                  expected_encoded_data1 + expected_encoded_data2 +
-                  expected_encoded_data3 + expected_encoded_data4))));
-  stream_.Flush();
+  std::string expected_encoded_data = QuicTextUtils::HexDecode(
+      "c500"          // Insert entry with static name reference.
+      "c28294e7"      // Insert entry with static name reference.
+      "6294e78294e7"  // Insert literal entry.
+      "11");          // Duplicate entry.
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.Flush());
 }
 
 // No writes should happen if QpackEncoderStreamSender::Flush() is called
 // when the buffer is empty.
 TEST_F(QpackEncoderStreamSenderTest, FlushEmpty) {
-  stream_.Flush();
+  EXPECT_EQ(0u, stream_.Flush());
 }
 
 }  // namespace