$packed = join "", map { chr() } (0x01..0x20); $plen = length( $packed ); $tmpl = "a" . $plen; print "unpacking $plen bytes using (a): "; $unpacked = unpack( $tmpl, $packed ); $result = ( $packed eq $unpacked ) ? "same" : "different"; print "$result\n";' #### my $iIcao = "???"; my $AtrFile = "some_file_name"; open( my $atrfh, $AtrFile ) or die "$AtrFile: $!"; binmode $atrfh; my $base_readsize = 8; my $base_block; if (( read $atrfh, $base_block, $base_readsize ) != $base_readsize ) { die "$AtrFile: read failed on first $base_readsize bytes: $!"; } my ($Cksum, $NxIdx) = unpack( 'II', $base_block ); my $offset = $base_readsize; my ( $lastrec, $bytecount ) = parse_records( $atrfh, $offset, "debug" ); # parse_records will die if there are problems with the file data print "$AtrFile: $lastrec records, $bytecount bytes read okay\n"; # Now that AtrFile has passed the sanity checks, start print to Type09File; # Just rewind $atrfh to the first LBL record and repeat the read loop print Type09File "$iIcao Set_Header: $Cksum, $NxIdx\n"; seek $atrfh, $base_readsize, 0; parse_records( $atrfh, $offset, "print" ); close( $atrfh ); sub parse_records { my ( $rfh, $offset, $mode ) = @_; my $lbl_readsize = 20; my ( $lbl_block, $num_block ); my $bytes_read; my $recid = 0; my $lbltmpl = 'i i b8 b16 b8 i C'; while (( $bytes_read = read $rfh, $lbl_block, $lbl_readsize ) == $lbl_readsize ) { $recid++; $offset += $lbl_readsize; my ( $NumLbl, $LblKnd, $ZmLvl, $FntSz, $res, $Lngth, $Ornt ) = unpack( $lbltmpl, $lbl_block ); if (( read $rfh, $num_block, $Lngth ) != $Lngth ) { die "$AtrFile: can't read $Lngth bytes at rec# $recid (offs: $offset): $!"; } # the following assumes that there is an open file handle # called "Type09File" -- might be better to make this a # "my" variable and pass it as an arg... if ( $mode eq 'print' ) { print Type09File "Label_Header: " . join( ", ", $NumLbl, $LblKnd, $ZmLvl, $FntSz, $res, $Lngth, $Ornt, "$num_block\n" ); } } if ( $bytes_read > 0 ) { die "$AtrFile: got $bytes_read bytes, not $lbl_readsize ". "after rec# $recid (offs: $offset)\n"; } elsif ( $bytes_read < 0 ) { die "$AtrFile: read error ($bytes_read) after rec# $recid (offs: $offset)\n"; } return ( $recid, $offset ); }