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