File Coverage

lib/Archive/Lha/Header/Level0.pm
Criterion Covered Total %
statement 18 52 34.6
branch 0 12 0.0
condition n/a
subroutine 6 7 85.7
pod 1 1 100.0
total 25 72 34.7


line stmt bran cond sub pod time code
1             package Archive::Lha::Header::Level0;
2              
3 17     17   113 use strict;
  17         34  
  17         664  
4 17     17   76 use warnings;
  17         43  
  17         808  
5 17     17   85 use Carp;
  17         53  
  17         1019  
6 17     17   7376 use Archive::Lha::Constants;
  17         51  
  17         129  
7 17     17   8959 use Archive::Lha::Header::Base;
  17         45  
  17         139  
8 17     17   10182 use Archive::Lha::Header::Utils;
  17         49  
  17         162  
9              
10             sub new {
11 0     0 1   my ($class, $stream) = @_;
12              
13 0           my $start = $stream->tell;
14 0           my $size = ord($stream->read(1)) + 2;
15              
16 0 0         croak "Header is broken: size is too small: $size" if $size < 24;
17              
18 0           $stream->seek($start);
19 0           my $buf = $stream->read($size);
20              
21 0           my $checksum = ord(substr($buf, 1, 1));
22             my $checksum1 = defined &Archive::Lha::Header::Utils::checksum
23             ? Archive::Lha::Header::Utils::checksum($buf, 2)
24 0 0         : do { my $s = 0; $s += $_ for unpack 'C*', substr($buf, 2); $s & CHAR_MAX };
  0            
  0            
  0            
25 0 0         croak "Header is broken: pos:$start checksum $checksum/$checksum1"
26             unless $checksum == $checksum1;
27              
28 0           my %header;
29 0           $header{header_top} = $start;
30 0           $header{header_size} = $size;
31 0           $header{header_checksum} = $checksum;
32 0           $header{method} = substr($buf, 3, 3);
33 0           $header{encoded_size} = unpack 'V', substr($buf, 7, 4);
34 0           $header{original_size} = unpack 'V', substr($buf, 11, 4);
35 0           $header{timestamp} = unpack 'V', substr($buf, 15, 4);
36              
37 0           my $pathname_length = ord(substr($buf, 21, 1));
38 0           $header{pathname} = substr($buf, 22, $pathname_length);
39 0 0         if ($header{pathname} =~ s/\0(.+)//s) {
40 0           $header{comment} = $1;
41             }
42 0           $header{crc16} = unpack 'v', substr($buf, 22 + $pathname_length, 2);
43              
44 0           my $ext_from = 24 + $pathname_length;
45 0 0         if ($ext_from < $size) {
46 0           my (undef, $ext) = _extended_header_buf($buf, $ext_from, $size - $ext_from);
47 0 0         %header = (%header, %{ $ext }) if %{ $ext };
  0            
  0            
48             }
49              
50 0           $header{data_top} = $start + $size;
51 0           $header{next_header} = $header{data_top} + $header{encoded_size};
52              
53 0           bless \%header, $class;
54             }
55              
56             1;
57              
58             __END__