blob: f478c249b073283761f43ac3135115d7379f7dc8 [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
12#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h"
13#include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder.h"
14#include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
17
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:
25 // Delegate is notified each time an instruction is decoded or when an error
26 // occurs.
27 class QUIC_EXPORT_PRIVATE Delegate {
28 public:
29 virtual ~Delegate() = default;
30
31 // Called when an instruction (including all its fields) is decoded.
32 // |instruction| points to an entry in |language|.
33 // Returns true if decoded fields are valid.
34 // Returns false otherwise, in which case QpackInstructionDecoder stops
35 // decoding: Delegate methods will not be called, and Decode() must not be
36 // called.
37 virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
38
39 // Called by QpackInstructionDecoder if an error has occurred.
40 // No more data is processed afterwards.
41 virtual void OnError(QuicStringPiece error_message) = 0;
42 };
43
44 // Both |*language| and |*delegate| must outlive this object.
45 QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
46 QpackInstructionDecoder() = delete;
47 QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
48 QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
49
50 // Provide a data fragment to decode. Must not be called after an error has
51 // occurred. Must not be called with empty |data|.
52 void Decode(QuicStringPiece data);
53
54 // Returns true if no decoding has taken place yet or if the last instruction
55 // has been entirely parsed.
56 bool AtInstructionBoundary() const;
57
58 // Accessors for decoded values. Should only be called for fields that are
59 // part of the most recently decoded instruction, and only after |this| calls
60 // Delegate::OnInstructionDecoded() but before Decode() is called again.
61 bool s_bit() const { return s_bit_; }
62 uint64_t varint() const { return varint_; }
63 uint64_t varint2() const { return varint2_; }
vasilvvc48c8712019-03-11 13:38:16 -070064 const std::string& name() const { return name_; }
65 const std::string& value() const { return value_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050066
67 private:
68 enum class State {
69 // Identify instruction.
70 kStartInstruction,
71 // Start decoding next field.
72 kStartField,
73 // Read a single bit.
74 kReadBit,
75 // Start reading integer.
76 kVarintStart,
77 // Resume reading integer.
78 kVarintResume,
79 // Done reading integer.
80 kVarintDone,
81 // Read string.
82 kReadString,
83 // Done reading string.
84 kReadStringDone
85 };
86
87 // One method for each state. Some take input data and return the number of
88 // octets processed. Some take input data but do have void return type
89 // because they not consume any bytes. Some do not take any arguments because
90 // they only change internal state.
91 void DoStartInstruction(QuicStringPiece data);
92 void DoStartField();
93 void DoReadBit(QuicStringPiece data);
94 size_t DoVarintStart(QuicStringPiece data);
95 size_t DoVarintResume(QuicStringPiece data);
96 void DoVarintDone();
97 size_t DoReadString(QuicStringPiece data);
98 void DoReadStringDone();
99
100 // Identify instruction based on opcode encoded in |byte|.
101 // Returns a pointer to an element of |*language_|.
102 const QpackInstruction* LookupOpcode(uint8_t byte) const;
103
104 // Stops decoding and calls Delegate::OnError().
105 void OnError(QuicStringPiece error_message);
106
107 // Describes the language used for decoding.
108 const QpackLanguage* const language_;
109
110 // The Delegate to notify of decoded instructions and errors.
111 Delegate* const delegate_;
112
113 // Storage for decoded field values.
114 bool s_bit_;
115 uint64_t varint_;
116 uint64_t varint2_;
vasilvvc48c8712019-03-11 13:38:16 -0700117 std::string name_;
118 std::string value_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500119 // Whether the currently decoded header name or value is Huffman encoded.
120 bool is_huffman_encoded_;
121 // Length of string being read into |name_| or |value_|.
122 size_t string_length_;
123
124 // Decoder instance for decoding integers.
125 http2::HpackVarintDecoder varint_decoder_;
126
127 // Decoder instance for decoding Huffman encoded strings.
128 http2::HpackHuffmanDecoder huffman_decoder_;
129
130 // True if a decoding error has been detected either by
131 // QpackInstructionDecoder or by Delegate.
132 bool error_detected_;
133
134 // Decoding state.
135 State state_;
136
137 // Instruction currently being decoded.
138 const QpackInstruction* instruction_;
139
140 // Field currently being decoded.
141 QpackInstructionFields::const_iterator field_;
142};
143
144} // namespace quic
145
146#endif // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_