Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: net/http2/hpack/decoder/hpack_decoder_string_buffer.cc

Issue 2554683003: Revert of Add new HTTP/2 and HPACK decoder in net/http2/. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "net/http2/hpack/decoder/hpack_decoder_string_buffer.h"
6
7 #include "base/logging.h"
8
9 using base::StringPiece;
10
11 namespace net {
12
13 std::ostream& operator<<(std::ostream& out,
14 const HpackDecoderStringBuffer::State v) {
15 switch (v) {
16 case HpackDecoderStringBuffer::State::RESET:
17 return out << "RESET";
18 case HpackDecoderStringBuffer::State::COLLECTING:
19 return out << "COLLECTING";
20 case HpackDecoderStringBuffer::State::COMPLETE:
21 return out << "COMPLETE";
22 default:
23 return out << "Unknown HpackDecoderStringBuffer::State!";
24 }
25 }
26
27 std::ostream& operator<<(std::ostream& out,
28 const HpackDecoderStringBuffer::Backing v) {
29 switch (v) {
30 case HpackDecoderStringBuffer::Backing::RESET:
31 return out << "RESET";
32 case HpackDecoderStringBuffer::Backing::UNBUFFERED:
33 return out << "UNBUFFERED";
34 case HpackDecoderStringBuffer::Backing::BUFFERED:
35 return out << "BUFFERED";
36 case HpackDecoderStringBuffer::Backing::STATIC:
37 return out << "STATIC";
38 default:
39 return out << "Unknown HpackDecoderStringBuffer::Backing!";
40 }
41 }
42
43 HpackDecoderStringBuffer::HpackDecoderStringBuffer() {
44 Reset();
45 }
46 HpackDecoderStringBuffer::~HpackDecoderStringBuffer() {}
47
48 // TODO(jamessynge): Consider eliminating most of Reset (i.e. do less); in
49 // particular, if a variable won't be read again until after it is next set
50 // (e.g. is_huffman_encoded_ or remaining_len_), then it doesn't need to be
51 // cleared here. This will be easier when not supporting both HpackDecoder2
52 // (in net/spdy/hpack) and HpackWholeEntryDecoder, so we can eliminate
53 // the Set() and str() methods.
54 void HpackDecoderStringBuffer::Reset() {
55 DVLOG(3) << "HpackDecoderStringBuffer::Reset";
56 buffer_.clear();
57 value_.clear();
58 remaining_len_ = 0;
59 is_huffman_encoded_ = false;
60 state_ = State::RESET;
61 backing_ = Backing::RESET;
62 }
63
64 void HpackDecoderStringBuffer::Set(StringPiece value, bool is_static) {
65 DVLOG(2) << "HpackDecoderStringBuffer::Set";
66 DCHECK_EQ(state_, State::RESET);
67 DCHECK_EQ(backing_, Backing::RESET);
68 value_ = value;
69 state_ = State::COMPLETE;
70 backing_ = is_static ? Backing::STATIC : Backing::UNBUFFERED;
71 }
72
73 void HpackDecoderStringBuffer::OnStart(bool huffman_encoded, size_t len) {
74 DVLOG(2) << "HpackDecoderStringBuffer::OnStart";
75 DCHECK_EQ(state_, State::RESET);
76 DCHECK_EQ(backing_, Backing::RESET);
77 buffer_.clear();
78 value_.clear();
79
80 remaining_len_ = len;
81 is_huffman_encoded_ = huffman_encoded;
82
83 state_ = State::COLLECTING;
84
85 if (huffman_encoded) {
86 decoder_.Reset();
87 backing_ = Backing::BUFFERED;
88
89 // Reserve space in buffer_ for the uncompressed string, assuming the
90 // maximum expansion. The shortest Huffman codes in the RFC are 5 bits long,
91 // which then expand to 8 bits during decoding (i.e. each code is for one
92 // plain text octet, aka byte), so the maximum size is 60% longer than the
93 // encoded size.
94 len = len * 8 / 5;
95 if (buffer_.capacity() < len) {
96 buffer_.reserve(len);
97 }
98 } else {
99 // Assume for now that we won't need to use buffer_, so don't reserve space
100 // in it.
101 backing_ = Backing::RESET;
102 }
103 }
104
105 bool HpackDecoderStringBuffer::OnData(const char* data, size_t len) {
106 DVLOG(2) << "HpackDecoderStringBuffer::OnData state=" << state_
107 << ", backing=" << backing_;
108 DCHECK_EQ(state_, State::COLLECTING);
109 DCHECK_LE(len, remaining_len_);
110 remaining_len_ -= len;
111
112 if (is_huffman_encoded_) {
113 DCHECK_EQ(backing_, Backing::BUFFERED);
114 // We don't set value_ for buffered strings until OnEnd,
115 // so it should be empty.
116 DCHECK_EQ(0u, value_.size());
117 return decoder_.Decode(StringPiece(data, len), &buffer_);
118 }
119
120 if (backing_ == Backing::RESET) {
121 // This is the first call to OnData.
122 DCHECK_EQ(0u, buffer_.size());
123 DCHECK_EQ(0u, value_.size());
124 // If data contains the entire string, don't copy the string. If we later
125 // find that the HPACK entry is split across input buffers, then we'll
126 // copy the string into buffer_.
127 if (remaining_len_ == 0) {
128 value_ = StringPiece(data, len);
129 backing_ = Backing::UNBUFFERED;
130 return true;
131 }
132
133 // We need to buffer the string because it is split across input buffers.
134 backing_ = Backing::BUFFERED;
135 buffer_.assign(data, len);
136 return true;
137 }
138
139 // This is not the first call to OnData for this string, so it should be
140 // buffered.
141 DCHECK_EQ(backing_, Backing::BUFFERED);
142 // We don't set value_ for buffered strings until OnEnd, so it should be
143 // empty.
144 DCHECK_EQ(0u, value_.size());
145
146 // Append to the current contents of the buffer.
147 buffer_.append(data, len);
148 return true;
149 }
150
151 bool HpackDecoderStringBuffer::OnEnd() {
152 DVLOG(2) << "HpackDecoderStringBuffer::OnEnd";
153 DCHECK_EQ(state_, State::COLLECTING);
154 DCHECK_EQ(0u, remaining_len_);
155
156 if (is_huffman_encoded_) {
157 DCHECK_EQ(backing_, Backing::BUFFERED);
158 // Did the Huffman encoding of the string end properly?
159 if (!decoder_.InputProperlyTerminated()) {
160 return false; // No, it didn't.
161 }
162 }
163 state_ = State::COMPLETE;
164 if (backing_ == Backing::BUFFERED) {
165 value_ = buffer_;
166 }
167 return true;
168 }
169
170 void HpackDecoderStringBuffer::BufferStringIfUnbuffered() {
171 DVLOG(3) << "HpackDecoderStringBuffer::BufferStringIfUnbuffered state="
172 << state_ << ", backing=" << backing_;
173 if (state_ != State::RESET && backing_ == Backing::UNBUFFERED) {
174 DVLOG(2) << "HpackDecoderStringBuffer buffering string of length "
175 << value_.size();
176 value_.CopyToString(&buffer_);
177 if (state_ == State::COMPLETE) {
178 value_ = buffer_;
179 }
180 backing_ = Backing::BUFFERED;
181 }
182 }
183
184 size_t HpackDecoderStringBuffer::BufferedLength() const {
185 DVLOG(3) << "HpackDecoderStringBuffer::BufferedLength";
186 return backing_ == Backing::BUFFERED ? buffer_.size() : 0;
187 }
188
189 StringPiece HpackDecoderStringBuffer::str() const {
190 DVLOG(3) << "HpackDecoderStringBuffer::str";
191 DCHECK_EQ(state_, State::COMPLETE);
192 return value_;
193 }
194
195 void HpackDecoderStringBuffer::OutputDebugStringTo(std::ostream& out) const {
196 out << "{state=" << state_;
197 if (state_ != State::RESET) {
198 out << ", backing=" << backing_;
199 out << ", remaining_len=" << remaining_len_;
200 out << ", is_huffman_encoded=" << is_huffman_encoded_;
201 if (backing_ == Backing::BUFFERED) {
202 out << ", buffer: " << buffer_;
203 } else {
204 out << ", value: " << value_;
205 }
206 }
207 out << "}";
208 }
209
210 std::ostream& operator<<(std::ostream& out, const HpackDecoderStringBuffer& v) {
211 v.OutputDebugStringTo(out);
212 return out;
213 }
214
215 } // namespace net
OLDNEW
« no previous file with comments | « net/http2/hpack/decoder/hpack_decoder_string_buffer.h ('k') | net/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698