blob: c484104acd175cb6c87e41030dc02a49c43beac2 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
#include <cstdint>
#include <string>
#include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
namespace quic {
// Generic instruction encoder class. Takes a QpackLanguage that describes a
// language, that is, a set of instruction opcodes together with a list of
// fields that follow each instruction.
class QUIC_EXPORT_PRIVATE QpackInstructionEncoder {
public:
QpackInstructionEncoder();
QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
// Setters for values to be encoded.
// |name| and |value| must remain valid until the instruction is encoded.
void set_s_bit(bool s_bit) { s_bit_ = s_bit; }
void set_varint(uint64_t varint) { varint_ = varint; }
void set_varint2(uint64_t varint2) { varint2_ = varint2; }
void set_name(QuicStringPiece name) { name_ = name; }
void set_value(QuicStringPiece value) { value_ = value; }
// Append encoded instruction to |output|.
void Encode(const QpackInstruction* instruction, std::string* output);
private:
enum class State {
// Write instruction opcode to |byte_|.
kOpcode,
// Select state based on type of current field.
kStartField,
// Write static bit to |byte_|.
kSbit,
// Encode an integer (|varint_| or |varint2_| or string length) with a
// prefix, using |byte_| for the high bits.
kVarintEncode,
// Determine if Huffman encoding should be used for |name_| or |value_|, set
// up |name_| or |value_| and |huffman_encoded_string_| accordingly, and
// write the Huffman bit to |byte_|.
kStartString,
// Write string.
kWriteString
};
// One method for each state. Some append encoded bytes to |output|.
// Some only change internal state.
void DoOpcode();
void DoStartField();
void DoStaticBit();
void DoVarintEncode(std::string* output);
void DoStartString();
void DoWriteString(std::string* output);
// Storage for field values to be encoded.
bool s_bit_;
uint64_t varint_;
uint64_t varint2_;
// The caller must keep the string that |name_| and |value_| point to
// valid until they are encoded.
QuicStringPiece name_;
QuicStringPiece value_;
// Storage for the Huffman encoded string literal to be written if Huffman
// encoding is used.
std::string huffman_encoded_string_;
// If Huffman encoding is used, points to a substring of
// |huffman_encoded_string_|.
// Otherwise points to a substring of |name_| or |value_|.
QuicStringPiece string_to_write_;
// Storage for a single byte that contains multiple fields, that is, multiple
// states are writing it.
uint8_t byte_;
// Encoding state.
State state_;
// Instruction currently being decoded.
const QpackInstruction* instruction_;
// Field currently being decoded.
QpackInstructionFields::const_iterator field_;
};
} // namespace quic
#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_