| Filename | /usr/lib/perl5/site_perl/5.14/Archive/Zip/ZipFileMember.pm | 
| Statements | Executed 739597 statements in 1.72s | 
| Calls | P | F | Exclusive Time | Inclusive Time | Subroutine | 
|---|---|---|---|---|---|
| 8601 | 1 | 1 | 404ms | 10.3s | Archive::Zip::ZipFileMember::rewindData | 
| 9982 | 1 | 1 | 371ms | 718ms | Archive::Zip::ZipFileMember::_readCentralDirectoryFileHeader | 
| 9982 | 2 | 1 | 325ms | 1.10s | Archive::Zip::ZipFileMember::_seekToLocalHeader | 
| 8601 | 1 | 1 | 300ms | 827ms | Archive::Zip::ZipFileMember::_skipLocalFileHeader | 
| 20174 | 2 | 1 | 145ms | 226ms | Archive::Zip::ZipFileMember::isDirectory | 
| 10349 | 1 | 1 | 127ms | 511ms | Archive::Zip::ZipFileMember::_readRawChunk | 
| 10192 | 1 | 1 | 112ms | 850ms | Archive::Zip::ZipFileMember::_newFromZipFile | 
| 1381 | 1 | 1 | 68.7ms | 1.09s | Archive::Zip::ZipFileMember::_become | 
| 1381 | 1 | 1 | 64.7ms | 162ms | Archive::Zip::ZipFileMember::_readLocalFileHeader | 
| 19964 | 3 | 1 | 45.0ms | 45.0ms | Archive::Zip::ZipFileMember::CORE:unpack (opcode) | 
| 9982 | 1 | 1 | 23.2ms | 23.2ms | Archive::Zip::ZipFileMember::localHeaderRelativeOffset | 
| 8601 | 1 | 1 | 19.8ms | 19.8ms | Archive::Zip::ZipFileMember::dataOffset | 
| 1 | 1 | 1 | 298µs | 313µs | Archive::Zip::ZipFileMember::BEGIN@3 | 
| 1 | 1 | 1 | 33µs | 33µs | Archive::Zip::ZipFileMember::BEGIN@6 | 
| 1 | 1 | 1 | 19µs | 870µs | Archive::Zip::ZipFileMember::BEGIN@11 | 
| 1 | 1 | 1 | 16µs | 116µs | Archive::Zip::ZipFileMember::BEGIN@4 | 
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::ZipFileMember::_readDataDescriptor | 
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::ZipFileMember::diskNumberStart | 
| Line | State ments | Time on line | Calls | Time in subs | Code | 
|---|---|---|---|---|---|
| 1 | package Archive::Zip::ZipFileMember; | ||||
| 2 | |||||
| 3 | 2 | 82µs | 2 | 328µs | # spent 313µs (298+15) within Archive::Zip::ZipFileMember::BEGIN@3 which was called:
#    once (298µs+15µs) by installer::archivefiles::BEGIN@30 at line 3 # spent   313µs making 1 call to Archive::Zip::ZipFileMember::BEGIN@3
# spent    15µs making 1 call to strict::import | 
| 4 | 2 | 98µs | 2 | 216µs | # spent 116µs (16+100) within Archive::Zip::ZipFileMember::BEGIN@4 which was called:
#    once (16µs+100µs) by installer::archivefiles::BEGIN@30 at line 4 # spent   116µs making 1 call to Archive::Zip::ZipFileMember::BEGIN@4
# spent   100µs making 1 call to vars::import | 
| 5 | |||||
| 6 | # spent 33µs within Archive::Zip::ZipFileMember::BEGIN@6 which was called:
#    once (33µs+0s) by installer::archivefiles::BEGIN@30 at line 9 | ||||
| 7 | 2 | 33µs | $VERSION = '1.30'; | ||
| 8 | @ISA = qw ( Archive::Zip::FileMember ); | ||||
| 9 | 1 | 115µs | 1 | 33µs | } # spent    33µs making 1 call to Archive::Zip::ZipFileMember::BEGIN@6 | 
| 10 | |||||
| 11 | 1 | 851µs | # spent 870µs (19+851) within Archive::Zip::ZipFileMember::BEGIN@11 which was called:
#    once (19µs+851µs) by installer::archivefiles::BEGIN@30 at line 16 # spent   851µs making 1 call to Exporter::import | ||
| 12 | :CONSTANTS | ||||
| 13 | :ERROR_CODES | ||||
| 14 | :PKZIP_CONSTANTS | ||||
| 15 | :UTILITY_METHODS | ||||
| 16 | 2 | 3.53ms | 1 | 870µs | ); # spent   870µs making 1 call to Archive::Zip::ZipFileMember::BEGIN@11 | 
| 17 | |||||
| 18 | # Create a new Archive::Zip::ZipFileMember | ||||
| 19 | # given a filename and optional open file handle | ||||
| 20 | # | ||||
| 21 | # spent 850ms (112+738) within Archive::Zip::ZipFileMember::_newFromZipFile which was called 10192 times, avg 83µs/call:
# 10192 times (112ms+738ms) by Archive::Zip::Member::_newFromZipFile at line 42 of Archive/Zip/Member.pm, avg 83µs/call | ||||
| 22 | 91728 | 115ms | my $class = shift; | ||
| 23 | my $fh = shift; | ||||
| 24 | my $externalFileName = shift; | ||||
| 25 | my $possibleEocdOffset = shift; # normally 0 | ||||
| 26 | |||||
| 27 | 10192 | 738ms | my $self = $class->new(     # spent   738ms making 10192 calls to Archive::Zip::Member::new, avg 72µs/call | ||
| 28 | 'crc32' => 0, | ||||
| 29 | 'diskNumberStart' => 0, | ||||
| 30 | 'localHeaderRelativeOffset' => 0, | ||||
| 31 | 'dataOffset' => 0, # localHeaderRelativeOffset + header length | ||||
| 32 | @_ | ||||
| 33 | ); | ||||
| 34 | $self->{'externalFileName'} = $externalFileName; | ||||
| 35 | $self->{'fh'} = $fh; | ||||
| 36 | $self->{'possibleEocdOffset'} = $possibleEocdOffset; | ||||
| 37 | return $self; | ||||
| 38 | } | ||||
| 39 | |||||
| 40 | # spent 226ms (145+80.7) within Archive::Zip::ZipFileMember::isDirectory which was called 20174 times, avg 11µs/call:
# 10192 times (71.3ms+38.6ms) by Archive::Zip::Member::unixFileAttributes at line 356 of Archive/Zip/Member.pm, avg 11µs/call
#  9982 times (73.5ms+42.1ms) by Archive::Zip::Member::_becomeDirectoryIfNecessary at line 127 of Archive/Zip/Member.pm, avg 12µs/call | ||||
| 41 | 40348 | 140ms | my $self = shift; | ||
| 42 | return ( | ||||
| 43 | 21555 | 80.7ms | substr( $self->fileName, -1, 1 ) eq '/'         # spent  77.4ms making 20174 calls to Archive::Zip::Member::fileName, avg 4µs/call
        # spent  3.29ms making  1381 calls to Archive::Zip::Member::uncompressedSize, avg 2µs/call | ||
| 44 | and | ||||
| 45 | $self->uncompressedSize == 0 | ||||
| 46 | ); | ||||
| 47 | } | ||||
| 48 | |||||
| 49 | # Seek to the beginning of the local header, just past the signature. | ||||
| 50 | # Verify that the local header signature is in fact correct. | ||||
| 51 | # Update the localHeaderRelativeOffset if necessary by adding the possibleEocdOffset. | ||||
| 52 | # Returns status. | ||||
| 53 | |||||
| 54 | # spent 1.10s (325ms+780ms) within Archive::Zip::ZipFileMember::_seekToLocalHeader which was called 9982 times, avg 111µs/call:
# 8601 times (282ms+673ms) by Archive::Zip::ZipFileMember::rewindData at line 391, avg 111µs/call
# 1381 times (42.9ms+107ms) by Archive::Zip::ZipFileMember::_become at line 106, avg 108µs/call | ||||
| 55 | 129766 | 254ms | my $self = shift; | ||
| 56 | my $where = shift; # optional | ||||
| 57 | my $previousWhere = shift; # optional | ||||
| 58 | |||||
| 59 | 9982 | 23.2ms | $where = $self->localHeaderRelativeOffset() unless defined($where);     # spent  23.2ms making 9982 calls to Archive::Zip::ZipFileMember::localHeaderRelativeOffset, avg 2µs/call | ||
| 60 | |||||
| 61 | # avoid loop on certain corrupt files (from Julian Field) | ||||
| 62 | return _formatError("corrupt zip file") | ||||
| 63 | if defined($previousWhere) && $where == $previousWhere; | ||||
| 64 | |||||
| 65 | my $status; | ||||
| 66 | my $signature; | ||||
| 67 | |||||
| 68 | 19964 | 214ms | $status = $self->fh()->seek( $where, IO::Seekable::SEEK_SET );     # spent   115ms making 9982 calls to IO::Seekable::seek, avg 11µs/call
    # spent  99.2ms making 9982 calls to Archive::Zip::FileMember::fh, avg 10µs/call | ||
