Remove QpackProgressiveEncoder.

Since encoding is not done incrementally any more, there is no need to keep a
lot of state about encoding progress in class members: local variables suffice.
This CL inlines QpackProgressiveEncoder's functionality into QpackEncoder and
removes QpackProgressiveEncoder.  No functional change.

gfe-relnote: n/a, QUIC v99-only change.
PiperOrigin-RevId: 254377802
Change-Id: I8d7b36748f6c7124f1b6e7a05e1beb0b27ef34ae
diff --git a/quic/core/qpack/qpack_encoder.cc b/quic/core/qpack/qpack_encoder.cc
index 67e409e..d5bea0d 100644
--- a/quic/core/qpack/qpack_encoder.cc
+++ b/quic/core/qpack/qpack_encoder.cc
@@ -6,7 +6,9 @@
 
 #include <string>
 
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_encoder.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
+#include "net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
 
@@ -25,16 +27,69 @@
 QpackEncoder::~QpackEncoder() {}
 
 std::string QpackEncoder::EncodeHeaderList(
-    QuicStreamId stream_id,
+    QuicStreamId /* stream_id */,
     const spdy::SpdyHeaderBlock* header_list) {
+  QpackInstructionEncoder instruction_encoder;
   std::string encoded_headers;
-  auto progressive_encoder = QuicMakeUnique<QpackProgressiveEncoder>(
-      stream_id, &header_table_, &encoder_stream_sender_, header_list);
-  while (progressive_encoder->HasNext()) {
-    progressive_encoder->Next(
-        /* max_encoded_bytes = */ std::numeric_limits<size_t>::max(),
-        &encoded_headers);
+
+  // TODO(bnc): Implement dynamic entries and set Required Insert Count and
+  // Delta Base accordingly.
+  instruction_encoder.set_varint(0);
+  instruction_encoder.set_varint2(0);
+  instruction_encoder.set_s_bit(false);
+
+  instruction_encoder.Encode(QpackPrefixInstruction());
+  DCHECK(instruction_encoder.HasNext());
+  instruction_encoder.Next(std::numeric_limits<size_t>::max(),
+                           &encoded_headers);
+  DCHECK(!instruction_encoder.HasNext());
+
+  for (const auto& header : ValueSplittingHeaderList(header_list)) {
+    QuicStringPiece name = header.first;
+    QuicStringPiece value = header.second;
+
+    bool is_static;
+    uint64_t index;
+
+    auto match_type =
+        header_table_.FindHeaderField(name, value, &is_static, &index);
+
+    switch (match_type) {
+      case QpackHeaderTable::MatchType::kNameAndValue:
+        DCHECK(is_static) << "Dynamic table entries not supported yet.";
+
+        instruction_encoder.set_s_bit(is_static);
+        instruction_encoder.set_varint(index);
+
+        instruction_encoder.Encode(QpackIndexedHeaderFieldInstruction());
+
+        break;
+      case QpackHeaderTable::MatchType::kName:
+        DCHECK(is_static) << "Dynamic table entries not supported yet.";
+
+        instruction_encoder.set_s_bit(is_static);
+        instruction_encoder.set_varint(index);
+        instruction_encoder.set_value(value);
+
+        instruction_encoder.Encode(
+            QpackLiteralHeaderFieldNameReferenceInstruction());
+
+        break;
+      case QpackHeaderTable::MatchType::kNoMatch:
+        instruction_encoder.set_name(name);
+        instruction_encoder.set_value(value);
+
+        instruction_encoder.Encode(QpackLiteralHeaderFieldInstruction());
+
+        break;
+    }
+
+    DCHECK(instruction_encoder.HasNext());
+    instruction_encoder.Next(std::numeric_limits<size_t>::max(),
+                             &encoded_headers);
+    DCHECK(!instruction_encoder.HasNext());
   }
+
   return encoded_headers;
 }
 
diff --git a/quic/core/qpack/qpack_progressive_encoder.cc b/quic/core/qpack/qpack_progressive_encoder.cc
deleted file mode 100644
index 731ec10..0000000
--- a/quic/core/qpack/qpack_progressive_encoder.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_encoder.h"
-
-#include <string>
-
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
-
-namespace quic {
-
-QpackProgressiveEncoder::QpackProgressiveEncoder(
-    QuicStreamId stream_id,
-    QpackHeaderTable* header_table,
-    QpackEncoderStreamSender* encoder_stream_sender,
-    const spdy::SpdyHeaderBlock* header_list)
-    : stream_id_(stream_id),
-      header_table_(header_table),
-      encoder_stream_sender_(encoder_stream_sender),
-      header_list_(header_list),
-      header_list_iterator_(header_list_.begin()),
-      prefix_encoded_(false) {
-  // TODO(bnc): Use |stream_id_| for dynamic table entry management, and
-  // remove this dummy DCHECK.
-  DCHECK_LE(0u, stream_id_);
-
-  DCHECK(header_table_);
-  DCHECK(encoder_stream_sender_);
-}
-
-bool QpackProgressiveEncoder::HasNext() const {
-  return header_list_iterator_ != header_list_.end() || !prefix_encoded_;
-}
-
-void QpackProgressiveEncoder::Next(size_t max_encoded_bytes,
-                                   std::string* output) {
-  DCHECK_NE(0u, max_encoded_bytes);
-  DCHECK(HasNext());
-
-  // Since QpackInstructionEncoder::Next() does not indicate the number of bytes
-  // written, save the maximum new size of |*output|.
-  const size_t max_length = output->size() + max_encoded_bytes;
-
-  DCHECK_LT(output->size(), max_length);
-
-  if (!prefix_encoded_ && !instruction_encoder_.HasNext()) {
-    // TODO(bnc): Implement dynamic entries and set Required Insert Count and
-    // Delta Base accordingly.
-    instruction_encoder_.set_varint(0);
-    instruction_encoder_.set_varint2(0);
-    instruction_encoder_.set_s_bit(false);
-
-    instruction_encoder_.Encode(QpackPrefixInstruction());
-
-    DCHECK(instruction_encoder_.HasNext());
-  }
-
-  do {
-    // Call QpackInstructionEncoder::Encode() for |*header_list_iterator_| if it
-    // has not been called yet.
-    if (!instruction_encoder_.HasNext()) {
-      DCHECK(prefix_encoded_);
-
-      // Even after |name| and |value| go out of scope, copies of these
-      // QuicStringPieces retained by QpackInstructionEncoder are still valid as
-      // long as |header_list_| is valid.
-      QuicStringPiece name = header_list_iterator_->first;
-      QuicStringPiece value = header_list_iterator_->second;
-
-      // |is_static| and |index| are saved by QpackInstructionEncoder by value,
-      // there are no lifetime concerns.
-      bool is_static;
-      uint64_t index;
-
-      auto match_type =
-          header_table_->FindHeaderField(name, value, &is_static, &index);
-
-      switch (match_type) {
-        case QpackHeaderTable::MatchType::kNameAndValue:
-          DCHECK(is_static) << "Dynamic table entries not supported yet.";
-
-          instruction_encoder_.set_s_bit(is_static);
-          instruction_encoder_.set_varint(index);
-
-          instruction_encoder_.Encode(QpackIndexedHeaderFieldInstruction());
-
-          break;
-        case QpackHeaderTable::MatchType::kName:
-          DCHECK(is_static) << "Dynamic table entries not supported yet.";
-
-          instruction_encoder_.set_s_bit(is_static);
-          instruction_encoder_.set_varint(index);
-          instruction_encoder_.set_value(value);
-
-          instruction_encoder_.Encode(
-              QpackLiteralHeaderFieldNameReferenceInstruction());
-
-          break;
-        case QpackHeaderTable::MatchType::kNoMatch:
-          instruction_encoder_.set_name(name);
-          instruction_encoder_.set_value(value);
-
-          instruction_encoder_.Encode(QpackLiteralHeaderFieldInstruction());
-
-          break;
-      }
-    }
-
-    DCHECK(instruction_encoder_.HasNext());
-
-    instruction_encoder_.Next(max_length - output->size(), output);
-
-    if (instruction_encoder_.HasNext()) {
-      // There was not enough room to completely encode current header field.
-      DCHECK_EQ(output->size(), max_length);
-
-      return;
-    }
-
-    // It is possible that the output buffer was just large enough for encoding
-    // the current header field, hence equality is allowed here.
-    DCHECK_LE(output->size(), max_length);
-
-    if (prefix_encoded_) {
-      // Move on to the next header field.
-      ++header_list_iterator_;
-    } else {
-      // Mark prefix as encoded.
-      prefix_encoded_ = true;
-    }
-  } while (HasNext() && output->size() < max_length);
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_progressive_encoder.h b/quic/core/qpack/qpack_progressive_encoder.h
deleted file mode 100644
index 98a3cfe..0000000
--- a/quic/core/qpack/qpack_progressive_encoder.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_ENCODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_ENCODER_H_
-
-#include <cstddef>
-
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h"
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
-#include "net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h"
-#include "net/third_party/quiche/src/quic/core/quic_types.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
-#include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QpackHeaderTable;
-
-// An implementation of ProgressiveEncoder interface that encodes a single
-// header block.
-class QUIC_EXPORT_PRIVATE QpackProgressiveEncoder
-    : public spdy::HpackEncoder::ProgressiveEncoder {
- public:
-  QpackProgressiveEncoder() = delete;
-  // |header_table|, |encoder_stream_sender|, and |header_list| must all outlive
-  // this object.
-  QpackProgressiveEncoder(QuicStreamId stream_id,
-                          QpackHeaderTable* header_table,
-                          QpackEncoderStreamSender* encoder_stream_sender,
-                          const spdy::SpdyHeaderBlock* header_list);
-  QpackProgressiveEncoder(const QpackProgressiveEncoder&) = delete;
-  QpackProgressiveEncoder& operator=(const QpackProgressiveEncoder&) = delete;
-  ~QpackProgressiveEncoder() override = default;
-
-  // Returns true iff more remains to encode.
-  bool HasNext() const override;
-
-  // Encodes up to |max_encoded_bytes| octets, appending to |output|.
-  void Next(size_t max_encoded_bytes, std::string* output) override;
-
- private:
-  const QuicStreamId stream_id_;
-  QpackInstructionEncoder instruction_encoder_;
-  const QpackHeaderTable* const header_table_;
-  QpackEncoderStreamSender* const encoder_stream_sender_;
-  const ValueSplittingHeaderList header_list_;
-
-  // Header field currently being encoded.
-  ValueSplittingHeaderList::const_iterator header_list_iterator_;
-
-  // False until prefix is fully encoded.
-  bool prefix_encoded_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_ENCODER_H_