Class: Nxxd::Dump

Inherits:
Object
  • Object
show all
Includes:
ReadChunks
Defined in:
lib/nxxd.rb

Constant Summary collapse

LINE_SIZE =
16
ADDR_FMT =
"%%0%dx:"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(full: nil, upper: false, line_size: nil, addr_len: nil, input: nil) ⇒ Dump

Returns a new instance of Dump.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/nxxd.rb', line 41

def initialize full: nil, upper: false, line_size: nil, addr_len: nil, input: nil
  @full = full
  @input = input
  @line_size = line_size||LINE_SIZE
  @addr_fmt = ADDR_FMT % (addr_len||8)
  @nib_fmt = "%02x"
  if upper then
    @addr_fmt.upcase!
    @nib_fmt.upcase!
  end
end

Class Method Details

.reverse(input, output = nil, consecutive: nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/nxxd.rb', line 88

def reverse input, output = nil, consecutive: nil
  output ||= ""
  o = String === output ? (WriteChunksString.new output) : output
  o.set_encoding Encoding::ASCII_8BIT
  r, repeat = nil, false
  input.each_line { |l|
    l.chomp!
    case l
    when /^\s*(?:#|$)/ then
      nil
    when /^\*/ then
      consecutive and
        raise "Addressless undump doesn't allow repeat specifications."
      repeat = true
    when /^(?:(\h+):)?\s*((?:\h\h ?)*)/ then
      addr, nibs = $~.captures
      if !consecutive && addr then
        addr = $1.to_i 0x10
        if repeat then
          loop do
            s = addr - o.tell
            break if s <= 0
            o.write s >= r.length ? r : r[ 0, s]
          end
          repeat = false
        end
        o.seek addr
      end
      r = (nibs.scan /\h\h/).map { |x| x.to_i 0x10 }.pack "C*"
      o.write r
    else
      raise "Uninterpretable hex dump: #{l.chomp}"
    end
  }
  output
end

Instance Method Details

#run(input) {|"# #@input"| ... } ⇒ Object

Yields:

  • ("# #@input")


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/nxxd.rb', line 53

def run input
  block_given? or return [].tap { |r| run input do |l| r.push l end }
  addr = 0
  prev, repeat = nil, false
  yield "# #@input" if @input
  read_chunks input do |b|
    if b == prev and not @full then
      unless repeat then
        yield "*"
        repeat = true
      end
    else
      r = @addr_fmt % addr
      r << " "
      h =  b.unpack "C*"
      sp = false
      @line_size.times {
        x = h.shift
        r << (x ? @nib_fmt % x : "  ")
        r << " " if sp
        sp = !sp
      }
      r << " " << (b.gsub /[^ -~]/, ".")
      yield r
      prev, repeat = b, false
    end
    addr += b.size
  end
  yield @addr_fmt % addr
  nil
end