hexdump 0.3.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +5 -6
  3. data/.gitignore +1 -0
  4. data/.yardopts +1 -1
  5. data/ChangeLog.md +79 -6
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +1 -1
  8. data/README.md +500 -137
  9. data/benchmark.rb +29 -22
  10. data/gemspec.yml +2 -1
  11. data/hexdump.gemspec +1 -4
  12. data/lib/hexdump/chars.rb +46 -0
  13. data/lib/hexdump/core_ext/file.rb +68 -6
  14. data/lib/hexdump/core_ext/io.rb +2 -2
  15. data/lib/hexdump/core_ext/kernel.rb +5 -0
  16. data/lib/hexdump/core_ext/string.rb +2 -2
  17. data/lib/hexdump/core_ext/string_io.rb +2 -2
  18. data/lib/hexdump/core_ext.rb +5 -4
  19. data/lib/hexdump/format_string.rb +43 -0
  20. data/lib/hexdump/hexdump.rb +766 -75
  21. data/lib/hexdump/mixin.rb +192 -0
  22. data/lib/hexdump/module_methods.rb +132 -0
  23. data/lib/hexdump/numeric/binary.rb +55 -0
  24. data/lib/hexdump/numeric/char_or_int.rb +95 -0
  25. data/lib/hexdump/numeric/decimal.rb +56 -0
  26. data/lib/hexdump/numeric/exceptions.rb +11 -0
  27. data/lib/hexdump/numeric/hexadecimal.rb +59 -0
  28. data/lib/hexdump/numeric/octal.rb +55 -0
  29. data/lib/hexdump/numeric.rb +5 -0
  30. data/lib/hexdump/reader.rb +313 -0
  31. data/lib/hexdump/theme/ansi.rb +82 -0
  32. data/lib/hexdump/theme/rule.rb +159 -0
  33. data/lib/hexdump/theme.rb +61 -0
  34. data/lib/hexdump/type.rb +233 -0
  35. data/lib/hexdump/types.rb +108 -0
  36. data/lib/hexdump/version.rb +1 -1
  37. data/lib/hexdump.rb +14 -3
  38. data/spec/chars_spec.rb +76 -0
  39. data/spec/core_ext_spec.rb +10 -6
  40. data/spec/format_string_spec.rb +22 -0
  41. data/spec/hexdump_class_spec.rb +1708 -0
  42. data/spec/hexdump_module_spec.rb +23 -0
  43. data/spec/mixin_spec.rb +37 -0
  44. data/spec/numeric/binary_spec.rb +239 -0
  45. data/spec/numeric/char_or_int_spec.rb +210 -0
  46. data/spec/numeric/decimal_spec.rb +317 -0
  47. data/spec/numeric/hexadecimal_spec.rb +320 -0
  48. data/spec/numeric/octal_spec.rb +239 -0
  49. data/spec/reader_spec.rb +866 -0
  50. data/spec/spec_helper.rb +2 -0
  51. data/spec/theme/ansi_spec.rb +242 -0
  52. data/spec/theme/rule_spec.rb +199 -0
  53. data/spec/theme_spec.rb +94 -0
  54. data/spec/type_spec.rb +317 -0
  55. data/spec/types_spec.rb +904 -0
  56. metadata +42 -12
  57. data/.gemtest +0 -0
  58. data/lib/hexdump/dumper.rb +0 -419
  59. data/lib/hexdump/extensions.rb +0 -2
  60. data/spec/dumper_spec.rb +0 -329
  61. data/spec/hexdump_spec.rb +0 -30
data/benchmark.rb CHANGED
@@ -5,43 +5,50 @@ $LOAD_PATH.unshift(File.expand_path('../lib',__FILE__))
5
5
  require 'hexdump'
6
6
  require 'benchmark'
7
7
 
8
- DATA = ((0..255).map { |b| b.chr }.join) * (1024 * 100)
9
- OUTPUT = Class.new { def <<(data); end }.new
8
+ class NullOutput
9
+ def <<(data)
10
+ end
11
+ end
12
+
13
+ size_mb = 1
14
+ puts "Generating #{size_mb}Mb of random data ..."
15
+ data = Array.new(size_mb * 1024 * 1024) { rand(255).chr }.join
16
+ output = NullOutput.new
10
17
 
