[Chicago-talk] Parsing a Hex file
Andrew Rodland
arodland at comcast.net
Sat Jan 20 03:40:26 PST 2007
On Friday 19 January 2007 3:41 pm, Pete Krawczyk wrote:
> unpack doesn't do the looping you want, as far as I'm aware. However, I'm
> pretty sure the following loop will do what you're looking for:
>
> while (length($file_contents)) {
> my ($field_num, $value) = unpack("SC/A", $file_contents);
> # something with $field_num and $value
> my $len = length($value);
> $file_contents = substr($file_contents,$len+3);
> }
>
> Of course, I'm using "C" to mean "8-bit integer", but I don't know any
> more elegant way to do that.
Unpack does do the looping, although you still have to do a little processing
on it afterwards until Perl6 shows up
# Jay's example input field, repeated 3x
my $input = "\x94\x00\x0b\x4a\x41\x59\x27\x53\x20\x46\x4f\x4f\x44\x53" x 3;
my @data = unpack("(SC/A)*", $input); # produce a key/value list
for (my $i = 0 ; $i < $#data ; $i += 2) { # and print out by pairs
print "$data[$i]:\t$data[$i+1]\n";
}
print ".\n";
=== will output ===
148: JAY'S FOODS
148: JAY'S FOODS
148: JAY'S FOODS
.
though if you weren't concerned of the order that the fields came in, there
_is_ one place where perl expects a list of alternating keys and values, and
that's in the assignment of a hash from a list.
%hash = unpack("SC/A", $etc);
will work if you don't care about order and can't have any dupes. You could
also use a for loop or a thoroughly evil map to turn (148, "JAY'S FOODS",
148, "JAY'S FOODS", 148, "JAY'S FOODS") into ([148, "JAY'S FOODS"],
[148, "JAY'S FOODS"], [148, "JAY'S FOODS]) which is slightly more convenient.
Hope I've put some good ideas into your head :)
Andrew
More information about the Chicago-talk
mailing list