lib/protocol/hpack/huffman.rb in protocol-hpack-1.4.3 vs lib/protocol/hpack/huffman.rb in protocol-hpack-1.5.0

- old
+ new

@@ -4,10 +4,11 @@ # Copyright, 2014-2015, by Kaoru Maeda. # Copyright, 2015, by Ilya Grigorik. # Copyright, 2015, by Tamir Duberstein. # Copyright, 2018-2024, by Samuel Williams. # Copyright, 2022, by Daniel Morrison. +# Copyright, 2024, by Nathan Froyd. require_relative 'huffman/machine' require_relative 'error' module Protocol @@ -20,29 +21,30 @@ # Encodes provided value via huffman encoding. # Length is not encoded in this method. # # @param str [String] # @return [String] binary string - def encode(str) + def self.encode(str) bitstring = str.each_byte.map {|chr| ENCODE_TABLE[chr]}.join bitstring << '1' * ((8 - bitstring.size) % 8) [bitstring].pack('B*') end # Decodes provided Huffman coded string. # # @param buf [Buffer] # @return [String] binary string # @raise [CompressionError] when Huffman coded string is malformed - def decode(buffer) + def self.decode(buffer) emit = String.new.b state = 0 # start state mask = (1 << BITS_AT_ONCE) - 1 buffer.each_byte do |c| - (8 / BITS_AT_ONCE - 1).downto(0) do |shift| - branch = (c >> (shift * BITS_AT_ONCE)) & mask + shift = BITS_AT_ONCE + while shift >= 0 + branch = (c >> shift) & 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. @@ -50,9 +52,10 @@ value, state = MACHINE[state][branch] raise CompressionError, 'Huffman decode error (EOS found)' if value == EOS emit << value.chr if value + shift -= BITS_AT_ONCE end end # Check whether partial input is correctly filled unless state <= MAX_FINAL_STATE raise CompressionError, 'Huffman decode error (EOS invalid)'