• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Generic instruction encoder class.  Takes a QpackLanguage that describes a
18 // language, that is, a set of instruction opcodes together with a list of
19 // fields that follow each instruction.
20 class QUIC_EXPORT_PRIVATE QpackInstructionEncoder {
21  public:
22   QpackInstructionEncoder();
23   QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
24   QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
25 
26   // Append encoded instruction to |output|.
27   void Encode(const QpackInstructionWithValues& instruction_with_values,
28               std::string* output);
29 
30  private:
31   enum class State {
32     // Write instruction opcode to |byte_|.
33     kOpcode,
34     // Select state based on type of current field.
35     kStartField,
36     // Write static bit to |byte_|.
37     kSbit,
38     // Encode an integer (|varint_| or |varint2_| or string length) with a
39     // prefix, using |byte_| for the high bits.
40     kVarintEncode,
41     // Determine if Huffman encoding should be used for the header name or
42     // value, set |use_huffman_| and |string_length_| appropriately, write the
43     // Huffman bit to |byte_|.
44     kStartString,
45     // Write header name or value, performing Huffman encoding if |use_huffman_|
46     // is true.
47     kWriteString
48   };
49 
50   // One method for each state.  Some append encoded bytes to |output|.
51   // Some only change internal state.
52   void DoOpcode();
53   void DoStartField();
54   void DoSBit(bool s_bit);
55   void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output);
56   void DoStartString(absl::string_view name, absl::string_view value);
57   void DoWriteString(absl::string_view name, absl::string_view value,
58                      std::string* output);
59 
60   // True if name or value should be Huffman encoded.
61   bool use_huffman_;
62 
63   // Length of name or value string to be written.
64   // If |use_huffman_| is true, length is after Huffman encoding.
65   size_t string_length_;
66 
67   // Storage for a single byte that contains multiple fields, that is, multiple
68   // states are writing it.
69   uint8_t byte_;
70 
71   // Encoding state.
72   State state_;
73 
74   // Instruction currently being decoded.
75   const QpackInstruction* instruction_;
76 
77   // Field currently being decoded.
78   QpackInstructionFields::const_iterator field_;
79 };
80 
81 }  // namespace quic
82 
83 #endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
84