| Filename | /usr/lib/perl5/site_perl/5.14/Archive/Zip/Member.pm |
| Statements | Executed 3321567 statements in 13.0s |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 8601 | 1 | 1 | 2.05s | 2.05s | Archive::Zip::Member::CORE:chmod (opcode) |
| 8601 | 1 | 1 | 1.77s | 1.77s | Archive::Zip::Member::CORE:utime (opcode) |
| 17202 | 1 | 1 | 633ms | 1.23s | Archive::Zip::Member::bitFlag |
| 154818 | 1 | 1 | 601ms | 601ms | Archive::Zip::Member::desiredCompressionLevel |
| 8601 | 1 | 1 | 553ms | 4.55s | Archive::Zip::Member::rewindData |
| 8601 | 1 | 1 | 522ms | 38.7s | Archive::Zip::Member::extractToFileNamed |
| 10349 | 1 | 1 | 436ms | 4.61s | Archive::Zip::Member::readChunk |
| 10212 | 1 | 1 | 350ms | 3.22s | Archive::Zip::Member::_inflateChunk |
| 8601 | 1 | 1 | 315ms | 6.22s | Archive::Zip::Member::_writeData |
| 8601 | 1 | 1 | 308ms | 18.1s | Archive::Zip::Member::extractToFileHandle |
| 20174 | 3 | 2 | 299ms | 665ms | Archive::Zip::Member::unixFileAttributes |
| 19964 | 1 | 1 | 298ms | 2.46s | Archive::Zip::Member::_dosToUnixTime |
| 61483 | 6 | 3 | 268ms | 278ms | Archive::Zip::Member::fileName |
| 36388 | 5 | 2 | 236ms | 236ms | Archive::Zip::Member::desiredCompressionMethod |
| 35182 | 1 | 1 | 235ms | 267ms | Archive::Zip::Member::endRead |
| 10192 | 1 | 1 | 228ms | 738ms | Archive::Zip::Member::new |
| 19964 | 2 | 2 | 210ms | 2.89s | Archive::Zip::Member::lastModTime |
| 20698 | 2 | 1 | 181ms | 247ms | Archive::Zip::Member::readIsDone |
| 20174 | 1 | 1 | 178ms | 215ms | Archive::Zip::Member::_mapPermissionsToUnix |
| 19964 | 1 | 1 | 155ms | 229ms | Archive::Zip::Member::lastModFileDateTime |
| 55105 | 5 | 2 | 120ms | 120ms | Archive::Zip::Member::compressionMethod |
| 10192 | 1 | 1 | 109ms | 971ms | Archive::Zip::Member::_newFromZipFile |
| 17202 | 2 | 1 | 98.6ms | 1.33s | Archive::Zip::Member::isEncrypted |
| 41670 | 4 | 1 | 86.9ms | 86.9ms | Archive::Zip::Member::_readDataRemaining |
| 9982 | 1 | 1 | 76.4ms | 1.29s | Archive::Zip::Member::_becomeDirectoryIfNecessary |
| 19964 | 1 | 1 | 74.3ms | 74.3ms | Archive::Zip::Member::CORE:match (opcode) |
| 18953 | 4 | 2 | 44.3ms | 44.3ms | Archive::Zip::Member::uncompressedSize |
| 20698 | 1 | 1 | 41.7ms | 41.7ms | Archive::Zip::Member::_dataEnded |
| 10192 | 1 | 1 | 40.7ms | 40.7ms | Archive::Zip::Member::_mapPermissionsFromUnix |
| 10192 | 1 | 1 | 37.4ms | 37.4ms | Archive::Zip::Member::localExtraField |
| 8368 | 1 | 1 | 23.6ms | 23.6ms | Archive::Zip::Member::_writeOffset |
| 10212 | 1 | 1 | 21.7ms | 21.7ms | Archive::Zip::Member::_inflater |
| 8231 | 1 | 1 | 18.7ms | 18.7ms | Archive::Zip::Member::compressedSize |
| 10192 | 1 | 1 | 13.7ms | 13.7ms | Archive::Zip::Member::DEFAULT_FILE_PERMISSIONS (xsub) |
| 10192 | 1 | 1 | 11.7ms | 11.7ms | Archive::Zip::Member::ZIPFILEMEMBERCLASS (xsub) |
| 1381 | 1 | 1 | 9.69ms | 9.69ms | Archive::Zip::Member::CORE:subst (opcode) |
| 1381 | 1 | 1 | 5.06ms | 5.06ms | Archive::Zip::Member::_become |
| 1 | 1 | 1 | 4.97ms | 5.68ms | Archive::Zip::Member::BEGIN@21 |
| 1381 | 1 | 1 | 4.86ms | 4.86ms | Archive::Zip::Member::hasDataDescriptor |
| 137 | 1 | 1 | 545µs | 545µs | Archive::Zip::Member::_copyChunk |
| 1 | 1 | 1 | 238µs | 248µs | Archive::Zip::Member::BEGIN@5 |
| 1 | 1 | 1 | 23µs | 277µs | Archive::Zip::Member::BEGIN@22 |
| 1 | 1 | 1 | 23µs | 73µs | Archive::Zip::Member::BEGIN@23 |
| 1 | 1 | 1 | 21µs | 21µs | Archive::Zip::Member::BEGIN@8 |
| 1 | 1 | 1 | 16µs | 105µs | Archive::Zip::Member::BEGIN@6 |
| 1 | 1 | 1 | 16µs | 89µs | Archive::Zip::Member::BEGIN@24 |
| 1 | 1 | 1 | 15µs | 1.12ms | Archive::Zip::Member::BEGIN@13 |
| 1 | 1 | 1 | 12µs | 64µs | Archive::Zip::Member::BEGIN@28 |
| 1 | 1 | 1 | 12µs | 72µs | Archive::Zip::Member::BEGIN@26 |
| 1 | 1 | 1 | 12µs | 62µs | Archive::Zip::Member::BEGIN@33 |
| 1 | 1 | 1 | 12µs | 64µs | Archive::Zip::Member::BEGIN@34 |
| 1 | 1 | 1 | 12µs | 64µs | Archive::Zip::Member::BEGIN@27 |
| 1 | 1 | 1 | 12µs | 64µs | Archive::Zip::Member::BEGIN@29 |
| 1 | 1 | 1 | 12µs | 62µs | Archive::Zip::Member::BEGIN@35 |
| 1 | 1 | 1 | 11µs | 63µs | Archive::Zip::Member::BEGIN@32 |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_centralDirectoryHeaderSize |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_deflateChunk |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_deflater |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_localHeaderSize |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_noChunk |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_readOffset |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_readRawChunk |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_refreshLocalFileHeader |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_unixToDosTime |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_usesFileNamed |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_writeCentralDirectoryFileHeader |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_writeDataDescriptor |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_writeLocalFileHeader |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_writeSymbolicLink |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::_writeToFileHandle |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::cdExtraField |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::contents |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::crc32 |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::crc32String |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::externalFileAttributes |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::externalFileName |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::extraFields |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::fileAttributeFormat |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::fileComment |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::internalFileAttributes |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::isBinaryFile |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::isDirectory |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::isSymbolicLink |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::isTextFile |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::newDirectoryNamed |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::newFromFile |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::newFromString |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::setLastModFileDateTimeFromUnix |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::versionMadeBy |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::versionNeededToExtract |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::wasWritten |
| 0 | 0 | 0 | 0s | 0s | Archive::Zip::Member::writeLocalHeaderRelativeOffset |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Archive::Zip::Member; | ||||
| 2 | |||||
| 3 | # A generic membet of an archive | ||||
| 4 | |||||
| 5 | 2 | 72µs | 2 | 259µs | # spent 248µs (238+10) within Archive::Zip::Member::BEGIN@5 which was called:
# once (238µs+10µs) by installer::archivefiles::BEGIN@30 at line 5 # spent 248µs making 1 call to Archive::Zip::Member::BEGIN@5
# spent 10µs making 1 call to strict::import |
| 6 | 2 | 82µs | 2 | 193µs | # spent 105µs (16+88) within Archive::Zip::Member::BEGIN@6 which was called:
# once (16µs+88µs) by installer::archivefiles::BEGIN@30 at line 6 # spent 105µs making 1 call to Archive::Zip::Member::BEGIN@6
# spent 88µs making 1 call to vars::import |
| 7 | |||||
| 8 | # spent 21µs within Archive::Zip::Member::BEGIN@8 which was called:
# once (21µs+0s) by installer::archivefiles::BEGIN@30 at line 11 | ||||
| 9 | 2 | 20µs | $VERSION = '1.30'; | ||
| 10 | @ISA = qw( Archive::Zip ); | ||||
| 11 | 1 | 64µs | 1 | 21µs | } # spent 21µs making 1 call to Archive::Zip::Member::BEGIN@8 |
| 12 | |||||
| 13 | 1 | 1.10ms | # spent 1.12ms (15µs+1.10) within Archive::Zip::Member::BEGIN@13 which was called:
# once (15µs+1.10ms) by installer::archivefiles::BEGIN@30 at line 19 # spent 1.10ms making 1 call to Exporter::import | ||
| 14 | :CONSTANTS | ||||
| 15 | :MISC_CONSTANTS | ||||
| 16 | :ERROR_CODES | ||||
| 17 | :PKZIP_CONSTANTS | ||||
| 18 | :UTILITY_METHODS | ||||
| 19 | 2 | 60µs | 1 | 1.12ms | ); # spent 1.12ms making 1 call to Archive::Zip::Member::BEGIN@13 |
| 20 | |||||
| 21 | 2 | 3.08ms | 1 | 5.68ms | # spent 5.68ms (4.97+718µs) within Archive::Zip::Member::BEGIN@21 which was called:
# once (4.97ms+718µs) by installer::archivefiles::BEGIN@30 at line 21 # spent 5.68ms making 1 call to Archive::Zip::Member::BEGIN@21 |
| 22 | 2 | 56µs | 2 | 531µs | # spent 277µs (23+254) within Archive::Zip::Member::BEGIN@22 which was called:
# once (23µs+254µs) by installer::archivefiles::BEGIN@30 at line 22 # spent 277µs making 1 call to Archive::Zip::Member::BEGIN@22
# spent 254µs making 1 call to Exporter::import |
| 23 | 2 | 56µs | 2 | 123µs | # spent 73µs (23+50) within Archive::Zip::Member::BEGIN@23 which was called:
# once (23µs+50µs) by installer::archivefiles::BEGIN@30 at line 23 # spent 73µs making 1 call to Archive::Zip::Member::BEGIN@23
# spent 50µs making 1 call to Exporter::import |
| 24 | 2 | 61µs | 2 | 162µs | # spent 89µs (16+73) within Archive::Zip::Member::BEGIN@24 which was called:
# once (16µs+73µs) by installer::archivefiles::BEGIN@30 at line 24 # spent 89µs making 1 call to Archive::Zip::Member::BEGIN@24
# spent 73µs making 1 call to Exporter::import |
| 25 | |||||
| 26 | 2 | 59µs | 2 | 133µs | # spent 72µs (12+60) within Archive::Zip::Member::BEGIN@26 which was called:
# once (12µs+60µs) by installer::archivefiles::BEGIN@30 at line 26 # spent 72µs making 1 call to Archive::Zip::Member::BEGIN@26
# spent 60µs making 1 call to constant::import |
| 27 | 2 | 59µs | 2 | 117µs | # spent 64µs (12+52) within Archive::Zip::Member::BEGIN@27 which was called:
# once (12µs+52µs) by installer::archivefiles::BEGIN@30 at line 27 # spent 64µs making 1 call to Archive::Zip::Member::BEGIN@27
# spent 52µs making 1 call to constant::import |
| 28 | 2 | 58µs | 2 | 115µs | # spent 64µs (12+51) within Archive::Zip::Member::BEGIN@28 which was called:
# once (12µs+51µs) by installer::archivefiles::BEGIN@30 at line 28 # spent 64µs making 1 call to Archive::Zip::Member::BEGIN@28
# spent 51µs making 1 call to constant::import |
| 29 | 2 | 61µs | 2 | 117µs | # spent 64µs (12+52) within Archive::Zip::Member::BEGIN@29 which was called:
# once (12µs+52µs) by installer::archivefiles::BEGIN@30 at line 29 # spent 64µs making 1 call to Archive::Zip::Member::BEGIN@29
# spent 52µs making 1 call to constant::import |
| 30 | |||||
| 31 | # Unix perms for default creation of files/dirs. | ||||
| 32 | 2 | 463µs | 2 | 114µs | # spent 63µs (11+51) within Archive::Zip::Member::BEGIN@32 which was called:
# once (11µs+51µs) by installer::archivefiles::BEGIN@30 at line 32 # spent 63µs making 1 call to Archive::Zip::Member::BEGIN@32
# spent 51µs making 1 call to constant::import |
| 33 | 2 | 57µs | 2 | 111µs | # spent 62µs (12+49) within Archive::Zip::Member::BEGIN@33 which was called:
# once (12µs+49µs) by installer::archivefiles::BEGIN@30 at line 33 # spent 62µs making 1 call to Archive::Zip::Member::BEGIN@33
# spent 49µs making 1 call to constant::import |
| 34 | 2 | 55µs | 2 | 115µs | # spent 64µs (12+52) within Archive::Zip::Member::BEGIN@34 which was called:
# once (12µs+52µs) by installer::archivefiles::BEGIN@30 at line 34 # spent 64µs making 1 call to Archive::Zip::Member::BEGIN@34
# spent 52µs making 1 call to constant::import |
| 35 | 2 | 9.55ms | 2 | 113µs | # spent 62µs (12+51) within Archive::Zip::Member::BEGIN@35 which was called:
# once (12µs+51µs) by installer::archivefiles::BEGIN@30 at line 35 # spent 62µs making 1 call to Archive::Zip::Member::BEGIN@35
# spent 50µs making 1 call to constant::import |
| 36 | |||||
| 37 | # Returns self if successful, else undef | ||||
| 38 | # Assumes that fh is positioned at beginning of central directory file header. | ||||
| 39 | # Leaves fh positioned immediately after file header or EOCD signature. | ||||
| 40 | # spent 971ms (109+862) within Archive::Zip::Member::_newFromZipFile which was called 10192 times, avg 95µs/call:
# 10192 times (109ms+862ms) by Archive::Zip::Archive::readFromFileHandle at line 599 of Archive/Zip/Archive.pm, avg 95µs/call | ||||
| 41 | 30576 | 119ms | my $class = shift; | ||
| 42 | 20384 | 862ms | my $self = $class->ZIPFILEMEMBERCLASS->_newFromZipFile(@_); # spent 850ms making 10192 calls to Archive::Zip::ZipFileMember::_newFromZipFile, avg 83µs/call
# spent 11.7ms making 10192 calls to Archive::Zip::Member::ZIPFILEMEMBERCLASS, avg 1µs/call | ||
| 43 | return $self; | ||||
| 44 | } | ||||
| 45 | |||||
| 46 | sub newFromString { | ||||
| 47 | my $class = shift; | ||||
| 48 | |||||
| 49 | my ( $stringOrStringRef, $fileName ); | ||||
| 50 | if ( ref( $_[0] ) eq 'HASH' ) { | ||||
| 51 | $stringOrStringRef = $_[0]->{string}; | ||||
| 52 | $fileName = $_[0]->{zipName}; | ||||
| 53 | } | ||||
| 54 | else { | ||||
| 55 | ( $stringOrStringRef, $fileName ) = @_; | ||||
| 56 | } | ||||
| 57 | |||||
| 58 | my $self = $class->STRINGMEMBERCLASS->_newFromString( $stringOrStringRef, | ||||
| 59 | $fileName ); | ||||
| 60 | return $self; | ||||
| 61 | } | ||||
| 62 | |||||
| 63 | sub newFromFile { | ||||
| 64 | my $class = shift; | ||||
| 65 | |||||
| 66 | my ( $fileName, $zipName ); | ||||
| 67 | if ( ref( $_[0] ) eq 'HASH' ) { | ||||
| 68 | $fileName = $_[0]->{fileName}; | ||||
| 69 | $zipName = $_[0]->{zipName}; | ||||
| 70 | } | ||||
| 71 | else { | ||||
| 72 | ( $fileName, $zipName ) = @_; | ||||
| 73 | } | ||||
| 74 | |||||
| 75 | my $self = $class->NEWFILEMEMBERCLASS->_newFromFileNamed( $fileName, | ||||
| 76 | $zipName ); | ||||
| 77 | return $self; | ||||
| 78 | } | ||||
| 79 | |||||
| 80 | sub newDirectoryNamed { | ||||
| 81 | my $class = shift; | ||||
| 82 | |||||
| 83 | my ( $directoryName, $newName ); | ||||
| 84 | if ( ref( $_[0] ) eq 'HASH' ) { | ||||
| 85 | $directoryName = $_[0]->{directoryName}; | ||||
| 86 | $newName = $_[0]->{zipName}; | ||||
| 87 | } | ||||
| 88 | else { | ||||
| 89 | ( $directoryName, $newName ) = @_; | ||||
| 90 | } | ||||
| 91 | |||||
| 92 | my $self = $class->DIRECTORYMEMBERCLASS->_newNamed( $directoryName, | ||||
| 93 | $newName ); | ||||
| 94 | return $self; | ||||
| 95 | } | ||||
| 96 | |||||
| 97 | # spent 738ms (228+510) within Archive::Zip::Member::new which was called 10192 times, avg 72µs/call:
# 10192 times (228ms+510ms) by Archive::Zip::ZipFileMember::_newFromZipFile at line 27 of Archive/Zip/ZipFileMember.pm, avg 72µs/call | ||||
| 98 | 50960 | 241ms | my $class = shift; | ||
| 99 | my $self = { | ||||
| 100 | 'lastModFileDateTime' => 0, | ||||
| 101 | 'fileAttributeFormat' => FA_UNIX, | ||||
| 102 | 'versionMadeBy' => 20, | ||||
| 103 | 'versionNeededToExtract' => 20, | ||||
| 104 | 'bitFlag' => 0, | ||||
| 105 | 'compressionMethod' => COMPRESSION_STORED, | ||||
| 106 | 'desiredCompressionMethod' => COMPRESSION_STORED, | ||||
| 107 | 'desiredCompressionLevel' => COMPRESSION_LEVEL_NONE, | ||||
| 108 | 'internalFileAttributes' => 0, | ||||
| 109 | 'externalFileAttributes' => 0, # set later | ||||
| 110 | 'fileName' => '', | ||||
| 111 | 'cdExtraField' => '', | ||||
| 112 | 'localExtraField' => '', | ||||
| 113 | 'fileComment' => '', | ||||
| 114 | 'crc32' => 0, | ||||
| 115 | 'compressedSize' => 0, | ||||
| 116 | 'uncompressedSize' => 0, | ||||
| 117 | 'isSymbolicLink' => 0, | ||||
| 118 | @_ | ||||
| 119 | }; | ||||
| 120 | bless( $self, $class ); | ||||
| 121 | 20384 | 510ms | $self->unixFileAttributes( $self->DEFAULT_FILE_PERMISSIONS ); # spent 497ms making 10192 calls to Archive::Zip::Member::unixFileAttributes, avg 49µs/call
# spent 13.7ms making 10192 calls to Archive::Zip::Member::DEFAULT_FILE_PERMISSIONS, avg 1µs/call | ||
| 122 | return $self; | ||||
| 123 | } | ||||
| 124 | |||||
| 125 | # spent 1.29s (76.4ms+1.21) within Archive::Zip::Member::_becomeDirectoryIfNecessary which was called 9982 times, avg 129µs/call:
# 9982 times (76.4ms+1.21s) by Archive::Zip::Archive::readFromFileHandle at line 610 of Archive/Zip/Archive.pm, avg 129µs/call | ||||
| 126 | 29946 | 70.6ms | my $self = shift; | ||
| 127 | 11363 | 1.21s | $self->_become(DIRECTORYMEMBERCLASS) # spent 1.09s making 1381 calls to Archive::Zip::ZipFileMember::_become, avg 793µs/call
# spent 116ms making 9982 calls to Archive::Zip::ZipFileMember::isDirectory, avg 12µs/call | ||
| 128 | if $self->isDirectory(); | ||||
| 129 | return $self; | ||||
| 130 | } | ||||
| 131 | |||||
| 132 | # Morph into given class (do whatever cleanup I need to do) | ||||
| 133 | # spent 5.06ms within Archive::Zip::Member::_become which was called 1381 times, avg 4µs/call:
# 1381 times (5.06ms+0s) by Archive::Zip::FileMember::_become at line 61 of Archive/Zip/FileMember.pm, avg 4µs/call | ||||
| 134 | 1381 | 7.96ms | return bless( $_[0], $_[1] ); | ||
| 135 | } | ||||
| 136 | |||||
| 137 | sub versionMadeBy { | ||||
| 138 | shift->{'versionMadeBy'}; | ||||
| 139 | } | ||||
| 140 | |||||
| 141 | sub fileAttributeFormat { | ||||
| 142 | my $self = shift; | ||||
| 143 | |||||
| 144 | if (@_) { | ||||
| 145 | $self->{fileAttributeFormat} = ( ref( $_[0] ) eq 'HASH' ) | ||||
| 146 | ? $_[0]->{format} : $_[0]; | ||||
| 147 | } | ||||
| 148 | else { | ||||
| 149 | return $self->{fileAttributeFormat}; | ||||
| 150 | } | ||||
| 151 | } | ||||
| 152 | |||||
| 153 | sub versionNeededToExtract { | ||||
| 154 | shift->{'versionNeededToExtract'}; | ||||
| 155 | } | ||||
| 156 | |||||
| 157 | # spent 1.23s (633ms+601ms) within Archive::Zip::Member::bitFlag which was called 17202 times, avg 72µs/call:
# 17202 times (633ms+601ms) by Archive::Zip::Member::isEncrypted at line 441, avg 72µs/call | ||||
| 158 | 51606 | 405ms | my $self = shift; | ||
| 159 | |||||
| 160 | # Set General Purpose Bit Flags according to the desiredCompressionLevel setting | ||||
| 161 | 154818 | 601ms | if ( $self->desiredCompressionLevel == 1 || $self->desiredCompressionLevel == 2 ) { # spent 601ms making 154818 calls to Archive::Zip::Member::desiredCompressionLevel, avg 4µs/call | ||
| 162 | $self->{'bitFlag'} = DEFLATING_COMPRESSION_FAST; | ||||
| 163 | } elsif ( $self->desiredCompressionLevel == 3 || $self->desiredCompressionLevel == 4 | ||||
| 164 | || $self->desiredCompressionLevel == 5 || $self->desiredCompressionLevel == 6 | ||||
| 165 | || $self->desiredCompressionLevel == 7 ) { | ||||
| 166 | $self->{'bitFlag'} = DEFLATING_COMPRESSION_NORMAL; | ||||
| 167 | } elsif ( $self->desiredCompressionLevel == 8 || $self->desiredCompressionLevel == 9 ) { | ||||
| 168 | $self->{'bitFlag'} = DEFLATING_COMPRESSION_MAXIMUM; | ||||
| 169 | } | ||||
| 170 | $self->{'bitFlag'}; | ||||
| 171 | } | ||||
| 172 | |||||
| 173 | # spent 120ms within Archive::Zip::Member::compressionMethod which was called 55105 times, avg 2µs/call:
# 17572 times (32.2ms+0s) by Archive::Zip::Member::rewindData at line 884, avg 2µs/call
# 10349 times (26.3ms+0s) by Archive::Zip::Member::readChunk at line 794, avg 3µs/call
# 9982 times (22.1ms+0s) by Archive::Zip::ZipFileMember::_readCentralDirectoryFileHeader at line 373 of Archive/Zip/ZipFileMember.pm, avg 2µs/call
# 8601 times (20.0ms+0s) by Archive::Zip::Member::rewindData at line 922, avg 2µs/call
# 8601 times (19.0ms+0s) by Archive::Zip::Member::rewindData at line 880, avg 2µs/call | ||||
| 174 | 55105 | 206ms | shift->{'compressionMethod'}; | ||
| 175 | } | ||||
| 176 | |||||
| 177 | # spent 236ms within Archive::Zip::Member::desiredCompressionMethod which was called 36388 times, avg 6µs/call:
# 9982 times (63.2ms+0s) by Archive::Zip::ZipFileMember::_readCentralDirectoryFileHeader at line 373 of Archive/Zip/ZipFileMember.pm, avg 6µs/call
# 8971 times (38.3ms+0s) by Archive::Zip::Member::rewindData at line 884, avg 4µs/call
# 8601 times (74.5ms+0s) by Archive::Zip::Member::extractToFileHandle at line 989, avg 9µs/call
# 8601 times (58.6ms+0s) by Archive::Zip::Member::extractToFileHandle at line 992, avg 7µs/call
# 233 times (1.67ms+0s) by Archive::Zip::Member::rewindData at line 876, avg 7µs/call | ||||
| 178 | 258684 | 302ms | my $self = shift; | ||
| 179 | my $newDesiredCompressionMethod = | ||||
| 180 | ( ref( $_[0] ) eq 'HASH' ) ? shift->{compressionMethod} : shift; | ||||
| 181 | my $oldDesiredCompressionMethod = $self->{'desiredCompressionMethod'}; | ||||
| 182 | if ( defined($newDesiredCompressionMethod) ) { | ||||
| 183 | $self->{'desiredCompressionMethod'} = $newDesiredCompressionMethod; | ||||
| 184 | if ( $newDesiredCompressionMethod == COMPRESSION_STORED ) { | ||||
| 185 | $self->{'desiredCompressionLevel'} = 0; | ||||
| 186 | $self->{'bitFlag'} &= ~GPBF_HAS_DATA_DESCRIPTOR_MASK; | ||||
| 187 | |||||
| 188 | } elsif ( $oldDesiredCompressionMethod == COMPRESSION_STORED ) { | ||||
| 189 | $self->{'desiredCompressionLevel'} = COMPRESSION_LEVEL_DEFAULT; | ||||
| 190 | } | ||||
| 191 | } | ||||
| 192 | return $oldDesiredCompressionMethod; | ||||
| 193 | } | ||||
| 194 | |||||
| 195 | # spent 601ms within Archive::Zip::Member::desiredCompressionLevel which was called 154818 times, avg 4µs/call:
# 154818 times (601ms+0s) by Archive::Zip::Member::bitFlag at line 161, avg 4µs/call | ||||
| 196 | 774090 | 854ms | my $self = shift; | ||
| 197 | my $newDesiredCompressionLevel = | ||||
| 198 | ( ref( $_[0] ) eq 'HASH' ) ? shift->{compressionLevel} : shift; | ||||
| 199 | my $oldDesiredCompressionLevel = $self->{'desiredCompressionLevel'}; | ||||
| 200 | if ( defined($newDesiredCompressionLevel) ) { | ||||
| 201 | $self->{'desiredCompressionLevel'} = $newDesiredCompressionLevel; | ||||
| 202 | $self->{'desiredCompressionMethod'} = ( | ||||
| 203 | $newDesiredCompressionLevel | ||||
| 204 | ? COMPRESSION_DEFLATED | ||||
| 205 | : COMPRESSION_STORED | ||||
| 206 | ); | ||||
| 207 | } | ||||
| 208 | return $oldDesiredCompressionLevel; | ||||
| 209 | } | ||||
| 210 | |||||
| 211 | # spent 278ms (268+9.69) within Archive::Zip::Member::fileName which was called 61483 times, avg 5µs/call:
# 20174 times (77.4ms+0s) by Archive::Zip::ZipFileMember::isDirectory at line 43 of Archive/Zip/ZipFileMember.pm, avg 4µs/call
# 17202 times (69.7ms+0s) by Archive::Zip::Archive::memberNames at line 72 of Archive/Zip/Archive.pm, avg 4µs/call
# 8601 times (51.0ms+0s) by Archive::Zip::Archive::extractTree at line 818 of Archive/Zip/Archive.pm, avg 6µs/call
# 8601 times (33.3ms+0s) by Archive::Zip::Archive::membersMatching at line 88 of Archive/Zip/Archive.pm, avg 4µs/call
# 5524 times (24.1ms+0s) by Archive::Zip::DirectoryMember::fileName at line 71 of Archive/Zip/DirectoryMember.pm, avg 4µs/call
# 1381 times (12.4ms+9.69ms) by Archive::Zip::ZipFileMember::_readLocalFileHeader at line 229 of Archive/Zip/ZipFileMember.pm, avg 16µs/call | ||||
| 212 | 248694 | 376ms | my $self = shift; | ||
| 213 | my $newName = shift; | ||||
| 214 | if ($newName) { | ||||
| 215 | 1381 | 9.69ms | $newName =~ s{[\\/]+}{/}g; # deal with dos/windoze problems # spent 9.69ms making 1381 calls to Archive::Zip::Member::CORE:subst, avg 7µs/call | ||
| 216 | $self->{'fileName'} = $newName; | ||||
| 217 | } | ||||
| 218 | return $self->{'fileName'}; | ||||
| 219 | } | ||||
| 220 | |||||
| 221 | # spent 229ms (155+74.3) within Archive::Zip::Member::lastModFileDateTime which was called 19964 times, avg 11µs/call:
# 19964 times (155ms+74.3ms) by Archive::Zip::Member::lastModTime at line 229, avg 11µs/call | ||||
| 222 | 59892 | 262ms | my $modTime = shift->{'lastModFileDateTime'}; | ||
| 223 | 19964 | 74.3ms | $modTime =~ m/^(\d+)$/; # untaint # spent 74.3ms making 19964 calls to Archive::Zip::Member::CORE:match, avg 4µs/call | ||
| 224 | return $1; | ||||
| 225 | } | ||||
| 226 | |||||
| 227 | # spent 2.89s (210ms+2.69) within Archive::Zip::Member::lastModTime which was called 19964 times, avg 145µs/call:
# 17202 times (181ms+2.31s) by Archive::Zip::Member::extractToFileNamed at line 492, avg 145µs/call
# 2762 times (28.2ms+373ms) by Archive::Zip::DirectoryMember::extractToFileNamed at line 63 of Archive/Zip/DirectoryMember.pm, avg 145µs/call | ||||
| 228 | 39928 | 169ms | my $self = shift; | ||
| 229 | 39928 | 2.69s | return _dosToUnixTime( $self->lastModFileDateTime() ); # spent 2.46s making 19964 calls to Archive::Zip::Member::_dosToUnixTime, avg 123µs/call
# spent 229ms making 19964 calls to Archive::Zip::Member::lastModFileDateTime, avg 11µs/call | ||
| 230 | } | ||||
| 231 | |||||
| 232 | sub setLastModFileDateTimeFromUnix { | ||||
| 233 | my $self = shift; | ||||
| 234 | my $time_t = shift; | ||||
| 235 | $self->{'lastModFileDateTime'} = _unixToDosTime($time_t); | ||||
| 236 | } | ||||
| 237 | |||||
| 238 | sub internalFileAttributes { | ||||
| 239 | shift->{'internalFileAttributes'}; | ||||
| 240 | } | ||||
| 241 | |||||
| 242 | sub externalFileAttributes { | ||||
| 243 | shift->{'externalFileAttributes'}; | ||||
| 244 | } | ||||
| 245 | |||||
| 246 | # Convert UNIX permissions into proper value for zip file | ||||
| 247 | # Usable as a function or a method | ||||
| 248 | # spent 40.7ms within Archive::Zip::Member::_mapPermissionsFromUnix which was called 10192 times, avg 4µs/call:
# 10192 times (40.7ms+0s) by Archive::Zip::Member::unixFileAttributes at line 363, avg 4µs/call | ||||
| 249 | 50960 | 57.6ms | my $self = shift; | ||
| 250 | my $mode = shift; | ||||
| 251 | my $attribs = $mode << 16; | ||||
| 252 | |||||
| 253 | # Microsoft Windows Explorer needs this bit set for directories | ||||
| 254 | if ( $mode & DIRECTORY_ATTRIB ) { | ||||
| 255 | $attribs |= 16; | ||||
| 256 | } | ||||
| 257 | |||||
| 258 | return $attribs; | ||||
| 259 | |||||
| 260 | # TODO: map more MS-DOS perms | ||||
| 261 | } | ||||
| 262 | |||||
| 263 | # Convert ZIP permissions into Unix ones | ||||
| 264 | # | ||||
| 265 | # This was taken from Info-ZIP group's portable UnZip | ||||
| 266 | # zipfile-extraction program, version 5.50. | ||||
| 267 | # http://www.info-zip.org/pub/infozip/ | ||||
| 268 | # | ||||
| 269 | # See the mapattr() function in unix/unix.c | ||||
| 270 | # See the attribute format constants in unzpriv.h | ||||
| 271 | # | ||||
| 272 | # XXX Note that there's one situation that isn't implemented | ||||
| 273 | # yet that depends on the "extra field." | ||||
| 274 | # spent 215ms (178+37.4) within Archive::Zip::Member::_mapPermissionsToUnix which was called 20174 times, avg 11µs/call:
# 20174 times (178ms+37.4ms) by Archive::Zip::Member::unixFileAttributes at line 350, avg 11µs/call | ||||
| 275 | 181566 | 196ms | my $self = shift; | ||
| 276 | |||||
| 277 | my $format = $self->{'fileAttributeFormat'}; | ||||
| 278 | my $attribs = $self->{'externalFileAttributes'}; | ||||
| 279 | |||||
| 280 | my $mode = 0; | ||||
| 281 | |||||
| 282 | if ( $format == FA_AMIGA ) { | ||||
| 283 | $attribs = $attribs >> 17 & 7; # Amiga RWE bits | ||||
| 284 | $mode = $attribs << 6 | $attribs << 3 | $attribs; | ||||
| 285 | return $mode; | ||||
| 286 | } | ||||
| 287 | |||||
| 288 | if ( $format == FA_THEOS ) { | ||||
| 289 | $attribs &= 0xF1FFFFFF; | ||||
| 290 | if ( ( $attribs & 0xF0000000 ) != 0x40000000 ) { | ||||
| 291 | $attribs &= 0x01FFFFFF; # not a dir, mask all ftype bits | ||||
| 292 | } | ||||
| 293 | else { | ||||
| 294 | $attribs &= 0x41FFFFFF; # leave directory bit as set | ||||
| 295 | } | ||||
| 296 | } | ||||
| 297 | |||||
| 298 | if ( $format == FA_UNIX | ||||
| 299 | || $format == FA_VAX_VMS | ||||
| 300 | || $format == FA_ACORN | ||||
| 301 | || $format == FA_ATARI_ST | ||||
| 302 | || $format == FA_BEOS | ||||
| 303 | || $format == FA_QDOS | ||||
| 304 | || $format == FA_TANDEM ) | ||||
| 305 | { | ||||
| 306 | $mode = $attribs >> 16; | ||||
| 307 | 10192 | 37.4ms | return $mode if $mode != 0 or not $self->localExtraField; # spent 37.4ms making 10192 calls to Archive::Zip::Member::localExtraField, avg 4µs/call | ||
| 308 | |||||
| 309 | # warn("local extra field is: ", $self->localExtraField, "\n"); | ||||
| 310 | |||||
| 311 | # XXX This condition is not implemented | ||||
| 312 | # I'm just including the comments from the info-zip section for now. | ||||
| 313 | |||||
| 314 | # Some (non-Info-ZIP) implementations of Zip for Unix and | ||||
| 315 | # VMS (and probably others ??) leave 0 in the upper 16-bit | ||||
| 316 | # part of the external_file_attributes field. Instead, they | ||||
| 317 | # store file permission attributes in some extra field. | ||||
| 318 | # As a work-around, we search for the presence of one of | ||||
| 319 | # these extra fields and fall back to the MSDOS compatible | ||||
| 320 | # part of external_file_attributes if one of the known | ||||
| 321 | # e.f. types has been detected. | ||||
| 322 | # Later, we might implement extraction of the permission | ||||
| 323 | # bits from the VMS extra field. But for now, the work-around | ||||
| 324 | # should be sufficient to provide "readable" extracted files. | ||||
| 325 | # (For ASI Unix e.f., an experimental remap from the e.f. | ||||
| 326 | # mode value IS already provided!) | ||||
| 327 | } | ||||
| 328 | |||||
| 329 | # PKWARE's PKZip for Unix marks entries as FA_MSDOS, but stores the | ||||
| 330 | # Unix attributes in the upper 16 bits of the external attributes | ||||
| 331 | # field, just like Info-ZIP's Zip for Unix. We try to use that | ||||
| 332 | # value, after a check for consistency with the MSDOS attribute | ||||
| 333 | # bits (see below). | ||||
| 334 | if ( $format == FA_MSDOS ) { | ||||
| 335 | $mode = $attribs >> 16; | ||||
| 336 | } | ||||
| 337 | |||||
| 338 | # FA_MSDOS, FA_OS2_HPFS, FA_WINDOWS_NTFS, FA_MACINTOSH, FA_TOPS20 | ||||
| 339 | $attribs = !( $attribs & 1 ) << 1 | ( $attribs & 0x10 ) >> 4; | ||||
| 340 | |||||
| 341 | # keep previous $mode setting when its "owner" | ||||
| 342 | # part appears to be consistent with DOS attribute flags! | ||||
| 343 | return $mode if ( $mode & 0700 ) == ( 0400 | $attribs << 6 ); | ||||
| 344 | $mode = 0444 | $attribs << 6 | $attribs << 3 | $attribs; | ||||
| 345 | return $mode; | ||||
| 346 | } | ||||
| 347 | |||||
| 348 | # spent 665ms (299+366) within Archive::Zip::Member::unixFileAttributes which was called 20174 times, avg 33µs/call:
# 10192 times (206ms+291ms) by Archive::Zip::Member::new at line 121, avg 49µs/call
# 8601 times (82.2ms+65.8ms) by Archive::Zip::Member::extractToFileNamed at line 490, avg 17µs/call
# 1381 times (10.8ms+9.45ms) by Archive::Zip::DirectoryMember::extractToFileNamed at line 61 of Archive/Zip/DirectoryMember.pm, avg 15µs/call | ||||
| 349 | 151830 | 253ms | my $self = shift; | ||
| 350 | 20174 | 215ms | my $oldPerms = $self->_mapPermissionsToUnix; # spent 215ms making 20174 calls to Archive::Zip::Member::_mapPermissionsToUnix, avg 11µs/call | ||
| 351 | |||||
| 352 | my $perms; | ||||
| 353 | if ( @_ ) { | ||||
| 354 | $perms = ( ref( $_[0] ) eq 'HASH' ) ? $_[0]->{attributes} : $_[0]; | ||||
| 355 | |||||
| 356 | 10192 | 110ms | if ( $self->isDirectory ) { # spent 110ms making 10192 calls to Archive::Zip::ZipFileMember::isDirectory, avg 11µs/call | ||
| 357 | $perms &= ~FILE_ATTRIB; | ||||
| 358 | $perms |= DIRECTORY_ATTRIB; | ||||
| 359 | } else { | ||||
| 360 | $perms &= ~DIRECTORY_ATTRIB; | ||||
| 361 | $perms |= FILE_ATTRIB; | ||||
| 362 | } | ||||
| 363 | 10192 | 40.7ms | $self->{externalFileAttributes} = $self->_mapPermissionsFromUnix($perms); # spent 40.7ms making 10192 calls to Archive::Zip::Member::_mapPermissionsFromUnix, avg 4µs/call | ||
| 364 | } | ||||
| 365 | |||||
| 366 | return $oldPerms; | ||||
| 367 | } | ||||
| 368 | |||||
| 369 | # spent 37.4ms within Archive::Zip::Member::localExtraField which was called 10192 times, avg 4µs/call:
# 10192 times (37.4ms+0s) by Archive::Zip::Member::_mapPermissionsToUnix at line 307, avg 4µs/call | ||||
| 370 | 30576 | 57.4ms | my $self = shift; | ||
| 371 | |||||
| 372 | if (@_) { | ||||
| 373 | $self->{localExtraField} = ( ref( $_[0] ) eq 'HASH' ) | ||||
| 374 | ? $_[0]->{field} : $_[0]; | ||||
| 375 | } | ||||
| 376 | else { | ||||
| 377 | return $self->{localExtraField}; | ||||
| 378 | } | ||||
| 379 | } | ||||
| 380 | |||||
| 381 | sub cdExtraField { | ||||
| 382 | my $self = shift; | ||||
| 383 | |||||
| 384 | if (@_) { | ||||
| 385 | $self->{cdExtraField} = ( ref( $_[0] ) eq 'HASH' ) | ||||
| 386 | ? $_[0]->{field} : $_[0]; | ||||
| 387 | } | ||||
| 388 | else { | ||||
| 389 | return $self->{cdExtraField}; | ||||
| 390 | } | ||||
| 391 | } | ||||
| 392 | |||||
| 393 | sub extraFields { | ||||
| 394 | my $self = shift; | ||||
| 395 | return $self->localExtraField() . $self->cdExtraField(); | ||||
| 396 | } | ||||
| 397 | |||||
| 398 | sub fileComment { | ||||
| 399 | my $self = shift; | ||||
| 400 | |||||
| 401 | if (@_) { | ||||
| 402 | $self->{fileComment} = ( ref( $_[0] ) eq 'HASH' ) | ||||
| 403 | ? pack( 'C0a*', $_[0]->{comment} ) : pack( 'C0a*', $_[0] ); | ||||
| 404 | } | ||||
| 405 | else { | ||||
| 406 | return $self->{fileComment}; | ||||
| 407 | } | ||||
| 408 | } | ||||
| 409 | |||||
| 410 | # spent 4.86ms within Archive::Zip::Member::hasDataDescriptor which was called 1381 times, avg 4µs/call:
# 1381 times (4.86ms+0s) by Archive::Zip::ZipFileMember::_readLocalFileHeader at line 242 of Archive/Zip/ZipFileMember.pm, avg 4µs/call | ||||
| 411 | 4143 | 7.19ms | my $self = shift; | ||
| 412 | if (@_) { | ||||
| 413 | my $shouldHave = shift; | ||||
| 414 | if ($shouldHave) { | ||||
| 415 | $self->{'bitFlag'} |= GPBF_HAS_DATA_DESCRIPTOR_MASK; | ||||
| 416 | } | ||||
| 417 | else { | ||||
| 418 | $self->{'bitFlag'} &= ~GPBF_HAS_DATA_DESCRIPTOR_MASK; | ||||
| 419 | } | ||||
| 420 | } | ||||
| 421 | return $self->{'bitFlag'} & GPBF_HAS_DATA_DESCRIPTOR_MASK; | ||||
| 422 | } | ||||
| 423 | |||||
| 424 | sub crc32 { | ||||
| 425 | shift->{'crc32'}; | ||||
| 426 | } | ||||
| 427 | |||||
| 428 | sub crc32String { | ||||
| 429 | sprintf( "%08x", shift->{'crc32'} ); | ||||
| 430 | } | ||||
| 431 | |||||
| 432 | # spent 18.7ms within Archive::Zip::Member::compressedSize which was called 8231 times, avg 2µs/call:
# 8231 times (18.7ms+0s) by Archive::Zip::Member::rewindData at line 922, avg 2µs/call | ||||
| 433 | 8231 | 30.3ms | shift->{'compressedSize'}; | ||
| 434 | } | ||||
| 435 | |||||
| 436 | # spent 44.3ms within Archive::Zip::Member::uncompressedSize which was called 18953 times, avg 2µs/call:
# 8601 times (22.2ms+0s) by Archive::Zip::Member::rewindData at line 876, avg 3µs/call
# 8601 times (18.1ms+0s) by Archive::Zip::Member::_writeData at line 1058, avg 2µs/call
# 1381 times (3.29ms+0s) by Archive::Zip::ZipFileMember::isDirectory at line 43 of Archive/Zip/ZipFileMember.pm, avg 2µs/call
# 370 times (721µs+0s) by Archive::Zip::Member::rewindData at line 922, avg 2µs/call | ||||
| 437 | 18953 | 77.5ms | shift->{'uncompressedSize'}; | ||
| 438 | } | ||||
| 439 | |||||
| 440 | # spent 1.33s (98.6ms+1.23) within Archive::Zip::Member::isEncrypted which was called 17202 times, avg 77µs/call:
# 8601 times (48.8ms+619ms) by Archive::Zip::Member::extractToFileHandle at line 986, avg 78µs/call
# 8601 times (49.8ms+614ms) by Archive::Zip::Member::extractToFileNamed at line 484, avg 77µs/call | ||||
| 441 | 17202 | 96.9ms | 17202 | 1.23s | shift->bitFlag() & GPBF_ENCRYPTED_MASK; # spent 1.23s making 17202 calls to Archive::Zip::Member::bitFlag, avg 72µs/call |
| 442 | } | ||||
| 443 | |||||
| 444 | sub isTextFile { | ||||
| 445 | my $self = shift; | ||||
| 446 | my $bit = $self->internalFileAttributes() & IFA_TEXT_FILE_MASK; | ||||
| 447 | if (@_) { | ||||
| 448 | my $flag = ( ref( $_[0] ) eq 'HASH' ) ? shift->{flag} : shift; | ||||
| 449 | $self->{'internalFileAttributes'} &= ~IFA_TEXT_FILE_MASK; | ||||
| 450 | $self->{'internalFileAttributes'} |= | ||||
| 451 | ( $flag ? IFA_TEXT_FILE: IFA_BINARY_FILE ); | ||||
| 452 | } | ||||
| 453 | return $bit == IFA_TEXT_FILE; | ||||
| 454 | } | ||||
| 455 | |||||
| 456 | sub isBinaryFile { | ||||
| 457 | my $self = shift; | ||||
| 458 | my $bit = $self->internalFileAttributes() & IFA_TEXT_FILE_MASK; | ||||
| 459 | if (@_) { | ||||
| 460 | my $flag = shift; | ||||
| 461 | $self->{'internalFileAttributes'} &= ~IFA_TEXT_FILE_MASK; | ||||
| 462 | $self->{'internalFileAttributes'} |= | ||||
| 463 | ( $flag ? IFA_BINARY_FILE: IFA_TEXT_FILE ); | ||||
| 464 | } | ||||
| 465 | return $bit == IFA_BINARY_FILE; | ||||
| 466 | } | ||||
| 467 | |||||
| 468 | # spent 38.7s (522ms+38.2) within Archive::Zip::Member::extractToFileNamed which was called 8601 times, avg 4.50ms/call:
# 8601 times (522ms+38.2s) by Archive::Zip::Archive::extractTree at line 822 of Archive/Zip/Archive.pm, avg 4.50ms/call | ||||
| 469 | 111813 | 4.28s | my $self = shift; | ||
| 470 | |||||
| 471 | # local FS name | ||||
| 472 | my $name = ( ref( $_[0] ) eq 'HASH' ) ? $_[0]->{name} : $_[0]; | ||||
| 473 | $self->{'isSymbolicLink'} = 0; | ||||
| 474 | |||||
| 475 | # Check if the file / directory is a symbolic link or not | ||||
| 476 | if ( $self->{'externalFileAttributes'} == 0xA1FF0000 ) { | ||||
| 477 | $self->{'isSymbolicLink'} = 1; | ||||
| 478 | $self->{'newName'} = $name; | ||||
| 479 | my ( $status, $fh ) = _newFileHandle( $name, 'r' ); | ||||
| 480 | my $retval = $self->extractToFileHandle($fh); | ||||
| 481 | $fh->close(); | ||||
| 482 | } else { | ||||
| 483 | #return _writeSymbolicLink($self, $name) if $self->isSymbolicLink(); | ||||
| 484 | 8601 | 664ms | return _error("encryption unsupported") if $self->isEncrypted(); # spent 664ms making 8601 calls to Archive::Zip::Member::isEncrypted, avg 77µs/call | ||
| 485 | 17202 | 2.11s | mkpath( dirname($name) ); # croaks on error # spent 1.32s making 8601 calls to File::Path::mkpath, avg 153µs/call
# spent 794ms making 8601 calls to File::Basename::dirname, avg 92µs/call | ||
| 486 | 8601 | 8.47s | my ( $status, $fh ) = _newFileHandle( $name, 'w' ); # spent 8.47s making 8601 calls to Archive::Zip::_newFileHandle, avg 985µs/call | ||
| 487 | return _ioError("Can't open file $name for write") unless $status; | ||||
| 488 | 8601 | 18.1s | my $retval = $self->extractToFileHandle($fh); # spent 18.1s making 8601 calls to Archive::Zip::Member::extractToFileHandle, avg 2.10ms/call | ||
| 489 | 8601 | 2.45s | $fh->close(); # spent 2.45s making 8601 calls to IO::Handle::close, avg 284µs/call | ||
| 490 | 17202 | 2.20s | chmod ($self->unixFileAttributes(), $name) # spent 2.05s making 8601 calls to Archive::Zip::Member::CORE:chmod, avg 239µs/call
# spent 148ms making 8601 calls to Archive::Zip::Member::unixFileAttributes, avg 17µs/call | ||
| 491 | or return _error("Can't chmod() ${name}: $!"); | ||||
| 492 | 25803 | 4.26s | utime( $self->lastModTime(), $self->lastModTime(), $name ); # spent 2.49s making 17202 calls to Archive::Zip::Member::lastModTime, avg 145µs/call
# spent 1.77s making 8601 calls to Archive::Zip::Member::CORE:utime, avg 206µs/call | ||
| 493 | return $retval; | ||||
| 494 | } | ||||
| 495 | } | ||||
| 496 | |||||
| 497 | sub _writeSymbolicLink { | ||||
| 498 | my $self = shift; | ||||
| 499 | my $name = shift; | ||||
| 500 | my $chunkSize = $Archive::Zip::ChunkSize; | ||||
| 501 | #my ( $outRef, undef ) = $self->readChunk($chunkSize); | ||||
| 502 | my $fh; | ||||
| 503 | my $retval = $self->extractToFileHandle($fh); | ||||
| 504 | my ( $outRef, undef ) = $self->readChunk(100); | ||||
| 505 | } | ||||
| 506 | |||||
| 507 | sub isSymbolicLink { | ||||
| 508 | my $self = shift; | ||||
| 509 | if ( $self->{'externalFileAttributes'} == 0xA1FF0000 ) { | ||||
| 510 | $self->{'isSymbolicLink'} = 1; | ||||
| 511 | } else { | ||||
| 512 | return 0; | ||||
| 513 | } | ||||
| 514 | 1; | ||||
| 515 | } | ||||
| 516 | |||||
| 517 | sub isDirectory { | ||||
| 518 | return 0; | ||||
| 519 | } | ||||
| 520 | |||||
| 521 | sub externalFileName { | ||||
| 522 | return undef; | ||||
| 523 | } | ||||
| 524 | |||||
| 525 | # The following are used when copying data | ||||
| 526 | # spent 23.6ms within Archive::Zip::Member::_writeOffset which was called 8368 times, avg 3µs/call:
# 8368 times (23.6ms+0s) by Archive::Zip::Member::_writeData at line 1073, avg 3µs/call | ||||
| 527 | 8368 | 34.6ms | shift->{'writeOffset'}; | ||
| 528 | } | ||||
| 529 | |||||
| 530 | sub _readOffset { | ||||
| 531 | shift->{'readOffset'}; | ||||
| 532 | } | ||||
| 533 | |||||
| 534 | sub writeLocalHeaderRelativeOffset { | ||||
| 535 | shift->{'writeLocalHeaderRelativeOffset'}; | ||||
| 536 | } | ||||
| 537 | |||||
| 538 | sub wasWritten { shift->{'wasWritten'} } | ||||
| 539 | |||||
| 540 | # spent 41.7ms within Archive::Zip::Member::_dataEnded which was called 20698 times, avg 2µs/call:
# 20698 times (41.7ms+0s) by Archive::Zip::Member::readIsDone at line 943, avg 2µs/call | ||||
| 541 | 20698 | 77.1ms | shift->{'dataEnded'}; | ||
| 542 | } | ||||
| 543 | |||||
| 544 | # spent 86.9ms within Archive::Zip::Member::_readDataRemaining which was called 41670 times, avg 2µs/call:
# 18717 times (36.5ms+0s) by Archive::Zip::Member::readChunk at line 783, avg 2µs/call
# 12467 times (23.7ms+0s) by Archive::Zip::Member::readIsDone at line 943, avg 2µs/call
# 8368 times (20.1ms+0s) by Archive::Zip::Member::_writeData at line 1061, avg 2µs/call
# 2118 times (6.61ms+0s) by Archive::Zip::Member::_writeData at line 1071, avg 3µs/call | ||||
| 545 | 41670 | 152ms | shift->{'readDataRemaining'}; | ||
| 546 | } | ||||
| 547 | |||||
| 548 | # spent 21.7ms within Archive::Zip::Member::_inflater which was called 10212 times, avg 2µs/call:
# 10212 times (21.7ms+0s) by Archive::Zip::Member::_inflateChunk at line 854, avg 2µs/call | ||||
| 549 | 10212 | 39.8ms | shift->{'inflater'}; | ||
| 550 | } | ||||
| 551 | |||||
| 552 | sub _deflater { | ||||
| 553 | shift->{'deflater'}; | ||||
| 554 | } | ||||
| 555 | |||||
| 556 | # Return the total size of my local header | ||||
| 557 | sub _localHeaderSize { | ||||
| 558 | my $self = shift; | ||||
| 559 | return SIGNATURE_LENGTH + LOCAL_FILE_HEADER_LENGTH + | ||||
| 560 | length( $self->fileName() ) + length( $self->localExtraField() ); | ||||
| 561 | } | ||||
| 562 | |||||
| 563 | # Return the total size of my CD header | ||||
| 564 | sub _centralDirectoryHeaderSize { | ||||
| 565 | my $self = shift; | ||||
| 566 | return SIGNATURE_LENGTH + CENTRAL_DIRECTORY_FILE_HEADER_LENGTH + | ||||
| 567 | length( $self->fileName() ) + length( $self->cdExtraField() ) + | ||||
| 568 | length( $self->fileComment() ); | ||||
| 569 | } | ||||
| 570 | |||||
| 571 | # DOS date/time format | ||||
| 572 | # 0-4 (5) Second divided by 2 | ||||
| 573 | # 5-10 (6) Minute (0-59) | ||||
| 574 | # 11-15 (5) Hour (0-23 on a 24-hour clock) | ||||
| 575 | # 16-20 (5) Day of the month (1-31) | ||||
| 576 | # 21-24 (4) Month (1 = January, 2 = February, etc.) | ||||
| 577 | # 25-31 (7) Year offset from 1980 (add 1980 to get actual year) | ||||
| 578 | |||||
| 579 | # Convert DOS date/time format to unix time_t format | ||||
| 580 | # NOT AN OBJECT METHOD! | ||||
| 581 | # spent 2.46s (298ms+2.16) within Archive::Zip::Member::_dosToUnixTime which was called 19964 times, avg 123µs/call:
# 19964 times (298ms+2.16s) by Archive::Zip::Member::lastModTime at line 229, avg 123µs/call | ||||
| 582 | 239568 | 292ms | my $dt = shift; | ||
| 583 | return time() unless defined($dt); | ||||
| 584 | |||||
| 585 | my $year = ( ( $dt >> 25 ) & 0x7f ) + 80; | ||||
| 586 | my $mon = ( ( $dt >> 21 ) & 0x0f ) - 1; | ||||
| 587 | my $mday = ( ( $dt >> 16 ) & 0x1f ); | ||||
| 588 | |||||
| 589 | my $hour = ( ( $dt >> 11 ) & 0x1f ); | ||||
| 590 | my $min = ( ( $dt >> 5 ) & 0x3f ); | ||||
| 591 | my $sec = ( ( $dt << 1 ) & 0x3e ); | ||||
| 592 | |||||
| 593 | # catch errors | ||||
| 594 | my $time_t = | ||||
| 595 | 19964 | 2.16s | eval { Time::Local::timelocal( $sec, $min, $hour, $mday, $mon, $year ); }; # spent 2.16s making 19964 calls to Time::Local::timelocal, avg 108µs/call | ||
| 596 | return time() if ($@); | ||||
| 597 | return $time_t; | ||||
| 598 | } | ||||
| 599 | |||||
| 600 | # Note, this isn't exactly UTC 1980, it's 1980 + 12 hours and 1 | ||||
| 601 | # minute so that nothing timezoney can muck us up. | ||||
| 602 | 1 | 1µs | my $safe_epoch = 315576060; | ||
| 603 | |||||
| 604 | # convert a unix time to DOS date/time | ||||
| 605 | # NOT AN OBJECT METHOD! | ||||
| 606 | sub _unixToDosTime { | ||||
| 607 | my $time_t = shift; | ||||
| 608 | unless ($time_t) { | ||||
| 609 | _error("Tried to add member with zero or undef value for time"); | ||||
| 610 | $time_t = $safe_epoch; | ||||
| 611 | } | ||||
| 612 | if ( $time_t < $safe_epoch ) { | ||||
| 613 | _ioError("Unsupported date before 1980 encountered, moving to 1980"); | ||||
| 614 | $time_t = $safe_epoch; | ||||
| 615 | } | ||||
| 616 | my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime($time_t); | ||||
| 617 | my $dt = 0; | ||||
| 618 | $dt += ( $sec >> 1 ); | ||||
| 619 | $dt += ( $min << 5 ); | ||||
| 620 | $dt += ( $hour << 11 ); | ||||
| 621 | $dt += ( $mday << 16 ); | ||||
| 622 | $dt += ( ( $mon + 1 ) << 21 ); | ||||
| 623 | $dt += ( ( $year - 80 ) << 25 ); | ||||
| 624 | return $dt; | ||||
| 625 | } | ||||
| 626 | |||||
| 627 | # Write my local header to a file handle. | ||||
| 628 | # Stores the offset to the start of the header in my | ||||
| 629 | # writeLocalHeaderRelativeOffset member. | ||||
| 630 | # Returns AZ_OK on success. | ||||
| 631 | sub _writeLocalFileHeader { | ||||
| 632 | my $self = shift; | ||||
| 633 | my $fh = shift; | ||||
| 634 | |||||
| 635 | my $signatureData = pack( SIGNATURE_FORMAT, LOCAL_FILE_HEADER_SIGNATURE ); | ||||
| 636 | $self->_print($fh, $signatureData) | ||||
| 637 | or return _ioError("writing local header signature"); | ||||
| 638 | |||||
| 639 | my $header = pack( | ||||
| 640 | LOCAL_FILE_HEADER_FORMAT, | ||||
| 641 | $self->versionNeededToExtract(), | ||||
| 642 | $self->bitFlag(), | ||||
| 643 | $self->desiredCompressionMethod(), | ||||
| 644 | $self->lastModFileDateTime(), | ||||
| 645 | $self->crc32(), | ||||
| 646 | $self->compressedSize(), # may need to be re-written later | ||||
| 647 | $self->uncompressedSize(), | ||||
| 648 | length( $self->fileName() ), | ||||
| 649 | length( $self->localExtraField() ) | ||||
| 650 | ); | ||||
| 651 | |||||
| 652 | $self->_print($fh, $header) or return _ioError("writing local header"); | ||||
| 653 | |||||
| 654 | # Check for a valid filename or a filename equal to a literal `0' | ||||
| 655 | if ( $self->fileName() || $self->fileName eq '0' ) { | ||||
| 656 | $self->_print($fh, $self->fileName() ) | ||||
| 657 | or return _ioError("writing local header filename"); | ||||
| 658 | } | ||||
| 659 | if ( $self->localExtraField() ) { | ||||
| 660 | $self->_print($fh, $self->localExtraField() ) | ||||
| 661 | or return _ioError("writing local extra field"); | ||||
| 662 | } | ||||
| 663 | |||||
| 664 | return AZ_OK; | ||||
| 665 | } | ||||
| 666 | |||||
| 667 | sub _writeCentralDirectoryFileHeader { | ||||
| 668 | my $self = shift; | ||||
| 669 | my $fh = shift; | ||||
| 670 | |||||
| 671 | my $sigData = | ||||
| 672 | pack( SIGNATURE_FORMAT, CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE ); | ||||
| 673 | $self->_print($fh, $sigData) | ||||
| 674 | or return _ioError("writing central directory header signature"); | ||||
| 675 | |||||
| 676 | my $fileNameLength = length( $self->fileName() ); | ||||
| 677 | my $extraFieldLength = length( $self->cdExtraField() ); | ||||
| 678 | my $fileCommentLength = length( $self->fileComment() ); | ||||
| 679 | |||||
| 680 | my $header = pack( | ||||
| 681 | CENTRAL_DIRECTORY_FILE_HEADER_FORMAT, | ||||
| 682 | $self->versionMadeBy(), | ||||
| 683 | $self->fileAttributeFormat(), | ||||
| 684 | $self->versionNeededToExtract(), | ||||
| 685 | $self->bitFlag(), | ||||
| 686 | $self->desiredCompressionMethod(), | ||||
| 687 | $self->lastModFileDateTime(), | ||||
| 688 | $self->crc32(), # these three fields should have been updated | ||||
| 689 | $self->_writeOffset(), # by writing the data stream out | ||||
| 690 | $self->uncompressedSize(), # | ||||
| 691 | $fileNameLength, | ||||
| 692 | $extraFieldLength, | ||||
| 693 | $fileCommentLength, | ||||
| 694 | 0, # {'diskNumberStart'}, | ||||
| 695 | $self->internalFileAttributes(), | ||||
| 696 | $self->externalFileAttributes(), | ||||
| 697 | $self->writeLocalHeaderRelativeOffset() | ||||
| 698 | ); | ||||
| 699 | |||||
| 700 | $self->_print($fh, $header) | ||||
| 701 | or return _ioError("writing central directory header"); | ||||
| 702 | if ($fileNameLength) { | ||||
| 703 | $self->_print($fh, $self->fileName() ) | ||||
| 704 | or return _ioError("writing central directory header signature"); | ||||
| 705 | } | ||||
| 706 | if ($extraFieldLength) { | ||||
| 707 | $self->_print($fh, $self->cdExtraField() ) | ||||
| 708 | or return _ioError("writing central directory extra field"); | ||||
| 709 | } | ||||
| 710 | if ($fileCommentLength) { | ||||
| 711 | $self->_print($fh, $self->fileComment() ) | ||||
| 712 | or return _ioError("writing central directory file comment"); | ||||
| 713 | } | ||||
| 714 | |||||
| 715 | return AZ_OK; | ||||
| 716 | } | ||||
| 717 | |||||
| 718 | # This writes a data descriptor to the given file handle. | ||||
| 719 | # Assumes that crc32, writeOffset, and uncompressedSize are | ||||
| 720 | # set correctly (they should be after a write). | ||||
| 721 | # Further, the local file header should have the | ||||
| 722 | # GPBF_HAS_DATA_DESCRIPTOR_MASK bit set. | ||||
| 723 | sub _writeDataDescriptor { | ||||
| 724 | my $self = shift; | ||||
| 725 | my $fh = shift; | ||||
| 726 | my $header = pack( | ||||
| 727 | SIGNATURE_FORMAT . DATA_DESCRIPTOR_FORMAT, | ||||
| 728 | DATA_DESCRIPTOR_SIGNATURE, | ||||
| 729 | $self->crc32(), | ||||
| 730 | $self->_writeOffset(), # compressed size | ||||
| 731 | $self->uncompressedSize() | ||||
| 732 | ); | ||||
| 733 | |||||
| 734 | $self->_print($fh, $header) | ||||
| 735 | or return _ioError("writing data descriptor"); | ||||
| 736 | return AZ_OK; | ||||
| 737 | } | ||||
| 738 | |||||
| 739 | # Re-writes the local file header with new crc32 and compressedSize fields. | ||||
| 740 | # To be called after writing the data stream. | ||||
| 741 | # Assumes that filename and extraField sizes didn't change since last written. | ||||
| 742 | sub _refreshLocalFileHeader { | ||||
| 743 | my $self = shift; | ||||
| 744 | my $fh = shift; | ||||
| 745 | |||||
| 746 | my $here = $fh->tell(); | ||||
| 747 | $fh->seek( $self->writeLocalHeaderRelativeOffset() + SIGNATURE_LENGTH, | ||||
| 748 | IO::Seekable::SEEK_SET ) | ||||
| 749 | or return _ioError("seeking to rewrite local header"); | ||||
| 750 | |||||
| 751 | my $header = pack( | ||||
| 752 | LOCAL_FILE_HEADER_FORMAT, | ||||
| 753 | $self->versionNeededToExtract(), | ||||
| 754 | $self->bitFlag(), | ||||
| 755 | $self->desiredCompressionMethod(), | ||||
| 756 | $self->lastModFileDateTime(), | ||||
| 757 | $self->crc32(), | ||||
| 758 | $self->_writeOffset(), # compressed size | ||||
| 759 | $self->uncompressedSize(), | ||||
| 760 | length( $self->fileName() ), | ||||
| 761 | length( $self->localExtraField() ) | ||||
| 762 | ); | ||||
| 763 | |||||
| 764 | $self->_print($fh, $header) | ||||
| 765 | or return _ioError("re-writing local header"); | ||||
| 766 | $fh->seek( $here, IO::Seekable::SEEK_SET ) | ||||
| 767 | or return _ioError("seeking after rewrite of local header"); | ||||
| 768 | |||||
| 769 | return AZ_OK; | ||||
| 770 | } | ||||
| 771 | |||||
| 772 | # spent 4.61s (436ms+4.18) within Archive::Zip::Member::readChunk which was called 10349 times, avg 446µs/call:
# 10349 times (436ms+4.18s) by Archive::Zip::Member::_writeData at line 1063, avg 446µs/call | ||||
| 773 | 165584 | 337ms | my $self = shift; | ||
| 774 | my $chunkSize = ( ref( $_[0] ) eq 'HASH' ) ? $_[0]->{chunkSize} : $_[0]; | ||||
| 775 | |||||
| 776 | 10349 | 147ms | if ( $self->readIsDone() ) { # spent 147ms making 10349 calls to Archive::Zip::Member::readIsDone, avg 14µs/call | ||
| 777 | $self->endRead(); | ||||
| 778 | my $dummy = ''; | ||||
| 779 | return ( \$dummy, AZ_STREAM_END ); | ||||
| 780 | } | ||||
| 781 | |||||
| 782 | $chunkSize = $Archive::Zip::ChunkSize if not defined($chunkSize); | ||||
| 783 | 18717 | 36.5ms | $chunkSize = $self->_readDataRemaining() # spent 36.5ms making 18717 calls to Archive::Zip::Member::_readDataRemaining, avg 2µs/call | ||
| 784 | if $chunkSize > $self->_readDataRemaining(); | ||||
| 785 | |||||
| 786 | my $buffer = ''; | ||||
| 787 | my $outputRef; | ||||
| 788 | 10349 | 511ms | my ( $bytesRead, $status ) = $self->_readRawChunk( \$buffer, $chunkSize ); # spent 511ms making 10349 calls to Archive::Zip::ZipFileMember::_readRawChunk, avg 49µs/call | ||
| 789 | return ( \$buffer, $status ) unless $status == AZ_OK; | ||||
| 790 | |||||
| 791 | $self->{'readDataRemaining'} -= $bytesRead; | ||||
| 792 | $self->{'readOffset'} += $bytesRead; | ||||
| 793 | |||||
| 794 | 10486 | 29.0ms | if ( $self->compressionMethod() == COMPRESSION_STORED ) { # spent 26.3ms making 10349 calls to Archive::Zip::Member::compressionMethod, avg 3µs/call
# spent 2.67ms making 137 calls to Archive::Zip::computeCRC32, avg 19µs/call | ||
| 795 | $self->{'crc32'} = $self->computeCRC32( $buffer, $self->{'crc32'} ); | ||||
| 796 | } | ||||
| 797 | |||||
| 798 | 10349 | 3.22s | ( $outputRef, $status ) = &{ $self->{'chunkHandler'} }( $self, \$buffer ); # spent 3.22s making 10212 calls to Archive::Zip::Member::_inflateChunk, avg 316µs/call
# spent 545µs making 137 calls to Archive::Zip::Member::_copyChunk, avg 4µs/call | ||
| 799 | $self->{'writeOffset'} += length($$outputRef); | ||||
| 800 | |||||
| 801 | 18717 | 230ms | $self->endRead() # spent 130ms making 8368 calls to Archive::Zip::FileMember::endRead, avg 16µs/call
# spent 99.9ms making 10349 calls to Archive::Zip::Member::readIsDone, avg 10µs/call | ||
| 802 | if $self->readIsDone(); | ||||
| 803 | |||||
| 804 | return ( $outputRef, $status ); | ||||
| 805 | } | ||||
| 806 | |||||
| 807 | # Read the next raw chunk of my data. Subclasses MUST implement. | ||||
| 808 | # my ( $bytesRead, $status) = $self->_readRawChunk( \$buffer, $chunkSize ); | ||||
| 809 | sub _readRawChunk { | ||||
| 810 | my $self = shift; | ||||
| 811 | return $self->_subclassResponsibility(); | ||||
| 812 | } | ||||
| 813 | |||||
| 814 | # A place holder to catch rewindData errors if someone ignores | ||||
| 815 | # the error code. | ||||
| 816 | sub _noChunk { | ||||
| 817 | my $self = shift; | ||||
| 818 | return ( \undef, _error("trying to copy chunk when init failed") ); | ||||
| 819 | } | ||||
| 820 | |||||
| 821 | # Basically a no-op so that I can have a consistent interface. | ||||
| 822 | # ( $outputRef, $status) = $self->_copyChunk( \$buffer ); | ||||
| 823 | # spent 545µs within Archive::Zip::Member::_copyChunk which was called 137 times, avg 4µs/call:
# 137 times (545µs+0s) by Archive::Zip::Member::readChunk at line 798, avg 4µs/call | ||||
| 824 | 274 | 747µs | my ( $self, $dataRef ) = @_; | ||
| 825 | return ( $dataRef, AZ_OK ); | ||||
| 826 | } | ||||
| 827 | |||||
| 828 | # ( $outputRef, $status) = $self->_deflateChunk( \$buffer ); | ||||
| 829 | sub _deflateChunk { | ||||
| 830 | my ( $self, $buffer ) = @_; | ||||
| 831 | my ( $status ) = $self->_deflater()->deflate( $buffer, my $out ); | ||||
| 832 | |||||
| 833 | if ( $self->_readDataRemaining() == 0 ) { | ||||
| 834 | my $extraOutput; | ||||
| 835 | ( $status ) = $self->_deflater()->flush($extraOutput); | ||||
| 836 | $out .= $extraOutput; | ||||
| 837 | $self->endRead(); | ||||
| 838 | return ( \$out, AZ_STREAM_END ); | ||||
| 839 | } | ||||
| 840 | elsif ( $status == Z_OK ) { | ||||
| 841 | return ( \$out, AZ_OK ); | ||||
| 842 | } | ||||
| 843 | else { | ||||
| 844 | $self->endRead(); | ||||
| 845 | my $retval = _error( 'deflate error', $status ); | ||||
| 846 | my $dummy = ''; | ||||
| 847 | return ( \$dummy, $retval ); | ||||
| 848 | } | ||||
| 849 | } | ||||
| 850 | |||||
| 851 | # ( $outputRef, $status) = $self->_inflateChunk( \$buffer ); | ||||
| 852 | # spent 3.22s (350ms+2.87) within Archive::Zip::Member::_inflateChunk which was called 10212 times, avg 316µs/call:
# 10212 times (350ms+2.87s) by Archive::Zip::Member::readChunk at line 798, avg 316µs/call | ||||
| 853 | 71484 | 2.54s | my ( $self, $buffer ) = @_; | ||
| 854 | 20424 | 2.28s | my ( $status ) = $self->_inflater()->inflate( $buffer, my $out ); # spent 2.26s making 10212 calls to Compress::Raw::Zlib::inflateStream::inflate, avg 221µs/call
# spent 21.7ms making 10212 calls to Archive::Zip::Member::_inflater, avg 2µs/call | ||
| 855 | my $retval; | ||||
| 856 | 18443 | 525ms | $self->endRead() unless $status == Z_OK; # spent 494ms making 8231 calls to Archive::Zip::FileMember::endRead, avg 60µs/call
# spent 30.6ms making 10212 calls to Compress::Raw::Zlib::__ANON__[Compress/Raw/Zlib.pm:80], avg 3µs/call | ||
| 857 | 18443 | 45.4ms | if ( $status == Z_OK || $status == Z_STREAM_END ) { # spent 45.3ms making 18442 calls to Compress::Raw::Zlib::__ANON__[Compress/Raw/Zlib.pm:80], avg 2µs/call
# spent 40µs making 1 call to Compress::Raw::Zlib::AUTOLOAD | ||
| 858 | 10212 | 21.0ms | $retval = ( $status == Z_STREAM_END ) ? AZ_STREAM_END: AZ_OK; # spent 21.0ms making 10212 calls to Compress::Raw::Zlib::__ANON__[Compress/Raw/Zlib.pm:80], avg 2µs/call | ||
| 859 | return ( \$out, $retval ); | ||||
| 860 | } | ||||
| 861 | else { | ||||
| 862 | $retval = _error( 'inflate error', $status ); | ||||
| 863 | my $dummy = ''; | ||||
| 864 | return ( \$dummy, $retval ); | ||||
| 865 | } | ||||
| 866 | } | ||||
| 867 | |||||
| 868 | # spent 4.55s (553ms+3.99) within Archive::Zip::Member::rewindData which was called 8601 times, avg 529µs/call:
# 8601 times (553ms+3.99s) by Archive::Zip::ZipFileMember::rewindData at line 381 of Archive/Zip/ZipFileMember.pm, avg 529µs/call | ||||
| 869 | 110703 | 468ms | my $self = shift; | ||
| 870 | my $status; | ||||
| 871 | |||||
| 872 | # set to trap init errors | ||||
| 873 | 8601 | 14.8ms | $self->{'chunkHandler'} = $self->can('_noChunk'); # spent 14.8ms making 8601 calls to UNIVERSAL::can, avg 2µs/call | ||
| 874 | |||||
| 875 | # Work around WinZip bug with 0-length DEFLATED files | ||||
| 876 | 8834 | 23.8ms | $self->desiredCompressionMethod(COMPRESSION_STORED) # spent 22.2ms making 8601 calls to Archive::Zip::Member::uncompressedSize, avg 3µs/call
# spent 1.67ms making 233 calls to Archive::Zip::Member::desiredCompressionMethod, avg 7µs/call | ||
| 877 | if $self->uncompressedSize() == 0; | ||||
| 878 | |||||
| 879 | # assume that we're going to read the whole file, and compute the CRC anew. | ||||
| 880 | 8601 | 19.0ms | $self->{'crc32'} = 0 # spent 19.0ms making 8601 calls to Archive::Zip::Member::compressionMethod, avg 2µs/call | ||
| 881 | if ( $self->compressionMethod() == COMPRESSION_STORED ); | ||||
| 882 | |||||
| 883 | # These are the only combinations of methods we deal with right now. | ||||
| 884 | 26913 | 71.3ms | if ( $self->compressionMethod() == COMPRESSION_STORED # spent 38.3ms making 8971 calls to Archive::Zip::Member::desiredCompressionMethod, avg 4µs/call
# spent 32.2ms making 17572 calls to Archive::Zip::Member::compressionMethod, avg 2µs/call
# spent 724µs making 370 calls to UNIVERSAL::can, avg 2µs/call | ||
| 885 | and $self->desiredCompressionMethod() == COMPRESSION_DEFLATED ) | ||||
| 886 | { | ||||
| 887 | ( $self->{'deflater'}, $status ) = Compress::Raw::Zlib::Deflate->new( | ||||
| 888 | '-Level' => $self->desiredCompressionLevel(), | ||||
| 889 | '-WindowBits' => -MAX_WBITS(), # necessary magic | ||||
| 890 | '-Bufsize' => $Archive::Zip::ChunkSize, | ||||
| 891 | @_ | ||||
| 892 | ); # pass additional options | ||||
| 893 | return _error( 'deflateInit error:', $status ) | ||||
| 894 | unless $status == Z_OK; | ||||
| 895 | $self->{'chunkHandler'} = $self->can('_deflateChunk'); | ||||
| 896 | } | ||||
| 897 | elsif ( $self->compressionMethod() == COMPRESSION_DEFLATED | ||||
| 898 | and $self->desiredCompressionMethod() == COMPRESSION_STORED ) | ||||
| 899 | { | ||||
| 900 | 16462 | 3.78s | ( $self->{'inflater'}, $status ) = Compress::Raw::Zlib::Inflate->new( # spent 3.76s making 8231 calls to Compress::Raw::Zlib::Inflate::new, avg 457µs/call
# spent 25.6ms making 8230 calls to Compress::Raw::Zlib::__ANON__[Compress/Raw/Zlib.pm:80], avg 3µs/call
# spent 81µs making 1 call to Compress::Raw::Zlib::AUTOLOAD | ||
| 901 | '-WindowBits' => -MAX_WBITS(), # necessary magic | ||||
| 902 | '-Bufsize' => $Archive::Zip::ChunkSize, | ||||
| 903 | @_ | ||||
| 904 | ); # pass additional options | ||||
| 905 | 8231 | 23.5ms | return _error( 'inflateInit error:', $status ) # spent 23.5ms making 8230 calls to Compress::Raw::Zlib::__ANON__[Compress/Raw/Zlib.pm:80], avg 3µs/call
# spent 31µs making 1 call to Compress::Raw::Zlib::AUTOLOAD | ||
| 906 | unless $status == Z_OK; | ||||
| 907 | 8231 | 16.1ms | $self->{'chunkHandler'} = $self->can('_inflateChunk'); # spent 16.1ms making 8231 calls to UNIVERSAL::can, avg 2µs/call | ||
| 908 | } | ||||
| 909 | elsif ( $self->compressionMethod() == $self->desiredCompressionMethod() ) { | ||||
| 910 | $self->{'chunkHandler'} = $self->can('_copyChunk'); | ||||
| 911 | } | ||||
| 912 | else { | ||||
| 913 | return _error( | ||||
| 914 | sprintf( | ||||
| 915 | "Unsupported compression combination: read %d, write %d", | ||||
| 916 | $self->compressionMethod(), | ||||
| 917 | $self->desiredCompressionMethod() | ||||
| 918 | ) | ||||
| 919 | ); | ||||
| 920 | } | ||||
| 921 | |||||
| 922 | 17202 | 39.4ms | $self->{'readDataRemaining'} = # spent 20.0ms making 8601 calls to Archive::Zip::Member::compressionMethod, avg 2µs/call
# spent 18.7ms making 8231 calls to Archive::Zip::Member::compressedSize, avg 2µs/call
# spent 721µs making 370 calls to Archive::Zip::Member::uncompressedSize, avg 2µs/call | ||
| 923 | ( $self->compressionMethod() == COMPRESSION_STORED ) | ||||
| 924 | ? $self->uncompressedSize() | ||||
| 925 | : $self->compressedSize(); | ||||
| 926 | $self->{'dataEnded'} = 0; | ||||
| 927 | $self->{'readOffset'} = 0; | ||||
| 928 | |||||
| 929 | return AZ_OK; | ||||
| 930 | } | ||||
| 931 | |||||
| 932 | # spent 267ms (235+31.5) within Archive::Zip::Member::endRead which was called 35182 times, avg 8µs/call:
# 35182 times (235ms+31.5ms) by Archive::Zip::FileMember::endRead at line 52 of Archive/Zip/FileMember.pm, avg 8µs/call | ||||
| 933 | 211092 | 324ms | my $self = shift; | ||
| 934 | 8231 | 31.5ms | delete $self->{'inflater'}; # spent 31.5ms making 8231 calls to Compress::Raw::Zlib::inflateStream::DESTROY, avg 4µs/call | ||
| 935 | delete $self->{'deflater'}; | ||||
| 936 | $self->{'dataEnded'} = 1; | ||||
| 937 | $self->{'readDataRemaining'} = 0; | ||||
| 938 | return AZ_OK; | ||||
| 939 | } | ||||
| 940 | |||||
| 941 | sub readIsDone { | ||||
| 942 | 41396 | 153ms | my $self = shift; | ||
| 943 | 33165 | 65.4ms | return ( $self->_dataEnded() or !$self->_readDataRemaining() ); # spent 41.7ms making 20698 calls to Archive::Zip::Member::_dataEnded, avg 2µs/call
# spent 23.7ms making 12467 calls to Archive::Zip::Member::_readDataRemaining, avg 2µs/call | ||
| 944 | } | ||||
| 945 | |||||
| 946 | sub contents { | ||||
| 947 | my $self = shift; | ||||
| 948 | my $newContents = shift; | ||||
| 949 | |||||
| 950 | if ( defined($newContents) ) { | ||||
| 951 | |||||
| 952 | # change our type and call the subclass contents method. | ||||
| 953 | $self->_become(STRINGMEMBERCLASS); | ||||
| 954 | return $self->contents( pack( 'C0a*', $newContents ) ) | ||||
| 955 | ; # in case of Unicode | ||||
| 956 | } | ||||
| 957 | else { | ||||
| 958 | my $oldCompression = | ||||
| 959 | $self->desiredCompressionMethod(COMPRESSION_STORED); | ||||
| 960 | my $status = $self->rewindData(@_); | ||||
| 961 | if ( $status != AZ_OK ) { | ||||
| 962 | $self->endRead(); | ||||
| 963 | return $status; | ||||
| 964 | } | ||||
| 965 | my $retval = ''; | ||||
| 966 | while ( $status == AZ_OK ) { | ||||
| 967 | my $ref; | ||||
| 968 | ( $ref, $status ) = $self->readChunk( $self->_readDataRemaining() ); | ||||
| 969 | |||||
| 970 | # did we get it in one chunk? | ||||
| 971 | if ( length($$ref) == $self->uncompressedSize() ) { | ||||
| 972 | $retval = $$ref; | ||||
| 973 | } | ||||
| 974 | else { $retval .= $$ref } | ||||
| 975 | } | ||||
| 976 | $self->desiredCompressionMethod($oldCompression); | ||||
| 977 | $self->endRead(); | ||||
| 978 | $status = AZ_OK if $status == AZ_STREAM_END; | ||||
| 979 | $retval = undef unless $status == AZ_OK; | ||||
| 980 | return wantarray ? ( $retval, $status ) : $retval; | ||||
| 981 | } | ||||
| 982 | } | ||||
| 983 | |||||
| 984 | # spent 18.1s (308ms+17.7) within Archive::Zip::Member::extractToFileHandle which was called 8601 times, avg 2.10ms/call:
# 8601 times (308ms+17.7s) by Archive::Zip::Member::extractToFileNamed at line 488, avg 2.10ms/call | ||||
| 985 | 86010 | 229ms | my $self = shift; | ||
| 986 | 8601 | 668ms | return _error("encryption unsupported") if $self->isEncrypted(); # spent 668ms making 8601 calls to Archive::Zip::Member::isEncrypted, avg 78µs/call | ||
| 987 | my $fh = ( ref( $_[0] ) eq 'HASH' ) ? shift->{fileHandle} : shift; | ||||
| 988 | 8601 | 270ms | _binmode($fh); # spent 270ms making 8601 calls to Archive::Zip::_binmode, avg 31µs/call | ||
| 989 | 8601 | 74.5ms | my $oldCompression = $self->desiredCompressionMethod(COMPRESSION_STORED); # spent 74.5ms making 8601 calls to Archive::Zip::Member::desiredCompressionMethod, avg 9µs/call | ||
| 990 | 8601 | 10.3s | my $status = $self->rewindData(@_); # spent 10.3s making 8601 calls to Archive::Zip::ZipFileMember::rewindData, avg 1.20ms/call | ||
| 991 | 8601 | 6.22s | $status = $self->_writeData($fh) if $status == AZ_OK; # spent 6.22s making 8601 calls to Archive::Zip::Member::_writeData, avg 723µs/call | ||
| 992 | 8601 | 58.6ms | $self->desiredCompressionMethod($oldCompression); # spent 58.6ms making 8601 calls to Archive::Zip::Member::desiredCompressionMethod, avg 7µs/call | ||
| 993 | 8601 | 144ms | $self->endRead(); # spent 144ms making 8601 calls to Archive::Zip::FileMember::endRead, avg 17µs/call | ||
| 994 | return $status; | ||||
| 995 | } | ||||
| 996 | |||||
| 997 | # write local header and data stream to file handle | ||||
| 998 | sub _writeToFileHandle { | ||||
| 999 | my $self = shift; | ||||
| 1000 | my $fh = shift; | ||||
| 1001 | my $fhIsSeekable = shift; | ||||
| 1002 | my $offset = shift; | ||||
| 1003 | |||||
| 1004 | return _error("no member name given for $self") | ||||
| 1005 | if $self->fileName() eq ''; | ||||
| 1006 | |||||
| 1007 | $self->{'writeLocalHeaderRelativeOffset'} = $offset; | ||||
| 1008 | $self->{'wasWritten'} = 0; | ||||
| 1009 | |||||
| 1010 | # Determine if I need to write a data descriptor | ||||
| 1011 | # I need to do this if I can't refresh the header | ||||
| 1012 | # and I don't know compressed size or crc32 fields. | ||||
| 1013 | my $headerFieldsUnknown = ( | ||||
| 1014 | ( $self->uncompressedSize() > 0 ) | ||||
| 1015 | and ($self->compressionMethod() == COMPRESSION_STORED | ||||
| 1016 | or $self->desiredCompressionMethod() == COMPRESSION_DEFLATED ) | ||||
| 1017 | ); | ||||
| 1018 | |||||
| 1019 | my $shouldWriteDataDescriptor = | ||||
| 1020 | ( $headerFieldsUnknown and not $fhIsSeekable ); | ||||
| 1021 | |||||
| 1022 | $self->hasDataDescriptor(1) | ||||
| 1023 | if ($shouldWriteDataDescriptor); | ||||
| 1024 | |||||
| 1025 | $self->{'writeOffset'} = 0; | ||||
| 1026 | |||||
| 1027 | my $status = $self->rewindData(); | ||||
| 1028 | ( $status = $self->_writeLocalFileHeader($fh) ) | ||||
| 1029 | if $status == AZ_OK; | ||||
| 1030 | ( $status = $self->_writeData($fh) ) | ||||
| 1031 | if $status == AZ_OK; | ||||
| 1032 | if ( $status == AZ_OK ) { | ||||
| 1033 | $self->{'wasWritten'} = 1; | ||||
| 1034 | if ( $self->hasDataDescriptor() ) { | ||||
| 1035 | $status = $self->_writeDataDescriptor($fh); | ||||
| 1036 | } | ||||
| 1037 | elsif ($headerFieldsUnknown) { | ||||
| 1038 | $status = $self->_refreshLocalFileHeader($fh); | ||||
| 1039 | } | ||||
| 1040 | } | ||||
| 1041 | |||||
| 1042 | return $status; | ||||
| 1043 | } | ||||
| 1044 | |||||
| 1045 | # Copy my (possibly compressed) data to given file handle. | ||||
| 1046 | # Returns C<AZ_OK> on success | ||||
| 1047 | # spent 6.22s (315ms+5.90) within Archive::Zip::Member::_writeData which was called 8601 times, avg 723µs/call:
# 8601 times (315ms+5.90s) by Archive::Zip::Member::extractToFileHandle at line 991, avg 723µs/call | ||||
| 1048 | 138338 | 254ms | my $self = shift; | ||
| 1049 | my $writeFh = shift; | ||||
| 1050 | |||||
| 1051 | # If symbolic link, just create one if the operating system is Linux, Unix, BSD or VMS | ||||
| 1052 | # TODO: Add checks for other operating systems | ||||
| 1053 | if ( $self->{'isSymbolicLink'} == 1 && $^O eq 'linux' ) { | ||||
| 1054 | my $chunkSize = $Archive::Zip::ChunkSize; | ||||
| 1055 | my ( $outRef, $status ) = $self->readChunk($chunkSize); | ||||
| 1056 | symlink $$outRef, $self->{'newName'}; | ||||
| 1057 | } else { | ||||
| 1058 | 8601 | 18.1ms | return AZ_OK if ( $self->uncompressedSize() == 0 ); # spent 18.1ms making 8601 calls to Archive::Zip::Member::uncompressedSize, avg 2µs/call | ||
| 1059 | my $status; | ||||
| 1060 | my $chunkSize = $Archive::Zip::ChunkSize; | ||||
| 1061 | 8368 | 20.1ms | while ( $self->_readDataRemaining() > 0 ) { # spent 20.1ms making 8368 calls to Archive::Zip::Member::_readDataRemaining, avg 2µs/call | ||
| 1062 | my $outRef; | ||||
| 1063 | 10349 | 4.61s | ( $outRef, $status ) = $self->readChunk($chunkSize); # spent 4.61s making 10349 calls to Archive::Zip::Member::readChunk, avg 446µs/call | ||
| 1064 | return $status if ( $status != AZ_OK and $status != AZ_STREAM_END ); | ||||
| 1065 | |||||
| 1066 | if ( length($$outRef) > 0 ) { | ||||
| 1067 | 10349 | 1.22s | $self->_print($writeFh, $$outRef) # spent 1.22s making 10349 calls to Archive::Zip::_print, avg 118µs/call | ||
| 1068 | or return _ioError("write error during copy"); | ||||
| 1069 | } | ||||
| 1070 | |||||
| 1071 | 2118 | 6.61ms | last if $status == AZ_STREAM_END; # spent 6.61ms making 2118 calls to Archive::Zip::Member::_readDataRemaining, avg 3µs/call | ||
| 1072 | } | ||||
| 1073 | 8368 | 23.6ms | $self->{'compressedSize'} = $self->_writeOffset(); # spent 23.6ms making 8368 calls to Archive::Zip::Member::_writeOffset, avg 3µs/call | ||
| 1074 | } | ||||
| 1075 | return AZ_OK; | ||||
| 1076 | } | ||||
| 1077 | |||||
| 1078 | # Return true if I depend on the named file | ||||
| 1079 | sub _usesFileNamed { | ||||
| 1080 | return 0; | ||||
| 1081 | } | ||||
| 1082 | |||||
| 1083 | 1 | 8µs | 1; | ||
# spent 2.05s within Archive::Zip::Member::CORE:chmod which was called 8601 times, avg 239µs/call:
# 8601 times (2.05s+0s) by Archive::Zip::Member::extractToFileNamed at line 490, avg 239µs/call | |||||
# spent 74.3ms within Archive::Zip::Member::CORE:match which was called 19964 times, avg 4µs/call:
# 19964 times (74.3ms+0s) by Archive::Zip::Member::lastModFileDateTime at line 223, avg 4µs/call | |||||
# spent 9.69ms within Archive::Zip::Member::CORE:subst which was called 1381 times, avg 7µs/call:
# 1381 times (9.69ms+0s) by Archive::Zip::Member::fileName at line 215, avg 7µs/call | |||||
# spent 1.77s within Archive::Zip::Member::CORE:utime which was called 8601 times, avg 206µs/call:
# 8601 times (1.77s+0s) by Archive::Zip::Member::extractToFileNamed at line 492, avg 206µs/call | |||||
# spent 13.7ms within Archive::Zip::Member::DEFAULT_FILE_PERMISSIONS which was called 10192 times, avg 1µs/call:
# 10192 times (13.7ms+0s) by Archive::Zip::Member::new at line 121, avg 1µs/call | |||||
# spent 11.7ms within Archive::Zip::Member::ZIPFILEMEMBERCLASS which was called 10192 times, avg 1µs/call:
# 10192 times (11.7ms+0s) by Archive::Zip::Member::_newFromZipFile at line 42, avg 1µs/call |