| 69 | return _ioError("seeking to local header") unless $status; | ||||
| 70 | |||||
| 71 | 29946 | 543ms | ( $status, $signature ) =     # spent   414ms making 9982 calls to Archive::Zip::_readSignature, avg 41µs/call
    # spent   101ms making 9982 calls to Archive::Zip::FileMember::fh, avg 10µs/call
    # spent  27.6ms making 9982 calls to Archive::Zip::FileMember::externalFileName, avg 3µs/call | ||
| 72 | _readSignature( $self->fh(), $self->externalFileName(), | ||||
| 73 | LOCAL_FILE_HEADER_SIGNATURE ); | ||||
| 74 | return $status if $status == AZ_IO_ERROR; | ||||
| 75 | |||||
| 76 | # retry with EOCD offset if any was given. | ||||
| 77 | if ( $status == AZ_FORMAT_ERROR && $self->{'possibleEocdOffset'} ) { | ||||
| 78 | $status = $self->_seekToLocalHeader( | ||||
| 79 | $self->localHeaderRelativeOffset() + $self->{'possibleEocdOffset'}, | ||||
| 80 | $where | ||||
| 81 | ); | ||||
| 82 | if ( $status == AZ_OK ) { | ||||
| 83 | $self->{'localHeaderRelativeOffset'} += | ||||
| 84 | $self->{'possibleEocdOffset'}; | ||||
| 85 | $self->{'possibleEocdOffset'} = 0; | ||||
| 86 | } | ||||
| 87 | } | ||||
| 88 | |||||
| 89 | return $status; | ||||
| 90 | } | ||||
| 91 | |||||
| 92 | # Because I'm going to delete the file handle, read the local file | ||||
| 93 | # header if the file handle is seekable. If it isn't, I assume that | ||||
| 94 | # I've already read the local header. | ||||
| 95 | # Return ( $status, $self ) | ||||
| 96 | |||||
| 97 | # spent 1.09s (68.7ms+1.03) within Archive::Zip::ZipFileMember::_become which was called 1381 times, avg 793µs/call:
# 1381 times (68.7ms+1.03s) by Archive::Zip::Member::_becomeDirectoryIfNecessary at line 127 of Archive/Zip/Member.pm, avg 793µs/call | ||||
| 98 | 13810 | 30.8ms | my $self = shift; | ||
| 99 | my $newClass = shift; | ||||
| 100 | return $self if ref($self) eq $newClass; | ||||
| 101 | |||||
| 102 | my $status = AZ_OK; | ||||
| 103 | |||||
| 104 | 6905 | 22.9ms | 2762 | 598ms | if ( _isSeekable( $self->fh() ) ) {     # spent   514ms making 1381 calls to Archive::Zip::FileMember::fh, avg 373µs/call
    # spent  83.1ms making 1381 calls to Archive::Zip::_isSeekable, avg 60µs/call | 
| 105 | 2762 | 23.1ms | my $here = $self->fh()->tell();         # spent  15.2ms making 1381 calls to Archive::Zip::FileMember::fh, avg 11µs/call
        # spent  7.97ms making 1381 calls to IO::Seekable::tell, avg 6µs/call | ||
| 106 | 1381 | 150ms | $status = $self->_seekToLocalHeader();         # spent   150ms making 1381 calls to Archive::Zip::ZipFileMember::_seekToLocalHeader, avg 108µs/call | ||
| 107 | 1381 | 162ms | $status = $self->_readLocalFileHeader() if $status == AZ_OK;         # spent   162ms making 1381 calls to Archive::Zip::ZipFileMember::_readLocalFileHeader, avg 117µs/call | ||
| 108 | 2762 | 31.2ms | $self->fh()->seek( $here, IO::Seekable::SEEK_SET );         # spent  17.3ms making 1381 calls to IO::Seekable::seek, avg 13µs/call
        # spent  13.9ms making 1381 calls to Archive::Zip::FileMember::fh, avg 10µs/call | ||
| 109 | return $status unless $status == AZ_OK; | ||||
| 110 | } | ||||
| 111 | |||||
| 112 | delete( $self->{'eocdCrc32'} ); | ||||
| 113 | delete( $self->{'diskNumberStart'} ); | ||||
| 114 | delete( $self->{'localHeaderRelativeOffset'} ); | ||||
| 115 | delete( $self->{'dataOffset'} ); | ||||
| 116 | |||||
| 117 | 1381 | 62.4ms | return $self->SUPER::_become($newClass);     # spent  62.4ms making 1381 calls to Archive::Zip::FileMember::_become, avg 45µs/call | ||
| 118 | } | ||||
| 119 | |||||
| 120 | sub diskNumberStart { | ||||
| 121 | shift->{'diskNumberStart'}; | ||||
| 122 | } | ||||
| 123 | |||||
| 124 | # spent 23.2ms within Archive::Zip::ZipFileMember::localHeaderRelativeOffset which was called 9982 times, avg 2µs/call:
# 9982 times (23.2ms+0s) by Archive::Zip::ZipFileMember::_seekToLocalHeader at line 59, avg 2µs/call | ||||
| 125 | 9982 | 41.5ms | shift->{'localHeaderRelativeOffset'}; | ||
| 126 | } | ||||
| 127 | |||||
| 128 | # spent 19.8ms within Archive::Zip::ZipFileMember::dataOffset which was called 8601 times, avg 2µs/call:
# 8601 times (19.8ms+0s) by Archive::Zip::ZipFileMember::rewindData at line 399, avg 2µs/call | ||||
| 129 | 8601 | 32.6ms | shift->{'dataOffset'}; | ||
| 130 | } | ||||
| 131 | |||||
| 132 | # Skip local file header, updating only extra field stuff. | ||||
| 133 | # Assumes that fh is positioned before signature. | ||||
| 134 | # spent 827ms (300+526) within Archive::Zip::ZipFileMember::_skipLocalFileHeader which was called 8601 times, avg 96µs/call:
# 8601 times (300ms+526ms) by Archive::Zip::ZipFileMember::rewindData at line 395, avg 96µs/call | ||||
| 135 | 111813 | 248ms | my $self = shift; | ||
| 136 | my $header; | ||||
| 137 | 17202 | 142ms | my $bytesRead = $self->fh()->read( $header, LOCAL_FILE_HEADER_LENGTH );     # spent  87.7ms making 8601 calls to Archive::Zip::FileMember::fh, avg 10µs/call
    # spent  54.5ms making 8601 calls to IO::Handle::read, avg 6µs/call | ||
