Archive-Zip
view release on metacpan or search on metacpan
lib/Archive/Zip/Member.pm view on Meta::CPAN
my $compressedSize = $self->_writeOffset();
my $uncompressedSize = $self->uncompressedSize();
my $localHeaderRelativeOffset = $self->writeLocalHeaderRelativeOffset();
my $cdExtraField = $self->cdExtraField();
if (!$zip64) {
# no-op
}
else {
return _zip64NotSupported() unless ZIP64_SUPPORTED;
$versionNeededToExtract = 45 if ($versionNeededToExtract < 45);
my $extraFieldFormat = '';
my @extraFieldValues = ();
my $extraFieldSize = 0;
if ($uncompressedSize > 0xffffffff) {
$extraFieldFormat .= 'Q< ';
push(@extraFieldValues, $uncompressedSize);
$extraFieldSize += 8;
$uncompressedSize = 0xffffffff;
}
if ($compressedSize > 0xffffffff) {
$extraFieldFormat .= 'Q< ';
push(@extraFieldValues, $compressedSize);
$extraFieldSize += 8;
$compressedSize = 0xffffffff;
}
# Avoid empty zip64 extended information extra fields
if ( $localHeaderRelativeOffset > 0xffffffff
|| @extraFieldValues == 0) {
$extraFieldFormat .= 'Q< ';
push(@extraFieldValues, $localHeaderRelativeOffset);
$extraFieldSize += 8;
$localHeaderRelativeOffset = 0xffffffff;
}
$cdExtraField .=
pack("S< S< $extraFieldFormat",
0x0001, $extraFieldSize,
@extraFieldValues);
}
my $fileNameLength = length($self->fileNameAsBytes());
my $extraFieldLength = length($cdExtraField);
my $fileCommentLength = length($self->fileComment());
my $sigData =
pack(SIGNATURE_FORMAT, CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE);
$self->_print($fh, $sigData)
or return _ioError("writing central directory header signature");
my $header = pack(
CENTRAL_DIRECTORY_FILE_HEADER_FORMAT,
$versionMadeBy,
$self->fileAttributeFormat(),
$versionNeededToExtract,
$self->bitFlag(),
$self->desiredCompressionMethod(),
$self->lastModFileDateTime(),
$self->crc32(), # these three fields should have been updated
$compressedSize, # by writing the data stream out
$uncompressedSize, #
$fileNameLength,
$extraFieldLength,
$fileCommentLength,
0, # {'diskNumberStart'},
$self->internalFileAttributes(),
$self->externalFileAttributes(),
$localHeaderRelativeOffset);
$self->_print($fh, $header)
or return _ioError("writing central directory header");
if ($fileNameLength) {
$self->_print($fh, $self->fileNameAsBytes())
or return _ioError("writing central directory header signature");
}
if ($extraFieldLength) {
$self->_print($fh, $cdExtraField)
or return _ioError("writing central directory extra field");
}
if ($fileCommentLength) {
$self->_print($fh, $self->fileComment())
or return _ioError("writing central directory file comment");
}
# Update object members with information which might have
# changed while writing this member. We already did the
# zip64 flag. We must not update the extra fields with any
# zip64 information, since we consider that internal.
$self->{'versionNeededToExtract'} = $versionNeededToExtract;
$self->{'compressedSize'} = $self->_writeOffset();
return
(AZ_OK,
CENTRAL_DIRECTORY_FILE_HEADER_LENGTH +
SIGNATURE_LENGTH +
$fileNameLength +
$extraFieldLength +
$fileCommentLength)
}
# This writes a data descriptor to the given file handle.
# Assumes that crc32, writeOffset, and uncompressedSize are
# set correctly (they should be after a write).
# Returns a pair (AZ_OK, $dataDescriptorSize) on success.
# Further, the local file header should have the
# GPBF_HAS_DATA_DESCRIPTOR_MASK bit set.
sub _writeDataDescriptor {
my $self = shift;
my $fh = shift;
my $descriptor;
if (! $self->zip64()) {
$descriptor =
pack(SIGNATURE_FORMAT . DATA_DESCRIPTOR_FORMAT,
DATA_DESCRIPTOR_SIGNATURE,
$self->crc32(),
$self->_writeOffset(), # compressed size
$self->uncompressedSize());
( run in 0.620 second using v1.01-cache-2.11-cpan-99c4e6809bf )