11
- Benchmark.bm(33) do |b|
12
- b.report('Hexdump.dump (output)') do
13
- Hexdump.dump(DATA, :output => OUTPUT)
18
+ types = Hexdump::TYPES.values.uniq.map(&Hexdump::TYPES.method(:key))
19
+
20
+ Benchmark.bm(42) do |b|
21
+ b.report('Hexdump.hexdump(data)') do
22
+ Hexdump.hexdump(data, output: output)
14
23
  end
15
24
 
16
- b.report('Hexdump.dump width=256 (output)') do
17
- Hexdump.dump(DATA, width: 256, output: OUTPUT)
25
+ b.report("Hexdump.hexdump(data, repeating: false)") do
26
+ Hexdump.hexdump(data, repeating: false, output: output)
18
27
  end
19
28
 
20
- b.report('Hexdump.dump ascii=true (output)') do
21
- Hexdump.dump(DATA, ascii: true, output: OUTPUT)
29
+ b.report("Hexdump.hexdump(data, chars_column: false)") do
30
+ Hexdump.hexdump(data, chars_column: false, output: output)
22
31
  end
23
32
 
24
- [2, 4, 8].each do |word_size|
25
- b.report("Hexdump.dump word_size=#{word_size} (output)") do
26
- Hexdump.dump(DATA, word_size: word_size, output: OUTPUT)
27
- end
33
+ b.report('Hexdump.hexdump(data, columns: 256)') do
34
+ Hexdump.hexdump(data, columns: 256, output: output)
28
35
  end
29
36
 
30
- b.report('Hexdump.dump (block)') do
31
- Hexdump.dump(DATA) { |index,hex,print| }
37
+ b.report('Hexdump.hexdump(data, group_columns: 4)') do
38
+ Hexdump.hexdump(data, group_columns: 4, output: output)
32
39
  end
33
40
 
34
- b.report('Hexdump.dump width=256 (block)') do
35
- Hexdump.dump(DATA, width: 256) { |index,hex,print| }
41
+ b.report('Hexdump.hexdump(data, group_chars: 4)') do
42
+ Hexdump.hexdump(data, group_chars: 4, output: output)
36
43
  end
37
44
 
38
- b.report('Hexdump.dump ascii=true (block)') do
39
- Hexdump.dump(DATA, ascii: true) { |index,hex,print| }
45
+ b.report('Hexdump.hexdump(data, encoding: :utf8)') do
46
+ Hexdump.hexdump(data, encoding: :utf8, output: output)
40
47
  end
41
48
 
42
- [2, 4, 8].each do |word_size|
43
- b.report("Hexdump.dump word_size=#{word_size} (block)") do
44
- Hexdump.dump(DATA, word_size: word_size) { |index,hex,print| }
49
+ types.each do |type|
50
+ b.report("Hexdump.hexdump(data, type: #{type.inspect})") do
51
+ Hexdump.hexdump(data, type: type, output: output)
45
52
  end
46
53
  end
47
54
  end
data/gemspec.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  name: hexdump
2
2
  summary: Hexdump Strings and IO objects.
3
- description: Simple and Fast hexdumping for Ruby.
3
+ description: Fully Featured and Fast hexdumping for Ruby.
4
4
  license: MIT
5
5
  authors: Postmodern
6
6
  email: postmodern.mod3@gmail.com
@@ -12,6 +12,7 @@ metadata:
12
12
  source_code_uri: https://github.com/postmodern/hexdump.rb
13
13
  bug_tracker_uri: https://github.com/postmodern/hexdump.rb/issues
14
14
  changelog_uri: https://github.com/postmodern/hexdump.rb/blob/master/ChangeLog.md
15
+ rubygems_mfa_required: 'true'
15
16
 
16
17
  required_ruby_version: ">= 2.0.0"
17
18
 
data/hexdump.gemspec CHANGED
@@ -7,10 +7,7 @@ Gem::Specification.new do |gem|
7
7
 
8
8
  gem.name = gemspec.fetch('name')
9
9
  gem.version = gemspec.fetch('version') do
10
- lib_dir = File.join(File.dirname(__FILE__),'lib')
11
- $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
12
-
13
- require 'hexdump/version'
10
+ require_relative 'lib/hexdump/version'
14
11
  Hexdump::VERSION