| 138 | if ( $bytesRead != LOCAL_FILE_HEADER_LENGTH ) { | ||||
| 139 | return _ioError("reading local file header"); | ||||
| 140 | } | ||||
| 141 | my $fileNameLength; | ||||
| 142 | my $extraFieldLength; | ||||
| 143 | my $bitFlag; | ||||
| 144 | ( | ||||
| 145 | undef, # $self->{'versionNeededToExtract'}, | ||||
| 146 | 8601 | 17.8ms | $bitFlag,         # spent  17.8ms making 8601 calls to Archive::Zip::ZipFileMember::CORE:unpack, avg 2µs/call | ||
| 147 | undef, # $self->{'compressionMethod'}, | ||||
| 148 | undef, # $self->{'lastModFileDateTime'}, | ||||
| 149 | undef, # $crc32, | ||||
| 150 | undef, # $compressedSize, | ||||
| 151 | undef, # $uncompressedSize, | ||||
| 152 | $fileNameLength, | ||||
| 153 | $extraFieldLength | ||||
| 154 | ) = unpack( LOCAL_FILE_HEADER_FORMAT, $header ); | ||||
| 155 | |||||
| 156 | 17202 | 204ms | if ($fileNameLength) {     # spent   116ms making 8601 calls to IO::Seekable::seek, avg 13µs/call
    # spent  88.0ms making 8601 calls to Archive::Zip::FileMember::fh, avg 10µs/call | ||
| 157 | $self->fh()->seek( $fileNameLength, IO::Seekable::SEEK_CUR ) | ||||
| 158 | or return _ioError("skipping local file name"); | ||||
| 159 | } | ||||
| 160 | |||||
| 161 | 1644 | 5.18ms | if ($extraFieldLength) { | ||
| 162 | 1644 | 22.7ms | $bytesRead =         # spent  14.4ms making 822 calls to IO::Handle::read, avg 18µs/call
        # spent  8.25ms making 822 calls to Archive::Zip::FileMember::fh, avg 10µs/call | ||
| 163 | $self->fh()->read( $self->{'localExtraField'}, $extraFieldLength ); | ||||
| 164 | if ( $bytesRead != $extraFieldLength ) { | ||||
| 165 | return _ioError("reading local extra field"); | ||||
| 166 | } | ||||
| 167 | } | ||||
| 168 | |||||
| 169 | 17202 | 139ms | $self->{'dataOffset'} = $self->fh()->tell();     # spent  86.9ms making 8601 calls to Archive::Zip::FileMember::fh, avg 10µs/call
    # spent  52.6ms making 8601 calls to IO::Seekable::tell, avg 6µs/call | ||
