Project import generated by Copybara.

PiperOrigin-RevId: 224614037
Change-Id: I14e53449d4aeccb328f86828c76b5f09dea0d4b8
diff --git a/http2/hpack/decoder/hpack_decoder_state.h b/http2/hpack/decoder/hpack_decoder_state.h
new file mode 100644
index 0000000..fd34179
--- /dev/null
+++ b/http2/hpack/decoder/hpack_decoder_state.h
@@ -0,0 +1,129 @@
+// Copyright 2016 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.
+
+// HpackDecoderState maintains the HPACK decompressor state; i.e. updates the
+// HPACK dynamic table according to RFC 7541 as the entries in an HPACK block
+// are decoded, and reads from the static and dynamic tables in order to build
+// complete header entries. Calls an HpackDecoderListener with the completely
+// decoded headers (i.e. after resolving table indices into names or values),
+// thus translating the decoded HPACK entries into HTTP/2 headers.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h"
+#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h"
+#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables.h"
+#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h"
+#include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h"
+#include "net/third_party/quiche/src/http2/platform/api/http2_export.h"
+#include "net/third_party/quiche/src/http2/platform/api/http2_string_piece.h"
+
+namespace http2 {
+namespace test {
+class HpackDecoderStatePeer;
+}  // namespace test
+
+class HTTP2_EXPORT_PRIVATE HpackDecoderState : public HpackWholeEntryListener {
+ public:
+  explicit HpackDecoderState(HpackDecoderListener* listener);
+  ~HpackDecoderState() override;
+
+  HpackDecoderState(const HpackDecoderState&) = delete;
+  HpackDecoderState& operator=(const HpackDecoderState&) = delete;
+
+  // Set the listener to be notified when a whole entry has been decoded,
+  // including resolving name or name and value references.
+  // The listener may be changed at any time.
+  HpackDecoderListener* listener() const { return listener_; }
+
+  // Set listener to be notified of insertions into the HPACK dynamic table,
+  // and uses of those entries.
+  void set_tables_debug_listener(
+      HpackDecoderTablesDebugListener* debug_listener);
+
+  // ApplyHeaderTableSizeSetting notifies this object that this endpoint has
+  // received a SETTINGS ACK frame acknowledging an earlier SETTINGS frame from
+  // this endpoint specifying a new value for SETTINGS_HEADER_TABLE_SIZE (the
+  // maximum size of the dynamic table that this endpoint will use to decode
+  // HPACK blocks).
+  // Because a SETTINGS frame can contain SETTINGS_HEADER_TABLE_SIZE values,
+  // the caller must keep track of those multiple changes, and make
+  // corresponding calls to this method. In particular, a call must be made
+  // with the lowest value acknowledged by the peer, and a call must be made
+  // with the final value acknowledged, in that order; additional calls may
+  // be made if additional values were sent. These calls must be made between
+  // decoding the SETTINGS ACK, and before the next HPACK block is decoded.
+  void ApplyHeaderTableSizeSetting(uint32_t max_header_table_size);
+
+  // OnHeaderBlockStart notifies this object that we're starting to decode the
+  // HPACK payload of a HEADERS or PUSH_PROMISE frame.
+  void OnHeaderBlockStart();
+
+  // Implement the HpackWholeEntryListener methods, each of which notifies this
+  // object when an entire entry has been decoded.
+  void OnIndexedHeader(size_t index) override;
+  void OnNameIndexAndLiteralValue(
+      HpackEntryType entry_type,
+      size_t name_index,
+      HpackDecoderStringBuffer* value_buffer) override;
+  void OnLiteralNameAndValue(HpackEntryType entry_type,
+                             HpackDecoderStringBuffer* name_buffer,
+                             HpackDecoderStringBuffer* value_buffer) override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+  void OnHpackDecodeError(Http2StringPiece error_message) override;
+
+  // OnHeaderBlockEnd notifies this object that an entire HPACK block has been
+  // decoded, which might have extended into CONTINUATION blocks.
+  void OnHeaderBlockEnd();
+
+  // Was an error detected? After an error has been detected and reported,
+  // no further callbacks will be made to the listener.
+  bool error_detected() const { return error_detected_; }
+
+  const HpackDecoderTables& decoder_tables_for_test() const {
+    return decoder_tables_;
+  }
+
+ private:
+  friend class test::HpackDecoderStatePeer;
+
+  // Reports an error to the listener IF this is the first error detected.
+  void ReportError(Http2StringPiece error_message);
+
+  // The static and dynamic HPACK tables.
+  HpackDecoderTables decoder_tables_;
+
+  // The listener to be notified of headers, the start and end of header
+  // lists, and of errors.
+  HpackDecoderListener* listener_;
+
+  // The most recent HEADER_TABLE_SIZE setting acknowledged by the peer.
+  uint32_t final_header_table_size_;
+
+  // The lowest HEADER_TABLE_SIZE setting acknowledged by the peer; valid until
+  // the next HPACK block is decoded.
+  // TODO(jamessynge): Test raising the HEADER_TABLE_SIZE.
+  uint32_t lowest_header_table_size_;
+
+  // Must the next (first) HPACK entry be a dynamic table size update?
+  bool require_dynamic_table_size_update_;
+
+  // May the next (first or second) HPACK entry be a dynamic table size update?
+  bool allow_dynamic_table_size_update_;
+
+  // Have we already seen a dynamic table size update in this HPACK block?
+  bool saw_dynamic_table_size_update_;
+
+  // Has an error already been detected and reported to the listener?
+  bool error_detected_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_