@@ -21,6 +21,10 @@ namespace proxygen::huffman {
2121constexpr static uint32_t kHuffmanDecodeSpaceNumerator = 3 ;
2222constexpr static uint32_t kHuffmanDecodeSpaceDenominator = 2 ;
2323
24+ // Decoded characters are batched into a stack buffer of this size before
25+ // being appended to the output string.
26+ constexpr static uint32_t kHuffmanDecodeOutputBufferSize = 1024 ;
27+
2428HuffTree::HuffTree (const uint32_t * codes, const uint8_t * bits)
2529 : codes_(codes), bits_(bits) {
2630 buildTree ();
@@ -41,6 +45,9 @@ bool HuffTree::decode(const uint8_t* buf,
4145 uint32_t w = 0 ;
4246 uint32_t wbits = 0 ;
4347 uint32_t i = 0 ;
48+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init): written before read
49+ std::array<char , kHuffmanDecodeOutputBufferSize > outBuf;
50+ uint32_t outPos = 0 ;
4451 while (i < size || wbits > 0 ) {
4552 // decide if we need to load more bits using an 8-bit chunk
4653 if (i < size && wbits < 8 ) {
@@ -63,7 +70,11 @@ bool HuffTree::decode(const uint8_t* buf,
6370 const HuffNode& node = snode->index [key];
6471 if (node.isLeaf ()) {
6572 // final node, we can emit the character
66- literal.push_back (node.data .ch );
73+ outBuf[outPos++] = static_cast <char >(node.data .ch );
74+ if (outPos == kHuffmanDecodeOutputBufferSize ) {
75+ literal.append (outBuf.data (), outPos);
76+ outPos = 0 ;
77+ }
6778 wbits -= node.metadata .bits ;
6879 snode = &table_[0 ];
6980 } else {
@@ -74,6 +85,9 @@ bool HuffTree::decode(const uint8_t* buf,
7485 // remove what we've just used
7586 w = w & ((1 << wbits) - 1 );
7687 }
88+ if (outPos > 0 ) {
89+ literal.append (outBuf.data (), outPos);
90+ }
7791 return true ;
7892}
7993
0 commit comments