| 170 | |||||
| 171 | if ( $bitFlag & GPBF_HAS_DATA_DESCRIPTOR_MASK ) { | ||||
| 172 | |||||
| 173 | # Read the crc32, compressedSize, and uncompressedSize from the | ||||
| 174 | # extended data descriptor, which directly follows the compressed data. | ||||
| 175 | # | ||||
| 176 | # Skip over the compressed file data (assumes that EOCD compressedSize | ||||
| 177 | # was correct) | ||||
| 178 | $self->fh()->seek( $self->{'compressedSize'}, IO::Seekable::SEEK_CUR ) | ||||
| 179 | or return _ioError("seeking to extended local header"); | ||||
| 180 | |||||
| 181 | # these values should be set correctly from before. | ||||
| 182 | my $oldCrc32 = $self->{'eocdCrc32'}; | ||||
| 183 | my $oldCompressedSize = $self->{'compressedSize'}; | ||||
| 184 | my $oldUncompressedSize = $self->{'uncompressedSize'}; | ||||
| 185 | |||||
| 186 | my $status = $self->_readDataDescriptor(); | ||||
| 187 | return $status unless $status == AZ_OK; | ||||
| 188 | |||||
| 189 | return _formatError( | ||||
| 190 | "CRC or size mismatch while skipping data descriptor") | ||||
| 191 | if ( $oldCrc32 != $self->{'crc32'} | ||||
| 192 | || $oldUncompressedSize != $self->{'uncompressedSize'} ); | ||||
| 193 | } | ||||
| 194 | |||||
| 195 | return AZ_OK; | ||||
| 196 | } | ||||
| 197 | |||||
| 198 | # Read from a local file header into myself. Returns AZ_OK if successful. | ||||
| 199 | # Assumes that fh is positioned after signature. | ||||
| 200 | # Note that crc32, compressedSize, and uncompressedSize will be 0 if | ||||
| 201 | # GPBF_HAS_DATA_DESCRIPTOR_MASK is set in the bitFlag. | ||||
| 202 | |||||
| 203 | # spent 162ms (64.7+97.5) within Archive::Zip::ZipFileMember::_readLocalFileHeader which was called 1381 times, avg 117µs/call:
# 1381 times (64.7ms+97.5ms) by Archive::Zip::ZipFileMember::_become at line 107, avg 117µs/call | ||||
| 204 | 20715 | 39.4ms | my $self = shift; | ||
| 205 | my $header; | ||||
| 206 | 2762 | 23.0ms | my $bytesRead = $self->fh()->read( $header, LOCAL_FILE_HEADER_LENGTH );     # spent  14.3ms making 1381 calls to Archive::Zip::FileMember::fh, avg 10µs/call
    # spent  8.70ms making 1381 calls to IO::Handle::read, avg 6µs/call | ||
