29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/binascii/qp.rb', line 29
def b2a_qp(data, header: false, quote_tabs: false, is_text: true)
@byte_cache ||= {}
String.new.tap do |result|
data_size = data.bytesize
line_len = 0
cr_lf = false
Utils.each_byte_quad(data) do |leading, byte, trailing1, trailing2|
repl = nil
repl_size = 1
if byte == 13 if is_text
repl = byte
else
repl = '=0D'
end
elsif byte == 10 if is_text
cr_lf = true if leading == 13
if cr_lf && leading != 13
repl = "\r\n"
repl_size = 2
else
repl = byte
end
else
repl = '=0A'
end
elsif byte == 95 repl = ? '=5F' : '_'
repl_size = repl.bytesize
elsif byte == 32 if (!trailing1 || trailing1 == 10 || (trailing1 == 13 && trailing2 == 10) || quote_tabs) && is_text
repl = "=20"
repl_size = 3
else
repl = ? '_' : ' '
end
elsif byte == 9 if (!trailing1 || trailing1 == 10 || (trailing1 == 13 && trailing2 == 10) || quote_tabs) && is_text
repl = "=09"
repl_size = 3
else
repl = "\t"
end
elsif byte == 46 if line_len == 0 && (!trailing1 || trailing1 == 10 || trailing1 == 13 || trailing1 == 0)
repl = '=2E'
repl_size = 3
else
repl = '.'
end
elsif (byte >= 33 && byte <= 126) && byte != 61 repl = byte
else
repl = (@byte_cache[byte] ||= "=#{byte.to_s(16).rjust(2, '0').upcase}")
repl_size = 3
end
if (line_len + repl_size) > LINE_MAX - 1
line_len = 0
result << "=\r\n"
result << repl
else
result << repl
end
line_len += repl_size
end
end
end
|