@@ -46,9 +46,9 @@ final class HpackHuffmanDecoder implements ByteProcessor {
4646 private static final byte HUFFMAN_EMIT_SYMBOL = 1 << 1 ;
4747 private static final byte HUFFMAN_FAIL = 1 << 2 ;
4848
49- private static final int HUFFMAN_COMPLETE_SHIFT = 1 << 8 ;
50- private static final int HUFFMAN_EMIT_SYMBOL_SHIFT = 1 << 9 ;
51- private static final int HUFFMAN_FAIL_SHIFT = 1 << 10 ;
49+ private static final int HUFFMAN_COMPLETE_SHIFT = HUFFMAN_COMPLETE << 8 ;
50+ private static final int HUFFMAN_EMIT_SYMBOL_SHIFT = HUFFMAN_EMIT_SYMBOL << 8 ;
51+ private static final int HUFFMAN_FAIL_SHIFT = HUFFMAN_FAIL << 8 ;
5252
5353 /**
5454 * A table of byte tuples (state, flags, output). They are packed together as:
@@ -4672,7 +4672,6 @@ final class HpackHuffmanDecoder implements ByteProcessor {
46724672 private byte [] dest ;
46734673 private int k ;
46744674 private int state ;
4675- private int flags ;
46764675
46774676 HpackHuffmanDecoder () { }
46784677
@@ -4696,7 +4695,7 @@ public AsciiString decode(ByteBuf buf, int length) throws Http2Exception {
46964695 if (endIndex == -1 ) {
46974696 // We did consume the requested length
46984697 buf .readerIndex (readerIndex + length );
4699- if ((flags & HUFFMAN_COMPLETE_SHIFT ) != HUFFMAN_COMPLETE_SHIFT ) {
4698+ if ((state & HUFFMAN_COMPLETE_SHIFT ) != HUFFMAN_COMPLETE_SHIFT ) {
47004699 throw BAD_ENCODING ;
47014700 }
47024701 return new AsciiString (dest , 0 , k , false );
@@ -4710,7 +4709,6 @@ public AsciiString decode(ByteBuf buf, int length) throws Http2Exception {
47104709 dest = null ;
47114710 k = 0 ;
47124711 state = 0 ;
4713- flags = 0 ;
47144712 }
47154713 }
47164714
@@ -4719,27 +4717,21 @@ public AsciiString decode(ByteBuf buf, int length) throws Http2Exception {
47194717 */
47204718 @ Override
47214719 public boolean process (byte input ) {
4722- int index = (state << 4 ) | ((input & 0xFF ) >>> 4 );
4723- int row = HUFFS [index ];
4724- flags = row & 0x00FF00 ;
4725- if ((flags & HUFFMAN_FAIL_SHIFT ) != 0 ) {
4726- return false ;
4727- }
4728- if ((flags & HUFFMAN_EMIT_SYMBOL_SHIFT ) != 0 ) {
4729- dest [k ++] = (byte ) (row & 0xFF );
4730- }
4731- state = row >> 16 ;
4720+ return processNibble (input >> 4 ) && processNibble (input );
4721+ }
47324722
4733- index = (state << 4 ) | (input & 0x0F );
4734- row = HUFFS [index ];
4735- flags = row & 0x00FF00 ;
4736- if ((flags & HUFFMAN_FAIL_SHIFT ) != 0 ) {
4723+ private boolean processNibble (int input ) {
4724+ // The high nibble of the flags byte of each row is always zero
4725+ // (low nibble after shifting row by 12), since there are only 3 flag bits
4726+ int index = state >> 12 | (input & 0x0F );
4727+ state = HUFFS [index ];
4728+ if ((state & HUFFMAN_FAIL_SHIFT ) != 0 ) {
47374729 return false ;
47384730 }
4739- if ((flags & HUFFMAN_EMIT_SYMBOL_SHIFT ) != 0 ) {
4740- dest [k ++] = (byte ) (row & 0xFF );
4731+ if ((state & HUFFMAN_EMIT_SYMBOL_SHIFT ) != 0 ) {
4732+ // state is always positive so can cast without mask here
4733+ dest [k ++] = (byte ) state ;
47414734 }
4742- state = row >> 16 ;
47434735 return true ;
47444736 }
47454737}
0 commit comments