xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instruction_encoder.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_ENCODER_H_
6 #define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
7 
8 #include <cstdint>
9 #include <string>
10 
11 #include "absl/strings/string_view.h"
12 #include "quiche/quic/core/qpack/qpack_instructions.h"
13 #include "quiche/quic/platform/api/quic_export.h"
14 
15 namespace quic {
16 
17 // Enum which specifies if Huffman encoding should be used when sending
18 // QPACK headers.
19 enum class HuffmanEncoding {
20   kEnabled,
21   kDisabled,
22 };
23 
24 // Generic instruction encoder class.  Takes a QpackLanguage that describes a
25 // language, that is, a set of instruction opcodes together with a list of
26 // fields that follow each instruction.
27 class QUICHE_EXPORT QpackInstructionEncoder {
28  public:
29   explicit QpackInstructionEncoder(HuffmanEncoding huffman_encoding);
30   QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
31   QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
32 
33   // Append encoded instruction to |output|.
34   void Encode(const QpackInstructionWithValues& instruction_with_values,
35               std::string* output);
36 
37  private:
38   enum class State {
39     // Write instruction opcode to |byte_|.
40     kOpcode,
41     // Select state based on type of current field.
42     kStartField,
43     // Write static bit to |byte_|.
44     kSbit,
45     // Encode an integer (|varint_| or |varint2_| or string length) with a
46     // prefix, using |byte_| for the high bits.
47     kVarintEncode,
48     // Determine if Huffman encoding should be used for the header name or
49     // value, set |use_huffman_| and |string_length_| appropriately, write the
50     // Huffman bit to |byte_|.
51     kStartString,
52     // Write header name or value, performing Huffman encoding if |use_huffman_|
53     // is true.
54     kWriteString
55   };
56 
57   // One method for each state.  Some append encoded bytes to |output|.
58   // Some only change internal state.
59   void DoOpcode();
60   void DoStartField();
61   void DoSBit(bool s_bit);
62   void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output);
63   void DoStartString(absl::string_view name, absl::string_view value);
64   void DoWriteString(absl::string_view name, absl::string_view value,
65                      std::string* output);
66 
67   // If true then Huffman encoding will not be used, regardless of the
68   // string size.
69   const HuffmanEncoding huffman_encoding_;
70 
71   // True if name or value should be Huffman encoded.
72   bool use_huffman_;
73 
74   // Length of name or value string to be written.
75   // If |use_huffman_| is true, length is after Huffman encoding.
76   size_t string_length_;
77 
78   // Storage for a single byte that contains multiple fields, that is, multiple
79   // states are writing it.
80   uint8_t byte_;
81 
82   // Encoding state.
83   State state_;
84 
85   // Instruction currently being decoded.
86   const QpackInstruction* instruction_;
87 
88   // Field currently being decoded.
89   QpackInstructionFields::const_iterator field_;
90 };
91 
92 }  // namespace quic
93 
94 #endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
95