15
12
  end
16
13
 
@@ -0,0 +1,46 @@
1
+ module Hexdump
2
+ #
3
+ # @api private
4
+ #
5
+ # @since 1.0.0
6
+ #
7
+ class Chars
8
+
9
+ # The encoding to convert the characters to.
10
+ #
11
+ # @return [Encoding, nil]
12
+ attr_reader :encoding
13
+
14
+ #
15
+ # Initializes the chars formatter.
16
+ #
17
+ # @param [Encoding, nil] encoding
18
+ # The encoding to convert characters to.
19
+ #
20
+ def initialize(encoding=nil)
21
+ @encoding = encoding
22
+ end
23
+
24
+ #
25
+ # Formats a string of characters.
26
+ #
27
+ # @param [String] chars
28
+ # The input string of raw characters.
29
+ #
30
+ # @return [String]
31
+ # The formatted string of raw characters.
32
+ #
33
+ def scrub(chars)
34
+ if @encoding
35
+ chars.force_encoding(@encoding)
36
+ chars.scrub!('.')
37
+ chars.gsub!(/[^[:print:]]/u,'.')
38
+ else
39
+ chars.tr!("^\x20-\x7e",'.')
40
+ end
41
+
42
+ chars
43
+ end
44
+
45
+ end
46
+ end
@@ -1,4 +1,4 @@
1
- require 'hexdump/hexdump'
1
+ require_relative 'io'
2
2
 
3
3
  class File
4
4
 
@@ -8,14 +8,76 @@ class File
8
8
  # @param [String] path
9
9
  # The path of the file.
10
10
  #
11
- # @param [Hash] options
12
- # Additional options.
11
+ # @param [Hash{Symbol => Object}] kwargs
12
+ # Additional keyword arguments for {Hexdump::Hexdump#initialize}.
13
13
  #
14
- # @see Hexdump.dump
14
+ # @option kwargs [#print] :output ($stdout)
15
+ # The output to print the hexdump to.
15
16
  #
16
- def self.hexdump(path,options={},&block)
17
+ # @option kwargs [:int8, :uint8, :char, :uchar, :byte, :int16, :int16_le, :int16_be, :int16_ne, :uint16, :uint16_le, :uint16_be, :uint16_ne, :short, :short_le, :short_be, :short_ne, :ushort, :ushort_le, :ushort_be, :ushort_ne, :int32, :int32_le, :int32_be, :int32_ne, :uint32, :uint32_le, :uint32_be, :uint32_ne, :int, :long, :long_le, :long_be, :long_ne, :uint, :ulong, :ulong_le, :ulong_be, :ulong_ne, :int64, :int64_le, :int64_be, :int64_ne, :uint64, :uint64_le, :uint64_be, :uint64_ne, :long_long, :long_long_le, :long_long_be, :long_long_ne, :ulong_long, :ulong_long_le, :ulong_long_be, :ulong_long_ne, :float, :float_le, :float_be, :float_ne, :double, :double_le, :double_be, :double_ne] :type (:byte)
18
+ # The type to decode the data as.
19
+ #
20
+ # @option kwargs [Integer, nil] :offset
21
+ # Controls whether to skip N number of bytes before starting to read data.
22
+ #
23
+ # @option kwargs [Integer, nil] :length
24
+ # Controls control many bytes to read.
25
+ #
26
+ # @option kwargs [Boolean] :zero_pad (false)
27
+ # Enables or disables zero padding of data, so that the remaining bytes
28
+ # can be decoded as a uint, int, or float.
29
+ #
30
+ # @option kwargs [Integer] :columns (16)
31
+ # The number of bytes to dump for each line.
32
+ #
33
+ # @option kwargs [Integer, nil] :group_columns
34
+ # Separate groups of columns with an additional space.
35
+ #
36
+ # @option kwargs [Integer, :type, nil] :group_chars
37
+ # Group chars into columns.
38
+ # If `:type`, then the chars will be grouped by the `type`'s size.
39
+ #
40
+ # @option kwargs [Boolean] :repeating
41
+ # Controls whether to omit repeating duplicate rows data with a `*`.
42
+ #
43
+ # @option kwargs [16, 10, 8, 2] :base (16)
44
+ # The base to print bytes in.
45
+ #
46
+ # @option kwargs [16, 10, 8, 2] :index_base (16)
47
+ # Control the base that the index is displayed in.
48
+ #
49
+ # @option kwargs [Integer, nil] :index_offset
50
+ # The offset to start the index at.
51
+ #
52
+ # @option kwargs [Boolean] :chars_column (true)
53
+ # Controls whether to display the characters column.
54
+ #
55
+ # @option kwargs [:ascii, :utf8, Encoding, nil] :encoding
56
+ # The encoding to display the characters in.
57
+ #
58
+ # @option kwargs [Boolean, Hash{:index,:numeric,:chars => Symbol,Array<Symbol>}] :style
59
+ # Enables theming of index, numeric, or chars columns.
60
+ #
61
+ # @option kwargs [Boolean, Hash{:index,:numeric,:chars => Hash{String,Regexp => Symbol,Array<Symbol>}}] :highlights
62
+ # Enables selective highlighting of index, numeric, or chars columns.
63
+ #
64
+ # @yield [hexdump]
65
+ # If a block is given, it will be passed the newly initialized hexdump
66
+ # instance.
67
+ #
68
+ # @yieldparam [Hexdump::Hexdump] hexdump
69
+ # The newly initialized hexdump instance.
70
+ #
71
+ # @see IO#hexdump
72
+ #
73
+ # @example
74
+ # File.hexdump("/bin/ls")
75
+ # # 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
76
+ # # ...
77
+ #
78
+ def self.hexdump(path,**kwargs,&block)
17
79
  self.open(path,'rb') do |file|
