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

Side by Side Diff: net/spdy/core/hpack/hpack_huffman_decoder.cc

Issue 2867693004: Snapshot of all changes to get jumbo in blink and content.
Patch Set: Rebased again Created 3 years, 5 months 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Decoder for strings encoded using the HPACK Huffman Code (see 5 // Decoder for strings encoded using the HPACK Huffman Code (see
6 // https://httpwg.github.io/specs/rfc7541.html#huffman.code). 6 // https://httpwg.github.io/specs/rfc7541.html#huffman.code).
7 // 7 //
8 // This implementation is inspired by the One-Shift algorithm described in 8 // This implementation is inspired by the One-Shift algorithm described in
9 // "On the Implementation of Minimum Redundancy Prefix Codes", by Alistair 9 // "On the Implementation of Minimum Redundancy Prefix Codes", by Alistair
10 // Moffat and Andrew Turpin, 1997. 10 // Moffat and Andrew Turpin, 1997.
(...skipping 17 matching lines...) Expand all
28 #include <bitset> 28 #include <bitset>
29 #include <limits> 29 #include <limits>
30 #include <utility> 30 #include <utility>
31 31
32 #include "base/logging.h" 32 #include "base/logging.h"
33 #include "net/spdy/core/hpack/hpack_input_stream.h" 33 #include "net/spdy/core/hpack/hpack_input_stream.h"
34 34
35 namespace net { 35 namespace net {
36 namespace { 36 namespace {
37 37
38 typedef HpackHuffmanDecoder::HuffmanWord HuffmanWord; 38 typedef SpdyHpackHuffmanDecoder::HuffmanWord HuffmanWord;
39 typedef HpackHuffmanDecoder::HuffmanCodeLength HuffmanCodeLength; 39 typedef SpdyHpackHuffmanDecoder::HuffmanCodeLength HuffmanCodeLength;
40 40
41 const HuffmanCodeLength kHuffmanWordLength = 41 const HuffmanCodeLength kHuffmanWordLength =
42 std::numeric_limits<HuffmanWord>::digits; 42 std::numeric_limits<HuffmanWord>::digits;
43 43
44 const HuffmanCodeLength kMinCodeLength = 5; 44 const HuffmanCodeLength kMinCodeLength = 5;
45 const HuffmanCodeLength kMaxCodeLength = 30; 45 const HuffmanCodeLength kMaxCodeLength = 30;
46 46
47 const HuffmanWord kInvalidLJCode = ~static_cast<HuffmanWord>(0); 47 const HuffmanWord kInvalidLJCode = ~static_cast<HuffmanWord>(0);
48 // Length of a code in bits to the first code with that length, left-justified. 48 // Length of a code in bits to the first code with that length, left-justified.
49 // Note that this can be computed from kLengthToFirstCanonical. 49 // Note that this can be computed from kLengthToFirstCanonical.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 173
174 #endif // DCHECK_IS_ON() 174 #endif // DCHECK_IS_ON()
175 175
176 } // namespace 176 } // namespace
177 177
178 // TODO(jamessynge): Should we read these magic numbers from 178 // TODO(jamessynge): Should we read these magic numbers from
179 // kLengthToFirstLJCode? Would that reduce cache consumption? Slow decoding? 179 // kLengthToFirstLJCode? Would that reduce cache consumption? Slow decoding?
180 // TODO(jamessynge): Is this being inlined by the compiler? Should we inline 180 // TODO(jamessynge): Is this being inlined by the compiler? Should we inline
181 // into DecodeString the tests for code lengths 5 through 8 (> 99% of codes 181 // into DecodeString the tests for code lengths 5 through 8 (> 99% of codes
182 // according to the HPACK spec)? 182 // according to the HPACK spec)?
183 HpackHuffmanDecoder::HuffmanCodeLength HpackHuffmanDecoder::CodeLengthOfPrefix( 183 SpdyHpackHuffmanDecoder::HuffmanCodeLength SpdyHpackHuffmanDecoder::CodeLengthOf Prefix(
184 HpackHuffmanDecoder::HuffmanWord value) { 184 SpdyHpackHuffmanDecoder::HuffmanWord value) {
185 HuffmanCodeLength length; 185 HuffmanCodeLength length;
186 if (value < 0xb8000000) { 186 if (value < 0xb8000000) {
187 if (value < 0x50000000) { 187 if (value < 0x50000000) {
188 length = 5; 188 length = 5;
189 } else { 189 } else {
190 length = 6; 190 length = 6;
191 } 191 }
192 } else { 192 } else {
193 if (value < 0xfe000000) { 193 if (value < 0xfe000000) {
194 if (value < 0xf8000000) { 194 if (value < 0xf8000000) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 260 }
261 } 261 }
262 } 262 }
263 } 263 }
264 } 264 }
265 } 265 }
266 } 266 }
267 return length; 267 return length;
268 } 268 }
269 269
270 HuffmanWord HpackHuffmanDecoder::DecodeToCanonical( 270 HuffmanWord SpdyHpackHuffmanDecoder::DecodeToCanonical(
271 HuffmanCodeLength code_length, 271 HuffmanCodeLength code_length,
272 HuffmanWord bits) { 272 HuffmanWord bits) {
273 DCHECK_LE(kMinCodeLength, code_length); 273 DCHECK_LE(kMinCodeLength, code_length);
274 DCHECK_LE(code_length, kMaxCodeLength); 274 DCHECK_LE(code_length, kMaxCodeLength);
275 275
276 // What is the first left-justified code of length |code_length|? 276 // What is the first left-justified code of length |code_length|?
277 HuffmanWord first_lj_code = kLengthToFirstLJCode[code_length]; 277 HuffmanWord first_lj_code = kLengthToFirstLJCode[code_length];
278 DCHECK_NE(kInvalidLJCode, first_lj_code); 278 DCHECK_NE(kInvalidLJCode, first_lj_code);
279 279
280 // Which canonical symbol corresponds to the high order |code_length| 280 // Which canonical symbol corresponds to the high order |code_length|
281 // bits of |first_lj_code|? 281 // bits of |first_lj_code|?
282 HuffmanWord first_canonical = kLengthToFirstCanonical[code_length]; 282 HuffmanWord first_canonical = kLengthToFirstCanonical[code_length];
283 DCHECK_NE(kInvalidCanonical, first_canonical); 283 DCHECK_NE(kInvalidCanonical, first_canonical);
284 284
285 // What is the position of the canonical symbol being decoded within 285 // What is the position of the canonical symbol being decoded within
286 // the canonical symbols of length |code_length|? 286 // the canonical symbols of length |code_length|?
287 HuffmanWord ordinal_in_length = 287 HuffmanWord ordinal_in_length =
288 ((bits - first_lj_code) >> (kHuffmanWordLength - code_length)); 288 ((bits - first_lj_code) >> (kHuffmanWordLength - code_length));
289 289
290 // Combined these two to produce the position of the canonical symbol 290 // Combined these two to produce the position of the canonical symbol
291 // being decoded within all of the canonical symbols. 291 // being decoded within all of the canonical symbols.
292 return first_canonical + ordinal_in_length; 292 return first_canonical + ordinal_in_length;
293 } 293 }
294 294
295 uint8_t HpackHuffmanDecoder::CanonicalToSource(HuffmanWord canonical) { 295 uint8_t SpdyHpackHuffmanDecoder::CanonicalToSource(HuffmanWord canonical) {
296 DCHECK_LT(canonical, 256u); 296 DCHECK_LT(canonical, 256u);
297 return kCanonicalToSymbol[canonical]; 297 return kCanonicalToSymbol[canonical];
298 } 298 }
299 299
300 // TODO(jamessynge): Maybe further refactorings, including just passing in a 300 // TODO(jamessynge): Maybe further refactorings, including just passing in a
301 // SpdyStringPiece instead of an HpackInputStream, thus avoiding the PeekBits 301 // SpdyStringPiece instead of an HpackInputStream, thus avoiding the PeekBits
302 // calls, and also allowing us to separate the code into portions dealing with 302 // calls, and also allowing us to separate the code into portions dealing with
303 // long strings, and a later portion dealing with the last few bytes of strings. 303 // long strings, and a later portion dealing with the last few bytes of strings.
304 // TODO(jamessynge): Determine if that is worth it by adding some counters to 304 // TODO(jamessynge): Determine if that is worth it by adding some counters to
305 // measure the distribution of string sizes seen in practice. 305 // measure the distribution of string sizes seen in practice.
306 bool HpackHuffmanDecoder::DecodeString(HpackInputStream* in, SpdyString* out) { 306 bool SpdyHpackHuffmanDecoder::DecodeString(HpackInputStream* in, SpdyString* out ) {
307 out->clear(); 307 out->clear();
308 308
309 // Load |bits| with the leading bits of the input stream, left justified 309 // Load |bits| with the leading bits of the input stream, left justified
310 // (i.e. the bits of the first byte are the high-order bits of |bits|, 310 // (i.e. the bits of the first byte are the high-order bits of |bits|,
311 // and the bits of the fourth byte are the low-order bits of |bits|). 311 // and the bits of the fourth byte are the low-order bits of |bits|).
312 // |peeked_success| if there are more bits in |*in| (i.e. the encoding 312 // |peeked_success| if there are more bits in |*in| (i.e. the encoding
313 // of the string to be decoded is more than 4 bytes). 313 // of the string to be decoded is more than 4 bytes).
314 314
315 auto bits_available_and_bits = in->InitializePeekBits(); 315 auto bits_available_and_bits = in->InitializePeekBits();
316 HuffmanCodeLength bits_available = bits_available_and_bits.first; 316 HuffmanCodeLength bits_available = bits_available_and_bits.first;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // Get some more bits for decoding (up to 8). |peeked_success| is true 391 // Get some more bits for decoding (up to 8). |peeked_success| is true
392 // if we got any bits. 392 // if we got any bits.
393 peeked_success = in->PeekBits(&bits_available, &bits); 393 peeked_success = in->PeekBits(&bits_available, &bits);
394 } 394 }
395 DLOG_IF(WARNING, (VLOG_IS_ON(2) && bits_available < 32 && !peeked_success)) 395 DLOG_IF(WARNING, (VLOG_IS_ON(2) && bits_available < 32 && !peeked_success))
396 << "no more peeking possible"; 396 << "no more peeking possible";
397 } 397 }
398 } 398 }
399 399
400 } // namespace net 400 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/core/hpack/hpack_huffman_decoder.h ('k') | net/spdy/core/hpack/hpack_huffman_decoder_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698