hexdump 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/spec/dumper_spec.rb
DELETED
@@ -1,329 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'hexdump/dumper'
|
3
|
-
|
4
|
-
describe Hexdump::Dumper do
|
5
|
-
let(:bytes) { [104, 101, 108, 108, 111] }
|
6
|
-
let(:hex_chars) { ['68', '65', '6c', '6c', '6f'] }
|
7
|
-
let(:decimal_chars) { ['104', '101', '108', '108', '111'] }
|
8
|
-
let(:octal_chars) { ['150', '145', '154', '154', '157'] }
|
9
|
-
let(:binary_chars) { ['01101000', '01100101', '01101100', '01101100', '01101111'] }
|
10
|
-
let(:print_chars) { ['h', 'e', 'l', 'l', 'o'] }
|
11
|
-
let(:data) { print_chars.join }
|
12
|
-
|
13
|
-
describe "#initialize" do
|
14
|
-
it "should only accept known base: values" do
|
15
|
-
expect {
|
16
|
-
described_class.new(data, base: :foo)
|
17
|
-
}.to raise_error(ArgumentError)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should only accept known endian: values" do
|
21
|
-
expect {
|
22
|
-
described_class.new(data, endian: :foo)
|
23
|
-
}.to raise_error(ArgumentError)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe "each_word" do
|
28
|
-
let(:data) { 'ABAB' }
|
29
|
-
let(:bytes) { [0x41, 0x42, 0x41, 0x42] }
|
30
|
-
|
31
|
-
it "should check if the data defines '#each_byte'" do
|
32
|
-
expect {
|
33
|
-
subject.each_word(Object.new).to_a
|
34
|
-
}.to raise_error(ArgumentError)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should iterate over each byte by default" do
|
38
|
-
expect(subject.each_word(data).to_a).to be == bytes
|
39
|
-
end
|
40
|
-
|
41
|
-
context "when initialized with a custom word_size:" do
|
42
|
-
subject { described_class.new(word_size: 3) }
|
43
|
-
|
44
|
-
let(:custom_words) { [0x414241, 0x42] }
|
45
|
-
|
46
|
-
it "should allow iterating over custom word-sizes" do
|
47
|
-
expect(subject.each_word(data).to_a).to be == custom_words
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context "when initialized with default endian:" do
|
52
|
-
subject { described_class.new(word_size: 2) }
|
53
|
-
|
54
|
-
let(:shorts_le) { [0x4241, 0x4241] }
|
55
|
-
|
56
|
-
it "should iterate over little-endian words by default" do
|
57
|
-
expect(subject.each_word(data).to_a).to be == shorts_le
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context "when initialized with endian: :big" do
|
62
|
-
subject { described_class.new(word_size: 2, endian: :big) }
|
63
|
-
|
64
|
-
let(:shorts_be) { [0x4142, 0x4142] }
|
65
|
-
|
66
|
-
it "should iterate over big-endian words" do
|
67
|
-
expect(subject.each_word(data).to_a).to be == shorts_be
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "#each" do
|
73
|
-
it "should yield the parts of each hexdump line to the given block" do
|
74
|
-
lines = []
|
75
|
-
|
76
|
-
subject.each(data) do |index,hex,print|
|
77
|
-
lines << [index, hex, print]
|
78
|
-
end
|
79
|
-
|
80
|
-
expect(lines.length).to be(1)
|
81
|
-
expect(lines[0][0]).to be == 0
|
82
|
-
expect(lines[0][1]).to be == hex_chars
|
83
|
-
expect(lines[0][2]).to be == print_chars
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should provide the index within the data for each line" do
|
87
|
-
indices = []
|
88
|
-
|
89
|
-
subject.each('A' * (16 * 10)) do |index,hex,print|
|
90
|
-
indices << index
|
91
|
-
end
|
92
|
-
|
93
|
-
expect(indices).to be == [0, 16, 32, 48, 64, 80, 96, 112, 128, 144]
|
94
|
-
end
|
95
|
-
|
96
|
-
context "when initialized with a custom wdith:" do
|
97
|
-
let(:width) { 10 }
|
98
|
-
|
99
|
-
subject { described_class.new(width: width) }
|
100
|
-
|
101
|
-
it "should change the width, in bytes, of each line" do
|
102
|
-
widths = []
|
103
|
-
count = 10
|
104
|
-
|
105
|
-
subject.each('A' * (width * count)) do |index,hex,print|
|
106
|
-
widths << hex.length
|
107
|
-
end
|
108
|
-
|
109
|
-
expect(widths).to be == ([width] * count)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
context "when there are leftover bytes" do
|
114
|
-
let(:width) { 10 }
|
115
|
-
|
116
|
-
subject { described_class.new(width: width) }
|
117
|
-
|
118
|
-
let(:chars) { ['B'] * 4 }
|
119
|
-
let(:string) { chars.join }
|
120
|
-
let(:leading) { 'A' * 100 }
|
121
|
-
|
122
|
-
it "should hexdump the remaining bytes" do
|
123
|
-
remainder = nil
|
124
|
-
|
125
|
-
subject.each(leading + string) do |index,hex,print|
|
126
|
-
remainder = print
|
127
|
-
end
|
128
|
-
|
129
|
-
expect(remainder).to be == chars
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
it "should provide the hexadecimal characters for each line" do
|
134
|
-
chars = []
|
135
|
-
length = (16 * 10)
|
136
|
-
|
137
|
-
subject.each(data * length) do |index,hex,print|
|
138
|
-
chars += hex
|
139
|
-
end
|
140
|
-
|
141
|
-
expect(chars).to be == (hex_chars * length)
|
142
|
-
end
|
143
|
-
|
144
|
-
context "when initialized with ascii: true" do
|
145
|
-
subject { described_class.new(ascii: true) }
|
146
|
-
|
147
|
-
it "should allow printing ASCII characters in place of hex characters" do
|
148
|
-
chars = []
|
149
|
-
|
150
|
-
subject.each(data) do |index,hex,print|
|
151
|
-
chars += hex
|
152
|
-
end
|
153
|
-
|
154
|
-
expect(chars).to be == print_chars
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should provide the print characters for each line" do
|
159
|
-
chars = []
|
160
|
-
length = (16 * 10)
|
161
|
-
|
162
|
-
subject.each(data * length) do |index,hex,print|
|
163
|
-
chars += print
|
164
|
-
end
|
165
|
-
|
166
|
-
expect(chars).to be == (print_chars * length)
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should map unprintable characters to '.'" do
|
170
|
-
unprintable = ((0x00..0x1f).map(&:chr) + (0x7f..0xff).map(&:chr)).join
|
171
|
-
chars = []
|
172
|
-
|
173
|
-
subject.each(unprintable) do |index,hex,print|
|
174
|
-
chars += print
|
175
|
-
end
|
176
|
-
|
177
|
-
expect(chars).to be == (['.'] * unprintable.length)
|
178
|
-
end
|
179
|
-
|
180
|
-
context "when initialized with base: :decimal" do
|
181
|
-
subject { described_class.new(base: :decimal) }
|
182
|
-
|
183
|
-
it "should support dumping bytes in decimal format" do
|
184
|
-
chars = []
|
185
|
-
|
186
|
-
subject.each(data) do |index,hex,print|
|
187
|
-
chars += hex
|
188
|
-
end
|
189
|
-
|
190
|
-
expect(chars).to be == decimal_chars
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
context "when initialized with base: :octal" do
|
195
|
-
subject { described_class.new(base: :octal) }
|
196
|
-
|
197
|
-
it "should support dumping bytes in octal format" do
|
198
|
-
chars = []
|
199
|
-
|
200
|
-
subject.each(data) do |index,hex,print|
|
201
|
-
chars += hex
|
202
|
-
end
|
203
|
-
|
204
|
-
expect(chars).to be == octal_chars
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
context "when initialized with base: :binary" do
|
209
|
-
subject { described_class.new(base: :binary) }
|
210
|
-
|
211
|
-
it "should support dumping bytes in binary format" do
|
212
|
-
chars = []
|
213
|
-
|
214
|
-
subject.each(data) do |index,hex,print|
|
215
|
-
chars += hex
|
216
|
-
end
|
217
|
-
|
218
|
-
expect(chars).to be == binary_chars
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
context "when initialized with word_size: and endian:" do
|
223
|
-
let(:options) { {:word_size => 2, :endian => :little} }
|
224
|
-
let(:hex_words) { ['6568', '6c6c', '006f'] }
|
225
|
-
|
226
|
-
subject { described_class.new(**options) }
|
227
|
-
|
228
|
-
it "should dump words in hexadecimal by default" do
|
229
|
-
words = []
|
230
|
-
|
231
|
-
subject.each(data) do |index,hex,print|
|
232
|
-
words += hex
|
233
|
-
end
|
234
|
-
|
235
|
-
expect(words).to be == hex_words
|
236
|
-
end
|
237
|
-
|
238
|
-
context "and base: :decimal" do
|
239
|
-
subject { described_class.new(base: :decimal, **options) }
|
240
|
-
|
241
|
-
let(:decimal_words) { ['25960', '27756', ' 111'] }
|
242
|
-
|
243
|
-
it "should dump words in decimal" do
|
244
|
-
words = []
|
245
|
-
|
246
|
-
subject.each(data) do |index,dec,print|
|
247
|
-
words += dec
|
248
|
-
end
|
249
|
-
|
250
|
-
expect(words).to be == decimal_words
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
context "and base: :octal" do
|
255
|
-
subject { described_class.new(base: :octal, **options) }
|
256
|
-
|
257
|
-
let(:octal_words) { ['062550', '066154', '000157'] }
|
258
|
-
|
259
|
-
it "should dump words in octal" do
|
260
|
-
words = []
|
261
|
-
|
262
|
-
subject.each(data) do |index,oct,print|
|
263
|
-
words += oct
|
264
|
-
end
|
265
|
-
|
266
|
-
expect(words).to be == octal_words
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
context "and base: :binary" do
|
271
|
-
subject { described_class.new(base: :binary, **options) }
|
272
|
-
|
273
|
-
let(:binary_words) { ['0110010101101000', '0110110001101100', '0000000001101111'] }
|
274
|
-
|
275
|
-
it "should dump words in binary" do
|
276
|
-
words = []
|
277
|
-
|
278
|
-
subject.each(data) do |index,bin,print|
|
279
|
-
words += bin
|
280
|
-
end
|
281
|
-
|
282
|
-
expect(words).to be == binary_words
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
it "must return the number of bytes read" do
|
288
|
-
length = 100
|
289
|
-
data = 'A' * length
|
290
|
-
|
291
|
-
expect(subject.each(data) { |index,hex,print| }).to be == length
|
292
|
-
end
|
293
|
-
|
294
|
-
context "when no block is given" do
|
295
|
-
it "must return an Enumerator" do
|
296
|
-
expect(subject.each(data)).to be_kind_of(Enumerator)
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
describe "#dump" do
|
302
|
-
it "should check if the output supports the '#<<' method" do
|
303
|
-
expect {
|
304
|
-
subject.dump(data,Object.new)
|
305
|
-
}.to raise_error(ArgumentError)
|
306
|
-
end
|
307
|
-
|
308
|
-
let(:index_format) { "%.8x" }
|
309
|
-
|
310
|
-
it "should append each line of the hexdump to the output" do
|
311
|
-
lines = []
|
312
|
-
|
313
|
-
subject.dump(data,lines)
|
314
|
-
|
315
|
-
expect(lines.length).to be(2)
|
316
|
-
expect(lines[0]).to start_with(index_format % 0)
|
317
|
-
expect(lines[0]).to include(hex_chars.join(' '))
|
318
|
-
expect(lines[0]).to end_with("|#{print_chars.join}|#{$/}")
|
319
|
-
end
|
320
|
-
|
321
|
-
it "must always print the total number of bytes read on the last line" do
|
322
|
-
lines = []
|
323
|
-
|
324
|
-
subject.dump(data,lines)
|
325
|
-
|
326
|
-
expect(lines.last).to start_with(index_format % data.length)
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end
|
data/spec/hexdump_spec.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'hexdump'
|
3
|
-
|
4
|
-
describe Hexdump do
|
5
|
-
describe "#hexdump" do
|
6
|
-
let(:bytes) { [104, 101, 108, 108, 111] }
|
7
|
-
let(:hex_chars) { ['68', '65', '6c', '6c', '6f'] }
|
8
|
-
|
9
|
-
subject do
|
10
|
-
obj = Object.new.extend(Hexdump)
|
11
|
-
|
12
|
-
each_byte = expect(obj).to receive(:each_byte)
|
13
|
-
bytes.each do |b|
|
14
|
-
each_byte = each_byte.and_yield(b)
|
15
|
-
end
|
16
|
-
|
17
|
-
obj
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should hexdump the object" do
|
21
|
-
chars = []
|
22
|
-
|
23
|
-
subject.hexdump do |index,hex,print|
|
24
|
-
chars += hex
|
25
|
-
end
|
26
|
-
|
27
|
-
expect(chars).to be == hex_chars
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|