hexdump 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,2 @@
1
- require 'hexdump/extensions/string'
2
- require 'hexdump/extensions/string_io'
3
- require 'hexdump/extensions/io'
4
- require 'hexdump/extensions/file'
1
+ # DEPRECATED: use hexdump/core_ext instead.
2
+ require 'hexdump/core_ext'
@@ -24,28 +24,25 @@ module Hexdump
24
24
  # @param [#each_byte] data
25
25
  # The data to be hexdumped.
26
26
  #
27
- # @param [Hash] options
28
- # Additional options.
29
- #
30
- # @option options [Integer] :width (16)
27
+ # @param [Integer] width (16)
31
28
  # The number of bytes to dump for each line.
32
29
  #
33
- # @option options [Integer] :endian (:little)
30
+ # @param [Integer] endian (:little)
34
31
  # The endianness that the bytes are organized in. Supported endianness
35
32
  # include `:little` and `:big`.
36
33
  #
37
- # @option options [Integer] :word_size (1)
34
+ # @param [Integer] word_size (1)
38
35
  # The number of bytes within a word.
39
36
  #
40
- # @option options [Symbol, Integer] :base (:hexadecimal)
37
+ # @param [Symbol, Integer] base (:hexadecimal)
41
38
  # The base to print bytes in. Supported bases include, `:hexadecimal`,
42
39
  # `:hex`, `16, `:decimal`, `:dec`, `10, `:octal`, `:oct`, `8`,
43
40
  # `:binary`, `:bin` and `2`.
44
41
  #
45
- # @option options [Boolean] :ascii (false)
42
+ # @param [Boolean] ascii (false)
46
43
  # Print ascii characters when possible.
47
44
  #
48
- # @option options [#<<] :output ($stdout)
45
+ # @param [#<<] output ($stdout)
49
46
  # The output to print the hexdump to.
50
47
  #
51
48
  # @yield [index,numeric,printable]
@@ -68,14 +65,11 @@ module Hexdump
68
65
  # the `:output` value does not support the `#<<` method or
69
66
  # the `:base` value was unknown.
70
67
  #
71
- def self.dump(data,options={},&block)
72
- output = (options.delete(:output) || $stdout)
73
- dumper = Dumper.new(options)
68
+ def self.dump(data, output: $stdout, **options,&block)
69
+ dumper = Dumper.new(**options)
74
70
 
75
- if block
76
- dumper.each(data,&block)
77
- else
78
- dumper.dump(data,output)
71
+ if block then dumper.each(data,&block)
72
+ else dumper.dump(data,output)
79
73
  end
80
74
 
81
75
  return nil
@@ -84,12 +78,9 @@ module Hexdump
84
78
  #
85
79
  # Hexdumps the object.
86
80
  #
87
- # @param [Hash] options
88
- # Additional options.
89
- #
90
81
  # @see Hexdump.dump
91
82
  #
92
- def hexdump(options={},&block)
93
- Hexdump.dump(self,options,&block)
83
+ def hexdump(**options,&block)
84
+ Hexdump.dump(self,**options,&block)
94
85
  end
95
86
  end
@@ -1,4 +1,4 @@
1
1
  module Hexdump
2
2
  # hexdump version
3
- VERSION = '0.2.4'
3
+ VERSION = '0.3.0'
4
4
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
- require 'hexdump/extensions'
2
+ require 'hexdump/core_ext'
3
3
 
4
- describe "Hexdump extensions" do
4
+ describe "Hexdump core_ext" do
5
5
  it "should include Hexdump into String" do
6
6
  expect(String).to include(Hexdump)
7
7
  end
data/spec/dumper_spec.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
-
3
2
  require 'hexdump/dumper'
4
3
 
5
4
  describe Hexdump::Dumper do
@@ -11,24 +10,23 @@ describe Hexdump::Dumper do
11
10
  let(:print_chars) { ['h', 'e', 'l', 'l', 'o'] }
12
11
  let(:data) { print_chars.join }
13
12
 
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
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
19
 
20
- it "should only accept known :endian values" do
21
- expect {
22
- described_class.new(data, :endian => :foo)
23
- }.to raise_error(ArgumentError)
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
24
25
  end
25
26
 
26
27
  describe "each_word" do
27
28
  let(:data) { 'ABAB' }
28
29
  let(:bytes) { [0x41, 0x42, 0x41, 0x42] }
29
- let(:shorts_le) { [0x4241, 0x4241] }
30
- let(:shorts_be) { [0x4142, 0x4142] }
31
- let(:custom_words) { [0x414241, 0x42] }
32
30
 
33
31
  it "should check if the data defines '#each_byte'" do