18
- Hexdump.dump(file,options,&block)
80
+ file.hexdump(**kwargs,&block)
19
81
  end
20
82
  end
21
83
 
@@ -1,7 +1,7 @@
1
- require 'hexdump/hexdump'
1
+ require_relative '../mixin'
2
2
 
3
3
  class IO
4
4
 
5
- include Hexdump
5
+ include Hexdump::Mixin
6
6
 
7
7
  end
@@ -0,0 +1,5 @@
1
+ require_relative '../module_methods'
2
+
3
+ module Kernel
4
+ include Hexdump::ModuleMethods
5
+ end
@@ -1,7 +1,7 @@
1
- require 'hexdump/hexdump'
1
+ require_relative '../mixin'
2
2
 
3
3
  class String
4
4
 
5
- include Hexdump
5
+ include Hexdump::Mixin
6
6
 
7
7
  end
@@ -1,9 +1,9 @@
1
- require 'hexdump/hexdump'
1
+ require_relative '../mixin'
2
2
 
3
3
  require 'stringio'
4
4
 
5
5
  class StringIO
6
6
 
7
- include Hexdump
7
+ include Hexdump::Mixin
8
8
 
9
9
  end
@@ -1,4 +1,5 @@
1
- require 'hexdump/core_ext/string'
2
- require 'hexdump/core_ext/string_io'
3
- require 'hexdump/core_ext/io'
4
- require 'hexdump/core_ext/file'
1
+ require_relative 'core_ext/string'
2
+ require_relative 'core_ext/string_io'
3
+ require_relative 'core_ext/io'
4
+ require_relative 'core_ext/file'
5
+ require_relative 'core_ext/kernel'
@@ -0,0 +1,43 @@
1
+ module Hexdump
2
+ #
3
+ # @api private
4
+ #
5
+ # @since 1.0.0
6
+ #
7
+ class FormatString
8
+
9
+ #
10
+ # Initializes the format string.
11
+ #
12
+ # @param [String] fmt
13
+ # The format string.
14
+ #
15
+ def initialize(fmt)
16
+ @fmt = fmt
17
+ end
18
+
19
+ #
20
+ # Formats the given value.
21
+ #
22
+ # @param [Integer, Float] value
23
+ # The given value.
24
+ #
25
+ # @return [String]
26
+ # The formatted value.
27
+ #
28
+ def %(value)
29
+ sprintf(@fmt,value)
30
+ end
31
+
32
+ #
33
+ # Converts the format string back into a String.
34
+ #
35
+ # @return [String]
36
+ # The raw format string.
37
+ #
38
+ def to_s
39
+ @fmt
40
+ end
41
+
42
+ end
43
+ end