1184250Smarcelpackage IO::Compress::Zip ; 2184250Smarcel 3184250Smarceluse strict ; 4184250Smarceluse warnings; 5184250Smarceluse bytes; 6184250Smarcel 7184250Smarceluse IO::Compress::Base::Common 2.204 qw(:Status ); 8184250Smarceluse IO::Compress::RawDeflate 2.204 (); 9184250Smarceluse IO::Compress::Adapter::Deflate 2.204 ; 10184250Smarceluse IO::Compress::Adapter::Identity 2.204 ; 11184250Smarceluse IO::Compress::Zlib::Extra 2.204 ; 12184250Smarceluse IO::Compress::Zip::Constants 2.204 ; 13184250Smarcel 14184250Smarceluse File::Spec(); 15184250Smarceluse Config; 16184250Smarcel 17184250Smarceluse Compress::Raw::Zlib 2.204 (); 18184250Smarcel 19184250SmarcelBEGIN 20184250Smarcel{ 21184250Smarcel eval { require IO::Compress::Adapter::Bzip2 ; 22184250Smarcel IO::Compress::Adapter::Bzip2->import( 2.201 ); 23184250Smarcel require IO::Compress::Bzip2 ; 24184250Smarcel IO::Compress::Bzip2->import( 2.201 ); 25184250Smarcel } ; 26184250Smarcel 27184250Smarcel eval { require IO::Compress::Adapter::Lzma ; 28184250Smarcel IO::Compress::Adapter::Lzma->import( 2.201 ); 29184250Smarcel require IO::Compress::Lzma ; 30184250Smarcel IO::Compress::Lzma->import( 2.201 ); 31184250Smarcel } ; 32186288Sraj 33186288Sraj eval { require IO::Compress::Adapter::Xz ; 34186288Sraj IO::Compress::Adapter::Xz->import( 2.201 ); 35186288Sraj require IO::Compress::Xz ; 36235937Smarcel IO::Compress::Xz->import( 2.201 ); 37235937Smarcel } ; 38235937Smarcel eval { require IO::Compress::Adapter::Zstd ; 39235937Smarcel IO::Compress::Adapter::Zstd->import( 2.201 ); 40235937Smarcel require IO::Compress::Zstd ; 41235937Smarcel IO::Compress::Zstd->import( 2.201 ); 42235937Smarcel } ; 43235937Smarcel} 44235937Smarcel 45235937Smarcel 46235937Smarcelrequire Exporter ; 47235937Smarcel 48235937Smarcelour ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $ZipError); 49235937Smarcel 50235937Smarcel$VERSION = '2.204'; 51235937Smarcel$ZipError = ''; 52235937Smarcel 53235937Smarcel@ISA = qw(IO::Compress::RawDeflate Exporter); 54235937Smarcel@EXPORT_OK = qw( $ZipError zip ) ; 55235937Smarcel%EXPORT_TAGS = %IO::Compress::RawDeflate::DEFLATE_CONSTANTS ; 56235937Smarcel 57235937Smarcelpush @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; 58235937Smarcel 59235937Smarcel$EXPORT_TAGS{zip_method} = [qw( ZIP_CM_STORE ZIP_CM_DEFLATE ZIP_CM_BZIP2 ZIP_CM_LZMA ZIP_CM_XZ ZIP_CM_ZSTD)]; 60235937Smarcelpush @{ $EXPORT_TAGS{all} }, @{ $EXPORT_TAGS{zip_method} }; 61235937Smarcel 62235937SmarcelExporter::export_ok_tags('all'); 63235937Smarcel 64235937Smarcelsub new 65186288Sraj{ 66186288Sraj my $class = shift ; 67186288Sraj 68186288Sraj my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$ZipError); 69186288Sraj $obj->_create(undef, @_); 70186288Sraj 71186288Sraj} 72186288Sraj 73186288Srajsub zip 74186288Sraj{ 75186288Sraj my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$ZipError); 76186288Sraj return $obj->_def(@_); 77186288Sraj} 78186288Sraj 79186288Srajsub isMethodAvailable 80186288Sraj{ 81186288Sraj my $method = shift; 82186288Sraj 83235937Smarcel # Store & Deflate are always available 84235937Smarcel return 1 85235937Smarcel if $method == ZIP_CM_STORE || $method == ZIP_CM_DEFLATE ; 86235937Smarcel 87235937Smarcel return 1 88235937Smarcel if $method == ZIP_CM_BZIP2 && 89209908Sraj defined $IO::Compress::Adapter::Bzip2::VERSION && 90235937Smarcel defined &{ "IO::Compress::Adapter::Bzip2::mkRawZipCompObject" }; 91235937Smarcel 92235937Smarcel return 1 93209908Sraj if $method == ZIP_CM_LZMA && 94209908Sraj defined $IO::Compress::Adapter::Lzma::VERSION && 95209908Sraj defined &{ "IO::Compress::Adapter::Lzma::mkRawZipCompObject" }; 96209908Sraj 97209908Sraj return 1 98209908Sraj if $method == ZIP_CM_XZ && 99209908Sraj defined $IO::Compress::Adapter::Xz::VERSION && 100209908Sraj defined &{ "IO::Compress::Adapter::Xz::mkRawZipCompObject" }; 101209908Sraj 102209908Sraj return 1 103209908Sraj if $method == ZIP_CM_ZSTD && 104186288Sraj defined $IO::Compress::Adapter::ZSTD::VERSION && 105186288Sraj defined &{ "IO::Compress::Adapter::ZSTD::mkRawZipCompObject" }; 106209908Sraj 107209908Sraj return 0; 108238045Smarcel} 109238045Smarcel 110209908Srajsub beforePayload 111209908Sraj{ 112238045Smarcel my $self = shift ; 113186288Sraj 114238045Smarcel if (*$self->{ZipData}{Sparse} ) { 115238045Smarcel my $inc = 1024 * 100 ; 116238045Smarcel my $NULLS = ("\x00" x $inc) ; 117238045Smarcel my $sparse = *$self->{ZipData}{Sparse} ; 118209908Sraj *$self->{CompSize}->add( $sparse ); 119209908Sraj *$self->{UnCompSize}->add( $sparse ); 120209908Sraj 121209908Sraj *$self->{FH}->seek($sparse, IO::Handle::SEEK_CUR); 122209908Sraj 123235937Smarcel *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32($NULLS, *$self->{ZipData}{CRC32}) 124209908Sraj for 1 .. int $sparse / $inc; 125238045Smarcel *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(substr($NULLS, 0, $sparse % $inc), 126238045Smarcel *$self->{ZipData}{CRC32}) 127209908Sraj if $sparse % $inc; 128209908Sraj } 129209908Sraj} 130209908Sraj 131209908Srajsub mkComp 132209908Sraj{ 133209908Sraj my $self = shift ; 134209908Sraj my $got = shift ; 135235937Smarcel 136235937Smarcel my ($obj, $errstr, $errno) ; 137235937Smarcel 138184250Smarcel if (*$self->{ZipData}{Method} == ZIP_CM_STORE) { 139 ($obj, $errstr, $errno) = IO::Compress::Adapter::Identity::mkCompObject( 140 $got->getValue('level'), 141 $got->getValue('strategy') 142 ); 143 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 144 } 145 elsif (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 146 ($obj, $errstr, $errno) = IO::Compress::Adapter::Deflate::mkCompObject( 147 $got->getValue('crc32'), 148 $got->getValue('adler32'), 149 $got->getValue('level'), 150 $got->getValue('strategy') 151 ); 152 } 153 elsif (*$self->{ZipData}{Method} == ZIP_CM_BZIP2) { 154 ($obj, $errstr, $errno) = IO::Compress::Adapter::Bzip2::mkCompObject( 155 $got->getValue('blocksize100k'), 156 $got->getValue('workfactor'), 157 $got->getValue('verbosity') 158 ); 159 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 160 } 161 elsif (*$self->{ZipData}{Method} == ZIP_CM_LZMA) { 162 ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzma::mkRawZipCompObject($got->getValue('preset'), 163 $got->getValue('extreme'), 164 ); 165 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 166 } 167 elsif (*$self->{ZipData}{Method} == ZIP_CM_XZ) { 168 ($obj, $errstr, $errno) = IO::Compress::Adapter::Xz::mkCompObject($got->getValue('preset'), 169 $got->getValue('extreme'), 170 0 171 ); 172 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 173 } 174 elsif (*$self->{ZipData}{Method} == ZIP_CM_ZSTD) { 175 ($obj, $errstr, $errno) = IO::Compress::Adapter::Zstd::mkCompObject(defined $got->getValue('level') ? $got->getValue('level') : 3, 176 ); 177 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 178 } 179 180 return $self->saveErrorString(undef, $errstr, $errno) 181 if ! defined $obj; 182 183 if (! defined *$self->{ZipData}{SizesOffset}) { 184 *$self->{ZipData}{SizesOffset} = 0; 185 *$self->{ZipData}{Offset} = U64->new(); 186 } 187 188 *$self->{ZipData}{AnyZip64} = 0 189 if ! defined *$self->{ZipData}{AnyZip64} ; 190 191 return $obj; 192} 193 194sub reset 195{ 196 my $self = shift ; 197 198 *$self->{Compress}->reset(); 199 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(''); 200 201 return STATUS_OK; 202} 203 204sub filterUncompressed 205{ 206 my $self = shift ; 207 208 if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 209 *$self->{ZipData}{CRC32} = *$self->{Compress}->crc32(); 210 } 211 else { 212 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(${$_[0]}, *$self->{ZipData}{CRC32}); 213 214 } 215} 216 217sub canonicalName 218{ 219 # This sub is derived from Archive::Zip::_asZipDirName 220 221 # Return the normalized name as used in a zip file (path 222 # separators become slashes, etc.). 223 # Will translate internal slashes in path components (i.e. on Macs) to 224 # underscores. Discards volume names. 225 # When $forceDir is set, returns paths with trailing slashes 226 # 227 # input output 228 # . '.' 229 # ./a a 230 # ./a/b a/b 231 # ./a/b/ a/b 232 # a/b/ a/b 233 # /a/b/ a/b 234 # c:\a\b\c.doc a/b/c.doc # on Windows 235 # "i/o maps:whatever" i_o maps/whatever # on Macs 236 237 my $name = shift; 238 my $forceDir = shift ; 239 240 my ( $volume, $directories, $file ) = 241 File::Spec->splitpath( File::Spec->canonpath($name), $forceDir ); 242 243 my @dirs = map { $_ =~ s{/}{_}g; $_ } 244 File::Spec->splitdir($directories); 245 246 if ( @dirs > 0 ) { pop (@dirs) if $dirs[-1] eq '' } # remove empty component 247 push @dirs, defined($file) ? $file : '' ; 248 249 my $normalised_path = join '/', @dirs; 250 251 # Leading directory separators should not be stored in zip archives. 252 # Example: 253 # C:\a\b\c\ a/b/c 254 # C:\a\b\c.txt a/b/c.txt 255 # /a/b/c/ a/b/c 256 # /a/b/c.txt a/b/c.txt 257 $normalised_path =~ s{^/}{}; # remove leading separator 258 259 return $normalised_path; 260} 261 262 263sub mkHeader 264{ 265 my $self = shift; 266 my $param = shift ; 267 268 *$self->{ZipData}{LocalHdrOffset} = U64::clone(*$self->{ZipData}{Offset}); 269 270 my $comment = ''; 271 $comment = $param->valueOrDefault('comment') ; 272 273 my $filename = ''; 274 $filename = $param->valueOrDefault('name') ; 275 276 $filename = canonicalName($filename) 277 if length $filename && $param->getValue('canonicalname') ; 278 279 if (defined *$self->{ZipData}{FilterName} ) { 280 local *_ = \$filename ; 281 &{ *$self->{ZipData}{FilterName} }() ; 282 } 283 284 if ( $param->getValue('efs') && $] >= 5.008004) { 285 if (length $filename) { 286 utf8::downgrade($filename, 1) 287 or Carp::croak "Wide character in zip filename"; 288 } 289 290 if (length $comment) { 291 utf8::downgrade($comment, 1) 292 or Carp::croak "Wide character in zip comment"; 293 } 294 } 295 296 my $hdr = ''; 297 298 my $time = _unixToDosTime($param->getValue('time')); 299 300 my $extra = ''; 301 my $ctlExtra = ''; 302 my $empty = 0; 303 my $osCode = $param->getValue('os_code') ; 304 my $extFileAttr = 0 ; 305 306 # This code assumes Unix. 307 # TODO - revisit this 308 $extFileAttr = 0100644 << 16 309 if $osCode == ZIP_OS_CODE_UNIX ; 310 311 if (*$self->{ZipData}{Zip64}) { 312 $empty = IO::Compress::Base::Common::MAX32; 313 314 my $x = ''; 315 $x .= pack "V V", 0, 0 ; # uncompressedLength 316 $x .= pack "V V", 0, 0 ; # compressedLength 317 318 # Zip64 needs to be first in extra field to workaround a Windows Explorer Bug 319 # See http://www.info-zip.org/phpBB3/viewtopic.php?f=3&t=440 for details 320 $extra .= IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $x); 321 } 322 323 if (! $param->getValue('minimal')) { 324 if ($param->parsed('mtime')) 325 { 326 $extra .= mkExtendedTime($param->getValue('mtime'), 327 $param->getValue('atime'), 328 $param->getValue('ctime')); 329 330 $ctlExtra .= mkExtendedTime($param->getValue('mtime')); 331 } 332 333 if ( $osCode == ZIP_OS_CODE_UNIX ) 334 { 335 if ( $param->getValue('want_exunixn') ) 336 { 337 my $ux3 = mkUnixNExtra( @{ $param->getValue('want_exunixn') }); 338 $extra .= $ux3; 339 $ctlExtra .= $ux3; 340 } 341 342 if ( $param->getValue('exunix2') ) 343 { 344 $extra .= mkUnix2Extra( @{ $param->getValue('exunix2') }); 345 $ctlExtra .= mkUnix2Extra(); 346 } 347 } 348 349 $extFileAttr = $param->getValue('extattr') 350 if defined $param->getValue('extattr') ; 351 352 $extra .= $param->getValue('extrafieldlocal') 353 if defined $param->getValue('extrafieldlocal'); 354 355 $ctlExtra .= $param->getValue('extrafieldcentral') 356 if defined $param->getValue('extrafieldcentral'); 357 } 358 359 my $method = *$self->{ZipData}{Method} ; 360 my $gpFlag = 0 ; 361 $gpFlag |= ZIP_GP_FLAG_STREAMING_MASK 362 if *$self->{ZipData}{Stream} ; 363 364 $gpFlag |= ZIP_GP_FLAG_LZMA_EOS_PRESENT 365 if $method == ZIP_CM_LZMA ; 366 367 $gpFlag |= ZIP_GP_FLAG_LANGUAGE_ENCODING 368 if $param->getValue('efs') && (length($filename) || length($comment)); 369 370 my $version = $ZIP_CM_MIN_VERSIONS{$method}; 371 $version = ZIP64_MIN_VERSION 372 if ZIP64_MIN_VERSION > $version && *$self->{ZipData}{Zip64}; 373 374 my $madeBy = ($param->getValue('os_code') << 8) + $version; 375 my $extract = $version; 376 377 *$self->{ZipData}{Version} = $version; 378 *$self->{ZipData}{MadeBy} = $madeBy; 379 380 my $ifa = 0; 381 $ifa |= ZIP_IFA_TEXT_MASK 382 if $param->getValue('textflag'); 383 384 $hdr .= pack "V", ZIP_LOCAL_HDR_SIG ; # signature 385 $hdr .= pack 'v', $extract ; # extract Version & OS 386 $hdr .= pack 'v', $gpFlag ; # general purpose flag (set streaming mode) 387 $hdr .= pack 'v', $method ; # compression method (deflate) 388 $hdr .= pack 'V', $time ; # last mod date/time 389 $hdr .= pack 'V', 0 ; # crc32 - 0 when streaming 390 $hdr .= pack 'V', $empty ; # compressed length - 0 when streaming 391 $hdr .= pack 'V', $empty ; # uncompressed length - 0 when streaming 392 $hdr .= pack 'v', length $filename ; # filename length 393 $hdr .= pack 'v', length $extra ; # extra length 394 395 $hdr .= $filename ; 396 397 # Remember the offset for the compressed & uncompressed lengths in the 398 # local header. 399 if (*$self->{ZipData}{Zip64}) { 400 *$self->{ZipData}{SizesOffset} = *$self->{ZipData}{Offset}->get64bit() 401 + length($hdr) + 4 ; 402 } 403 else { 404 *$self->{ZipData}{SizesOffset} = *$self->{ZipData}{Offset}->get64bit() 405 + 18; 406 } 407 408 $hdr .= $extra ; 409 410 411 my $ctl = ''; 412 413 $ctl .= pack "V", ZIP_CENTRAL_HDR_SIG ; # signature 414 $ctl .= pack 'v', $madeBy ; # version made by 415 $ctl .= pack 'v', $extract ; # extract Version 416 $ctl .= pack 'v', $gpFlag ; # general purpose flag (streaming mode) 417 $ctl .= pack 'v', $method ; # compression method (deflate) 418 $ctl .= pack 'V', $time ; # last mod date/time 419 $ctl .= pack 'V', 0 ; # crc32 420 $ctl .= pack 'V', $empty ; # compressed length 421 $ctl .= pack 'V', $empty ; # uncompressed length 422 $ctl .= pack 'v', length $filename ; # filename length 423 424 *$self->{ZipData}{ExtraOffset} = length $ctl; 425 *$self->{ZipData}{ExtraSize} = length $ctlExtra ; 426 427 $ctl .= pack 'v', length $ctlExtra ; # extra length 428 $ctl .= pack 'v', length $comment ; # file comment length 429 $ctl .= pack 'v', 0 ; # disk number start 430 $ctl .= pack 'v', $ifa ; # internal file attributes 431 $ctl .= pack 'V', $extFileAttr ; # external file attributes 432 433 # offset to local hdr 434 if (*$self->{ZipData}{LocalHdrOffset}->is64bit() ) { 435 $ctl .= pack 'V', IO::Compress::Base::Common::MAX32 ; 436 } 437 else { 438 $ctl .= *$self->{ZipData}{LocalHdrOffset}->getPacked_V32() ; 439 } 440 441 $ctl .= $filename ; 442 443 *$self->{ZipData}{Offset}->add32(length $hdr) ; 444 445 *$self->{ZipData}{CentralHeader} = [ $ctl, $ctlExtra, $comment]; 446 447 return $hdr; 448} 449 450sub mkTrailer 451{ 452 my $self = shift ; 453 454 my $crc32 ; 455 if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 456 $crc32 = pack "V", *$self->{Compress}->crc32(); 457 } 458 else { 459 $crc32 = pack "V", *$self->{ZipData}{CRC32}; 460 } 461 462 my ($ctl, $ctlExtra, $comment) = @{ *$self->{ZipData}{CentralHeader} }; 463 464 my $sizes ; 465 if (! *$self->{ZipData}{Zip64}) { 466 $sizes .= *$self->{CompSize}->getPacked_V32() ; # Compressed size 467 $sizes .= *$self->{UnCompSize}->getPacked_V32() ; # Uncompressed size 468 } 469 else { 470 $sizes .= *$self->{CompSize}->getPacked_V64() ; # Compressed size 471 $sizes .= *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size 472 } 473 474 my $data = $crc32 . $sizes ; 475 476 my $xtrasize = *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size 477 $xtrasize .= *$self->{CompSize}->getPacked_V64() ; # Compressed size 478 479 my $hdr = ''; 480 481 if (*$self->{ZipData}{Stream}) { 482 $hdr = pack "V", ZIP_DATA_HDR_SIG ; # signature 483 $hdr .= $data ; 484 } 485 else { 486 $self->writeAt(*$self->{ZipData}{LocalHdrOffset}->get64bit() + 14, $crc32) 487 or return undef; 488 $self->writeAt(*$self->{ZipData}{SizesOffset}, 489 *$self->{ZipData}{Zip64} ? $xtrasize : $sizes) 490 or return undef; 491 } 492 493 # Central Header Record/Zip64 extended field 494 495 substr($ctl, 16, length $crc32) = $crc32 ; 496 497 my $zip64Payload = ''; 498 499 # uncompressed length - only set zip64 if needed 500 if (*$self->{UnCompSize}->isAlmost64bit()) { # || *$self->{ZipData}{Zip64}) { 501 $zip64Payload .= *$self->{UnCompSize}->getPacked_V64() ; 502 } else { 503 substr($ctl, 24, 4) = *$self->{UnCompSize}->getPacked_V32() ; 504 } 505 506 # compressed length - only set zip64 if needed 507 if (*$self->{CompSize}->isAlmost64bit()) { # || *$self->{ZipData}{Zip64}) { 508 $zip64Payload .= *$self->{CompSize}->getPacked_V64() ; 509 } else { 510 substr($ctl, 20, 4) = *$self->{CompSize}->getPacked_V32() ; 511 } 512 513 # Local Header offset 514 $zip64Payload .= *$self->{ZipData}{LocalHdrOffset}->getPacked_V64() 515 if *$self->{ZipData}{LocalHdrOffset}->is64bit() ; 516 517 # disk no - always zero, so don't need to include it. 518 #$zip64Payload .= pack "V", 0 ; 519 520 my $zip64Xtra = ''; 521 522 if (length $zip64Payload) { 523 $zip64Xtra = IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $zip64Payload); 524 525 substr($ctl, *$self->{ZipData}{ExtraOffset}, 2) = 526 pack 'v', *$self->{ZipData}{ExtraSize} + length $zip64Xtra; 527 528 *$self->{ZipData}{AnyZip64} = 1; 529 } 530 531 # Zip64 needs to be first in extra field to workaround a Windows Explorer Bug 532 # See http://www.info-zip.org/phpBB3/viewtopic.php?f=3&t=440 for details 533 $ctl .= $zip64Xtra . $ctlExtra . $comment; 534 535 *$self->{ZipData}{Offset}->add32(length($hdr)); 536 *$self->{ZipData}{Offset}->add( *$self->{CompSize} ); 537 push @{ *$self->{ZipData}{CentralDir} }, $ctl ; 538 539 return $hdr; 540} 541 542sub mkFinalTrailer 543{ 544 my $self = shift ; 545 546 my $comment = ''; 547 $comment = *$self->{ZipData}{ZipComment} ; 548 549 my $cd_offset = *$self->{ZipData}{Offset}->get32bit() ; # offset to start central dir 550 551 my $entries = @{ *$self->{ZipData}{CentralDir} }; 552 553 *$self->{ZipData}{AnyZip64} = 1 554 if *$self->{ZipData}{Offset}->is64bit || $entries >= 0xFFFF ; 555 556 my $cd = join '', @{ *$self->{ZipData}{CentralDir} }; 557 my $cd_len = length $cd ; 558 559 my $z64e = ''; 560 561 if ( *$self->{ZipData}{AnyZip64} ) { 562 563 my $v = *$self->{ZipData}{Version} ; 564 my $mb = *$self->{ZipData}{MadeBy} ; 565 $z64e .= pack 'v', $mb ; # Version made by 566 $z64e .= pack 'v', $v ; # Version to extract 567 $z64e .= pack 'V', 0 ; # number of disk 568 $z64e .= pack 'V', 0 ; # number of disk with central dir 569 $z64e .= U64::pack_V64 $entries ; # entries in central dir on this disk 570 $z64e .= U64::pack_V64 $entries ; # entries in central dir 571 $z64e .= U64::pack_V64 $cd_len ; # size of central dir 572 $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to start central dir 573 $z64e .= *$self->{ZipData}{extrafieldzip64} # otional extra field 574 if defined *$self->{ZipData}{extrafieldzip64} ; 575 576 $z64e = pack("V", ZIP64_END_CENTRAL_REC_HDR_SIG) # signature 577 . U64::pack_V64(length $z64e) 578 . $z64e ; 579 580 *$self->{ZipData}{Offset}->add32(length $cd) ; 581 582 $z64e .= pack "V", ZIP64_END_CENTRAL_LOC_HDR_SIG; # signature 583 $z64e .= pack 'V', 0 ; # number of disk with central dir 584 $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to end zip64 central dir 585 $z64e .= pack 'V', 1 ; # Total number of disks 586 587 $cd_offset = IO::Compress::Base::Common::MAX32 ; 588 $cd_len = IO::Compress::Base::Common::MAX32 if IO::Compress::Base::Common::isGeMax32 $cd_len ; 589 $entries = 0xFFFF if $entries >= 0xFFFF ; 590 } 591 592 my $ecd = ''; 593 $ecd .= pack "V", ZIP_END_CENTRAL_HDR_SIG ; # signature 594 $ecd .= pack 'v', 0 ; # number of disk 595 $ecd .= pack 'v', 0 ; # number of disk with central dir 596 $ecd .= pack 'v', $entries ; # entries in central dir on this disk 597 $ecd .= pack 'v', $entries ; # entries in central dir 598 $ecd .= pack 'V', $cd_len ; # size of central dir 599 $ecd .= pack 'V', $cd_offset ; # offset to start central dir 600 $ecd .= pack 'v', length $comment ; # zipfile comment length 601 $ecd .= $comment; 602 603 return $cd . $z64e . $ecd ; 604} 605 606sub ckParams 607{ 608 my $self = shift ; 609 my $got = shift; 610 611 $got->setValue('crc32' => 1); 612 613 if (! $got->parsed('time') ) { 614 # Modification time defaults to now. 615 $got->setValue('time' => time) ; 616 } 617 618 if ($got->parsed('extime') ) { 619 my $timeRef = $got->getValue('extime'); 620 if ( defined $timeRef) { 621 return $self->saveErrorString(undef, "exTime not a 3-element array ref") 622 if ref $timeRef ne 'ARRAY' || @$timeRef != 3; 623 } 624 625 $got->setValue("mtime", $timeRef->[1]); 626 $got->setValue("atime", $timeRef->[0]); 627 $got->setValue("ctime", $timeRef->[2]); 628 } 629 630 # Unix2/3 Extended Attribute 631 for my $name (qw(exunix2 exunixn)) 632 { 633 if ($got->parsed($name) ) { 634 my $idRef = $got->getValue($name); 635 if ( defined $idRef) { 636 return $self->saveErrorString(undef, "$name not a 2-element array ref") 637 if ref $idRef ne 'ARRAY' || @$idRef != 2; 638 } 639 640 $got->setValue("uid", $idRef->[0]); 641 $got->setValue("gid", $idRef->[1]); 642 $got->setValue("want_$name", $idRef); 643 } 644 } 645 646 *$self->{ZipData}{AnyZip64} = 1 647 if $got->getValue('zip64') || $got->getValue('extrafieldzip64') ; 648 *$self->{ZipData}{Zip64} = $got->getValue('zip64'); 649 *$self->{ZipData}{Stream} = $got->getValue('stream'); 650 651 my $method = $got->getValue('method'); 652 return $self->saveErrorString(undef, "Unknown Method '$method'") 653 if ! defined $ZIP_CM_MIN_VERSIONS{$method}; 654 655 return $self->saveErrorString(undef, "Bzip2 not available") 656 if $method == ZIP_CM_BZIP2 and 657 ! defined $IO::Compress::Adapter::Bzip2::VERSION; 658 659 return $self->saveErrorString(undef, "Lzma not available") 660 if $method == ZIP_CM_LZMA 661 and ! defined $IO::Compress::Adapter::Lzma::VERSION; 662 663 *$self->{ZipData}{Method} = $method; 664 665 *$self->{ZipData}{ZipComment} = $got->getValue('zipcomment') ; 666 667 for my $name (qw( extrafieldlocal extrafieldcentral extrafieldzip64)) 668 { 669 my $data = $got->getValue($name) ; 670 if (defined $data) { 671 my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, 1, 0) ; 672 return $self->saveErrorString(undef, "Error with $name Parameter: $bad") 673 if $bad ; 674 675 $got->setValue($name, $data) ; 676 *$self->{ZipData}{$name} = $data; 677 } 678 } 679 680 return undef 681 if defined $IO::Compress::Bzip2::VERSION 682 and ! IO::Compress::Bzip2::ckParams($self, $got); 683 684 if ($got->parsed('sparse') ) { 685 *$self->{ZipData}{Sparse} = $got->getValue('sparse') ; 686 *$self->{ZipData}{Method} = ZIP_CM_STORE; 687 } 688 689 if ($got->parsed('filtername')) { 690 my $v = $got->getValue('filtername') ; 691 *$self->{ZipData}{FilterName} = $v 692 if ref $v eq 'CODE' ; 693 } 694 695 return 1 ; 696} 697 698sub outputPayload 699{ 700 my $self = shift ; 701 return 1 if *$self->{ZipData}{Sparse} ; 702 return $self->output(@_); 703} 704 705 706#sub newHeader 707#{ 708# my $self = shift ; 709# 710# return $self->mkHeader(*$self->{Got}); 711#} 712 713 714our %PARAMS = ( 715 'stream' => [IO::Compress::Base::Common::Parse_boolean, 1], 716 #'store' => [IO::Compress::Base::Common::Parse_boolean, 0], 717 'method' => [IO::Compress::Base::Common::Parse_unsigned, ZIP_CM_DEFLATE], 718 719# # Zip header fields 720 'minimal' => [IO::Compress::Base::Common::Parse_boolean, 0], 721 'zip64' => [IO::Compress::Base::Common::Parse_boolean, 0], 722 'comment' => [IO::Compress::Base::Common::Parse_any, ''], 723 'zipcomment'=> [IO::Compress::Base::Common::Parse_any, ''], 724 'name' => [IO::Compress::Base::Common::Parse_any, ''], 725 'filtername'=> [IO::Compress::Base::Common::Parse_code, undef], 726 'canonicalname'=> [IO::Compress::Base::Common::Parse_boolean, 0], 727 'efs' => [IO::Compress::Base::Common::Parse_boolean, 0], 728 'time' => [IO::Compress::Base::Common::Parse_any, undef], 729 'extime' => [IO::Compress::Base::Common::Parse_any, undef], 730 'exunix2' => [IO::Compress::Base::Common::Parse_any, undef], 731 'exunixn' => [IO::Compress::Base::Common::Parse_any, undef], 732 'extattr' => [IO::Compress::Base::Common::Parse_any, 733 $Compress::Raw::Zlib::gzip_os_code == 3 734 ? 0100644 << 16 735 : 0], 736 'os_code' => [IO::Compress::Base::Common::Parse_unsigned, $Compress::Raw::Zlib::gzip_os_code], 737 738 'textflag' => [IO::Compress::Base::Common::Parse_boolean, 0], 739 'extrafieldlocal' => [IO::Compress::Base::Common::Parse_any, undef], 740 'extrafieldcentral'=> [IO::Compress::Base::Common::Parse_any, undef], 741 'extrafieldzip64' => [IO::Compress::Base::Common::Parse_any, undef], 742 743 # Lzma 744 'preset' => [IO::Compress::Base::Common::Parse_unsigned, 6], 745 'extreme' => [IO::Compress::Base::Common::Parse_boolean, 0], 746 747 # For internal use only 748 'sparse' => [IO::Compress::Base::Common::Parse_unsigned, 0], 749 750 IO::Compress::RawDeflate::getZlibParams(), 751 defined $IO::Compress::Bzip2::VERSION 752 ? IO::Compress::Bzip2::getExtraParams() 753 : () 754 755 756 ); 757 758sub getExtraParams 759{ 760 return %PARAMS ; 761} 762 763sub getInverseClass 764{ 765 no warnings 'once'; 766 return ('IO::Uncompress::Unzip', 767 \$IO::Uncompress::Unzip::UnzipError); 768} 769 770sub getFileInfo 771{ 772 my $self = shift ; 773 my $params = shift; 774 my $filename = shift ; 775 776 if (IO::Compress::Base::Common::isaScalar($filename)) 777 { 778 $params->setValue(zip64 => 1) 779 if IO::Compress::Base::Common::isGeMax32 length (${ $filename }) ; 780 781 return ; 782 } 783 784 my ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) ; 785 if ( $params->parsed('storelinks') ) 786 { 787 ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) 788 = (lstat($filename))[2, 4,5,7, 8,9,10] ; 789 } 790 else 791 { 792 ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) 793 = (stat($filename))[2, 4,5,7, 8,9,10] ; 794 } 795 796 $params->setValue(textflag => -T $filename ) 797 if ! $params->parsed('textflag'); 798 799 $params->setValue(zip64 => 1) 800 if IO::Compress::Base::Common::isGeMax32 $size ; 801 802 $params->setValue('name' => $filename) 803 if ! $params->parsed('name') ; 804 805 $params->setValue('time' => $mtime) 806 if ! $params->parsed('time') ; 807 808 if ( ! $params->parsed('extime')) 809 { 810 $params->setValue('mtime' => $mtime) ; 811 $params->setValue('atime' => $atime) ; 812 $params->setValue('ctime' => undef) ; # No Creation time 813 # TODO - see if can fillout creation time on non-Unix 814 } 815 816 # NOTE - Unix specific code alert 817 if (! $params->parsed('extattr')) 818 { 819 use Fcntl qw(:mode) ; 820 my $attr = $mode << 16; 821 $attr |= ZIP_A_RONLY if ($mode & S_IWRITE) == 0 ; 822 $attr |= ZIP_A_DIR if ($mode & S_IFMT ) == S_IFDIR ; 823 824 $params->setValue('extattr' => $attr); 825 } 826 827 $params->setValue('want_exunixn', [$uid, $gid]); 828 $params->setValue('uid' => $uid) ; 829 $params->setValue('gid' => $gid) ; 830 831} 832 833sub mkExtendedTime 834{ 835 # order expected is m, a, c 836 837 my $times = ''; 838 my $bit = 1 ; 839 my $flags = 0; 840 841 for my $time (@_) 842 { 843 if (defined $time) 844 { 845 $flags |= $bit; 846 $times .= pack("V", $time); 847 } 848 849 $bit <<= 1 ; 850 } 851 852 return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_EXT_TIMESTAMP, 853 pack("C", $flags) . $times); 854} 855 856sub mkUnix2Extra 857{ 858 my $ids = ''; 859 for my $id (@_) 860 { 861 $ids .= pack("v", $id); 862 } 863 864 return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIX2, 865 $ids); 866} 867 868sub mkUnixNExtra 869{ 870 my $uid = shift; 871 my $gid = shift; 872 873 # Assumes UID/GID are 32-bit 874 my $ids ; 875 $ids .= pack "C", 1; # version 876 $ids .= pack "C", $Config{uidsize}; 877 $ids .= pack "V", $uid; 878 $ids .= pack "C", $Config{gidsize}; 879 $ids .= pack "V", $gid; 880 881 return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIXN, 882 $ids); 883} 884 885 886# from Archive::Zip 887sub _unixToDosTime # Archive::Zip::Member 888{ 889 my $time_t = shift; 890 891 # TODO - add something to cope with unix time < 1980 892 my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime($time_t); 893 my $dt = 0; 894 $dt += ( $sec >> 1 ); 895 $dt += ( $min << 5 ); 896 $dt += ( $hour << 11 ); 897 $dt += ( $mday << 16 ); 898 $dt += ( ( $mon + 1 ) << 21 ); 899 $dt += ( ( $year - 80 ) << 25 ); 900 return $dt; 901} 902 9031; 904 905__END__ 906 907=head1 NAME 908 909IO::Compress::Zip - Write zip files/buffers 910 911=head1 SYNOPSIS 912 913 use IO::Compress::Zip qw(zip $ZipError) ; 914 915 my $status = zip $input => $output [,OPTS] 916 or die "zip failed: $ZipError\n"; 917 918 my $z = IO::Compress::Zip->new( $output [,OPTS] ) 919 or die "zip failed: $ZipError\n"; 920 921 $z->print($string); 922 $z->printf($format, $string); 923 $z->write($string); 924 $z->syswrite($string [, $length, $offset]); 925 $z->flush(); 926 $z->tell(); 927 $z->eof(); 928 $z->seek($position, $whence); 929 $z->binmode(); 930 $z->fileno(); 931 $z->opened(); 932 $z->autoflush(); 933 $z->input_line_number(); 934 $z->newStream( [OPTS] ); 935 936 $z->deflateParams(); 937 938 $z->close() ; 939 940 $ZipError ; 941 942 # IO::File mode 943 944 print $z $string; 945 printf $z $format, $string; 946 tell $z 947 eof $z 948 seek $z, $position, $whence 949 binmode $z 950 fileno $z 951 close $z ; 952 953=head1 DESCRIPTION 954 955This module provides a Perl interface that allows writing zip 956compressed data to files or buffer. 957 958The primary purpose of this module is to provide streaming write access to 959zip files and buffers. 960 961At present the following compression methods are supported by IO::Compress::Zip 962 963=over 5 964 965=item Store (0) 966 967=item Deflate (8) 968 969=item Bzip2 (12) 970 971To write Bzip2 content, the module C<IO::Uncompress::Bunzip2> must 972be installed. 973 974=item Lzma (14) 975 976To write LZMA content, the module C<IO::Uncompress::UnLzma> must 977be installed. 978 979=item Zstandard (93) 980 981To write Zstandard content, the module C<IO::Compress::Zstd> must 982be installed. 983 984=item Xz (95) 985 986To write Xz content, the module C<IO::Uncompress::UnXz> must 987be installed. 988 989=back 990 991For reading zip files/buffers, see the companion module 992L<IO::Uncompress::Unzip|IO::Uncompress::Unzip>. 993 994=head1 Functional Interface 995 996A top-level function, C<zip>, is provided to carry out 997"one-shot" compression between buffers and/or files. For finer 998control over the compression process, see the L</"OO Interface"> 999section. 1000 1001 use IO::Compress::Zip qw(zip $ZipError) ; 1002 1003 zip $input_filename_or_reference => $output_filename_or_reference [,OPTS] 1004 or die "zip failed: $ZipError\n"; 1005 1006The functional interface needs Perl5.005 or better. 1007 1008=head2 zip $input_filename_or_reference => $output_filename_or_reference [, OPTS] 1009 1010C<zip> expects at least two parameters, 1011C<$input_filename_or_reference> and C<$output_filename_or_reference> 1012and zero or more optional parameters (see L</Optional Parameters>) 1013 1014=head3 The C<$input_filename_or_reference> parameter 1015 1016The parameter, C<$input_filename_or_reference>, is used to define the 1017source of the uncompressed data. 1018 1019It can take one of the following forms: 1020 1021=over 5 1022 1023=item A filename 1024 1025If the C<$input_filename_or_reference> parameter is a simple scalar, it is 1026assumed to be a filename. This file will be opened for reading and the 1027input data will be read from it. 1028 1029=item A filehandle 1030 1031If the C<$input_filename_or_reference> parameter is a filehandle, the input 1032data will be read from it. The string '-' can be used as an alias for 1033standard input. 1034 1035=item A scalar reference 1036 1037If C<$input_filename_or_reference> is a scalar reference, the input data 1038will be read from C<$$input_filename_or_reference>. 1039 1040=item An array reference 1041 1042If C<$input_filename_or_reference> is an array reference, each element in 1043the array must be a filename. 1044 1045The input data will be read from each file in turn. 1046 1047The complete array will be walked to ensure that it only 1048contains valid filenames before any data is compressed. 1049 1050=item An Input FileGlob string 1051 1052If C<$input_filename_or_reference> is a string that is delimited by the 1053characters "<" and ">" C<zip> will assume that it is an 1054I<input fileglob string>. The input is the list of files that match the 1055fileglob. 1056 1057See L<File::GlobMapper|File::GlobMapper> for more details. 1058 1059=back 1060 1061If the C<$input_filename_or_reference> parameter is any other type, 1062C<undef> will be returned. 1063 1064In addition, if C<$input_filename_or_reference> corresponds to a filename 1065from the filesystem, a number of zip file header fields will be populated by default 1066using the following attributes from the input file 1067 1068=over 5 1069 1070=item * the full filename contained in C<$input_filename_or_reference> 1071 1072=item * the file protection attributes 1073 1074=item * the UID/GID for the file 1075 1076=item * the file timestamps 1077 1078=back 1079 1080If you do not want to use these defaults they can be overridden by 1081explicitly setting one, or more, of the C<Name>, C<Time>, C<TextFlag>, C<ExtAttr>, C<exUnixN> and C<exTime> options or by setting the 1082C<Minimal> parameter. 1083 1084=head3 The C<$output_filename_or_reference> parameter 1085 1086The parameter C<$output_filename_or_reference> is used to control the 1087destination of the compressed data. This parameter can take one of 1088these forms. 1089 1090=over 5 1091 1092=item A filename 1093 1094If the C<$output_filename_or_reference> parameter is a simple scalar, it is 1095assumed to be a filename. This file will be opened for writing and the 1096compressed data will be written to it. 1097 1098=item A filehandle 1099 1100If the C<$output_filename_or_reference> parameter is a filehandle, the 1101compressed data will be written to it. The string '-' can be used as 1102an alias for standard output. 1103 1104=item A scalar reference 1105 1106If C<$output_filename_or_reference> is a scalar reference, the 1107compressed data will be stored in C<$$output_filename_or_reference>. 1108 1109=item An Array Reference 1110 1111If C<$output_filename_or_reference> is an array reference, 1112the compressed data will be pushed onto the array. 1113 1114=item An Output FileGlob 1115 1116If C<$output_filename_or_reference> is a string that is delimited by the 1117characters "<" and ">" C<zip> will assume that it is an 1118I<output fileglob string>. The output is the list of files that match the 1119fileglob. 1120 1121When C<$output_filename_or_reference> is an fileglob string, 1122C<$input_filename_or_reference> must also be a fileglob string. Anything 1123else is an error. 1124 1125See L<File::GlobMapper|File::GlobMapper> for more details. 1126 1127=back 1128 1129If the C<$output_filename_or_reference> parameter is any other type, 1130C<undef> will be returned. 1131 1132=head2 Notes 1133 1134When C<$input_filename_or_reference> maps to multiple files/buffers and 1135C<$output_filename_or_reference> is a single 1136file/buffer the input files/buffers will each be stored 1137in C<$output_filename_or_reference> as a distinct entry. 1138 1139=head2 Optional Parameters 1140 1141The optional parameters for the one-shot function C<zip> 1142are (for the most part) identical to those used with the OO interface defined in the 1143L</"Constructor Options"> section. The exceptions are listed below 1144 1145=over 5 1146 1147=item C<< AutoClose => 0|1 >> 1148 1149This option applies to any input or output data streams to 1150C<zip> that are filehandles. 1151 1152If C<AutoClose> is specified, and the value is true, it will result in all 1153input and/or output filehandles being closed once C<zip> has 1154completed. 1155 1156This parameter defaults to 0. 1157 1158=item C<< BinModeIn => 0|1 >> 1159 1160This option is now a no-op. All files will be read in binmode. 1161 1162=item C<< Append => 0|1 >> 1163 1164The behaviour of this option is dependent on the type of output data 1165stream. 1166 1167=over 5 1168 1169=item * A Buffer 1170 1171If C<Append> is enabled, all compressed data will be append to the end of 1172the output buffer. Otherwise the output buffer will be cleared before any 1173compressed data is written to it. 1174 1175=item * A Filename 1176 1177If C<Append> is enabled, the file will be opened in append mode. Otherwise 1178the contents of the file, if any, will be truncated before any compressed 1179data is written to it. 1180 1181=item * A Filehandle 1182 1183If C<Append> is enabled, the filehandle will be positioned to the end of 1184the file via a call to C<seek> before any compressed data is 1185written to it. Otherwise the file pointer will not be moved. 1186 1187=back 1188 1189When C<Append> is specified, and set to true, it will I<append> all compressed 1190data to the output data stream. 1191 1192So when the output is a filehandle it will carry out a seek to the eof 1193before writing any compressed data. If the output is a filename, it will be opened for 1194appending. If the output is a buffer, all compressed data will be 1195appended to the existing buffer. 1196 1197Conversely when C<Append> is not specified, or it is present and is set to 1198false, it will operate as follows. 1199 1200When the output is a filename, it will truncate the contents of the file 1201before writing any compressed data. If the output is a filehandle 1202its position will not be changed. If the output is a buffer, it will be 1203wiped before any compressed data is output. 1204 1205Defaults to 0. 1206 1207=back 1208 1209=head2 Examples 1210 1211Here are a few example that show the capabilities of the module. 1212 1213=head3 Streaming 1214 1215This very simple command line example demonstrates the streaming capabilities of the module. 1216The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT. 1217 1218 $ echo hello world | perl -MIO::Compress::Zip=zip -e 'zip \*STDIN => \*STDOUT' >output.zip 1219 1220The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>, 1221so the above can be rewritten as 1222 1223 $ echo hello world | perl -MIO::Compress::Zip=zip -e 'zip "-" => "-"' >output.zip 1224 1225One problem with creating a zip archive directly from STDIN can be demonstrated by looking at 1226the contents of the zip file, output.zip, that we have just created. 1227 1228 $ unzip -l output.zip 1229 Archive: output.zip 1230 Length Date Time Name 1231 --------- ---------- ----- ---- 1232 12 2019-08-16 22:21 1233 --------- ------- 1234 12 1 file 1235 1236The archive member (filename) used is the empty string. 1237 1238If that doesn't suit your needs, you can explicitly set the filename used 1239in the zip archive by specifying the L<Name|"File Naming Options"> option, like so 1240 1241 echo hello world | perl -MIO::Compress::Zip=zip -e 'zip "-" => "-", Name => "hello.txt"' >output.zip 1242 1243Now the contents of the zip file looks like this 1244 1245 $ unzip -l output.zip 1246 Archive: output.zip 1247 Length Date Time Name 1248 --------- ---------- ----- ---- 1249 12 2019-08-16 22:22 hello.txt 1250 --------- ------- 1251 12 1 file 1252 1253=head3 Compressing a file from the filesystem 1254 1255To read the contents of the file C<file1.txt> and write the compressed 1256data to the file C<file1.txt.zip>. 1257 1258 use strict ; 1259 use warnings ; 1260 use IO::Compress::Zip qw(zip $ZipError) ; 1261 1262 my $input = "file1.txt"; 1263 zip $input => "$input.zip" 1264 or die "zip failed: $ZipError\n"; 1265 1266=head3 Reading from a Filehandle and writing to an in-memory buffer 1267 1268To read from an existing Perl filehandle, C<$input>, and write the 1269compressed data to a buffer, C<$buffer>. 1270 1271 use strict ; 1272 use warnings ; 1273 use IO::Compress::Zip qw(zip $ZipError) ; 1274 use IO::File ; 1275 1276 my $input = IO::File->new( "<file1.txt" ) 1277 or die "Cannot open 'file1.txt': $!\n" ; 1278 my $buffer ; 1279 zip $input => \$buffer 1280 or die "zip failed: $ZipError\n"; 1281 1282=head3 Compressing multiple files 1283 1284To create a zip file, C<output.zip>, that contains the compressed contents 1285of the files C<alpha.txt> and C<beta.txt> 1286 1287 use strict ; 1288 use warnings ; 1289 use IO::Compress::Zip qw(zip $ZipError) ; 1290 1291 zip [ 'alpha.txt', 'beta.txt' ] => 'output.zip' 1292 or die "zip failed: $ZipError\n"; 1293 1294Alternatively, rather than having to explicitly name each of the files that 1295you want to compress, you could use a fileglob to select all the C<txt> 1296files in the current directory, as follows 1297 1298 use strict ; 1299 use warnings ; 1300 use IO::Compress::Zip qw(zip $ZipError) ; 1301 1302 my @files = <*.txt>; 1303 zip \@files => 'output.zip' 1304 or die "zip failed: $ZipError\n"; 1305 1306or more succinctly 1307 1308 zip [ <*.txt> ] => 'output.zip' 1309 or die "zip failed: $ZipError\n"; 1310 1311=head1 OO Interface 1312 1313=head2 Constructor 1314 1315The format of the constructor for C<IO::Compress::Zip> is shown below 1316 1317 my $z = IO::Compress::Zip->new( $output [,OPTS] ) 1318 or die "IO::Compress::Zip failed: $ZipError\n"; 1319 1320It returns an C<IO::Compress::Zip> object on success and undef on failure. 1321The variable C<$ZipError> will contain an error message on failure. 1322 1323If you are running Perl 5.005 or better the object, C<$z>, returned from 1324IO::Compress::Zip can be used exactly like an L<IO::File|IO::File> filehandle. 1325This means that all normal output file operations can be carried out 1326with C<$z>. 1327For example, to write to a compressed file/buffer you can use either of 1328these forms 1329 1330 $z->print("hello world\n"); 1331 print $z "hello world\n"; 1332 1333The mandatory parameter C<$output> is used to control the destination 1334of the compressed data. This parameter can take one of these forms. 1335 1336=over 5 1337 1338=item A filename 1339 1340If the C<$output> parameter is a simple scalar, it is assumed to be a 1341filename. This file will be opened for writing and the compressed data 1342will be written to it. 1343 1344=item A filehandle 1345 1346If the C<$output> parameter is a filehandle, the compressed data will be 1347written to it. 1348The string '-' can be used as an alias for standard output. 1349 1350=item A scalar reference 1351 1352If C<$output> is a scalar reference, the compressed data will be stored 1353in C<$$output>. 1354 1355=back 1356 1357If the C<$output> parameter is any other type, C<IO::Compress::Zip>::new will 1358return undef. 1359 1360=head2 Constructor Options 1361 1362C<OPTS> is any combination of zero or more the following options: 1363 1364=over 5 1365 1366=item C<< AutoClose => 0|1 >> 1367 1368This option is only valid when the C<$output> parameter is a filehandle. If 1369specified, and the value is true, it will result in the C<$output> being 1370closed once either the C<close> method is called or the C<IO::Compress::Zip> 1371object is destroyed. 1372 1373This parameter defaults to 0. 1374 1375=item C<< Append => 0|1 >> 1376 1377Opens C<$output> in append mode. 1378 1379The behaviour of this option is dependent on the type of C<$output>. 1380 1381=over 5 1382 1383=item * A Buffer 1384 1385If C<$output> is a buffer and C<Append> is enabled, all compressed data 1386will be append to the end of C<$output>. Otherwise C<$output> will be 1387cleared before any data is written to it. 1388 1389=item * A Filename 1390 1391If C<$output> is a filename and C<Append> is enabled, the file will be 1392opened in append mode. Otherwise the contents of the file, if any, will be 1393truncated before any compressed data is written to it. 1394 1395=item * A Filehandle 1396 1397If C<$output> is a filehandle, the file pointer will be positioned to the 1398end of the file via a call to C<seek> before any compressed data is written 1399to it. Otherwise the file pointer will not be moved. 1400 1401=back 1402 1403This parameter defaults to 0. 1404 1405=back 1406 1407=head3 File Naming Options 1408 1409A quick bit of zip file terminology -- A zip archive consists of one or more I<archive members>, where each member has an associated 1410filename, known as the I<archive member name>. 1411 1412The options listed in this section control how the I<archive member name> (or filename) is stored the zip archive. 1413 1414=over 5 1415 1416=item C<< Name => $string >> 1417 1418This option is used to explicitly set the I<archive member name> in 1419the zip archive to C<$string>. 1420Most of the time you don't need to make use of this option. 1421By default when adding a filename to the zip archive, the I<archive member name> will match the filename. 1422 1423You should only need to use this option if you want the I<archive member name> 1424to be different from the uncompressed filename or when the input is a filehandle or a buffer. 1425 1426The default behaviour for what I<archive member name> is used when the C<Name> option 1427is I<not> specified depends on the form of the C<$input> parameter: 1428 1429=over 5 1430 1431=item * 1432 1433If the C<$input> parameter is a filename, the 1434value of C<$input> will be used for the I<archive member name> . 1435 1436=item * 1437If the C<$input> parameter is not a filename, 1438the I<archive member name> will be an empty string. 1439 1440=back 1441 1442Note that both the C<CanonicalName> and C<FilterName> options 1443can modify the value used for the I<archive member name>. 1444 1445Also note that you should set the C<Efs> option to true if you are working 1446with UTF8 filenames. 1447 1448=item C<< CanonicalName => 0|1 >> 1449 1450This option controls whether the I<archive member name> is 1451I<normalized> into Unix format before being written to the zip file. 1452 1453It is recommended that you enable this option unless you really need 1454to create a non-standard Zip file. 1455 1456This is what APPNOTE.TXT has to say on what should be stored in the zip 1457filename header field. 1458 1459 The name of the file, with optional relative path. 1460 The path stored should not contain a drive or 1461 device letter, or a leading slash. All slashes 1462 should be forward slashes '/' as opposed to 1463 backwards slashes '\' for compatibility with Amiga 1464 and UNIX file systems etc. 1465 1466This option defaults to B<false>. 1467 1468=item C<< FilterName => sub { ... } >> 1469 1470This option allow the I<archive member> name to be modified 1471before it is written to the zip file. 1472 1473This option takes a parameter that must be a reference to a sub. On entry 1474to the sub the C<$_> variable will contain the name to be filtered. If no 1475filename is available C<$_> will contain an empty string. 1476 1477The value of C<$_> when the sub returns will be used as the I<archive member name>. 1478 1479Note that if C<CanonicalName> is enabled, a 1480normalized filename will be passed to the sub. 1481 1482If you use C<FilterName> to modify the filename, it is your responsibility 1483to keep the filename in Unix format. 1484 1485Although this option can be used with the OO interface, it is of most use 1486with the one-shot interface. For example, the code below shows how 1487C<FilterName> can be used to remove the path component from a series of 1488filenames before they are stored in C<$zipfile>. 1489 1490 sub compressTxtFiles 1491 { 1492 my $zipfile = shift ; 1493 my $dir = shift ; 1494 1495 zip [ <$dir/*.txt> ] => $zipfile, 1496 FilterName => sub { s[^$dir/][] } ; 1497 } 1498 1499=item C<< Efs => 0|1 >> 1500 1501This option controls setting of the "Language Encoding Flag" (EFS) in the zip 1502archive. When set, the filename and comment fields for the zip archive MUST 1503be valid UTF-8. 1504 1505If the string used for the filename and/or comment is not valid UTF-8 when this option 1506is true, the script will die with a "wide character" error. 1507 1508Note that this option only works with Perl 5.8.4 or better. 1509 1510This option defaults to B<false>. 1511 1512=back 1513 1514=head3 Overall Zip Archive Structure 1515 1516=over 5 1517 1518=item C<< Minimal => 1|0 >> 1519 1520If specified, this option will disable the creation of all extra fields 1521in the zip local and central headers. So the C<exTime>, C<exUnix2>, 1522C<exUnixN>, C<ExtraFieldLocal> and C<ExtraFieldCentral> options will 1523be ignored. 1524 1525This parameter defaults to 0. 1526 1527=item C<< Stream => 0|1 >> 1528 1529This option controls whether the zip file/buffer output is created in 1530streaming mode. 1531 1532Note that when outputting to a file with streaming mode disabled (C<Stream> 1533is 0), the output file must be seekable. 1534 1535The default is 1. 1536 1537=item C<< Zip64 => 0|1 >> 1538 1539Create a Zip64 zip file/buffer. This option is used if you want 1540to store files larger than 4 Gig or store more than 64K files in a single 1541zip archive. 1542 1543C<Zip64> will be automatically set, as needed, if working with the one-shot 1544interface when the input is either a filename or a scalar reference. 1545 1546If you intend to manipulate the Zip64 zip files created with this module 1547using an external zip/unzip, make sure that it supports Zip64. 1548 1549In particular, if you are using Info-Zip you need to have zip version 3.x 1550or better to update a Zip64 archive and unzip version 6.x to read a zip64 1551archive. 1552 1553The default is 0. 1554 1555=back 1556 1557=head3 Deflate Compression Options 1558 1559=over 5 1560 1561=item -Level 1562 1563Defines the compression level used by zlib. The value should either be 1564a number between 0 and 9 (0 means no compression and 9 is maximum 1565compression), or one of the symbolic constants defined below. 1566 1567 Z_NO_COMPRESSION 1568 Z_BEST_SPEED 1569 Z_BEST_COMPRESSION 1570 Z_DEFAULT_COMPRESSION 1571 1572The default is Z_DEFAULT_COMPRESSION. 1573 1574Note, these constants are not imported by C<IO::Compress::Zip> by default. 1575 1576 use IO::Compress::Zip qw(:strategy); 1577 use IO::Compress::Zip qw(:constants); 1578 use IO::Compress::Zip qw(:all); 1579 1580=item -Strategy 1581 1582Defines the strategy used to tune the compression. Use one of the symbolic 1583constants defined below. 1584 1585 Z_FILTERED 1586 Z_HUFFMAN_ONLY 1587 Z_RLE 1588 Z_FIXED 1589 Z_DEFAULT_STRATEGY 1590 1591The default is Z_DEFAULT_STRATEGY. 1592 1593=back 1594 1595=head3 Bzip2 Compression Options 1596 1597=over 5 1598 1599=item C<< BlockSize100K => number >> 1600 1601Specify the number of 100K blocks bzip2 uses during compression. 1602 1603Valid values are from 1 to 9, where 9 is best compression. 1604 1605This option is only valid if the C<Method> is ZIP_CM_BZIP2. It is ignored 1606otherwise. 1607 1608The default is 1. 1609 1610=item C<< WorkFactor => number >> 1611 1612Specifies how much effort bzip2 should take before resorting to a slower 1613fallback compression algorithm. 1614 1615Valid values range from 0 to 250, where 0 means use the default value 30. 1616 1617This option is only valid if the C<Method> is ZIP_CM_BZIP2. It is ignored 1618otherwise. 1619 1620The default is 0. 1621 1622=back 1623 1624=head3 Lzma and Xz Compression Options 1625 1626=over 5 1627 1628=item C<< Preset => number >> 1629 1630Used to choose the LZMA compression preset. 1631 1632Valid values are 0-9 and C<LZMA_PRESET_DEFAULT>. 1633 16340 is the fastest compression with the lowest memory usage and the lowest 1635compression. 1636 16379 is the slowest compression with the highest memory usage but with the best 1638compression. 1639 1640This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored 1641otherwise. 1642 1643Defaults to C<LZMA_PRESET_DEFAULT> (6). 1644 1645=item C<< Extreme => 0|1 >> 1646 1647Makes LZMA compression a lot slower, but a small compression gain. 1648 1649This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored 1650otherwise. 1651 1652Defaults to 0. 1653 1654=back 1655 1656=head3 Other Options 1657 1658=over 5 1659 1660=item C<< Time => $number >> 1661 1662Sets the last modified time field in the zip header to $number. 1663 1664This field defaults to the time the C<IO::Compress::Zip> object was created 1665if this option is not specified and the C<$input> parameter is not a 1666filename. 1667 1668=item C<< ExtAttr => $attr >> 1669 1670This option controls the "external file attributes" field in the central 1671header of the zip file. This is a 4 byte field. 1672 1673If you are running a Unix derivative this value defaults to 1674 1675 0100644 << 16 1676 1677This should allow read/write access to any files that are extracted from 1678the zip file/buffer`. 1679 1680For all other systems it defaults to 0. 1681 1682=item C<< exTime => [$atime, $mtime, $ctime] >> 1683 1684This option expects an array reference with exactly three elements: 1685C<$atime>, C<mtime> and C<$ctime>. These correspond to the last access 1686time, last modification time and creation time respectively. 1687 1688It uses these values to set the extended timestamp field (ID is "UT") in 1689the local zip header using the three values, $atime, $mtime, $ctime. In 1690addition it sets the extended timestamp field in the central zip header 1691using C<$mtime>. 1692 1693If any of the three values is C<undef> that time value will not be used. 1694So, for example, to set only the C<$mtime> you would use this 1695 1696 exTime => [undef, $mtime, undef] 1697 1698If the C<Minimal> option is set to true, this option will be ignored. 1699 1700By default no extended time field is created. 1701 1702=item C<< exUnix2 => [$uid, $gid] >> 1703 1704This option expects an array reference with exactly two elements: C<$uid> 1705and C<$gid>. These values correspond to the numeric User ID (UID) and Group ID 1706(GID) of the owner of the files respectively. 1707 1708When the C<exUnix2> option is present it will trigger the creation of a 1709Unix2 extra field (ID is "Ux") in the local zip header. This will be populated 1710with C<$uid> and C<$gid>. An empty Unix2 extra field will also 1711be created in the central zip header. 1712 1713Note - The UID & GID are stored as 16-bit 1714integers in the "Ux" field. Use C<< exUnixN >> if your UID or GID are 171532-bit. 1716 1717If the C<Minimal> option is set to true, this option will be ignored. 1718 1719By default no Unix2 extra field is created. 1720 1721=item C<< exUnixN => [$uid, $gid] >> 1722 1723This option expects an array reference with exactly two elements: C<$uid> 1724and C<$gid>. These values correspond to the numeric User ID (UID) and Group ID 1725(GID) of the owner of the files respectively. 1726 1727When the C<exUnixN> option is present it will trigger the creation of a 1728UnixN extra field (ID is "ux") in both the local and central zip headers. 1729This will be populated with C<$uid> and C<$gid>. 1730The UID & GID are stored as 32-bit integers. 1731 1732If the C<Minimal> option is set to true, this option will be ignored. 1733 1734By default no UnixN extra field is created. 1735 1736=item C<< Comment => $comment >> 1737 1738Stores the contents of C<$comment> in the Central File Header of 1739the zip file. 1740 1741Set the C<Efs> option to true if you want to store a UTF8 comment. 1742 1743By default, no comment field is written to the zip file. 1744 1745=item C<< ZipComment => $comment >> 1746 1747Stores the contents of C<$comment> in the End of Central Directory record 1748of the zip file. 1749 1750By default, no comment field is written to the zip file. 1751 1752=item C<< Method => $method >> 1753 1754Controls which compression method is used. At present the compression 1755methods supported are: Store (no compression at all), Deflate, 1756Bzip2, Zstd, Xz and Lzma. 1757 1758The symbols ZIP_CM_STORE, ZIP_CM_DEFLATE, ZIP_CM_BZIP2, ZIP_CM_ZSTD, ZIP_CM_XZ and ZIP_CM_LZMA 1759are used to select the compression method. 1760 1761These constants are not imported by C<IO::Compress::Zip> by default. 1762 1763 use IO::Compress::Zip qw(:zip_method); 1764 use IO::Compress::Zip qw(:constants); 1765 use IO::Compress::Zip qw(:all); 1766 1767Note that to create Bzip2 content, the module C<IO::Compress::Bzip2> must 1768be installed. A fatal error will be thrown if you attempt to create Bzip2 1769content when C<IO::Compress::Bzip2> is not available. 1770 1771Note that to create Lzma content, the module C<IO::Compress::Lzma> must 1772be installed. A fatal error will be thrown if you attempt to create Lzma 1773content when C<IO::Compress::Lzma> is not available. 1774 1775Note that to create Xz content, the module C<IO::Compress::Xz> must 1776be installed. A fatal error will be thrown if you attempt to create Xz 1777content when C<IO::Compress::Xz> is not available. 1778 1779Note that to create Zstd content, the module C<IO::Compress::Zstd> must 1780be installed. A fatal error will be thrown if you attempt to create Zstd 1781content when C<IO::Compress::Zstd> is not available. 1782 1783The default method is ZIP_CM_DEFLATE. 1784 1785=item C<< TextFlag => 0|1 >> 1786 1787This parameter controls the setting of a bit in the zip central header. It 1788is used to signal that the data stored in the zip file/buffer is probably 1789text. 1790 1791In one-shot mode this flag will be set to true if the Perl C<-T> operator thinks 1792the file contains text. 1793 1794The default is 0. 1795 1796=item C<< ExtraFieldLocal => $data >> 1797 1798=item C<< ExtraFieldCentral => $data >> 1799 1800The C<ExtraFieldLocal> option is used to store additional metadata in the 1801local header for the zip file/buffer. The C<ExtraFieldCentral> does the 1802same for the matching central header. 1803 1804An extra field consists of zero or more subfields. Each subfield consists 1805of a two byte header followed by the subfield data. 1806 1807The list of subfields can be supplied in any of the following formats 1808 1809 ExtraFieldLocal => [$id1, $data1, 1810 $id2, $data2, 1811 ... 1812 ] 1813 1814 ExtraFieldLocal => [ [$id1 => $data1], 1815 [$id2 => $data2], 1816 ... 1817 ] 1818 1819 ExtraFieldLocal => { $id1 => $data1, 1820 $id2 => $data2, 1821 ... 1822 } 1823 1824Where C<$id1>, C<$id2> are two byte subfield ID's. 1825 1826If you use the hash syntax, you have no control over the order in which 1827the ExtraSubFields are stored, plus you cannot have SubFields with 1828duplicate ID. 1829 1830Alternatively the list of subfields can by supplied as a scalar, thus 1831 1832 ExtraField => $rawdata 1833 1834In this case C<IO::Compress::Zip> will check that C<$rawdata> consists of 1835zero or more conformant sub-fields. 1836 1837The Extended Time field (ID "UT"), set using the C<exTime> option, and the 1838Unix2 extra field (ID "Ux), set using the C<exUnix2> option, are examples 1839of extra fields. 1840 1841If the C<Minimal> option is set to true, this option will be ignored. 1842 1843The maximum size of an extra field 65535 bytes. 1844 1845=item C<< Strict => 0|1 >> 1846 1847This is a placeholder option. 1848 1849=back 1850 1851=head2 Examples 1852 1853TODO 1854 1855=head1 Methods 1856 1857=head2 print 1858 1859Usage is 1860 1861 $z->print($data) 1862 print $z $data 1863 1864Compresses and outputs the contents of the C<$data> parameter. This 1865has the same behaviour as the C<print> built-in. 1866 1867Returns true if successful. 1868 1869=head2 printf 1870 1871Usage is 1872 1873 $z->printf($format, $data) 1874 printf $z $format, $data 1875 1876Compresses and outputs the contents of the C<$data> parameter. 1877 1878Returns true if successful. 1879 1880=head2 syswrite 1881 1882Usage is 1883 1884 $z->syswrite $data 1885 $z->syswrite $data, $length 1886 $z->syswrite $data, $length, $offset 1887 1888Compresses and outputs the contents of the C<$data> parameter. 1889 1890Returns the number of uncompressed bytes written, or C<undef> if 1891unsuccessful. 1892 1893=head2 write 1894 1895Usage is 1896 1897 $z->write $data 1898 $z->write $data, $length 1899 $z->write $data, $length, $offset 1900 1901Compresses and outputs the contents of the C<$data> parameter. 1902 1903Returns the number of uncompressed bytes written, or C<undef> if 1904unsuccessful. 1905 1906=head2 flush 1907 1908Usage is 1909 1910 $z->flush; 1911 $z->flush($flush_type); 1912 1913Flushes any pending compressed data to the output file/buffer. 1914 1915This method takes an optional parameter, C<$flush_type>, that controls 1916how the flushing will be carried out. By default the C<$flush_type> 1917used is C<Z_FINISH>. Other valid values for C<$flush_type> are 1918C<Z_NO_FLUSH>, C<Z_SYNC_FLUSH>, C<Z_FULL_FLUSH> and C<Z_BLOCK>. It is 1919strongly recommended that you only set the C<flush_type> parameter if 1920you fully understand the implications of what it does - overuse of C<flush> 1921can seriously degrade the level of compression achieved. See the C<zlib> 1922documentation for details. 1923 1924Returns true on success. 1925 1926=head2 tell 1927 1928Usage is 1929 1930 $z->tell() 1931 tell $z 1932 1933Returns the uncompressed file offset. 1934 1935=head2 eof 1936 1937Usage is 1938 1939 $z->eof(); 1940 eof($z); 1941 1942Returns true if the C<close> method has been called. 1943 1944=head2 seek 1945 1946 $z->seek($position, $whence); 1947 seek($z, $position, $whence); 1948 1949Provides a sub-set of the C<seek> functionality, with the restriction 1950that it is only legal to seek forward in the output file/buffer. 1951It is a fatal error to attempt to seek backward. 1952 1953Empty parts of the file/buffer will have NULL (0x00) bytes written to them. 1954 1955The C<$whence> parameter takes one the usual values, namely SEEK_SET, 1956SEEK_CUR or SEEK_END. 1957 1958Returns 1 on success, 0 on failure. 1959 1960=head2 binmode 1961 1962Usage is 1963 1964 $z->binmode 1965 binmode $z ; 1966 1967This is a noop provided for completeness. 1968 1969=head2 opened 1970 1971 $z->opened() 1972 1973Returns true if the object currently refers to a opened file/buffer. 1974 1975=head2 autoflush 1976 1977 my $prev = $z->autoflush() 1978 my $prev = $z->autoflush(EXPR) 1979 1980If the C<$z> object is associated with a file or a filehandle, this method 1981returns the current autoflush setting for the underlying filehandle. If 1982C<EXPR> is present, and is non-zero, it will enable flushing after every 1983write/print operation. 1984 1985If C<$z> is associated with a buffer, this method has no effect and always 1986returns C<undef>. 1987 1988B<Note> that the special variable C<$|> B<cannot> be used to set or 1989retrieve the autoflush setting. 1990 1991=head2 input_line_number 1992 1993 $z->input_line_number() 1994 $z->input_line_number(EXPR) 1995 1996This method always returns C<undef> when compressing. 1997 1998=head2 fileno 1999 2000 $z->fileno() 2001 fileno($z) 2002 2003If the C<$z> object is associated with a file or a filehandle, C<fileno> 2004will return the underlying file descriptor. Once the C<close> method is 2005called C<fileno> will return C<undef>. 2006 2007If the C<$z> object is associated with a buffer, this method will return 2008C<undef>. 2009 2010=head2 close 2011 2012 $z->close() ; 2013 close $z ; 2014 2015Flushes any pending compressed data and then closes the output file/buffer. 2016 2017For most versions of Perl this method will be automatically invoked if 2018the IO::Compress::Zip object is destroyed (either explicitly or by the 2019variable with the reference to the object going out of scope). The 2020exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In 2021these cases, the C<close> method will be called automatically, but 2022not until global destruction of all live objects when the program is 2023terminating. 2024 2025Therefore, if you want your scripts to be able to run on all versions 2026of Perl, you should call C<close> explicitly and not rely on automatic 2027closing. 2028 2029Returns true on success, otherwise 0. 2030 2031If the C<AutoClose> option has been enabled when the IO::Compress::Zip 2032object was created, and the object is associated with a file, the 2033underlying file will also be closed. 2034 2035=head2 newStream([OPTS]) 2036 2037Usage is 2038 2039 $z->newStream( [OPTS] ) 2040 2041Closes the current compressed data stream and starts a new one. 2042 2043OPTS consists of any of the options that are available when creating 2044the C<$z> object. 2045 2046See the L</"Constructor Options"> section for more details. 2047 2048=head2 deflateParams 2049 2050Usage is 2051 2052 $z->deflateParams 2053 2054TODO 2055 2056=head1 Importing 2057 2058A number of symbolic constants are required by some methods in 2059C<IO::Compress::Zip>. None are imported by default. 2060 2061=over 5 2062 2063=item :all 2064 2065Imports C<zip>, C<$ZipError> and all symbolic 2066constants that can be used by C<IO::Compress::Zip>. Same as doing this 2067 2068 use IO::Compress::Zip qw(zip $ZipError :constants) ; 2069 2070=item :constants 2071 2072Import all symbolic constants. Same as doing this 2073 2074 use IO::Compress::Zip qw(:flush :level :strategy :zip_method) ; 2075 2076=item :flush 2077 2078These symbolic constants are used by the C<flush> method. 2079 2080 Z_NO_FLUSH 2081 Z_PARTIAL_FLUSH 2082 Z_SYNC_FLUSH 2083 Z_FULL_FLUSH 2084 Z_FINISH 2085 Z_BLOCK 2086 2087=item :level 2088 2089These symbolic constants are used by the C<Level> option in the constructor. 2090 2091 Z_NO_COMPRESSION 2092 Z_BEST_SPEED 2093 Z_BEST_COMPRESSION 2094 Z_DEFAULT_COMPRESSION 2095 2096=item :strategy 2097 2098These symbolic constants are used by the C<Strategy> option in the constructor. 2099 2100 Z_FILTERED 2101 Z_HUFFMAN_ONLY 2102 Z_RLE 2103 Z_FIXED 2104 Z_DEFAULT_STRATEGY 2105 2106=item :zip_method 2107 2108These symbolic constants are used by the C<Method> option in the 2109constructor. 2110 2111 ZIP_CM_STORE 2112 ZIP_CM_DEFLATE 2113 ZIP_CM_BZIP2 2114 2115=back 2116 2117=head1 EXAMPLES 2118 2119=head2 Apache::GZip Revisited 2120 2121See L<IO::Compress::FAQ|IO::Compress::FAQ/"Apache::GZip Revisited"> 2122 2123=head2 Working with Net::FTP 2124 2125See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP"> 2126 2127=head1 SUPPORT 2128 2129General feedback/questions/bug reports should be sent to 2130L<https://github.com/pmqs/IO-Compress/issues> (preferred) or 2131L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>. 2132 2133=head1 SEE ALSO 2134 2135L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress> 2136 2137L<IO::Compress::FAQ|IO::Compress::FAQ> 2138 2139L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, 2140L<Archive::Tar|Archive::Tar>, 2141L<IO::Zlib|IO::Zlib> 2142 2143For RFC 1950, 1951 and 1952 see 2144L<https://datatracker.ietf.org/doc/html/rfc1950>, 2145L<https://datatracker.ietf.org/doc/html/rfc1951> and 2146L<https://datatracker.ietf.org/doc/html/rfc1952> 2147 2148The I<zlib> compression library was written by Jean-loup Gailly 2149C<gzip@prep.ai.mit.edu> and Mark Adler C<madler@alumni.caltech.edu>. 2150 2151The primary site for the I<zlib> compression library is 2152L<http://www.zlib.org>. 2153 2154The primary site for the I<zlib-ng> compression library is 2155L<https://github.com/zlib-ng/zlib-ng>. 2156 2157The primary site for gzip is L<http://www.gzip.org>. 2158 2159=head1 AUTHOR 2160 2161This module was written by Paul Marquess, C<pmqs@cpan.org>. 2162 2163=head1 MODIFICATION HISTORY 2164 2165See the Changes file. 2166 2167=head1 COPYRIGHT AND LICENSE 2168 2169Copyright (c) 2005-2023 Paul Marquess. All rights reserved. 2170 2171This program is free software; you can redistribute it and/or 2172modify it under the same terms as Perl itself. 2173