File Coverage

blib/lib/IO/Compress/Zip.pm
Criterion Covered Total %
statement 359 424 84.6
branch 106 180 58.8
condition 29 63 46.0
subroutine 32 35 91.4
pod 2 19 10.5
total 528 721 73.2


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