34
32
  expect {
@@ -40,22 +38,34 @@ describe Hexdump::Dumper do
40
38
  expect(subject.each_word(data).to_a).to be == bytes
41
39
  end
42
40
 
43
- it "should allow iterating over custom word-sizes" do
44
- dumper = described_class.new(:word_size => 3)
41
+ context "when initialized with a custom word_size:" do
42
+ subject { described_class.new(word_size: 3) }
45
43
 
46
- expect(dumper.each_word(data).to_a).to be == custom_words
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
47
49
  end
48
50
 
49
- it "should iterate over little-endian words by default" do
50
- dumper = described_class.new(:word_size => 2)
51
+ context "when initialized with default endian:" do
52
+ subject { described_class.new(word_size: 2) }
51
53
 
52
- expect(dumper.each_word(data).to_a).to be == shorts_le
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
53
59
  end
54
60
 
55
- it "should iterate over big-endian words" do
56
- dumper = described_class.new(:word_size => 2, :endian => :big)
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] }
57
65
 
58
- expect(dumper.each_word(data).to_a).to be == shorts_be
66
+ it "should iterate over big-endian words" do
67
+ expect(subject.each_word(data).to_a).to be == shorts_be
68
+ end
59
69
  end
60
70
  end
61
71
 
@@ -74,72 +84,86 @@ describe Hexdump::Dumper do
74
84
  end
75
85
 
76
86
  it "should provide the index within the data for each line" do
77
- dumper = described_class.new(:width => 10)
78
87
  indices = []
79
88
 
80
- dumper.each('A' * 100) do |index,hex,print|
89
+ subject.each('A' * (16 * 10)) do |index,hex,print|
81
90
  indices << index
82
91
  end
83
92
 
84
- expect(indices).to be == [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
93
+ expect(indices).to be == [0, 16, 32, 48, 64, 80, 96, 112, 128, 144]
85
94
  end
86
95
 
87
- it "should allow configuring the width, in bytes, of each line" do
88
- dumper = described_class.new(:width => 10)
89
- widths = []
96
+ context "when initialized with a custom wdith:" do
97
+ let(:width) { 10 }
90
98
 
91
- dumper.each('A' * 100) do |index,hex,print|
92
- widths << hex.length
93
- end
99
+ subject { described_class.new(width: width) }
94
100
 
95
- expect(widths).to be == ([10] * 10)
96
- end
101
+ it "should change the width, in bytes, of each line" do
102
+ widths = []
103
+ count = 10
97
104
 
98
- it "should hexdump the remaining bytes" do
99
- dumper = described_class.new(:width => 10)
100
- chars = (['B'] * 4)
101
- string = chars.join
102
- leading = ('A' * 100)
103
- remainder = nil
105
+ subject.each('A' * (width * count)) do |index,hex,print|
106
+ widths << hex.length
107
+ end
104
108
 
105
- dumper.each(leading + string) do |index,hex,print|
106
- remainder = print
109
+ expect(widths).to be == ([width] * count)
107
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) }
108
117
 
109
- expect(remainder).to be == chars
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
110
131
  end
111
132
 
112
133
  it "should provide the hexadecimal characters for each line" do
113
- dumper = described_class.new(:width => 10)
114
134
  chars = []
135
+ length = (16 * 10)
115
136
 
116
- dumper.each(data * 100) do |index,hex,print|
137
+ subject.each(data * length) do |index,hex,print|
117
138
  chars += hex
118
139
  end
119
140
 
120
- expect(chars).to be == (hex_chars * 100)
141
+ expect(chars).to be == (hex_chars * length)
121
142
  end
122
143
 
123
- it "should allow printing ASCII characters in place of hex characters" do
124
- dumper = described_class.new(:ascii => true)
125
- chars = []
144
+ context "when initialized with ascii: true" do
145
+ subject { described_class.new(ascii: true) }
126
146
 
127
- dumper.each(data) do |index,hex,print|
128
- chars += hex
129
- end
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
130
153
 
131
- expect(chars).to be == print_chars
154
+ expect(chars).to be == print_chars
155
+ end
132
156
  end
133
157
 
134
158
  it "should provide the print characters for each line" do
135
- dumper = described_class.new(:width => 10)
136
159
  chars = []
160
+ length = (16 * 10)
137
161
 
138
- dumper.each(data * 100) do |index,hex,print|
162
+ subject.each(data * length) do |index,hex,print|
139
163
  chars += print
140
164
  end
141
165
 
142
- expect(chars).to be == (print_chars * 100)
166
+ expect(chars).to be == (print_chars * length)
143
167
  end
144
168
 
145
169
  it "should map unprintable characters to '.'" do
@@ -153,108 +177,153 @@ describe Hexdump::Dumper do
153
177
  expect(chars).to be == (['.'] * unprintable.length)
154
178
  end
155
179
 
156
- it "should support dumping bytes in decimal format" do
157
- dumper = described_class.new(:base => :decimal)
158
- chars = []
180
+ context "when initialized with base: :decimal" do
181
+ subject { described_class.new(base: :decimal) }
159
182
 
160
- dumper.each(data) do |index,hex,print|
161
- chars += hex
162
- end
183
+ it "should support dumping bytes in decimal format" do
184
+ chars = []
163
185
 
