Skip to content

Commit 6fecf4d

Browse files
committed
decode_raw: Use a buffer string for encoding the 32-bit words instead of Array#pack
1 parent e5ecfd1 commit 6fecf4d

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

lib/ascii85.rb

+14-2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def encode(str_or_io, wrap_lines = 80, out: nil)
8989
next if (chunk.bytesize & 0b11).zero?
9090

9191
# If we have leftover bytes, we need to zero-pad to a multiple of four
92+
# before converting to a 32-bit word.
9293
padding_length = (-chunk.bytesize) % 4
9394
trailing = chunk[-(4 - padding_length)..]
9495
word = (trailing + padding[0...padding_length]).unpack1('N')
@@ -234,6 +235,7 @@ def decode_raw(str_or_io, out: nil)
234235
# Decode
235236
word = 0
236237
count = 0
238+
wordbuf = "\0\0\0\0".dup
237239

238240
bufreader.each_chunk do |chunk|
239241
chunk.each_byte do |c|
@@ -256,7 +258,17 @@ def decode_raw(str_or_io, out: nil)
256258
if count == 5 && word > 0xffffffff
257259
raise(Ascii85::DecodingError, "Invalid Ascii85 5-tuple (#{word} >= 2**32)")
258260
elsif count == 5
259-
bufwriter.write([word].pack('N'))
261+
b3 = word & 0xff; word >>= 8
262+
b2 = word & 0xff; word >>= 8
263+
b1 = word & 0xff; word >>= 8
264+
b0 = word
265+
266+
wordbuf.setbyte(0, b0)
267+
wordbuf.setbyte(1, b1)
268+
wordbuf.setbyte(2, b2)
269+
wordbuf.setbyte(3, b3)
270+
271+
bufwriter.write(wordbuf)
260272

261273
word = 0
262274
count = 0
@@ -280,7 +292,7 @@ def decode_raw(str_or_io, out: nil)
280292
count -= 1
281293
word += lut[count]
282294

283-
bufwriter.write(((word >> 24) & 0xff).chr) if count >= 1
295+
bufwriter.write((word >> 24).chr) if count >= 1
284296
bufwriter.write(((word >> 16) & 0xff).chr) if count >= 2
285297
bufwriter.write(((word >> 8) & 0xff).chr) if count == 3
286298
bufwriter.flush

0 commit comments

Comments
 (0)