xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instruction_decoder.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
6 #define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <string>
11 
12 #include "absl/strings/string_view.h"
13 #include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
14 #include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
15 #include "quiche/quic/core/qpack/qpack_instructions.h"
16 #include "quiche/quic/platform/api/quic_export.h"
17 
18 namespace quic {
19 
20 // Generic instruction decoder class.  Takes a QpackLanguage that describes a
21 // language, that is, a set of instruction opcodes together with a list of
22 // fields that follow each instruction.
23 class QUICHE_EXPORT QpackInstructionDecoder {
24  public:
25   enum class ErrorCode {
26     INTEGER_TOO_LARGE,
27     STRING_LITERAL_TOO_LONG,
28     HUFFMAN_ENCODING_ERROR,
29   };
30 
31   // Delegate is notified each time an instruction is decoded or when an error
32   // occurs.
33   class QUICHE_EXPORT Delegate {
34    public:
35     virtual ~Delegate() = default;
36 
37     // Called when an instruction (including all its fields) is decoded.
38     // |instruction| points to an entry in |language|.
39     // Returns true if decoded fields are valid.
40     // Returns false otherwise, in which case QpackInstructionDecoder stops
41     // decoding: Delegate methods will not be called, and Decode() must not be
42     // called.  Implementations are allowed to destroy the
43     // QpackInstructionDecoder instance synchronously if OnInstructionDecoded()
44     // returns false.
45     virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
46 
47     // Called by QpackInstructionDecoder if an error has occurred.
48     // No more data is processed afterwards.
49     // Implementations are allowed to destroy the QpackInstructionDecoder
50     // instance synchronously.
51     virtual void OnInstructionDecodingError(
52         ErrorCode error_code, absl::string_view error_message) = 0;
53   };
54 
55   // Both |*language| and |*delegate| must outlive this object.
56   QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
57   QpackInstructionDecoder() = delete;
58   QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
59   QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
60 
61   // Provide a data fragment to decode.  Must not be called after an error has
62   // occurred.  Must not be called with empty |data|.  Return true on success,
63   // false on error (in which case Delegate::OnInstructionDecodingError() is
64   // called synchronously).
65   bool Decode(absl::string_view data);
66 
67   // Returns true if no decoding has taken place yet or if the last instruction
68   // has been entirely parsed.
69   bool AtInstructionBoundary() const;
70 
71   // Accessors for decoded values.  Should only be called for fields that are
72   // part of the most recently decoded instruction, and only after |this| calls
73   // Delegate::OnInstructionDecoded() but before Decode() is called again.
s_bit()74   bool s_bit() const { return s_bit_; }
varint()75   uint64_t varint() const { return varint_; }
varint2()76   uint64_t varint2() const { return varint2_; }
name()77   const std::string& name() const { return name_; }
value()78   const std::string& value() const { return value_; }
79 
80  private:
81   enum class State {
82     // Identify instruction.
83     kStartInstruction,
84     // Start decoding next field.
85     kStartField,
86     // Read a single bit.
87     kReadBit,
88     // Start reading integer.
89     kVarintStart,
90     // Resume reading integer.
91     kVarintResume,
92     // Done reading integer.
93     kVarintDone,
94     // Read string.
95     kReadString,
96     // Done reading string.
97     kReadStringDone
98   };
99 
100   // One method for each state.  They each return true on success, false on
101   // error (in which case |this| might already be destroyed).  Some take input
102   // data and set |*bytes_consumed| to the number of octets processed.  Some
103   // take input data but do not consume any bytes.  Some do not take any
104   // arguments because they only change internal state.
105   bool DoStartInstruction(absl::string_view data);
106   bool DoStartField();
107   bool DoReadBit(absl::string_view data);
108   bool DoVarintStart(absl::string_view data, size_t* bytes_consumed);
109   bool DoVarintResume(absl::string_view data, size_t* bytes_consumed);
110   bool DoVarintDone();
111   bool DoReadString(absl::string_view data, size_t* bytes_consumed);
112   bool DoReadStringDone();
113 
114   // Identify instruction based on opcode encoded in |byte|.
115   // Returns a pointer to an element of |*language_|.
116   const QpackInstruction* LookupOpcode(uint8_t byte) const;
117 
118   // Stops decoding and calls Delegate::OnInstructionDecodingError().
119   void OnError(ErrorCode error_code, absl::string_view error_message);
120 
121   // Describes the language used for decoding.
122   const QpackLanguage* const language_;
123 
124   // The Delegate to notify of decoded instructions and errors.
125   Delegate* const delegate_;
126 
127   // Storage for decoded field values.
128   bool s_bit_;
129   uint64_t varint_;
130   uint64_t varint2_;
131   std::string name_;
132   std::string value_;
133   // Whether the currently decoded header name or value is Huffman encoded.
134   bool is_huffman_encoded_;
135   // Length of string being read into |name_| or |value_|.
136   size_t string_length_;
137 
138   // Decoder instance for decoding integers.
139   http2::HpackVarintDecoder varint_decoder_;
140 
141   // Decoder instance for decoding Huffman encoded strings.
142   http2::HpackHuffmanDecoder huffman_decoder_;
143 
144   // True if a decoding error has been detected by QpackInstructionDecoder.
145   // Only used in QUICHE_DCHECKs.
146   bool error_detected_;
147 
148   // Decoding state.
149   State state_;
150 
151   // Instruction currently being decoded.
152   const QpackInstruction* instruction_;
153 
154   // Field currently being decoded.
155   QpackInstructionFields::const_iterator field_;
156 };
157 
158 }  // namespace quic
159 
160 #endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
161