Skip to content

Commit 1827e1e

Browse files
committed
refactor: Add constants for String literals, method for copying/unfreezing Strings
1 parent 7a53950 commit 1827e1e

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

lib/ascii85.rb

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
#
1515
module Ascii85
1616
class << self
17+
EMPTY_STRING = ''.dup.force_encoding(Encoding::ASCII_8BIT)
18+
START_MARKER = '<~'.dup.force_encoding(Encoding::ASCII_8BIT)
19+
ENDING_MARKER = '~>'.dup.force_encoding(Encoding::ASCII_8BIT)
20+
LINE_BREAK = "\n".dup.force_encoding(Encoding::ASCII_8BIT)
21+
1722
#
1823
# Encodes the bytes of the given String or IO-like object as Ascii85.
1924
#
@@ -55,20 +60,17 @@ def encode(str_or_io, wrap_lines = 80, out: nil)
5560
StringIO.new(str_or_io.to_s, 'rb')
5661
end
5762

58-
return ''.dup if reader.eof?
63+
return EMPTY_STRING.dup if reader.eof?
5964

6065
# Setup buffered Reader and Writers
6166
bufreader = BufferedReader.new(reader, unencoded_chunk_size)
6267
bufwriter = BufferedWriter.new(out || StringIO.new(String.new, 'wb'), encoded_chunk_size)
6368
writer = wrap_lines ? Wrapper.new(bufwriter, wrap_lines) : DummyWrapper.new(bufwriter)
6469

65-
# We need to enforce the encoding here, because this source file is in UTF-8,
66-
# but we want ASCII-8BIT output.
67-
padding = "\0\0\0\0".dup.force_encoding(Encoding::ASCII_8BIT)
68-
tuplebuf = '!!!!!'.dup.force_encoding(Encoding::ASCII_8BIT)
69-
70-
exclamations = '!!!!!'.dup.force_encoding(Encoding::ASCII_8BIT)
71-
z = 'z'.dup.force_encoding(Encoding::ASCII_8BIT)
70+
padding = unfrozen_binary_copy("\0\0\0\0")
71+
tuplebuf = unfrozen_binary_copy('!!!!!')
72+
exclamations = unfrozen_binary_copy('!!!!!')
73+
z = unfrozen_binary_copy('z')
7274

7375
bufreader.each_chunk do |chunk|
7476
chunk.unpack('N*').each do |word|
@@ -156,8 +158,8 @@ def extract(str)
156158

157159
# Get the positions of the opening/closing delimiters. If there is no pair
158160
# of opening/closing delimiters, return an unfrozen empty String.
159-
(start_pos = input.index(opening_delim)) or return ''.dup
160-
(end_pos = input.index(closing_delim, start_pos + 2)) or return ''.dup
161+
(start_pos = input.index(opening_delim)) or return EMPTY_STRING.dup
162+
(end_pos = input.index(closing_delim, start_pos + 2)) or return EMPTY_STRING.dup
161163

162164
# Get the String inside the delimiter-pair
163165
input[(start_pos + 2)...end_pos]
@@ -231,7 +233,7 @@ def decode_raw(str_or_io, out: nil)
231233
end
232234

233235
# Return an unfrozen String on empty input
234-
return ''.dup if reader.eof?
236+
return EMPTY_STRING.dup if reader.eof?
235237

236238
# Setup buffered Reader and Writers
237239
bufreader = BufferedReader.new(reader, encoded_chunk_size)
@@ -243,8 +245,8 @@ def decode_raw(str_or_io, out: nil)
243245
# Decode
244246
word = 0
245247
count = 0
246-
wordbuf = "\0\0\0\0".dup.force_encoding(Encoding::ASCII_8BIT)
247-
zeroes = "\0\0\0\0".dup.force_encoding(Encoding::ASCII_8BIT)
248+
zeroes = unfrozen_binary_copy("\0\0\0\0")
249+
wordbuf = zeroes.dup
248250

249251
bufreader.each_chunk do |chunk|
250252
chunk.each_byte do |c|
@@ -311,6 +313,12 @@ def decode_raw(str_or_io, out: nil)
311313

312314
private
313315

316+
# Copies the given String and forces the encoding of the returned copy to
317+
# be Encoding::ASCII_8BIT.
318+
def unfrozen_binary_copy(str)
319+
str.dup.force_encoding(Encoding::ASCII_8BIT)
320+
end
321+
314322
# Buffers an underlying IO object to increase efficiency. You do not need
315323
# to use this directly.
316324
#
@@ -364,20 +372,17 @@ def flush
364372
# @private
365373
#
366374
class DummyWrapper
367-
START = '<~'.dup.force_encoding(Encoding::ASCII_8BIT)
368-
ENDING = '~>'.dup.force_encoding(Encoding::ASCII_8BIT)
369-
370375
def initialize(out)
371376
@out = out
372-
@out.write(START)
377+
@out.write(START_MARKER)
373378
end
374379

375380
def write(buffer)
376381
@out.write(buffer)
377382
end
378383

379384
def finish
380-
@out.write(ENDING)
385+
@out.write(ENDING_MARKER)
381386
@out.flush
382387

383388
@out
@@ -390,15 +395,11 @@ def finish
390395
# @private
391396
#
392397
class Wrapper
393-
LINE_BREAK = 10.chr.force_encoding(Encoding::ASCII_8BIT)
394-
START = '<~'.dup.force_encoding(Encoding::ASCII_8BIT)
395-
ENDING = '~>'.dup.force_encoding(Encoding::ASCII_8BIT)
396-
397398
def initialize(out, wrap_lines)
398399
@line_length = [2, wrap_lines.to_i].max
399400

400401
@out = out
401-
@out.write(START)
402+
@out.write(START_MARKER)
402403

403404
@cur_len = 2
404405
end
@@ -425,7 +426,7 @@ def write(buffer)
425426
def finish
426427
# Add the closing delimiter (may need to be pushed to the next line)
427428
@out.write(LINE_BREAK) if @cur_len + 2 > @line_length
428-
@out.write(ENDING)
429+
@out.write(ENDING_MARKER)
429430

430431
@out.flush
431432
@out

0 commit comments

Comments
 (0)