164
- expect(chars).to be == decimal_chars
186
+ subject.each(data) do |index,hex,print|
187
+ chars += hex
188
+ end
189
+
190
+ expect(chars).to be == decimal_chars
191
+ end
165
192
  end
166
193
 
167
- it "should support dumping bytes in octal format" do
168
- dumper = described_class.new(:base => :octal)
169
- chars = []
194
+ context "when initialized with base: :octal" do
195
+ subject { described_class.new(base: :octal) }
170
196
 
171
- dumper.each(data) do |index,hex,print|
172
- chars += hex
173
- end
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
174
203
 
175
- expect(chars).to be == octal_chars
204
+ expect(chars).to be == octal_chars
205
+ end
176
206
  end
177
207
 
178
- it "should support dumping bytes in binary format" do
179
- dumper = described_class.new(:base => :binary)
180
- chars = []
208
+ context "when initialized with base: :binary" do
209
+ subject { described_class.new(base: :binary) }
181
210
 
182
- dumper.each(data) do |index,hex,print|
183
- chars += hex
184
- end
211
+ it "should support dumping bytes in binary format" do
212
+ chars = []
185
213
 
186
- expect(chars).to be == binary_chars
214
+ subject.each(data) do |index,hex,print|
215
+ chars += hex
216
+ end
217
+
218
+ expect(chars).to be == binary_chars
219
+ end
187
220
  end
188
221
 
189
- context ":word_size" do
222
+ context "when initialized with word_size: and endian:" do
190
223
  let(:options) { {:word_size => 2, :endian => :little} }
191
-
192
224
  let(:hex_words) { ['6568', '6c6c', '006f'] }
193
- let(:decimal_words) { ['25960', '27756', ' 111'] }
194
- let(:octal_words) { ['062550', '066154', '000157'] }
195
- let(:binary_words) { ['0110010101101000', '0110110001101100', '0000000001101111'] }
196
225
 
197
- it "should dump words in hexadecimal" do
198
- dumper = described_class.new(options)
226
+ subject { described_class.new(**options) }
227
+
228
+ it "should dump words in hexadecimal by default" do
199
229
  words = []
200
230
 
201
- dumper.each(data) do |index,hex,print|
231
+ subject.each(data) do |index,hex,print|
202
232
  words += hex
203
233
  end
204
234
 
205
235
  expect(words).to be == hex_words
206
236
  end
207
237
 
208
- it "should dump words in decimal" do
209
- dumper = described_class.new(options.merge(:base => :decimal))
210
- words = []
238
+ context "and base: :decimal" do
239
+ subject { described_class.new(base: :decimal, **options) }
211
240
 
212
- dumper.each(data) do |index,dec,print|
213
- words += dec
214
- end
241
+ let(:decimal_words) { ['25960', '27756', ' 111'] }
215
242
 
216
- expect(words).to be == decimal_words
217
- end
243
+ it "should dump words in decimal" do
244
+ words = []
218
245
 
219
- it "should dump words in octal" do
220
- dumper = described_class.new(options.merge(:base => :octal))
221
- words = []
246
+ subject.each(data) do |index,dec,print|
247
+ words += dec
248
+ end
222
249
 
223
- dumper.each(data) do |index,oct,print|
224
- words += oct
250
+ expect(words).to be == decimal_words
225
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 = []
226
261
 
227
- expect(words).to be == octal_words
262
+ subject.each(data) do |index,oct,print|
263
+ words += oct
264
+ end
265
+
266
+ expect(words).to be == octal_words
267
+ end
228
268
  end
229
269
 
230
- it "should dump words in binary" do
231
- dumper = described_class.new(options.merge(:base => :binary))
232
- words = []
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 = []
233
277
 
234
- dumper.each(data) do |index,bin,print|
235
- words += bin
278
+ subject.each(data) do |index,bin,print|
279
+ words += bin
280
+ end
281
+
282
+ expect(words).to be == binary_words
236
283
  end
284
+ end
285
+ end
237
286
 
238
- expect(words).to be == binary_words
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)
239
297
  end
240
298
  end
241
299
  end
242
300
 
243
301
  describe "#dump" do
244
- it "should check if the :output supports the '#<<' method" do
302
+ it "should check if the output supports the '#<<' method" do
245
303
  expect {
246
304
  subject.dump(data,Object.new)
247
305
  }.to raise_error(ArgumentError)
248
306
  end
249
307
 
308
+ let(:index_format) { "%.8x" }
309
+
250
310
  it "should append each line of the hexdump to the output" do
251
311
  lines = []
252
312
 
253
313
  subject.dump(data,lines)
254
314
 
255
- expect(lines.length).to be(1)
315
+ expect(lines.length).to be(2)
316
+ expect(lines[0]).to start_with(index_format % 0)
256
317
  expect(lines[0]).to include(hex_chars.join(' '))
257
- expect(lines[0]).to include(print_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)
258
327
  end
259
328
  end
260
329
  end