| 207 | if ( $bytesRead != LOCAL_FILE_HEADER_LENGTH ) { | ||||
| 208 | return _ioError("reading local file header"); | ||||
| 209 | } | ||||
| 210 | my $fileNameLength; | ||||
| 211 | my $crc32; | ||||
| 212 | my $compressedSize; | ||||
| 213 | my $uncompressedSize; | ||||
| 214 | my $extraFieldLength; | ||||
| 215 | ( | ||||
| 216 | 1381 | 2.63ms | $self->{'versionNeededToExtract'}, $self->{'bitFlag'},         # spent  2.63ms making 1381 calls to Archive::Zip::ZipFileMember::CORE:unpack, avg 2µs/call | ||
| 217 | $self->{'compressionMethod'}, $self->{'lastModFileDateTime'}, | ||||
| 218 | $crc32, $compressedSize, | ||||
| 219 | $uncompressedSize, $fileNameLength, | ||||
| 220 | $extraFieldLength | ||||
| 221 | ) = unpack( LOCAL_FILE_HEADER_FORMAT, $header ); | ||||
| 222 | |||||
| 223 | 5524 | 11.8ms | if ($fileNameLength) { | ||
| 224 | my $fileName; | ||||
| 225 | 2762 | 22.8ms | $bytesRead = $self->fh()->read( $fileName, $fileNameLength );         # spent  14.3ms making 1381 calls to Archive::Zip::FileMember::fh, avg 10µs/call
        # spent  8.50ms making 1381 calls to IO::Handle::read, avg 6µs/call | ||
| 226 | if ( $bytesRead != $fileNameLength ) { | ||||
| 227 | return _ioError("reading local file name"); | ||||
| 228 | } | ||||
| 229 | 1381 | 22.1ms | $self->fileName($fileName);         # spent  22.1ms making 1381 calls to Archive::Zip::Member::fileName, avg 16µs/call | ||
| 230 | } | ||||
| 231 | |||||
| 232 | 4 | 11µs | if ($extraFieldLength) { | ||
| 233 | 4 | 33µs | $bytesRead =         # spent    20µs making 2 calls to Archive::Zip::FileMember::fh, avg 10µs/call
        # spent    13µs making 2 calls to IO::Handle::read, avg 7µs/call | ||
| 234 | $self->fh()->read( $self->{'localExtraField'}, $extraFieldLength ); | ||||
| 235 | if ( $bytesRead != $extraFieldLength ) { | ||||
| 236 | return _ioError("reading local extra field"); | ||||
| 237 | } | ||||
| 238 | } | ||||
| 239 | |||||
| 240 | 2762 | 22.0ms | $self->{'dataOffset'} = $self->fh()->tell();     # spent  14.4ms making 1381 calls to Archive::Zip::FileMember::fh, avg 10µs/call
    # spent  7.67ms making 1381 calls to IO::Seekable::tell, avg 6µs/call | ||
