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
@@ -0,0 +1,317 @@
1
+ require 'spec_helper'
2
+ require 'hexdump/numeric/decimal'
3
+ require 'hexdump/type'
4
+
5
+ describe Hexdump::Numeric::Decimal do
6
+ describe "#initialize" do
7
+ subject { described_class.new(type) }
8
+
9
+ context "when given a Type::Int type" do
10
+ context "and size is 1" do
11
+ let(:type) { Hexdump::Type::Int8.new }
12
+
13
+ it "must set #width to 3 + 1" do
14
+ expect(subject.width).to eq(3 + 1)
15
+ end
16
+ end
17
+
18
+ context "and size is 2" do
19
+ let(:type) { Hexdump::Type::Int16.new }
20
+
21
+ it "must set #width to 5 + 1" do
22
+ expect(subject.width).to eq(5 + 1)
23
+ end
24
+ end
25
+
26
+ context "and size is 4" do
27
+ let(:type) { Hexdump::Type::Int32.new }
28
+
29
+ it "must set #width to 10 + 1" do
30
+ expect(subject.width).to eq(10 + 1)
31
+ end
32
+ end
33
+
34
+ context "and size is 8" do
35
+ let(:type) { Hexdump::Type::Int64.new }
36
+
37
+ it "must set #width to 20 + 1" do
38
+ expect(subject.width).to eq(20 + 1)
39
+ end
40
+ end
41
+
42
+ context "but it has an unsupported size" do
43
+ class UnsupportedIntType < Hexdump::Type::Int
44
+
45
+ def initialize
46
+ super(size: 3)
47
+ end
48
+
49
+ end
50
+
51
+ let(:type) { UnsupportedIntType.new }
52
+
53
+ it do
54
+ expect {
55
+ described_class.new(type)
56
+ }.to raise_error(NotImplementedError)
57
+ end
58
+ end
59
+ end
60
+
61
+ context "when given a Type::UInt type" do
62
+ context "and size is 1" do
63
+ let(:type) { Hexdump::Type::UInt8.new }
64
+
65
+ it "must set #width to 3" do
66
+ expect(subject.width).to eq(3)
67
+ end
68
+ end
69
+
70
+ context "and size is 2" do
71
+ let(:type) { Hexdump::Type::UInt16.new }
72
+
73
+ it "must set #width to 5" do
74
+ expect(subject.width).to eq(5)
75
+ end
76
+ end
77
+
78
+ context "and size is 4" do
79
+ let(:type) { Hexdump::Type::UInt32.new }
80
+
81
+ it "must set #width to 10" do
82
+ expect(subject.width).to eq(10)
83
+ end
84
+ end
85
+
86
+ context "and size is 8" do
87
+ let(:type) { Hexdump::Type::UInt64.new }
88
+
89
+ it "must set #width to 20" do
90
+ expect(subject.width).to eq(20)
91
+ end
92
+ end
93
+
94
+ context "but it has an unsupported size" do
95
+ class UnsupportedUIntType < Hexdump::Type::UInt
96
+
97
+ def initialize
98
+ super(size: 3)
99
+ end
100
+
101
+ end
102
+
103
+ let(:type) { UnsupportedUIntType.new }
104
+
105
+ it do
106
+ expect {
107
+ described_class.new(type)
108
+ }.to raise_error(NotImplementedError)
109
+ end
110
+ end
111
+ end
112
+
113
+ context "when given a Type::Float type" do
114
+ context "and size is 4" do
115
+ let(:type) { Hexdump::Type::Float32.new }
116
+
117
+ it "must set #width to 15 + 1" do
118
+ expect(subject.width).to eq(15 + 1)
119
+ end
120
+ end
121
+
122
+ context "and size is 8" do
123
+ let(:type) { Hexdump::Type::Float64.new }
124
+
125
+ it "must set #width to 24 + 1" do
126
+ expect(subject.width).to eq(24 + 1)
127
+ end
128
+ end
129
+
130
+ context "but it has an unsupported size" do
131
+ class UnsupportedFloatType < Hexdump::Type::Float
132
+
133
+ def initialize
134
+ super(size: 3)
135
+ end
136
+
137
+ end
138
+
139
+ let(:type) { UnsupportedFloatType.new }
140
+
141
+ it do
142
+ expect {
143
+ described_class.new(type)
144
+ }.to raise_error(NotImplementedError)
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ describe "#%" do
151
+ subject { described_class.new(type) }
152
+
153
+ context "when the given type is a Type::UInt" do
154
+ context "and the given type has size 1" do
155
+ let(:type) { Hexdump::Type::UInt8.new }
156
+
157
+ let(:value) { 0xf }
158
+ let(:decimal) { '15' }
159
+
160
+ it "must return a left-padded decimal string of length 3" do
161
+ expect(subject % value).to eq(" #{decimal}")
162
+ end
163
+ end
164
+
165
+ context "and the given type has size 2" do
166
+ let(:type) { Hexdump::Type::UInt16.new }
167
+
168
+ let(:value) { 0xff }
169
+ let(:decimal) { '255' }
170
+
171
+ it "must return a left-padded decimal string of length 5" do
172
+ expect(subject % value).to eq(" #{decimal}")
173
+ end
174
+ end
175
+
176
+ context "and the given type has size 4" do
177
+ let(:type) { Hexdump::Type::UInt32.new }
178
+
179
+ let(:value) { 0xffff }
180
+ let(:decimal) { '65535' }
181
+
182
+ it "must return a left-padded decimal string of length 10" do
183
+ expect(subject % value).to eq(" #{decimal}")
184
+ end
185
+ end
186
+
187
+ context "and the given type has size 8" do
188
+ let(:type) { Hexdump::Type::UInt64.new }
189
+
190
+ let(:value) { 0xffffffff }
191
+ let(:decimal) { '4294967295' }
192
+
193
+ it "must return a left-padded decimal string of length 20" do
194
+ expect(subject % value).to eq(" #{decimal}")
195
+ end
196
+ end
197
+ end
198
+
199
+ context "when the given type is a Type::Int" do
200
+ context "and the given type has size 1" do
201
+ let(:type) { Hexdump::Type::Int8.new }
202
+
203
+ let(:value) { 0xf }
204
+ let(:decimal) { '15' }
205
+
206
+ context "and the value is positive" do
207
+ it "must return a decimal string of length 3 prefixed with a ' '" do
208
+ expect(subject % value).to eq(" #{decimal}".rjust(3))
209
+ end
210
+ end
211
+
212
+ context "and the value is negative" do
213
+ it "must return a decimal string of length 3 prefixed with a '-'" do
214
+ expect(subject % -value).to eq("-#{decimal}".rjust(3))
215
+ end
216
+ end
217
+ end
218
+
219
+ context "and the given type has size 2" do
220
+ let(:type) { Hexdump::Type::Int16.new }
221
+
222
+ let(:value) { 0xff }
223
+ let(:decimal) { '255' }
224
+
225
+ context "and the value is positive" do
226
+ it "must return a decimal string of length 5 prefixed with a ' '" do
227
+ expect(subject % value).to eq(" #{decimal}".rjust(5))
228
+ end
229
+ end
230
+
231
+ context "and the value is negative" do
232
+ it "must return a decimal string of length 5 prefixed with a '-'" do
233
+ expect(subject % -value).to eq(" -#{decimal}".rjust(5))
234
+ end
235
+ end
236
+ end
237
+
238
+ context "and the given type has size 4" do
239
+ let(:type) { Hexdump::Type::Int32.new }
240
+
241
+ let(:value) { 0xffff }
242
+ let(:decimal) { '65535' }
243
+
244
+ context "and the value is positive" do
245
+ it "must return a decimal string of length 10 prefixed with a ' '" do
246
+ expect(subject % value).to eq(" #{decimal}".rjust(10))
247
+ end
248
+ end
249
+
250
+ context "and the value is negative" do
251
+ it "must return a decimal string of length 10 prefixed with a '-'" do
252
+ expect(subject % -value).to eq(" -#{decimal}".rjust(10))
253
+ end
254
+ end
255
+ end
256
+
257
+ context "when the given type has size 8" do
258
+ let(:type) { Hexdump::Type::Int64.new }
259
+
260
+ let(:value) { 0xffffffff }
261
+ let(:decimal) { '4294967295' }
262
+
263
+ context "and the value is positive" do
264
+ it "must return a decimal string of length 20 prefixed with a ' '" do
265
+ expect(subject % value).to eq(" #{decimal}".rjust(20))
266
+ end
267
+ end
268
+
269
+ context "and the value is negative" do
270
+ it "must return a decimal string of length 20 prefixed with a '-'" do
271
+ expect(subject % -value).to eq("-#{decimal}".rjust(20))
272
+ end
273
+ end
274
+ end
275
+ end
276
+
277
+ context "when the given type is a Type::Float" do
278
+ context "and the given type has size 4" do
279
+ let(:type) { Hexdump::Type::Float32.new }
280
+
281
+ let(:value) { 123456789.123456789 }
282
+ let(:float) { "1.23457e+08" }
283
+
284
+ context "and the value is positive" do
285
+ it "must return a float string of length 16 prefixed with a ' '" do
286
+ expect(subject % value).to eq(" #{float}".rjust(15))
287
+ end
288
+ end
289
+
290
+ context "and the value is negative" do
291
+ it "must return a float string of length 16 prefixed with a '-'" do
292
+ expect(subject % -value).to eq("-#{float}".rjust(15))
293
+ end
294
+ end
295
+ end
296
+
297
+ context "and the given type has size 8" do
298
+ let(:type) { Hexdump::Type::Float64.new }
299
+
300
+ let(:value) { 123456789.123456789 }
301
+ let(:float) { "1.23457e+08" }
302
+
303
+ context "and the value is positive" do
304
+ it "must return a float string of length 25 prefixed with a ' '" do
305
+ expect(subject % value).to eq(" #{float}".rjust(24))
306
+ end
307
+ end
308
+
309
+ context "and the value is negative" do
310
+ it "must return a float string of length 25 prefixed with a '-'" do
311
+ expect(subject % -value).to eq("-#{float}".rjust(24))
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
@@ -0,0 +1,320 @@
1
+ require 'spec_helper'
2
+ require 'hexdump/numeric/hexadecimal'
3
+ require 'hexdump/type'
4
+
5
+ describe Hexdump::Numeric::Hexadecimal do
6
+ describe "#initialize" do
7
+ subject { described_class.new(type) }
8
+
9
+ context "when given a Type::Int type" do
10
+ context "and size is 1" do
11
+ let(:type) { Hexdump::Type::Int8.new }
12
+
13
+ it "must set #width to 2 + 1" do
14
+ expect(subject.width).to eq(2 + 1)
15
+ end
16
+ end
17
+
18
+ context "and size is 2" do
19
+ let(:type) { Hexdump::Type::Int16.new }
20
+
21
+ it "must set #width to 4 + 1" do
22
+ expect(subject.width).to eq(4 + 1)
23
+ end
24
+ end
25
+
26
+ context "and size is 4" do
27
+ let(:type) { Hexdump::Type::Int32.new }
28
+
29
+ it "must set #width to 8 + 1" do
30
+ expect(subject.width).to eq(8 + 1)
31
+ end
32
+ end
33
+
34
+ context "and size is 8" do
35
+ let(:type) { Hexdump::Type::Int64.new }
36
+
37
+ it "must set #width to 16 + 1" do
38
+ expect(subject.width).to eq(16 + 1)
39
+ end
40
+ end
41
+
42
+ context "and it has an unsupported size" do
43
+ class UnsupportedIntType < Hexdump::Type::Int
44
+
45
+ def initialize
46
+ super(size: 3)
47
+ end
48
+
49
+ end
50
+
51
+ let(:type) { UnsupportedIntType.new }
52
+
53
+ it do
54
+ expect {
55
+ described_class.new(type)
56
+ }.to raise_error(NotImplementedError)
57
+ end
58
+ end
59
+ end
60
+
61
+ context "when given a Type::UInt type" do
62
+ context "and size is 1" do
63
+ let(:type) { Hexdump::Type::UInt8.new }
64
+
65
+ it "must set #width to 2" do
66
+ expect(subject.width).to eq(2)
67
+ end
68
+ end
69
+
70
+ context "and size is 2" do
71
+ let(:type) { Hexdump::Type::UInt16.new }
72
+
73
+ it "must set #width to 4" do
74
+ expect(subject.width).to eq(4)
75
+ end
76
+ end
77
+
78
+ context "and size is 4" do
79
+ let(:type) { Hexdump::Type::UInt32.new }
80
+
81
+ it "must set #width to 8" do
82
+ expect(subject.width).to eq(8)
83
+ end
84
+ end
85
+
86
+ context "and size is 8" do
87
+ let(:type) { Hexdump::Type::UInt64.new }
88
+
89
+ it "must set #width to 16" do
90
+ expect(subject.width).to eq(16)
91
+ end
92
+ end
93
+
94
+ context "and it has an unsupported size" do
95
+ class UnsupportedUIntType < Hexdump::Type::UInt
96
+
97
+ def initialize
98
+ super(size: 3)
99
+ end
100
+
101
+ end
102
+
103
+ let(:type) { UnsupportedUIntType.new }
104
+
105
+ it do
106
+ expect {
107
+ described_class.new(type)
108
+ }.to raise_error(NotImplementedError)
109
+ end
110
+ end
111
+ end
112
+
113
+ context "when given a Type::Float type" do
114
+ context "and the type size is 4" do
115
+ let(:type) { Hexdump::Type::Float32.new }
116
+
117
+ it "must set #width to 20 + 1" do
118
+ begin
119
+ expect(subject.width).to eq(20 + 1)
120
+ rescue NotImplementedError => error
121
+ skip error.message
122
+ end
123
+ end
124
+ end
125
+
126
+ context "and the type size is 8" do
127
+ let(:type) { Hexdump::Type::Float64.new }
128
+
129
+ it "must set #width to 20 + 1" do
130
+ begin
131
+ expect(subject.width).to eq(20 + 1)
132
+ rescue NotImplementedError => error
133
+ skip error.message
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "#%" do
141
+ subject { described_class.new(type) }
142
+
143
+ context "when the given type is a Type::UInt" do
144
+ context "and the type's size is 1" do
145
+ let(:type) { Hexdump::Type::UInt8.new }
146
+
147
+ let(:value) { 0xf }
148
+ let(:hex) { '0f' }
149
+
150
+ it "must return a hexadecimal string of length 2" do
151
+ expect(subject % value).to eq(hex)
152
+ end
153
+ end
154
+
155
+ context "when the given type has size 2" do
156
+ let(:type) { Hexdump::Type::UInt16.new }
157
+
158
+ let(:value) { 0xff }
159
+ let(:hex) { '00ff' }
160
+
161
+ it "must return a left-padded decimal string of length 4" do
162
+ expect(subject % value).to eq(hex)
163
+ end
164
+ end
165
+
166
+ context "when the given type has size 4" do
167
+ let(:type) { Hexdump::Type::UInt32.new }
168
+
169
+ let(:value) { 0xffff }
170
+ let(:hex) { '0000ffff' }
171
+
172
+ it "must return a left-padded decimal string of length 8" do
173
+ expect(subject % value).to eq(hex)
174
+ end
175
+ end
176
+
177
+ context "when the given type has size 8" do
178
+ let(:type) { Hexdump::Type::UInt64.new }
179
+
180
+ let(:value) { 0xffffffff }
181
+ let(:hex) { '00000000ffffffff' }
182
+
183
+ it "must return a hexadecimal string of length 16" do
184
+ expect(subject % value).to eq(hex)
185
+ end
186
+ end
187
+ end
188
+
189
+ context "when the given type is a Type::Int" do
190
+ context "and the type's size is 1" do
191
+ let(:type) { Hexdump::Type::Int8.new }
192
+
193
+ let(:value) { 0xf }
194
+ let(:hex) { '0f' }
195
+
196
+ context "and the value is positive" do
197
+ it "must return a hexadecimal string prefixed with a ' '" do
198
+ expect(subject % value).to eq(" #{hex}")
199
+ end
200
+ end
201
+
202
+ context "and the value is negative" do
203
+ it "must return a hexadecimal string prefixed with a '-'" do
204
+ expect(subject % -value).to eq("-#{hex}")
205
+ end
206
+ end
207
+ end
208
+
209
+ context "and the given type has size 2" do
210
+ let(:type) { Hexdump::Type::Int16.new }
211
+
212
+ let(:value) { 0xff }
213
+ let(:hex) { '00ff' }
214
+
215
+ context "and the value is positive" do
216
+ it "must return a hexadecimal string prefixed with a ' '" do
217
+ expect(subject % value).to eq(" #{hex}")
218
+ end
219
+ end
220
+
221
+ context "and the value is negative" do
222
+ it "must return a hexadecimal string prefixed with a '-'" do
223
+ expect(subject % -value).to eq("-#{hex}")
224
+ end
225
+ end
226
+ end
227
+
228
+ context "and the given type has size 4" do
229
+ let(:type) { Hexdump::Type::Int32.new }
230
+
231
+ let(:value) { 0xffff }
232
+ let(:hex) { '0000ffff' }
233
+
234
+ context "and the value is positive" do
235
+ it "must return a hexadecimal string of prefixed with a ' '" do
236
+ expect(subject % value).to eq(" #{hex}")
237
+ end
238
+ end
239
+
240
+ context "and the value is negative" do
241
+ it "must return a hexadecimal string prefixed with a '-'" do
242
+ expect(subject % -value).to eq("-#{hex}")
243
+ end
244
+ end
245
+ end
246
+
247
+ context "and the given type has size 8" do
248
+ let(:type) { Hexdump::Type::Int64.new }
249
+
250
+ let(:value) { 0xffffffff }
251
+ let(:hex) { '00000000ffffffff' }
252
+
253
+ context "and the value is positive" do
254
+ it "must return a hexadecimal string of length 64 prefixed with a ' '" do
255
+ expect(subject % value).to eq(" #{hex}")
256
+ end
257
+ end
258
+
259
+ context "and the value is negative" do
260
+ it "must return a hexadecimal string of length 64 prefixed with a '-'" do
261
+ expect(subject % -value).to eq("-#{hex}")
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ context "when the given type is a Type::Float" do
268
+ let(:value) { 1.234567899 }
269
+ let(:hex) { '0x1.3c0ca44ee57c8p+0' }
270
+
271
+ context "when the given type has size 4" do
272
+ let(:type) { Hexdump::Type::Float32.new }
273
+
274
+ context "and the value is positive" do
275
+ it "must return a hexadecimal string of length 20 prefixed with a ' '" do
276
+ begin
277
+ expect(subject % value).to eq(" #{hex}")
278
+ rescue NotImplementedError => error
279
+ skip error.message
280
+ end
281
+ end
282
+ end
283
+
284
+ context "and the value is negative" do
285
+ it "must return a hexadecimal string of length 20 prefixed with a '-'" do
286
+ begin
287
+ expect(subject % -value).to eq("-#{hex}")
288
+ rescue NotImplementedError => error
289
+ skip error.message
290
+ end
291
+ end
292
+ end
293
+ end
294
+
295
+ context "when the given type has size 8" do
296
+ let(:type) { Hexdump::Type::Float64.new }
297
+
298
+ context "and the value is positive" do
299
+ it "must return a hexadecimal string of length 20 prefixed with a ' '" do
300
+ begin
301
+ expect(subject % value).to eq(" #{hex}")
302
+ rescue NotImplementedError => error
303
+ skip error.message
304
+ end
305
+ end
306
+ end
307
+
308
+ context "and the value is negative" do
309
+ it "must return a hexadecimal string of length 20 prefixed with a '-'" do
310
+ begin
311
+ expect(subject % -value).to eq("-#{hex}")
312
+ rescue NotImplementedError => error
313
+ skip error.message
314
+ end
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end
320
+ end