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)'