hexdump 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +68 -2
  3. data/Gemfile +1 -0
  4. data/README.md +486 -135
  5. data/benchmark.rb +29 -22
  6. data/lib/hexdump/chars.rb +46 -0
  7. data/lib/hexdump/core_ext/file.rb +68 -6
  8. data/lib/hexdump/core_ext/io.rb +2 -2
  9. data/lib/hexdump/core_ext/kernel.rb +7 -0
  10. data/lib/hexdump/core_ext/string.rb +2 -2
  11. data/lib/hexdump/core_ext/string_io.rb +2 -2
  12. data/lib/hexdump/core_ext.rb +1 -0
  13. data/lib/hexdump/format_string.rb +43 -0
  14. data/lib/hexdump/hexdump.rb +768 -75
  15. data/lib/hexdump/mixin.rb +198 -0
  16. data/lib/hexdump/module_methods.rb +132 -0
  17. data/lib/hexdump/numeric/binary.rb +55 -0
  18. data/lib/hexdump/numeric/char_or_int.rb +90 -0
  19. data/lib/hexdump/numeric/decimal.rb +56 -0
  20. data/lib/hexdump/numeric/exceptions.rb +11 -0
  21. data/lib/hexdump/numeric/hexadecimal.rb +59 -0
  22. data/lib/hexdump/numeric/octal.rb +55 -0
  23. data/lib/hexdump/numeric.rb +5 -0
  24. data/lib/hexdump/reader.rb +314 -0
  25. data/lib/hexdump/theme/ansi.rb +81 -0
  26. data/lib/hexdump/theme/rule.rb +159 -0
  27. data/lib/hexdump/theme.rb +61 -0
  28. data/lib/hexdump/type.rb +232 -0
  29. data/lib/hexdump/types.rb +108 -0
  30. data/lib/hexdump/version.rb +1 -1
  31. data/lib/hexdump.rb +12 -1
  32. data/spec/chars_spec.rb +76 -0
  33. data/spec/core_ext_spec.rb +10 -6
  34. data/spec/hexdump_class_spec.rb +1708 -0
  35. data/spec/hexdump_module_spec.rb +23 -0
  36. data/spec/mixin_spec.rb +37 -0
  37. data/spec/numeric/binary_spec.rb +239 -0
  38. data/spec/numeric/char_or_int_spec.rb +210 -0
  39. data/spec/numeric/decimal_spec.rb +317 -0
  40. data/spec/numeric/hexadecimal_spec.rb +320 -0
  41. data/spec/numeric/octal_spec.rb +239 -0
  42. data/spec/reader_spec.rb +863 -0
  43. data/spec/theme/ansi_spec.rb +242 -0
  44. data/spec/theme/rule_spec.rb +199 -0
  45. data/spec/theme_spec.rb +94 -0
  46. data/spec/type_spec.rb +317 -0
  47. data/spec/types_spec.rb +904 -0
  48. metadata +39 -10
  49. data/.gemtest +0 -0
  50. data/lib/hexdump/dumper.rb +0 -419
  51. data/spec/dumper_spec.rb +0 -329
  52. 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