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.
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