| 241 | |||||
| 242 | 1381 | 1.59ms | 1381 | 4.86ms | if ( $self->hasDataDescriptor() ) {     # spent  4.86ms making 1381 calls to Archive::Zip::Member::hasDataDescriptor, avg 4µs/call | 
| 243 | |||||
| 244 | # Read the crc32, compressedSize, and uncompressedSize from the | ||||
| 245 | # extended data descriptor. | ||||
| 246 | # Skip over the compressed file data (assumes that EOCD compressedSize | ||||
| 247 | # was correct) | ||||
| 248 | $self->fh()->seek( $self->{'compressedSize'}, IO::Seekable::SEEK_CUR ) | ||||
| 249 | or return _ioError("seeking to extended local header"); | ||||
| 250 | |||||
| 251 | my $status = $self->_readDataDescriptor(); | ||||
| 252 | return $status unless $status == AZ_OK; | ||||
| 253 | } | ||||
| 254 | else { | ||||
| 255 | return _formatError( | ||||
| 256 | "CRC or size mismatch after reading data descriptor") | ||||
| 257 | if ( $self->{'crc32'} != $crc32 | ||||
| 258 | || $self->{'uncompressedSize'} != $uncompressedSize ); | ||||
| 259 | } | ||||
| 260 | |||||
| 261 | return AZ_OK; | ||||
| 262 | } | ||||
| 263 | |||||
| 264 | # This will read the data descriptor, which is after the end of compressed file | ||||
| 265 | # data in members that that have GPBF_HAS_DATA_DESCRIPTOR_MASK set in their | ||||
| 266 | # bitFlag. | ||||
| 267 | # The only reliable way to find these is to rely on the EOCD compressedSize. | ||||
| 268 | # Assumes that file is positioned immediately after the compressed data. | ||||
| 269 | # Returns status; sets crc32, compressedSize, and uncompressedSize. | ||||
| 270 | sub _readDataDescriptor { | ||||
| 271 | my $self = shift; | ||||
| 272 | my $signatureData; | ||||
| 273 | my $header; | ||||
| 274 | my $crc32; | ||||
| 275 | my $compressedSize; | ||||
| 276 | my $uncompressedSize; | ||||
| 277 | |||||
| 278 | my $bytesRead = $self->fh()->read( $signatureData, SIGNATURE_LENGTH ); | ||||
| 279 | return _ioError("reading header signature") | ||||
| 280 | if $bytesRead != SIGNATURE_LENGTH; | ||||
| 281 | my $signature = unpack( SIGNATURE_FORMAT, $signatureData ); | ||||
| 282 | |||||
| 283 | # unfortunately, the signature appears to be optional. | ||||
| 284 | if ( $signature == DATA_DESCRIPTOR_SIGNATURE | ||||
| 285 | && ( $signature != $self->{'crc32'} ) ) | ||||
| 286 | { | ||||
| 287 | $bytesRead = $self->fh()->read( $header, DATA_DESCRIPTOR_LENGTH ); | ||||
| 288 | return _ioError("reading data descriptor") | ||||
| 289 | if $bytesRead != DATA_DESCRIPTOR_LENGTH; | ||||
| 290 | |||||
| 291 | ( $crc32, $compressedSize, $uncompressedSize ) = | ||||
| 292 | unpack( DATA_DESCRIPTOR_FORMAT, $header ); | ||||
| 293 | } | ||||
| 294 | else { | ||||
| 295 | $bytesRead = | ||||
| 296 | $self->fh()->read( $header, DATA_DESCRIPTOR_LENGTH_NO_SIG ); | ||||
| 297 | return _ioError("reading data descriptor") | ||||
| 298 | if $bytesRead != DATA_DESCRIPTOR_LENGTH_NO_SIG; | ||||
| 299 | |||||
| 300 | $crc32 = $signature; | ||||
| 301 | ( $compressedSize, $uncompressedSize ) = | ||||
| 302 | unpack( DATA_DESCRIPTOR_FORMAT_NO_SIG, $header ); | ||||
| 303 | } | ||||
| 304 | |||||
| 305 | $self->{'eocdCrc32'} = $self->{'crc32'} | ||||
| 306 | unless defined( $self->{'eocdCrc32'} ); | ||||
| 307 | $self->{'crc32'} = $crc32; | ||||
| 308 | $self->{'compressedSize'} = $compressedSize; | ||||
| 309 | $self->{'uncompressedSize'} = $uncompressedSize; | ||||
| 310 | |||||
| 311 | return AZ_OK; | ||||
| 312 | } | ||||
| 313 | |||||
| 314 | # Read a Central Directory header. Return AZ_OK on success. | ||||
| 315 | # Assumes that fh is positioned right after the signature. | ||||
| 316 | |||||
| 317 | # spent 718ms (371+347) within Archive::Zip::ZipFileMember::_readCentralDirectoryFileHeader which was called 9982 times, avg 72µs/call:
# 9982 times (371ms+347ms) by Archive::Zip::Archive::readFromFileHandle at line 606 of Archive/Zip/Archive.pm, avg 72µs/call | ||||
| 318 | 139748 | 290ms | my $self = shift; | ||
| 319 | 9982 | 105ms | my $fh        = $self->fh();     # spent   105ms making 9982 calls to Archive::Zip::FileMember::fh, avg 10µs/call | ||
| 320 | my $header = ''; | ||||
| 321 | 9982 | 61.7ms | my $bytesRead = $fh->read( $header, CENTRAL_DIRECTORY_FILE_HEADER_LENGTH );     # spent  61.7ms making 9982 calls to IO::Handle::read, avg 6µs/call | ||
| 322 | if ( $bytesRead != CENTRAL_DIRECTORY_FILE_HEADER_LENGTH ) { | ||||
| 323 | return _ioError("reading central dir header"); | ||||
| 324 | } | ||||
| 325 | my ( $fileNameLength, $extraFieldLength, $fileCommentLength ); | ||||
| 326 | ( | ||||
| 327 | 9982 | 24.5ms | $self->{'versionMadeBy'},         # spent  24.5ms making 9982 calls to Archive::Zip::ZipFileMember::CORE:unpack, avg 2µs/call | ||
| 328 | $self->{'fileAttributeFormat'}, | ||||
| 329 | $self->{'versionNeededToExtract'}, | ||||
| 330 | $self->{'bitFlag'}, | ||||
| 331 | $self->{'compressionMethod'}, | ||||
| 332 | $self->{'lastModFileDateTime'}, | ||||
| 333 | $self->{'crc32'}, | ||||
| 334 | $self->{'compressedSize'}, | ||||
| 335 | $self->{'uncompressedSize'}, | ||||
| 336 | $fileNameLength, | ||||
| 337 | $extraFieldLength, | ||||
| 338 | $fileCommentLength, | ||||
| 339 | $self->{'diskNumberStart'}, | ||||
| 340 | $self->{'internalFileAttributes'}, | ||||
| 341 | $self->{'externalFileAttributes'}, | ||||
| 342 | $self->{'localHeaderRelativeOffset'} | ||||
| 343 | ) = unpack( CENTRAL_DIRECTORY_FILE_HEADER_FORMAT, $header ); | ||||
| 344 | |||||
| 345 | $self->{'eocdCrc32'} = $self->{'crc32'}; | ||||
| 346 | |||||
| 347 | 19964 | 34.0ms | if ($fileNameLength) { | ||
| 348 | 9982 | 65.4ms | $bytesRead = $fh->read( $self->{'fileName'}, $fileNameLength );         # spent  65.4ms making 9982 calls to IO::Handle::read, avg 7µs/call | ||
| 349 | if ( $bytesRead != $fileNameLength ) { | ||||
| 350 | _ioError("reading central dir filename"); | ||||
| 351 | } | ||||
| 352 | } | ||||
| 353 | 1648 | 2.60ms | if ($extraFieldLength) { | ||
| 354 | 824 | 5.02ms | $bytesRead = $fh->read( $self->{'cdExtraField'}, $extraFieldLength );         # spent  5.02ms making 824 calls to IO::Handle::read, avg 6µs/call | ||
| 355 | if ( $bytesRead != $extraFieldLength ) { | ||||
| 356 | return _ioError("reading central dir extra field"); | ||||
| 357 | } | ||||
| 358 | } | ||||
| 359 | if ($fileCommentLength) { | ||||
| 360 | $bytesRead = $fh->read( $self->{'fileComment'}, $fileCommentLength ); | ||||
| 361 | if ( $bytesRead != $fileCommentLength ) { | ||||
| 362 | return _ioError("reading central dir file comment"); | ||||
| 363 | } | ||||
| 364 | } | ||||
| 365 | |||||
| 366 | # NK 10/21/04: added to avoid problems with manipulated headers | ||||
| 367 | if ( $self->{'uncompressedSize'} != $self->{'compressedSize'} | ||||
| 368 | and $self->{'compressionMethod'} == COMPRESSION_STORED ) | ||||
| 369 | { | ||||
| 370 | $self->{'uncompressedSize'} = $self->{'compressedSize'}; | ||||
| 371 | } | ||||
| 372 | |||||
| 373 | 19964 | 85.3ms | $self->desiredCompressionMethod( $self->compressionMethod() );     # spent  63.2ms making 9982 calls to Archive::Zip::Member::desiredCompressionMethod, avg 6µs/call
    # spent  22.1ms making 9982 calls to Archive::Zip::Member::compressionMethod, avg 2µs/call | ||
