File: HexDump.pm

package info (click to toggle)
libdata-hexdump-perl 0.04-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 124 kB
  • sloc: perl: 165; makefile: 2
file content (281 lines) | stat: -rw-r--r-- 7,350 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
84
85
86
87
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# -*- mode: Perl -*-

##########################################################################
#
#   HexDump.pm  -  Hexadecial Dumper
#
# Copyright (c) 1998, 1999, Fabien Tassin <fta@oleane.net>
##########################################################################
# ABSOLUTELY NO WARRANTY WITH THIS PACKAGE. USE IT AT YOUR OWN RISKS.
##########################################################################

package Data::HexDump;
$Data::HexDump::VERSION = '0.04';
use 5.006;
use strict;
use warnings;

use parent 'Exporter';
use Carp;
use FileHandle;

our @EXPORT = qw( HexDump );

sub new {
  my $this = shift;
  my $class = ref($this) || $this;
  my $self = {};
  bless $self, $class;
  $self->{'readsize'} = 128;
  return $self;
}

sub DESTROY {
  my $self = shift;
  $self->{'fh'}->close if defined $self->{'file'};
}

sub file {
  my $self = shift;
  my $file = shift;
  $self->{'file'} = $file if defined $file;
  $self->{'file'};
}

sub fh {
  my $self = shift;
  my $fh = shift;
  $self->{'fh'} = $fh if defined $fh;
  $self->{'fh'};
}

sub data {
  my $self = shift;
  my $data = shift;
  $self->{'data'} = $data if defined $data;
  $self->{'data'};
}

sub block_size {
  my $self = shift;
  my $bs = shift;
  $self->{'blocksize'} = $bs if defined $bs;
  $self->{'blocksize'};
}

sub dump {
  my $self = shift;

  my $out;
  my $l;
  $self->{'i'} = 0 unless defined $self->{'i'};
  $self->{'j'} = 0 unless defined $self->{'j'};
  my $i = $self->{'i'};
  my $j = $self->{'j'};
  unless ($i || $j) {
    $out = "          ";
    $l = "";
    for (my $i = 0; $i < 16; $i++) {
      $out .= sprintf "%02X", $i;
      $out .= " " if $i < 15;
      $out .= "- " if $i == 7;
      $l .= sprintf "%X", $i;
    }
    $i = $j = 0;
    $out .= "  $l\n\n";
  }
  return undef if $self->{'eod'};
  $out .= sprintf "%08X  ", $j * 16;
  $l = "";
  my $val;
  while (($val = $self->get) ne '') {
    while (length $val && defined (my $v = substr $val, 0, 1, '')) {
      $out .= sprintf "%02X", ord $v;
      $out .= " " if $i < 15;
      $out .= "- " if $i == 7 &&
                      (length $val || !($self->{'eod'} || length $val));
      $i++;
      $l .= ord($v) >= 0x20 && ord($v) <= 0x7E ? $v : ".";
      if ($i == 16) {
        $i = 0;
        $j++;
        $out .= "  " . $l;
        $l = "";
        $out .= "\n";
        if (defined $self->{'blocksize'} && $self->{'blocksize'} &&
                    ($j - $self->{'j'}) > $self->{'blocksize'} / 16) {
          $self->{'i'} = $i;
          $self->{'j'} = $j;
          $self->{'val'} = $val;
          return $out;
        }
        $out .= sprintf "%08X  ", $j * 16 if length $val || !length $val &&
                                             !$self->{'eod'};
      }
    }
  }
  if ($i || (!$i && !$j)) {
    $out .= " " x (3 * (17 - $i) - 2 * ($i > 8));
    $out .= "$l\n";
  }
  $self->{'i'} = $i;
  $self->{'j'} = $j;
  $self->{'val'} = $val;
  return $out;
}

