class HTTP2Next::Header::Huffman

Huffman encoder/decoder

Constants

BITS_AT_ONCE
CODES

Huffman table as specified in

ENCODE_TABLE
EOS

Public Instance Methods

decode(buf) click to toggle source

Decodes provided Huffman coded string.

@param buf [Buffer] @return [String] binary string @raise [CompressionError] when Huffman coded string is malformed

# File lib/http/2/next/header/huffman.rb, line 37
def decode(buf)
  emit = "".b
  state = 0 # start state

  mask = (1 << BITS_AT_ONCE) - 1
  buf.each_byte do |chr|
    (8 / BITS_AT_ONCE - 1).downto(0) do |shift|
      branch = (chr >> (shift * BITS_AT_ONCE)) & mask
      # MACHINE[state] = [final, [transitions]]
      #  [final] unfinished bits so far are prefix of the EOS code.
      # Each transition is [emit, next]
      #  [emit] character to be emitted on this transition, empty string, or EOS.
      #  [next] next state number.
      trans = MACHINE[state][branch]
      raise CompressionError, "Huffman decode error (EOS found)" if trans.first == EOS

      emit << trans.first.chr if trans.first
      state = trans.last
    end
  end
  # Check whether partial input is correctly filled
  raise CompressionError, "Huffman decode error (EOS invalid)" unless state <= MAX_FINAL_STATE

  emit.force_encoding(Encoding::BINARY)
end
encode(str) click to toggle source

Encodes provided value via huffman encoding. Length is not encoded in this method.

@param str [String] @return [String] binary string

# File lib/http/2/next/header/huffman.rb, line 26
def encode(str)
  bitstring = str.each_byte.map { |chr| ENCODE_TABLE[chr] }.join
  bitstring << "1" * ((8 - bitstring.size) % 8)
  [bitstring].pack("B*")
end