| 374 | |||||
| 375 | return AZ_OK; | ||||
| 376 | } | ||||
| 377 | |||||
| 378 | # spent 10.3s (404ms+9.90) within Archive::Zip::ZipFileMember::rewindData which was called 8601 times, avg 1.20ms/call:
# 8601 times (404ms+9.90s) by Archive::Zip::Member::extractToFileHandle at line 990 of Archive/Zip/Member.pm, avg 1.20ms/call | ||||
| 379 | 94611 | 334ms | my $self = shift; | ||
| 380 | |||||
| 381 | 8601 | 4.55s | my $status = $self->SUPER::rewindData(@_);     # spent  4.55s making 8601 calls to Archive::Zip::Member::rewindData, avg 529µs/call | ||
| 382 | return $status unless $status == AZ_OK; | ||||
| 383 | |||||
| 384 | 8601 | 3.27s | return AZ_IO_ERROR unless $self->fh();     # spent  3.27s making 8601 calls to Archive::Zip::FileMember::fh, avg 381µs/call | ||
| 385 | |||||
| 386 | 17202 | 115ms | $self->fh()->clearerr();     # spent  98.4ms making 8601 calls to Archive::Zip::FileMember::fh, avg 11µs/call
    # spent  16.3ms making 8601 calls to IO::Handle::clearerr, avg 2µs/call | ||