# get data from different sources (scalar, filehandle, file..)
sub get {
  my $self = shift;

  my $buf;
  my $length = $self->{'readsize'};
  undef $self->{'val'} if defined $self->{'val'} && ! length $self->{'val'};
  if (defined $self->{'val'}) {
    $buf = $self->{'val'};
    undef $self->{'val'};
  }
  elsif (defined $self->{'data'}) {
    $self->{'data_offs'} = 0 unless defined $self->{'data_offs'};
    my $offset = $self->{'data_offs'};
    $buf = substr $self->{'data'}, $offset, $length;
    $self->{'data_offs'} += length $buf;
    $self->{'eod'} = 1 if $self->{'data_offs'} == length $self->{'data'};
  }
  elsif (defined $self->{'fh'}) {
    read $self->{'fh'}, $buf, $length;
    $self->{'eod'} = eof $self->{'fh'};
  }
  elsif (defined $self->{'file'}) {
    $self->{'fh'} = FileHandle->new($self->{'file'});
    read $self->{'fh'}, $buf, $length;
    $self->{'eod'} = eof $self->{'fh'};
  }
  else {
    print "Not yet implemented\n";
  }
  $buf;
}

sub HexDump ($) {
  my $val = shift;

  my $f = Data::HexDump->new();
  $f->data($val);
  $f->dump;
}

1;

=head1 NAME

Data::HexDump - Hexadecial Dumper

=head1 SYNOPSIS

Functional interface:

  use Data::HexDump;
  print HexDump($data_string);

OO interface:

  use Data::HexDump;
  my $dumper = Data::HexDump->new();
  print while $_ = $dumper->dump;

=head1 DESCRIPTION

This module will generate a hexadecimal dump of a data string or file.
You can either use the exported function,
as shown in the SYNOPSIS above,
or the OO interface, described below.

The second example from the SYNOPSIS generated this output:

           00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF

 00000000  23 21 2F 75 73 72 2F 62 - 69 6E 2F 70 65 72 6C 0A  #!/usr/bin/perl.
 00000010  75 73 65 20 73 74 72 69 - 63 74 3B 0A 75 73 65 20  use strict;.use
 00000020  77 61 72 6E 69 6E 67 73 - 3B 0A 0A 70 72 69 6E 74  warnings;..print
 00000030  20 22 48 65 6C 6C 6F 2C - 20 77 6F 72 6C 64 5C 6E   "Hello, world\n
 00000040  22 3B 0A                                           ";.

The result is returned in a string.
Each line of the result consists of the offset in the
source in the leftmost column of each line,
followed by one or more columns of data from the source in hexadecimal.
The rightmost column of each line shows the printable characters
(all others are shown as single dots).

=head2 Functional Interface

This module exports a single function, C<HexDump>,
which takes a scalar value and returns a string which
contains the hexdump of the passed data.


=head2 OO Interface

You first construct a C<Data::HexDump> object,
then tell it where to get the data from,
and then generate the hex dump:

    my $dh = Data::HexDump->new();

    $dh->data($scalar);      # dump the data in this scalar
    $dh->fh($fh);            # read this filehandle
    $dh->file($filename);    # read this file and dump contents

    print while $_ = $dh->dump;

The different potential sources for data are considered
in the order given above,
so if you pass to the C<data> method,
then any subsequent calls to C<fh()> or C<file()>
will have no effect.

=head1 SEE ALSO

L<Data::Hexify>, by Johan Vromans, is another simple option,
similar to this module. Last release in 2004.

L<Data::Hexdumper> (by David Cantrell, DCANTRELL)
is another hex dumper,
with more features than this module.

L<App::colourhexdump> (by Kent Fredric, RIP)
provides a script which gives colourised output
with character class highlighting.

L<Data::HexDump::Range> provides more functions, colour output,
and the ability to skip uninteresting parts of the input data.

L<Data::HexDump::XXD> provides hex dumps like xxd.
It doesn't say what xxd is, or provide a link,
and there's no example output.
But if you know and like xxd, this might be the one for you!

L<Devel::Hexdump> provides some configuration options,
but there are other more featured modules,
and this one doesn't have example output in the doc.

L<Data::Peek> is a collection of functions for displaying data,
including C<DHexDump> which generates a simple hex dump
from a string.

L<String::HexConvert> will convert ASCII strings to hex and reverse.


=head1 AUTHOR

Fabien Tassin E<lt>fta@oleane.netE<gt>


=head1 COPYRIGHT

Copyright (c) 1998-1999 Fabien Tassin. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut