hexdump 0.3.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +68 -2
- data/Gemfile +1 -0
- data/README.md +486 -135
- data/benchmark.rb +29 -22
- data/lib/hexdump/chars.rb +46 -0
- data/lib/hexdump/core_ext/file.rb +68 -6
- data/lib/hexdump/core_ext/io.rb +2 -2
- data/lib/hexdump/core_ext/kernel.rb +7 -0
- data/lib/hexdump/core_ext/string.rb +2 -2
- data/lib/hexdump/core_ext/string_io.rb +2 -2
- data/lib/hexdump/core_ext.rb +1 -0
- data/lib/hexdump/format_string.rb +43 -0
- data/lib/hexdump/hexdump.rb +768 -75
- data/lib/hexdump/mixin.rb +198 -0
- data/lib/hexdump/module_methods.rb +132 -0
- data/lib/hexdump/numeric/binary.rb +55 -0
- data/lib/hexdump/numeric/char_or_int.rb +90 -0
- data/lib/hexdump/numeric/decimal.rb +56 -0
- data/lib/hexdump/numeric/exceptions.rb +11 -0
- data/lib/hexdump/numeric/hexadecimal.rb +59 -0
- data/lib/hexdump/numeric/octal.rb +55 -0
- data/lib/hexdump/numeric.rb +5 -0
- data/lib/hexdump/reader.rb +314 -0
- data/lib/hexdump/theme/ansi.rb +81 -0
- data/lib/hexdump/theme/rule.rb +159 -0
- data/lib/hexdump/theme.rb +61 -0
- data/lib/hexdump/type.rb +232 -0
- data/lib/hexdump/types.rb +108 -0
- data/lib/hexdump/version.rb +1 -1
- data/lib/hexdump.rb +12 -1
- data/spec/chars_spec.rb +76 -0
- data/spec/core_ext_spec.rb +10 -6
- data/spec/hexdump_class_spec.rb +1708 -0
- data/spec/hexdump_module_spec.rb +23 -0
- data/spec/mixin_spec.rb +37 -0
- data/spec/numeric/binary_spec.rb +239 -0
- data/spec/numeric/char_or_int_spec.rb +210 -0
- data/spec/numeric/decimal_spec.rb +317 -0
- data/spec/numeric/hexadecimal_spec.rb +320 -0
- data/spec/numeric/octal_spec.rb +239 -0
- data/spec/reader_spec.rb +863 -0
- data/spec/theme/ansi_spec.rb +242 -0
- data/spec/theme/rule_spec.rb +199 -0
- data/spec/theme_spec.rb +94 -0
- data/spec/type_spec.rb +317 -0
- data/spec/types_spec.rb +904 -0
- metadata +39 -10
- data/.gemtest +0 -0
- data/lib/hexdump/dumper.rb +0 -419
- data/spec/dumper_spec.rb +0 -329
- data/spec/hexdump_spec.rb +0 -30
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hexdump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -34,7 +34,6 @@ extra_rdoc_files:
|
|
34
34
|
- README.md
|
35
35
|
files:
|
36
36
|
- ".document"
|
37
|
-
- ".gemtest"
|
38
37
|
- ".github/workflows/ruby.yml"
|
39
38
|
- ".gitignore"
|
40
39
|
- ".rspec"
|
@@ -48,19 +47,49 @@ files:
|
|
48
47
|
- gemspec.yml
|
49
48
|
- hexdump.gemspec
|
50
49
|
- lib/hexdump.rb
|
50
|
+
- lib/hexdump/chars.rb
|
51
51
|
- lib/hexdump/core_ext.rb
|
52
52
|
- lib/hexdump/core_ext/file.rb
|
53
53
|
- lib/hexdump/core_ext/io.rb
|
54
|
+
- lib/hexdump/core_ext/kernel.rb
|
54
55
|
- lib/hexdump/core_ext/string.rb
|
55
56
|
- lib/hexdump/core_ext/string_io.rb
|
56
|
-
- lib/hexdump/dumper.rb
|
57
57
|
- lib/hexdump/extensions.rb
|
58
|
+
- lib/hexdump/format_string.rb
|
58
59
|
- lib/hexdump/hexdump.rb
|
60
|
+
- lib/hexdump/mixin.rb
|
61
|
+
- lib/hexdump/module_methods.rb
|
62
|
+
- lib/hexdump/numeric.rb
|
63
|
+
- lib/hexdump/numeric/binary.rb
|
64
|
+
- lib/hexdump/numeric/char_or_int.rb
|
65
|
+
- lib/hexdump/numeric/decimal.rb
|
66
|
+
- lib/hexdump/numeric/exceptions.rb
|
67
|
+
- lib/hexdump/numeric/hexadecimal.rb
|
68
|
+
- lib/hexdump/numeric/octal.rb
|
69
|
+
- lib/hexdump/reader.rb
|
70
|
+
- lib/hexdump/theme.rb
|
71
|
+
- lib/hexdump/theme/ansi.rb
|
72
|
+
- lib/hexdump/theme/rule.rb
|
73
|
+
- lib/hexdump/type.rb
|
74
|
+
- lib/hexdump/types.rb
|
59
75
|
- lib/hexdump/version.rb
|
76
|
+
- spec/chars_spec.rb
|
60
77
|
- spec/core_ext_spec.rb
|
61
|
-
- spec/
|
62
|
-
- spec/
|
78
|
+
- spec/hexdump_class_spec.rb
|
79
|
+
- spec/hexdump_module_spec.rb
|
80
|
+
- spec/mixin_spec.rb
|
81
|
+
- spec/numeric/binary_spec.rb
|
82
|
+
- spec/numeric/char_or_int_spec.rb
|
83
|
+
- spec/numeric/decimal_spec.rb
|
84
|
+
- spec/numeric/hexadecimal_spec.rb
|
85
|
+
- spec/numeric/octal_spec.rb
|
86
|
+
- spec/reader_spec.rb
|
63
87
|
- spec/spec_helper.rb
|
88
|
+
- spec/theme/ansi_spec.rb
|
89
|
+
- spec/theme/rule_spec.rb
|
90
|
+
- spec/theme_spec.rb
|
91
|
+
- spec/type_spec.rb
|
92
|
+
- spec/types_spec.rb
|
64
93
|
homepage: https://github.com/postmodern/hexdump.rb#readme
|
65
94
|
licenses:
|
66
95
|
- MIT
|
@@ -69,7 +98,7 @@ metadata:
|
|
69
98
|
source_code_uri: https://github.com/postmodern/hexdump.rb
|
70
99
|
bug_tracker_uri: https://github.com/postmodern/hexdump.rb/issues
|
71
100
|
changelog_uri: https://github.com/postmodern/hexdump.rb/blob/master/ChangeLog.md
|
72
|
-
post_install_message:
|
101
|
+
post_install_message:
|
73
102
|
rdoc_options: []
|
74
103
|
require_paths:
|
75
104
|
- lib
|
@@ -84,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
113
|
- !ruby/object:Gem::Version
|
85
114
|
version: '0'
|
86
115
|
requirements: []
|
87
|
-
rubygems_version: 3.
|
88
|
-
signing_key:
|
116
|
+
rubygems_version: 3.2.22
|
117
|
+
signing_key:
|
89
118
|
specification_version: 4
|
90
119
|
summary: Hexdump Strings and IO objects.
|
91
120
|
test_files: []
|
data/.gemtest
DELETED
File without changes
|
data/lib/hexdump/dumper.rb
DELETED
@@ -1,419 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Hexdump
|
4
|
-
#
|
5
|
-
# Handles the parsing of data and formatting of the hexdump.
|
6
|
-
#
|
7
|
-
# @since 0.2.0
|
8
|
-
#
|
9
|
-
class Dumper
|
10
|
-
|
11
|
-
# Widths for formatted numbers
|
12
|
-
WIDTHS = {
|
13
|
-
hexadecimal: ->(word_size) { word_size * 2 },
|
14
|
-
decimal: {
|
15
|
-
1 => 3,
|
16
|
-
2 => 5,
|
17
|
-
4 => 10,
|
18
|
-
8 => 20
|
19
|
-
},
|
20
|
-
octal: {
|
21
|
-
1 => 3,
|
22
|
-
2 => 6,
|
23
|
-
4 => 11,
|
24
|
-
8 => 22
|
25
|
-
},
|
26
|
-
binary: ->(word_size) { word_size * 8 }
|
27
|
-
}
|
28
|
-
|
29
|
-
# Format Strings for the various bases
|
30
|
-
FORMATS = {
|
31
|
-
hexadecimal: ->(width) { "%.#{width}x" },
|
32
|
-
decimal: ->(width) { "%#{width}.d" },
|
33
|
-
octal: ->(width) { "%.#{width}o" },
|
34
|
-
binary: ->(width) { "%.#{width}b" }
|
35
|
-
}
|
36
|
-
|
37
|
-
# Character to represent unprintable characters
|
38
|
-
UNPRINTABLE = '.'
|
39
|
-
|
40
|
-
# ASCII printable bytes and characters
|
41
|
-
PRINTABLE = {
|
42
|
-
0x20 => " ",
|
43
|
-
0x21 => "!",
|
44
|
-
0x22 => "\"",
|
45
|
-
0x23 => "#",
|
46
|
-
0x24 => "$",
|
47
|
-
0x25 => "%",
|
48
|
-
0x26 => "&",
|
49
|
-
0x27 => "'",
|
50
|
-
0x28 => "(",
|
51
|
-
0x29 => ")",
|
52
|
-
0x2a => "*",
|
53
|
-
0x2b => "+",
|
54
|
-
0x2c => ",",
|
55
|
-
0x2d => "-",
|
56
|
-
0x2e => ".",
|
57
|
-
0x2f => "/",
|
58
|
-
0x30 => "0",
|
59
|
-
0x31 => "1",
|
60
|
-
0x32 => "2",
|
61
|
-
0x33 => "3",
|
62
|
-
0x34 => "4",
|
63
|
-
0x35 => "5",
|
64
|
-
0x36 => "6",
|
65
|
-
0x37 => "7",
|
66
|
-
0x38 => "8",
|
67
|
-
0x39 => "9",
|
68
|
-
0x3a => ":",
|
69
|
-
0x3b => ";",
|
70
|
-
0x3c => "<",
|
71
|
-
0x3d => "=",
|
72
|
-
0x3e => ">",
|
73
|
-
0x3f => "?",
|
74
|
-
0x40 => "@",
|
75
|
-
0x41 => "A",
|
76
|
-
0x42 => "B",
|
77
|
-
0x43 => "C",
|
78
|
-
0x44 => "D",
|
79
|
-
0x45 => "E",
|
80
|
-
0x46 => "F",
|
81
|
-
0x47 => "G",
|
82
|
-
0x48 => "H",
|
83
|
-
0x49 => "I",
|
84
|
-
0x4a => "J",
|
85
|
-
0x4b => "K",
|
86
|
-
0x4c => "L",
|
87
|
-
0x4d => "M",
|
88
|
-
0x4e => "N",
|
89
|
-
0x4f => "O",
|
90
|
-
0x50 => "P",
|
91
|
-
0x51 => "Q",
|
92
|
-
0x52 => "R",
|
93
|
-
0x53 => "S",
|
94
|
-
0x54 => "T",
|
95
|
-
0x55 => "U",
|
96
|
-
0x56 => "V",
|
97
|
-
0x57 => "W",
|
98
|
-
0x58 => "X",
|
99
|
-
0x59 => "Y",
|
100
|
-
0x5a => "Z",
|
101
|
-
0x5b => "[",
|
102
|
-
0x5c => "\\",
|
103
|
-
0x5d => "]",
|
104
|
-
0x5e => "^",
|
105
|
-
0x5f => "_",
|
106
|
-
0x60 => "`",
|
107
|
-
0x61 => "a",
|
108
|
-
0x62 => "b",
|
109
|
-
0x63 => "c",
|
110
|
-
0x64 => "d",
|
111
|
-
0x65 => "e",
|
112
|
-
0x66 => "f",
|
113
|
-
0x67 => "g",
|
114
|
-
0x68 => "h",
|
115
|
-
0x69 => "i",
|
116
|
-
0x6a => "j",
|
117
|
-
0x6b => "k",
|
118
|
-
0x6c => "l",
|
119
|
-
0x6d => "m",
|
120
|
-
0x6e => "n",
|
121
|
-
0x6f => "o",
|
122
|
-
0x70 => "p",
|
123
|
-
0x71 => "q",
|
124
|
-
0x72 => "r",
|
125
|
-
0x73 => "s",
|
126
|
-
0x74 => "t",
|
127
|
-
0x75 => "u",
|
128
|
-
0x76 => "v",
|
129
|
-
0x77 => "w",
|
130
|
-
0x78 => "x",
|
131
|
-
0x79 => "y",
|
132
|
-
0x7a => "z",
|
133
|
-
0x7b => "{",
|
134
|
-
0x7c => "|",
|
135
|
-
0x7d => "}",
|
136
|
-
0x7e => "~"
|
137
|
-
}
|
138
|
-
|
139
|
-
PRINTABLE.default = UNPRINTABLE
|
140
|
-
|
141
|
-
# The base to dump words as.
|
142
|
-
attr_reader :base
|
143
|
-
|
144
|
-
# The size of the words parse from the data.
|
145
|
-
attr_reader :word_size
|
146
|
-
|
147
|
-
# The endianness of the words parsed from the data.
|
148
|
-
attr_reader :endian
|
149
|
-
|
150
|
-
# The width in words of each hexdump line.
|
151
|
-
attr_reader :width
|
152
|
-
|
153
|
-
# Whether to display ASCII characters alongside numeric values.
|
154
|
-
attr_reader :ascii
|
155
|
-
|
156
|
-
#
|
157
|
-
# Creates a new Hexdump dumper.
|
158
|
-
#
|
159
|
-
# @param [Integer] width (16)
|
160
|
-
# The number of bytes to dump for each line.
|
161
|
-
#
|
162
|
-
# @param [Integer] endian (:little)
|
163
|
-
# The endianness that the bytes are organized in. Supported endianness
|
164
|
-
# include `:little` and `:big`.
|
165
|
-
#
|
166
|
-
# @param [Integer] word_size (1)
|
167
|
-
# The number of bytes within a word.
|
168
|
-
#
|
169
|
-
# @param [Symbol, Integer] base (:hexadecimal)
|
170
|
-
# The base to print bytes in. Supported bases include, `:hexadecimal`,
|
171
|
-
# `:hex`, `16, `:decimal`, `:dec`, `10, `:octal`, `:oct`, `8`,
|
172
|
-
# `:binary`, `:bin` and `2`.
|
173
|
-
#
|
174
|
-
# @param [Boolean] ascii (false)
|
175
|
-
# Print ascii characters when possible.
|
176
|
-
#
|
177
|
-
# @raise [ArgumentError]
|
178
|
-
# The values for `:base` or `:endian` were unknown.
|
179
|
-
#
|
180
|
-
# @since 0.2.0
|
181
|
-
#
|
182
|
-
def initialize(width: 16,
|
183
|
-
endian: :little,
|
184
|
-
word_size: 1,
|
185
|
-
base: :hexadecimal,
|
186
|
-
ascii: false)
|
187
|
-
|
188
|
-
@base = case base
|
189
|
-
when :hexadecimal, :hex, 16 then :hexadecimal
|
190
|
-
when :decimal, :dec, 10 then :decimal
|
191
|
-
when :octal, :oct, 8 then :octal
|
192
|
-
when :binary, :bin, 2 then :binary
|
193
|
-
when nil then :hexadecimal
|
194
|
-
else
|
195
|
-
raise(ArgumentError,"unknown base #{base.inspect}")
|
196
|
-
end
|
197
|
-
|
198
|
-
@word_size = word_size
|
199
|
-
@endian = case endian
|
200
|
-
when 'little', :little then :little
|
201
|
-
when 'big', :big then :big
|
202
|
-
when nil then :little
|
203
|
-
else
|
204
|
-
raise(ArgumentError,"unknown endian: #{endian.inspect}")
|
205
|
-
end
|
206
|
-
|
207
|
-
@width = (width / @word_size)
|
208
|
-
@ascii = ascii
|
209
|
-
|
210
|
-
@format_width = (WIDTHS[@base][@word_size] || 1)
|
211
|
-
@format = FORMATS[@base][@format_width]
|
212
|
-
|
213
|
-
if @word_size == 1
|
214
|
-
@format_cache = Hash.new do |hash,key|
|
215
|
-
hash[key] = sprintf(@format,key)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
#
|
221
|
-
# Iterates over every word within the data.
|
222
|
-
#
|
223
|
-
# @param [#each_byte] data
|
224
|
-
# The data containing bytes.
|
225
|
-
#
|
226
|
-
# @yield [word]
|
227
|
-
# The given block will be passed each word within the data.
|
228
|
-
#
|
229
|
-
# @yieldparam [Integer]
|
230
|
-
# An unpacked word from the data.
|
231
|
-
#
|
232
|
-
# @return [Enumerator]
|
233
|
-
# If no block is given, an Enumerator will be returned.
|
234
|
-
#
|
235
|
-
# @raise [ArgumentError]
|
236
|
-
# The given data does not define the `#each_byte` method.
|
237
|
-
#
|
238
|
-
# @since 0.2.0
|
239
|
-
#
|
240
|
-
def each_word(data,&block)
|
241
|
-
return enum_for(:each_word,data) unless block
|
242
|
-
|
243
|
-
unless data.respond_to?(:each_byte)
|
244
|
-
raise(ArgumentError,"the data to hexdump must define #each_byte")
|
245
|
-
end
|
246
|
-
|
247
|
-
if @word_size > 1
|
248
|
-
word = 0
|
249
|
-
count = 0
|
250
|
-
|
251
|
-
init_shift = if @endian == :big then ((@word_size - 1) * 8)
|
252
|
-
else 0
|
253
|
-
end
|
254
|
-
shift = init_shift
|
255
|
-
|
256
|
-
data.each_byte do |b|
|
257
|
-
word |= (b << shift)
|
258
|
-
|
259
|
-
if @endian == :big then shift -= 8
|
260
|
-
else shift += 8
|
261
|
-
end
|
262
|
-
|
263
|
-
count += 1
|
264
|
-
|
265
|
-
if count >= @word_size
|
266
|
-
yield word
|
267
|
-
|
268
|
-
word = 0
|
269
|
-
count = 0
|
270
|
-
shift = init_shift
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
# yield the remaining word
|
275
|
-
yield word if count > 0
|
276
|
-
else
|
277
|
-
data.each_byte(&block)
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
#
|
282
|
-
# Iterates over the hexdump.
|
283
|
-
#
|
284
|
-
# @param [#each_byte] data
|
285
|
-
# The data to be hexdumped.
|
286
|
-
#
|
287
|
-
# @yield [index,numeric,printable]
|
288
|
-
# The given block will be passed the hexdump break-down of each
|
289
|
-
# segment.
|
290
|
-
#
|
291
|
-
# @yieldparam [Integer] index
|
292
|
-
# The index of the hexdumped segment.
|
293
|
-
#
|
294
|
-
# @yieldparam [Array<String>] numeric
|
295
|
-
# The numeric representation of the segment.
|
296
|
-
#
|
297
|
-
# @yieldparam [Array<String>] printable
|
298
|
-
# The printable representation of the segment.
|
299
|
-
#
|
300
|
-
# @return [Integer, Enumerator]
|
301
|
-
# If a block is given, then the final number of bytes read is returned.
|
302
|
-
# If no block is given, an Enumerator will be returned.
|
303
|
-
#
|
304
|
-
# @since 0.2.0
|
305
|
-
#
|
306
|
-
def each(data)
|
307
|
-
return enum_for(:each,data) unless block_given?
|
308
|
-
|
309
|
-
index = 0
|
310
|
-
count = 0
|
311
|
-
|
312
|
-
numeric = Array.new(@width)
|
313
|
-
printable = Array.new(@width)
|
314
|
-
|
315
|
-
each_word(data) do |word|
|
316
|
-
numeric[count] = format_numeric(word)
|
317
|
-
printable[count] = format_printable(word)
|
318
|
-
|
319
|
-
count += 1
|
320
|
-
|
321
|
-
if count >= @width
|
322
|
-
yield index, numeric, printable
|
323
|
-
|
324
|
-
index += (@width * @word_size)
|
325
|
-
count = 0
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
if count > 0
|
330
|
-
# yield the remaining data
|
331
|
-
yield index, numeric[0,count], printable[0,count]
|
332
|
-
|
333
|
-
index += (count * @word_size)
|
334
|
-
end
|
335
|
-
|
336
|
-
return index
|
337
|
-
end
|
338
|
-
|
339
|
-
#
|
340
|
-
# Dumps the hexdump.
|
341
|
-
#
|
342
|
-
# @param [#each_byte] data
|
343
|
-
# The data to be hexdumped.
|
344
|
-
#
|
345
|
-
# @param [#<<] output
|
346
|
-
# The output to dump the hexdump to.
|
347
|
-
#
|
348
|
-
# @return [nil]
|
349
|
-
#
|
350
|
-
# @raise [ArgumentError]
|
351
|
-
# The output value does not support the `#<<` method.
|
352
|
-
#
|
353
|
-
# @since 0.2.0
|
354
|
-
#
|
355
|
-
def dump(data,output=$stdout)
|
356
|
-
unless output.respond_to?(:<<)
|
357
|
-
raise(ArgumentError,"output must support the #<< method")
|
358
|
-
end
|
359
|
-
|
360
|
-
bytes_segment_width = ((@width * @format_width) + @width)
|
361
|
-
index_format = "%.8x"
|
362
|
-
line_format = "#{index_format} %-#{bytes_segment_width}s |%s|#{$/}"
|
363
|
-
|
364
|
-
length = each(data) do |index,numeric,printable|
|
365
|
-
output << sprintf(line_format,index,numeric.join(' '),printable.join)
|
366
|
-
end
|
367
|
-
|
368
|
-
output << sprintf("#{index_format}#{$/}",length)
|
369
|
-
return nil
|
370
|
-
end
|
371
|
-
|
372
|
-
#
|
373
|
-
# Converts the word into a numeric String.
|
374
|
-
#
|
375
|
-
# @param [Integer] word
|
376
|
-
# The word to convert.
|
377
|
-
#
|
378
|
-
# @return [String]
|
379
|
-
# The numeric representation of the word.
|
380
|
-
#
|
381
|
-
# @since 0.2.0
|
382
|
-
#
|
383
|
-
def format_numeric(word)
|
384
|
-
if @word_size == 1
|
385
|
-
if (@ascii && (word >= 0x20 && word <= 0x7e))
|
386
|
-
PRINTABLE[word]
|
387
|
-
else
|
388
|
-
@format_cache[word]
|
389
|
-
end
|
390
|
-
else
|
391
|
-
sprintf(@format,word)
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
#
|
396
|
-
# Converts a word into a printable String.
|
397
|
-
#
|
398
|
-
# @param [Integer] word
|
399
|
-
# The word to convert.
|
400
|
-
#
|
401
|
-
# @return [String]
|
402
|
-
# The printable representation of the word.
|
403
|
-
#
|
404
|
-
# @since 0.2.0
|
405
|
-
#
|
406
|
-
def format_printable(word)
|
407
|
-
if @word_size == 1
|
408
|
-
PRINTABLE[word]
|
409
|
-
elsif word >= 0 && word <= 0x7fffffff
|
410
|
-
# XXX: https://github.com/jruby/jruby/issues/6652
|
411
|
-
char = word.chr(Encoding::UTF_8) rescue nil
|
412
|
-
char || UNPRINTABLE
|
413
|
-
else
|
414
|
-
UNPRINTABLE
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
end
|
419
|
-
end
|