| 387 | |||||
| 388 | # Seek to local file header. | ||||
| 389 | # The only reason that I'm doing this this way is that the extraField | ||||
| 390 | # length seems to be different between the CD header and the LF header. | ||||
| 391 | 8601 | 955ms | $status = $self->_seekToLocalHeader();     # spent   955ms making 8601 calls to Archive::Zip::ZipFileMember::_seekToLocalHeader, avg 111µs/call | ||
| 392 | return $status unless $status == AZ_OK; | ||||
| 393 | |||||
| 394 | # skip local file header | ||||
| 395 | 8601 | 827ms | $status = $self->_skipLocalFileHeader();     # spent   827ms making 8601 calls to Archive::Zip::ZipFileMember::_skipLocalFileHeader, avg 96µs/call | ||
| 396 | return $status unless $status == AZ_OK; | ||||
| 397 | |||||
| 398 | # Seek to beginning of file data | ||||
| 399 | 25803 | 189ms | $self->fh()->seek( $self->dataOffset(), IO::Seekable::SEEK_SET )     # spent  84.9ms making 8601 calls to Archive::Zip::FileMember::fh, avg 10µs/call
    # spent  84.6ms making 8601 calls to IO::Seekable::seek, avg 10µs/call
    # spent  19.8ms making 8601 calls to Archive::Zip::ZipFileMember::dataOffset, avg 2µs/call | ||
| 400 | or return _ioError("seeking to beginning of file data"); | ||||
| 401 | |||||
| 402 | return AZ_OK; | ||||
| 403 | } | ||||
| 404 | |||||
| 405 | # Return bytes read. Note that first parameter is a ref to a buffer. | ||||
| 406 | # my $data; | ||||
| 407 | # my ( $bytesRead, $status) = $self->readRawChunk( \$data, $chunkSize ); | ||||
| 408 | # spent 511ms (127+383) within Archive::Zip::ZipFileMember::_readRawChunk which was called 10349 times, avg 49µs/call:
# 10349 times (127ms+383ms) by Archive::Zip::Member::readChunk at line 788 of Archive/Zip/Member.pm, avg 49µs/call | ||||
| 409 | 41396 | 109ms | my ( $self, $dataRef, $chunkSize ) = @_; | ||
| 410 | return ( 0, AZ_OK ) unless $chunkSize; | ||||
| 411 | 20698 | 383ms | my $bytesRead = $self->fh()->read( $$dataRef, $chunkSize )     # spent   276ms making 10349 calls to IO::Handle::read, avg 27µs/call
    # spent   108ms making 10349 calls to Archive::Zip::FileMember::fh, avg 10µs/call | ||
| 412 | or return ( 0, _ioError("reading data") ); | ||||
| 413 | return ( $bytesRead, AZ_OK ); | ||||
| 414 | } | ||||
| 415 | |||||
| 416 | 1 | 8µs | 1; | ||
| # spent 45.0ms within Archive::Zip::ZipFileMember::CORE:unpack which was called 19964 times, avg 2µs/call:
# 9982 times (24.5ms+0s) by Archive::Zip::ZipFileMember::_readCentralDirectoryFileHeader at line 327, avg 2µs/call
# 8601 times (17.8ms+0s) by Archive::Zip::ZipFileMember::_skipLocalFileHeader at line 146, avg 2µs/call
# 1381 times (2.63ms+0s) by Archive::Zip::ZipFileMember::_readLocalFileHeader at line 216, avg 2µs/call |