proxygen
HPACKEncodeBuffer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
12 #include <memory>
16 
17 using folly::IOBuf;
19 using std::string;
20 using std::unique_ptr;
21 
22 namespace proxygen {
23 
25  uint32_t growthSize,
26  bool huffmanEnabled) :
27  buf_(&bufQueue_, growthSize),
28  growthSize_(growthSize),
29  huffmanEnabled_(huffmanEnabled) {
30 }
31 
33  buf_(&bufQueue_, growthSize),
34  growthSize_(growthSize),
35  huffmanEnabled_(false) {
36 }
37 
39  // we expect that this function is called before any encoding happens
40  CHECK(bufQueue_.front() == nullptr);
41  // create a custom IOBuf and add it to the queue
42  unique_ptr<IOBuf> buf = IOBuf::create(std::max(headroom, growthSize_));
43  buf->advance(headroom);
45 }
46 
48  buf_.push(&byte, 1);
49 }
50 
52  return encodeInteger(value, 0, 8);
53 }
54 
57  const HPACK::Instruction& instruction) {
58  return encodeInteger(value, instruction.code, instruction.prefixLength);
59 }
60 
62  uint8_t nbit) {
63  CHECK(nbit > 0 && nbit <= 8);
64  uint32_t count = 0;
65  uint8_t mask = HPACK::NBIT_MASKS[nbit];
66  // The instruction should not extend into mask
67  DCHECK_EQ(instruction & mask, 0);
68 
69  // write the first byte
70  uint8_t byte = instruction;
71  if (value < mask) {
72  // fits in the first byte
73  byte |= value;
74  append(byte);
75  return 1;
76  }
77 
78  byte |= mask;
79  value -= mask;
80  ++count;
81  append(byte);
82  // variable length encoding
83  while (value >= 128) {
84  byte = 128 | (127 & value);
85  append(byte);
86  value = value >> 7;
87  ++count;
88  }
89  // last byte, which should always fit on 1 byte
90  append(value);
91  ++count;
92  return count;
93 }
94 
96  return encodeHuffman(0, 7, literal);
97 }
98 
99 /*
100  * Huffman encode the literal and serialize, with an optional leading
101  * instruction. The instruction can be at most 8 - 1 - nbit bits long. nbit
102  * bits of the first byte will contain the prefix of the encoded literal's
103  * length. For HPACK instruction/nbit should always be 0/7.
104  *
105  * The encoded output looks like this
106  *
107  * | instruction | 1 | Length... | Huffman Coded Literal |
108  */
110  folly::StringPiece literal) {
111  static const auto& huffmanTree = huffman::huffTree();
112  uint32_t size = huffmanTree.getEncodeSize(literal);
113  // add the length
114  DCHECK_LE(nbit, 7);
115  uint8_t huffmanOn = uint8_t(1 << nbit);
116  DCHECK_EQ(instruction & huffmanOn, 0);
117  uint32_t count = encodeInteger(size, instruction | huffmanOn, nbit);
118  // ensure we have enough bytes before performing the encoding
119  count += huffmanTree.encode(literal, buf_);
120  return count;
121 }
122 
124  return encodeLiteral(0, 7, literal);
125 }
126 
128  folly::StringPiece literal) {
129  if (huffmanEnabled_) {
130  return encodeHuffman(instruction, nbit, literal);
131  }
132  // otherwise use simple layout
133  uint32_t count =
134  encodeInteger(literal.size(), instruction, nbit);
135  // copy the entire string
136  buf_.push((uint8_t*)literal.data(), literal.size());
137  count += literal.size();
138  return count;
139 }
140 
143 }
144 
145 }
uint32_t encodeHuffman(folly::StringPiece literal)
HPACKEncodeBuffer(uint32_t growthSize, bool huffmanEnabled)
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
uint32_t encodeLiteral(folly::StringPiece literal)
LogLevel max
Definition: LogLevel.cpp:31
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
constexpr size_type size() const
Definition: Range.h:431
static std::string printBin(const folly::IOBuf *buf, bool coalesce=false)
Definition: Logging.h:140
void push(const uint8_t *buf, size_t len)
Definition: Cursor.h:755
void addHeadroom(uint32_t bytes)
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
constexpr Iter data() const
Definition: Range.h:446
uint32_t encodeInteger(uint64_t value, uint8_t instruction, uint8_t nbit)
static const char *const value
Definition: Conv.cpp:50
int * count
const char * string
Definition: Conv.cpp:212
folly::io::QueueAppender buf_
const HuffTree & huffTree()
Definition: Huffman.cpp:252
const uint8_t NBIT_MASKS[9]