| // Copyright 2016 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. | |
| #include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder.h" | |
| #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" | |
| namespace http2 { | |
| HpackVarintEncoder::HpackVarintEncoder() | |
| : varint_(0), encoding_in_progress_(false) {} | |
| unsigned char HpackVarintEncoder::StartEncoding(uint8_t high_bits, | |
| uint8_t prefix_length, | |
| uint64_t varint) { | |
| DCHECK(!encoding_in_progress_); | |
| DCHECK_EQ(0u, varint_); | |
| DCHECK_LE(1u, prefix_length); | |
| DCHECK_LE(prefix_length, 8u); | |
| // prefix_mask defines the sequence of low-order bits of the first byte | |
| // that encode the prefix of the value. It is also the marker in those bits | |
| // of the first byte indicating that at least one extension byte is needed. | |
| const uint8_t prefix_mask = (1 << prefix_length) - 1; | |
| DCHECK_EQ(0, high_bits & prefix_mask); | |
| if (varint < prefix_mask) { | |
| // The integer fits into the prefix in its entirety. | |
| return high_bits | static_cast<unsigned char>(varint); | |
| } | |
| // We need extension bytes. | |
| varint_ = varint - prefix_mask; | |
| encoding_in_progress_ = true; | |
| return high_bits | prefix_mask; | |
| } | |
| size_t HpackVarintEncoder::ResumeEncoding(size_t max_encoded_bytes, | |
| Http2String* output) { | |
| DCHECK(encoding_in_progress_); | |
| DCHECK_NE(0u, max_encoded_bytes); | |
| size_t encoded_bytes = 0; | |
| while (encoded_bytes < max_encoded_bytes) { | |
| ++encoded_bytes; | |
| if (varint_ < 128) { | |
| // Encode final seven bits, with continuation bit set to zero. | |
| output->push_back(varint_); | |
| varint_ = 0; | |
| encoding_in_progress_ = false; | |
| break; | |
| } | |
| // Encode the next seven bits, with continuation bit set to one. | |
| output->push_back(0b10000000 | (varint_ % 128)); | |
| varint_ >>= 7; | |
| } | |
| return encoded_bytes; | |
| } | |
| bool HpackVarintEncoder::IsEncodingInProgress() const { | |
| return encoding_in_progress_; | |
| } | |
| } // namespace http2 |