hexdump 0.2.4 → 0.3.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.
@@ -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