| // 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 "http2/hpack/varint/hpack_varint_encoder.h" |
| |
| #include <limits> |
| |
| #include "http2/platform/api/http2_logging.h" |
| |
| namespace http2 { |
| |
| // static |
| void HpackVarintEncoder::Encode(uint8_t high_bits, |
| uint8_t prefix_length, |
| uint64_t varint, |
| std::string* output) { |
| 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. |
| unsigned char first_byte = high_bits | static_cast<unsigned char>(varint); |
| output->push_back(first_byte); |
| return; |
| } |
| |
| // Extension bytes are needed. |
| unsigned char first_byte = high_bits | prefix_mask; |
| output->push_back(first_byte); |
| |
| varint -= prefix_mask; |
| while (varint >= 128) { |
| // Encode the next seven bits, with continuation bit set to one. |
| output->push_back(0b10000000 | (varint % 128)); |
| varint >>= 7; |
| } |
| |
| // Encode final seven bits, with continuation bit set to zero. |
| output->push_back(varint); |
| } |
| |
| } // namespace http2 |