Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/qpack/qpack_instruction_decoder.h b/quic/core/qpack/qpack_instruction_decoder.h
new file mode 100644
index 0000000..9d674c3
--- /dev/null
+++ b/quic/core/qpack/qpack_instruction_decoder.h
@@ -0,0 +1,146 @@
+// Copyright 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_INSTRUCTION_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h"
+#include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+
+namespace quic {
+
+// Generic instruction decoder class.  Takes a QpackLanguage that describes a
+// language, that is, a set of instruction opcodes together with a list of
+// fields that follow each instruction.
+class QUIC_EXPORT_PRIVATE QpackInstructionDecoder {
+ public:
+  // Delegate is notified each time an instruction is decoded or when an error
+  // occurs.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // Called when an instruction (including all its fields) is decoded.
+    // |instruction| points to an entry in |language|.
+    // Returns true if decoded fields are valid.
+    // Returns false otherwise, in which case QpackInstructionDecoder stops
+    // decoding: Delegate methods will not be called, and Decode() must not be
+    // called.
+    virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
+
+    // Called by QpackInstructionDecoder if an error has occurred.
+    // No more data is processed afterwards.
+    virtual void OnError(QuicStringPiece error_message) = 0;
+  };
+
+  // Both |*language| and |*delegate| must outlive this object.
+  QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
+  QpackInstructionDecoder() = delete;
+  QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
+  QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
+
+  // Provide a data fragment to decode.  Must not be called after an error has
+  // occurred.  Must not be called with empty |data|.
+  void Decode(QuicStringPiece data);
+
+  // Returns true if no decoding has taken place yet or if the last instruction
+  // has been entirely parsed.
+  bool AtInstructionBoundary() const;
+
+  // Accessors for decoded values.  Should only be called for fields that are
+  // part of the most recently decoded instruction, and only after |this| calls
+  // Delegate::OnInstructionDecoded() but before Decode() is called again.
+  bool s_bit() const { return s_bit_; }
+  uint64_t varint() const { return varint_; }
+  uint64_t varint2() const { return varint2_; }
+  const QuicString& name() const { return name_; }
+  const QuicString& value() const { return value_; }
+
+ private:
+  enum class State {
+    // Identify instruction.
+    kStartInstruction,
+    // Start decoding next field.
+    kStartField,
+    // Read a single bit.
+    kReadBit,
+    // Start reading integer.
+    kVarintStart,
+    // Resume reading integer.
+    kVarintResume,
+    // Done reading integer.
+    kVarintDone,
+    // Read string.
+    kReadString,
+    // Done reading string.
+    kReadStringDone
+  };
+
+  // One method for each state.  Some take input data and return the number of
+  // octets processed.  Some take input data but do have void return type
+  // because they not consume any bytes.  Some do not take any arguments because
+  // they only change internal state.
+  void DoStartInstruction(QuicStringPiece data);
+  void DoStartField();
+  void DoReadBit(QuicStringPiece data);
+  size_t DoVarintStart(QuicStringPiece data);
+  size_t DoVarintResume(QuicStringPiece data);
+  void DoVarintDone();
+  size_t DoReadString(QuicStringPiece data);
+  void DoReadStringDone();
+
+  // Identify instruction based on opcode encoded in |byte|.
+  // Returns a pointer to an element of |*language_|.
+  const QpackInstruction* LookupOpcode(uint8_t byte) const;
+
+  // Stops decoding and calls Delegate::OnError().
+  void OnError(QuicStringPiece error_message);
+
+  // Describes the language used for decoding.
+  const QpackLanguage* const language_;
+
+  // The Delegate to notify of decoded instructions and errors.
+  Delegate* const delegate_;
+
+  // Storage for decoded field values.
+  bool s_bit_;
+  uint64_t varint_;
+  uint64_t varint2_;
+  QuicString name_;
+  QuicString value_;
+  // Whether the currently decoded header name or value is Huffman encoded.
+  bool is_huffman_encoded_;
+  // Length of string being read into |name_| or |value_|.
+  size_t string_length_;
+
+  // Decoder instance for decoding integers.
+  http2::HpackVarintDecoder varint_decoder_;
+
+  // Decoder instance for decoding Huffman encoded strings.
+  http2::HpackHuffmanDecoder huffman_decoder_;
+
+  // True if a decoding error has been detected either by
+  // QpackInstructionDecoder or by Delegate.
+  bool error_detected_;
+
+  // Decoding state.
+  State state_;
+
+  // Instruction currently being decoded.
+  const QpackInstruction* instruction_;
+
+  // Field currently being decoded.
+  QpackInstructionFields::const_iterator field_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_