[Chicago-talk] Parsing a Hex file

Steven Lembark lembark at wrkhors.com
Sun Jan 21 14:31:58 PST 2007


Andrew Rodland wrote:
> 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";
> }

Another approach for fairly small files is to break the
whole thing up into bytes and re-combine them as needed
into ingeters:

  my $row = 0;

  my @bytz
  = do
  {
    local $/;

    unpack 'A*', <ARGV>
  };

  while( @bytz )
  {
    # discard the two-bytes of rowid in favor of a
    # counter, read the size to decide how much more
    # data to read.

    my( undef, undef, $size ) = splice @bytz, 0, 3;

    die "bad value: too large" unless @bytz >= $size;

    my @valz = splice $bytz, 0, $size;

    # combine the values into some output

    ...

    print ++$row, , "\t", $output, "\n";
  }


-- 
Steven Lembark                                         85-09 90th Street
Workhorse Computing                                  Woodhaven, NY 11421
lembark at wrkhors.com                                      +1 888 359 3508


More information about the Chicago-talk mailing list