blob: 224146b2e89945478947022da805361db7d54b5d [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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_DECODER_H_
6#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
7
8#include <cstddef>
9#include <cstdint>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011
vasilvv7cac7b02020-10-08 12:32:10 -070012#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050013#include "http2/hpack/huffman/hpack_huffman_decoder.h"
14#include "http2/hpack/varint/hpack_varint_decoder.h"
15#include "quic/core/qpack/qpack_instructions.h"
16#include "quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017
18namespace quic {
19
20// Generic instruction decoder class. Takes a QpackLanguage that describes a
21// language, that is, a set of instruction opcodes together with a list of
22// fields that follow each instruction.
23class QUIC_EXPORT_PRIVATE QpackInstructionDecoder {
24 public:
bnc4e440102020-10-20 17:32:29 -070025 enum class ErrorCode {
26 INTEGER_TOO_LARGE,
27 STRING_LITERAL_TOO_LONG,
28 HUFFMAN_ENCODING_ERROR,
29 };
30
QUICHE teama6ef0a62019-03-07 20:34:33 -050031 // Delegate is notified each time an instruction is decoded or when an error
32 // occurs.
33 class QUIC_EXPORT_PRIVATE Delegate {
34 public:
35 virtual ~Delegate() = default;
36
37 // Called when an instruction (including all its fields) is decoded.
38 // |instruction| points to an entry in |language|.
39 // Returns true if decoded fields are valid.
40 // Returns false otherwise, in which case QpackInstructionDecoder stops
41 // decoding: Delegate methods will not be called, and Decode() must not be
bncfb4f4fc2019-11-18 17:14:56 -080042 // called. Implementations are allowed to destroy the
43 // QpackInstructionDecoder instance synchronously if OnInstructionDecoded()
44 // returns false.
QUICHE teama6ef0a62019-03-07 20:34:33 -050045 virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
46
47 // Called by QpackInstructionDecoder if an error has occurred.
48 // No more data is processed afterwards.
bncfb4f4fc2019-11-18 17:14:56 -080049 // Implementations are allowed to destroy the QpackInstructionDecoder
50 // instance synchronously.
bnc34a26802020-10-17 05:09:54 -070051 virtual void OnInstructionDecodingError(
bnc4e440102020-10-20 17:32:29 -070052 ErrorCode error_code,
bnc34a26802020-10-17 05:09:54 -070053 absl::string_view error_message) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050054 };
55
56 // Both |*language| and |*delegate| must outlive this object.
57 QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
58 QpackInstructionDecoder() = delete;
59 QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
60 QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
61
62 // Provide a data fragment to decode. Must not be called after an error has
bncfb4f4fc2019-11-18 17:14:56 -080063 // occurred. Must not be called with empty |data|. Return true on success,
bnc34a26802020-10-17 05:09:54 -070064 // false on error (in which case Delegate::OnInstructionDecodingError() is
65 // called synchronously).
vasilvv7cac7b02020-10-08 12:32:10 -070066 bool Decode(absl::string_view data);
QUICHE teama6ef0a62019-03-07 20:34:33 -050067
68 // Returns true if no decoding has taken place yet or if the last instruction
69 // has been entirely parsed.
70 bool AtInstructionBoundary() const;
71
72 // Accessors for decoded values. Should only be called for fields that are
73 // part of the most recently decoded instruction, and only after |this| calls
74 // Delegate::OnInstructionDecoded() but before Decode() is called again.
75 bool s_bit() const { return s_bit_; }
76 uint64_t varint() const { return varint_; }
77 uint64_t varint2() const { return varint2_; }
vasilvvc48c8712019-03-11 13:38:16 -070078 const std::string& name() const { return name_; }
79 const std::string& value() const { return value_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050080
81 private:
82 enum class State {
83 // Identify instruction.
84 kStartInstruction,
85 // Start decoding next field.
86 kStartField,
87 // Read a single bit.
88 kReadBit,
89 // Start reading integer.
90 kVarintStart,
91 // Resume reading integer.
92 kVarintResume,
93 // Done reading integer.
94 kVarintDone,
95 // Read string.
96 kReadString,
97 // Done reading string.
98 kReadStringDone
99 };
100
bncfb4f4fc2019-11-18 17:14:56 -0800101 // One method for each state. They each return true on success, false on
102 // error (in which case |this| might already be destroyed). Some take input
103 // data and set |*bytes_consumed| to the number of octets processed. Some
104 // take input data but do not consume any bytes. Some do not take any
105 // arguments because they only change internal state.
vasilvv7cac7b02020-10-08 12:32:10 -0700106 bool DoStartInstruction(absl::string_view data);
bncfb4f4fc2019-11-18 17:14:56 -0800107 bool DoStartField();
vasilvv7cac7b02020-10-08 12:32:10 -0700108 bool DoReadBit(absl::string_view data);
109 bool DoVarintStart(absl::string_view data, size_t* bytes_consumed);
110 bool DoVarintResume(absl::string_view data, size_t* bytes_consumed);
bncfb4f4fc2019-11-18 17:14:56 -0800111 bool DoVarintDone();
vasilvv7cac7b02020-10-08 12:32:10 -0700112 bool DoReadString(absl::string_view data, size_t* bytes_consumed);
bncfb4f4fc2019-11-18 17:14:56 -0800113 bool DoReadStringDone();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114
115 // Identify instruction based on opcode encoded in |byte|.
116 // Returns a pointer to an element of |*language_|.
117 const QpackInstruction* LookupOpcode(uint8_t byte) const;
118
bnc34a26802020-10-17 05:09:54 -0700119 // Stops decoding and calls Delegate::OnInstructionDecodingError().
bnc4e440102020-10-20 17:32:29 -0700120 void OnError(ErrorCode error_code, absl::string_view error_message);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500121
122 // Describes the language used for decoding.
123 const QpackLanguage* const language_;
124
125 // The Delegate to notify of decoded instructions and errors.
126 Delegate* const delegate_;
127
128 // Storage for decoded field values.
129 bool s_bit_;
130 uint64_t varint_;
131 uint64_t varint2_;
vasilvvc48c8712019-03-11 13:38:16 -0700132 std::string name_;
133 std::string value_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500134 // Whether the currently decoded header name or value is Huffman encoded.
135 bool is_huffman_encoded_;
136 // Length of string being read into |name_| or |value_|.
137 size_t string_length_;
138
139 // Decoder instance for decoding integers.
140 http2::HpackVarintDecoder varint_decoder_;
141
142 // Decoder instance for decoding Huffman encoded strings.
143 http2::HpackHuffmanDecoder huffman_decoder_;
144
bncfb4f4fc2019-11-18 17:14:56 -0800145 // True if a decoding error has been detected by QpackInstructionDecoder.
146 // Only used in DCHECKs.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 bool error_detected_;
148
149 // Decoding state.
150 State state_;
151
152 // Instruction currently being decoded.
153 const QpackInstruction* instruction_;
154
155 // Field currently being decoded.
156 QpackInstructionFields::const_iterator field_;
157};
158
159} // namespace quic
160
161#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_