xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 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_INSTRUCTIONS_H_
6 #define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
7 
8 #include <cstdint>
9 #include <string>
10 #include <tuple>
11 #include <vector>
12 
13 #include "absl/strings/string_view.h"
14 #include "quiche/quic/platform/api/quic_export.h"
15 
16 namespace quic {
17 
18 namespace test {
19 class QpackInstructionWithValuesPeer;
20 }  // namespace test
21 
22 // Each instruction is identified with an opcode in the first byte.
23 // |mask| determines which bits are part of the opcode.
24 // |value| is the value of these bits.  (Other bits in value must be zero.)
25 struct QUICHE_EXPORT QpackInstructionOpcode {
26   uint8_t value;
27   uint8_t mask;
28 };
29 
30 bool operator==(const QpackInstructionOpcode& a,
31                 const QpackInstructionOpcode& b);
32 
33 // Possible types of an instruction field.  Decoding a static bit does not
34 // consume the current byte.  Decoding an integer or a length-prefixed string
35 // literal consumes all bytes containing the field value.
36 enum class QpackInstructionFieldType {
37   // A single bit indicating whether the index refers to the static table, or
38   // indicating the sign of Delta Base.  Called "S" bit because both "static"
39   // and "sign" start with the letter "S".
40   kSbit,
41   // An integer encoded with variable length encoding.  This could be an index,
42   // stream ID, maximum size, or Encoded Required Insert Count.
43   kVarint,
44   // A second integer encoded with variable length encoding.  This could be
45   // Delta Base.
46   kVarint2,
47   // A header name or header value encoded as:
48   //   a bit indicating whether it is Huffman encoded;
49   //   the encoded length of the string;
50   //   the header name or value optionally Huffman encoded.
51   kName,
52   kValue
53 };
54 
55 // Each instruction field has a type and a parameter.
56 // The meaning of the parameter depends on the field type.
57 struct QUICHE_EXPORT QpackInstructionField {
58   QpackInstructionFieldType type;
59   // For a kSbit field, |param| is a mask with exactly one bit set.
60   // For kVarint fields, |param| is the prefix length of the integer encoding.
61   // For kName and kValue fields, |param| is the prefix length of the length of
62   // the string, and the bit immediately preceding the prefix is interpreted as
63   // the Huffman bit.
64   uint8_t param;
65 };
66 
67 using QpackInstructionFields = std::vector<QpackInstructionField>;
68 
69 // A QPACK instruction consists of an opcode identifying the instruction,
70 // followed by a non-empty list of fields.  The last field must be integer or
71 // string literal type to guarantee that all bytes of the instruction are
72 // consumed.
73 struct QUICHE_EXPORT QpackInstruction {
QpackInstructionQpackInstruction74   QpackInstruction(QpackInstructionOpcode opcode, QpackInstructionFields fields)
75       : opcode(std::move(opcode)), fields(std::move(fields)) {}
76 
77   QpackInstruction(const QpackInstruction&) = delete;
78   const QpackInstruction& operator=(const QpackInstruction&) = delete;
79 
80   QpackInstructionOpcode opcode;
81   QpackInstructionFields fields;
82 };
83 
84 // A language is a collection of instructions.  The order does not matter.
85 // Every possible input must match exactly one instruction.
86 using QpackLanguage = std::vector<const QpackInstruction*>;
87 
88 // Wire format defined in
89 // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5
90 
91 // 5.2 Encoder stream instructions
92 
93 // 5.2.1 Insert With Name Reference
94 const QpackInstruction* InsertWithNameReferenceInstruction();
95 
96 // 5.2.2 Insert Without Name Reference
97 const QpackInstruction* InsertWithoutNameReferenceInstruction();
98 
99 // 5.2.3 Duplicate
100 const QpackInstruction* DuplicateInstruction();
101 
102 // 5.2.4 Dynamic Table Size Update
103 const QpackInstruction* SetDynamicTableCapacityInstruction();
104 
105 // Encoder stream language.
106 const QpackLanguage* QpackEncoderStreamLanguage();
107 
108 // 5.3 Decoder stream instructions
109 
110 // 5.3.1 Insert Count Increment
111 const QpackInstruction* InsertCountIncrementInstruction();
112 
113 // 5.3.2 Header Acknowledgement
114 const QpackInstruction* HeaderAcknowledgementInstruction();
115 
116 // 5.3.3 Stream Cancellation
117 const QpackInstruction* StreamCancellationInstruction();
118 
119 // Decoder stream language.
120 const QpackLanguage* QpackDecoderStreamLanguage();
121 
122 // 5.4.1. Header data prefix instructions
123 
124 const QpackInstruction* QpackPrefixInstruction();
125 
126 const QpackLanguage* QpackPrefixLanguage();
127 
128 // 5.4.2. Request and push stream instructions
129 
130 // 5.4.2.1. Indexed Header Field
131 const QpackInstruction* QpackIndexedHeaderFieldInstruction();
132 
133 // 5.4.2.2. Indexed Header Field With Post-Base Index
134 const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction();
135 
136 // 5.4.2.3. Literal Header Field With Name Reference
137 const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction();
138 
139 // 5.4.2.4. Literal Header Field With Post-Base Name Reference
140 const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction();
141 
142 // 5.4.2.5. Literal Header Field Without Name Reference
143 const QpackInstruction* QpackLiteralHeaderFieldInstruction();
144 
145 // Request and push stream language.
146 const QpackLanguage* QpackRequestStreamLanguage();
147 
148 // Storage for instruction and field values to be encoded.
149 // This class can only be instantiated using factory methods that take exactly
150 // the arguments that the corresponding instruction needs.
151 class QUICHE_EXPORT QpackInstructionWithValues {
152  public:
153   // 5.2 Encoder stream instructions
154   static QpackInstructionWithValues InsertWithNameReference(
155       bool is_static, uint64_t name_index, absl::string_view value);
156   static QpackInstructionWithValues InsertWithoutNameReference(
157       absl::string_view name, absl::string_view value);
158   static QpackInstructionWithValues Duplicate(uint64_t index);
159   static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity);
160 
161   // 5.3 Decoder stream instructions
162   static QpackInstructionWithValues InsertCountIncrement(uint64_t increment);
163   static QpackInstructionWithValues HeaderAcknowledgement(uint64_t stream_id);
164   static QpackInstructionWithValues StreamCancellation(uint64_t stream_id);
165 
166   // 5.4.1. Header data prefix.  Delta Base is hardcoded to be zero.
167   static QpackInstructionWithValues Prefix(uint64_t required_insert_count);
168 
169   // 5.4.2. Request and push stream instructions
170   static QpackInstructionWithValues IndexedHeaderField(bool is_static,
171                                                        uint64_t index);
172   static QpackInstructionWithValues LiteralHeaderFieldNameReference(
173       bool is_static, uint64_t index, absl::string_view value);
174   static QpackInstructionWithValues LiteralHeaderField(absl::string_view name,
175                                                        absl::string_view value);
176 
instruction()177   const QpackInstruction* instruction() const { return instruction_; }
s_bit()178   bool s_bit() const { return s_bit_; }
varint()179   uint64_t varint() const { return varint_; }
varint2()180   uint64_t varint2() const { return varint2_; }
name()181   absl::string_view name() const { return name_; }
value()182   absl::string_view value() const { return value_; }
183 
184   // Used by QpackEncoder, because in the first pass it stores absolute indices,
185   // which are converted into relative indices in the second pass after base is
186   // determined.
set_varint(uint64_t varint)187   void set_varint(uint64_t varint) { varint_ = varint; }
188 
189  private:
190   friend test::QpackInstructionWithValuesPeer;
191 
192   QpackInstructionWithValues() = default;
193 
194   // |*instruction| is not owned.
195   const QpackInstruction* instruction_ = nullptr;
196   bool s_bit_ = false;
197   uint64_t varint_ = 0;
198   uint64_t varint2_ = 0;
199   absl::string_view name_;
200   absl::string_view value_;
201 };
202 
203 }  // namespace quic
204 
205 #endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
206