xref: /openbsd-src/gnu/usr.bin/perl/cpan/IO-Compress/lib/IO/Compress/Zip.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1b39c5158Smillertpackage IO::Compress::Zip ;
2b39c5158Smillert
3b39c5158Smillertuse strict ;
4b39c5158Smillertuse warnings;
5b39c5158Smillertuse bytes;
6b39c5158Smillert
7*3d61058aSafresh1use IO::Compress::Base::Common  2.212 qw(:Status );
8*3d61058aSafresh1use IO::Compress::RawDeflate 2.212 ();
9*3d61058aSafresh1use IO::Compress::Adapter::Deflate 2.212 ;
10*3d61058aSafresh1use IO::Compress::Adapter::Identity 2.212 ;
11*3d61058aSafresh1use IO::Compress::Zlib::Extra 2.212 ;
12*3d61058aSafresh1use IO::Compress::Zip::Constants 2.212 ;
13b39c5158Smillert
14898184e3Ssthenuse File::Spec();
15898184e3Ssthenuse Config;
16b39c5158Smillert
17*3d61058aSafresh1use Compress::Raw::Zlib  2.212 ();
18898184e3Ssthen
19b39c5158SmillertBEGIN
20b39c5158Smillert{
21b39c5158Smillert    eval { require IO::Compress::Adapter::Bzip2 ;
22*3d61058aSafresh1           IO::Compress::Adapter::Bzip2->VERSION( 2.212 );
23b39c5158Smillert           require IO::Compress::Bzip2 ;
24*3d61058aSafresh1           IO::Compress::Bzip2->VERSION( 2.212 );
25b39c5158Smillert         } ;
26898184e3Ssthen
27898184e3Ssthen    eval { require IO::Compress::Adapter::Lzma ;
28*3d61058aSafresh1           IO::Compress::Adapter::Lzma->VERSION( 2.212 );
29898184e3Ssthen           require IO::Compress::Lzma ;
30*3d61058aSafresh1           IO::Compress::Lzma->VERSION( 2.212 );
31eac174f2Safresh1         } ;
32eac174f2Safresh1
33eac174f2Safresh1    eval { require IO::Compress::Adapter::Xz ;
34*3d61058aSafresh1           IO::Compress::Adapter::Xz->VERSION( 2.212 );
35eac174f2Safresh1           require IO::Compress::Xz ;
36*3d61058aSafresh1           IO::Compress::Xz->VERSION( 2.212 );
37eac174f2Safresh1         } ;
38eac174f2Safresh1    eval { require IO::Compress::Adapter::Zstd ;
39*3d61058aSafresh1           IO::Compress::Adapter::Zstd->VERSION( 2.212 );
40eac174f2Safresh1           require IO::Compress::Zstd ;
41*3d61058aSafresh1           IO::Compress::Zstd->VERSION( 2.212 );
42898184e3Ssthen         } ;
43b39c5158Smillert}
44b39c5158Smillert
45b39c5158Smillert
46b39c5158Smillertrequire Exporter ;
47b39c5158Smillert
48898184e3Ssthenour ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $ZipError);
49b39c5158Smillert
50*3d61058aSafresh1$VERSION = '2.212';
51b39c5158Smillert$ZipError = '';
52b39c5158Smillert
539f11ffb7Safresh1@ISA = qw(IO::Compress::RawDeflate Exporter);
54b39c5158Smillert@EXPORT_OK = qw( $ZipError zip ) ;
55b39c5158Smillert%EXPORT_TAGS = %IO::Compress::RawDeflate::DEFLATE_CONSTANTS ;
56898184e3Ssthen
57b39c5158Smillertpush @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
58b39c5158Smillert
59eac174f2Safresh1$EXPORT_TAGS{zip_method} = [qw( ZIP_CM_STORE ZIP_CM_DEFLATE ZIP_CM_BZIP2 ZIP_CM_LZMA ZIP_CM_XZ ZIP_CM_ZSTD)];
60b39c5158Smillertpush @{ $EXPORT_TAGS{all} }, @{ $EXPORT_TAGS{zip_method} };
61b39c5158Smillert
62b39c5158SmillertExporter::export_ok_tags('all');
63b39c5158Smillert
64b39c5158Smillertsub new
65b39c5158Smillert{
66b39c5158Smillert    my $class = shift ;
67b39c5158Smillert
6891f110e0Safresh1    my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$ZipError);
69b39c5158Smillert    $obj->_create(undef, @_);
70898184e3Ssthen
71b39c5158Smillert}
72b39c5158Smillert
73b39c5158Smillertsub zip
74b39c5158Smillert{
7591f110e0Safresh1    my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$ZipError);
76b39c5158Smillert    return $obj->_def(@_);
77b39c5158Smillert}
78b39c5158Smillert
79898184e3Ssthensub isMethodAvailable
80898184e3Ssthen{
81898184e3Ssthen    my $method = shift;
82898184e3Ssthen
83898184e3Ssthen    # Store & Deflate are always available
84898184e3Ssthen    return 1
85898184e3Ssthen        if $method == ZIP_CM_STORE || $method == ZIP_CM_DEFLATE ;
86898184e3Ssthen
87898184e3Ssthen    return 1
88e0680481Safresh1        if $method == ZIP_CM_BZIP2 &&
89e0680481Safresh1           defined $IO::Compress::Adapter::Bzip2::VERSION &&
90e0680481Safresh1           defined &{ "IO::Compress::Adapter::Bzip2::mkRawZipCompObject" };
91898184e3Ssthen
92898184e3Ssthen    return 1
93e0680481Safresh1        if $method == ZIP_CM_LZMA &&
94e0680481Safresh1           defined $IO::Compress::Adapter::Lzma::VERSION &&
95e0680481Safresh1           defined &{ "IO::Compress::Adapter::Lzma::mkRawZipCompObject" };
96898184e3Ssthen
97eac174f2Safresh1    return 1
98e0680481Safresh1        if $method == ZIP_CM_XZ &&
99e0680481Safresh1           defined $IO::Compress::Adapter::Xz::VERSION &&
100e0680481Safresh1           defined &{ "IO::Compress::Adapter::Xz::mkRawZipCompObject" };
101eac174f2Safresh1
102eac174f2Safresh1    return 1
103e0680481Safresh1        if $method == ZIP_CM_ZSTD &&
104e0680481Safresh1           defined $IO::Compress::Adapter::ZSTD::VERSION &&
105e0680481Safresh1           defined &{ "IO::Compress::Adapter::ZSTD::mkRawZipCompObject" };
106eac174f2Safresh1
107898184e3Ssthen    return 0;
108898184e3Ssthen}
109898184e3Ssthen
110898184e3Ssthensub beforePayload
111898184e3Ssthen{
112898184e3Ssthen    my $self = shift ;
113898184e3Ssthen
114898184e3Ssthen    if (*$self->{ZipData}{Sparse} ) {
115898184e3Ssthen        my $inc = 1024 * 100 ;
116898184e3Ssthen        my $NULLS = ("\x00" x $inc) ;
117898184e3Ssthen        my $sparse = *$self->{ZipData}{Sparse} ;
118898184e3Ssthen        *$self->{CompSize}->add( $sparse );
119898184e3Ssthen        *$self->{UnCompSize}->add( $sparse );
120898184e3Ssthen
121898184e3Ssthen        *$self->{FH}->seek($sparse, IO::Handle::SEEK_CUR);
122898184e3Ssthen
123898184e3Ssthen        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32($NULLS, *$self->{ZipData}{CRC32})
124898184e3Ssthen            for 1 .. int $sparse / $inc;
125898184e3Ssthen        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(substr($NULLS, 0,  $sparse % $inc),
126898184e3Ssthen                                         *$self->{ZipData}{CRC32})
127898184e3Ssthen            if $sparse % $inc;
128898184e3Ssthen    }
129898184e3Ssthen}
130898184e3Ssthen
131b39c5158Smillertsub mkComp
132b39c5158Smillert{
133b39c5158Smillert    my $self = shift ;
134b39c5158Smillert    my $got = shift ;
135b39c5158Smillert
136b39c5158Smillert    my ($obj, $errstr, $errno) ;
137b39c5158Smillert
138b39c5158Smillert    if (*$self->{ZipData}{Method} == ZIP_CM_STORE) {
139b39c5158Smillert        ($obj, $errstr, $errno) = IO::Compress::Adapter::Identity::mkCompObject(
14091f110e0Safresh1                                                 $got->getValue('level'),
14191f110e0Safresh1                                                 $got->getValue('strategy')
142b39c5158Smillert                                                 );
143898184e3Ssthen        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef);
144b39c5158Smillert    }
145b39c5158Smillert    elsif (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) {
146b39c5158Smillert        ($obj, $errstr, $errno) = IO::Compress::Adapter::Deflate::mkCompObject(
14791f110e0Safresh1                                                 $got->getValue('crc32'),
14891f110e0Safresh1                                                 $got->getValue('adler32'),
14991f110e0Safresh1                                                 $got->getValue('level'),
15091f110e0Safresh1                                                 $got->getValue('strategy')
151b39c5158Smillert                                                 );
152b39c5158Smillert    }
153b39c5158Smillert    elsif (*$self->{ZipData}{Method} == ZIP_CM_BZIP2) {
154b39c5158Smillert        ($obj, $errstr, $errno) = IO::Compress::Adapter::Bzip2::mkCompObject(
15591f110e0Safresh1                                                $got->getValue('blocksize100k'),
15691f110e0Safresh1                                                $got->getValue('workfactor'),
15791f110e0Safresh1                                                $got->getValue('verbosity')
158b39c5158Smillert                                               );
159898184e3Ssthen        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef);
160b39c5158Smillert    }
161898184e3Ssthen    elsif (*$self->{ZipData}{Method} == ZIP_CM_LZMA) {
16291f110e0Safresh1        ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzma::mkRawZipCompObject($got->getValue('preset'),
16391f110e0Safresh1                                                                                 $got->getValue('extreme'),
164898184e3Ssthen                                                                                 );
165898184e3Ssthen        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef);
166898184e3Ssthen    }
167eac174f2Safresh1    elsif (*$self->{ZipData}{Method} == ZIP_CM_XZ) {
168eac174f2Safresh1        ($obj, $errstr, $errno) = IO::Compress::Adapter::Xz::mkCompObject($got->getValue('preset'),
169eac174f2Safresh1                                                                                 $got->getValue('extreme'),
170eac174f2Safresh1                                                                                 0
171eac174f2Safresh1                                                                                 );
172eac174f2Safresh1        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef);
173eac174f2Safresh1    }
174eac174f2Safresh1    elsif (*$self->{ZipData}{Method} == ZIP_CM_ZSTD) {
175eac174f2Safresh1        ($obj, $errstr, $errno) = IO::Compress::Adapter::Zstd::mkCompObject(defined $got->getValue('level') ? $got->getValue('level') : 3,
176eac174f2Safresh1                                                                           );
177eac174f2Safresh1        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef);
178eac174f2Safresh1    }
179b39c5158Smillert
180b39c5158Smillert    return $self->saveErrorString(undef, $errstr, $errno)
181b39c5158Smillert       if ! defined $obj;
182b39c5158Smillert
183b39c5158Smillert    if (! defined *$self->{ZipData}{SizesOffset}) {
184b39c5158Smillert        *$self->{ZipData}{SizesOffset} = 0;
185eac174f2Safresh1        *$self->{ZipData}{Offset} = U64->new();
186b39c5158Smillert    }
187b39c5158Smillert
188b39c5158Smillert    *$self->{ZipData}{AnyZip64} = 0
189b39c5158Smillert        if ! defined  *$self->{ZipData}{AnyZip64} ;
190b39c5158Smillert
191b39c5158Smillert    return $obj;
192b39c5158Smillert}
193b39c5158Smillert
194b39c5158Smillertsub reset
195b39c5158Smillert{
196b39c5158Smillert    my $self = shift ;
197b39c5158Smillert
198b39c5158Smillert    *$self->{Compress}->reset();
199b39c5158Smillert    *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32('');
200b39c5158Smillert
201b39c5158Smillert    return STATUS_OK;
202b39c5158Smillert}
203b39c5158Smillert
204b39c5158Smillertsub filterUncompressed
205b39c5158Smillert{
206b39c5158Smillert    my $self = shift ;
207b39c5158Smillert
208b39c5158Smillert    if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) {
209b39c5158Smillert        *$self->{ZipData}{CRC32} = *$self->{Compress}->crc32();
210b39c5158Smillert    }
211b39c5158Smillert    else {
212898184e3Ssthen        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(${$_[0]}, *$self->{ZipData}{CRC32});
213b39c5158Smillert
214b39c5158Smillert    }
215b39c5158Smillert}
216b39c5158Smillert
217898184e3Ssthensub canonicalName
218898184e3Ssthen{
219898184e3Ssthen    # This sub is derived from Archive::Zip::_asZipDirName
220898184e3Ssthen
221898184e3Ssthen    # Return the normalized name as used in a zip file (path
222898184e3Ssthen    # separators become slashes, etc.).
223898184e3Ssthen    # Will translate internal slashes in path components (i.e. on Macs) to
224898184e3Ssthen    # underscores.  Discards volume names.
225898184e3Ssthen    # When $forceDir is set, returns paths with trailing slashes
226898184e3Ssthen    #
227898184e3Ssthen    # input         output
228898184e3Ssthen    # .             '.'
229898184e3Ssthen    # ./a           a
230898184e3Ssthen    # ./a/b         a/b
231898184e3Ssthen    # ./a/b/        a/b
232898184e3Ssthen    # a/b/          a/b
233898184e3Ssthen    # /a/b/         a/b
234898184e3Ssthen    # c:\a\b\c.doc  a/b/c.doc      # on Windows
235898184e3Ssthen    # "i/o maps:whatever"   i_o maps/whatever   # on Macs
236898184e3Ssthen
237898184e3Ssthen    my $name      = shift;
238898184e3Ssthen    my $forceDir  = shift ;
239898184e3Ssthen
240898184e3Ssthen    my ( $volume, $directories, $file ) =
241898184e3Ssthen      File::Spec->splitpath( File::Spec->canonpath($name), $forceDir );
242898184e3Ssthen
243898184e3Ssthen    my @dirs = map { $_ =~ s{/}{_}g; $_ }
244898184e3Ssthen               File::Spec->splitdir($directories);
245898184e3Ssthen
246898184e3Ssthen    if ( @dirs > 0 ) { pop (@dirs) if $dirs[-1] eq '' }   # remove empty component
247898184e3Ssthen    push @dirs, defined($file) ? $file : '' ;
248898184e3Ssthen
249898184e3Ssthen    my $normalised_path = join '/', @dirs;
250898184e3Ssthen
251898184e3Ssthen    # Leading directory separators should not be stored in zip archives.
252898184e3Ssthen    # Example:
253898184e3Ssthen    #   C:\a\b\c\      a/b/c
254898184e3Ssthen    #   C:\a\b\c.txt   a/b/c.txt
255898184e3Ssthen    #   /a/b/c/        a/b/c
256898184e3Ssthen    #   /a/b/c.txt     a/b/c.txt
257898184e3Ssthen    $normalised_path =~ s{^/}{};  # remove leading separator
258898184e3Ssthen
259898184e3Ssthen    return $normalised_path;
260898184e3Ssthen}
261898184e3Ssthen
262898184e3Ssthen
263b39c5158Smillertsub mkHeader
264b39c5158Smillert{
265b39c5158Smillert    my $self  = shift;
266b39c5158Smillert    my $param = shift ;
267b39c5158Smillert
268b39c5158Smillert    *$self->{ZipData}{LocalHdrOffset} = U64::clone(*$self->{ZipData}{Offset});
269b39c5158Smillert
270898184e3Ssthen    my $comment = '';
27191f110e0Safresh1    $comment = $param->valueOrDefault('comment') ;
272898184e3Ssthen
273b39c5158Smillert    my $filename = '';
27491f110e0Safresh1    $filename = $param->valueOrDefault('name') ;
275b39c5158Smillert
276898184e3Ssthen    $filename = canonicalName($filename)
27791f110e0Safresh1        if length $filename && $param->getValue('canonicalname') ;
278898184e3Ssthen
279898184e3Ssthen    if (defined *$self->{ZipData}{FilterName} ) {
280898184e3Ssthen        local *_ = \$filename ;
281898184e3Ssthen        &{ *$self->{ZipData}{FilterName} }() ;
282898184e3Ssthen    }
283898184e3Ssthen
28456d68f1eSafresh1   if ( $param->getValue('efs') && $] >= 5.008004) {
28556d68f1eSafresh1        if (length $filename) {
28656d68f1eSafresh1            utf8::downgrade($filename, 1)
28756d68f1eSafresh1                or Carp::croak "Wide character in zip filename";
28856d68f1eSafresh1        }
28956d68f1eSafresh1
29056d68f1eSafresh1        if (length $comment) {
29156d68f1eSafresh1            utf8::downgrade($comment, 1)
29256d68f1eSafresh1                or Carp::croak "Wide character in zip comment";
29356d68f1eSafresh1        }
29456d68f1eSafresh1   }
295b39c5158Smillert
296b39c5158Smillert    my $hdr = '';
297b39c5158Smillert
29891f110e0Safresh1    my $time = _unixToDosTime($param->getValue('time'));
299b39c5158Smillert
300b39c5158Smillert    my $extra = '';
301b39c5158Smillert    my $ctlExtra = '';
302b39c5158Smillert    my $empty = 0;
30391f110e0Safresh1    my $osCode = $param->getValue('os_code') ;
304b39c5158Smillert    my $extFileAttr = 0 ;
305b39c5158Smillert
306b39c5158Smillert    # This code assumes Unix.
307898184e3Ssthen    # TODO - revisit this
308898184e3Ssthen    $extFileAttr = 0100644 << 16
309b39c5158Smillert        if $osCode == ZIP_OS_CODE_UNIX ;
310b39c5158Smillert
311b39c5158Smillert    if (*$self->{ZipData}{Zip64}) {
31291f110e0Safresh1        $empty = IO::Compress::Base::Common::MAX32;
313b39c5158Smillert
314b39c5158Smillert        my $x = '';
315b39c5158Smillert        $x .= pack "V V", 0, 0 ; # uncompressedLength
316b39c5158Smillert        $x .= pack "V V", 0, 0 ; # compressedLength
317b8851fccSafresh1
318b8851fccSafresh1        # Zip64 needs to be first in extra field to workaround a Windows Explorer Bug
319b8851fccSafresh1        # See http://www.info-zip.org/phpBB3/viewtopic.php?f=3&t=440 for details
320b39c5158Smillert        $extra .= IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $x);
321b39c5158Smillert    }
322b39c5158Smillert
32391f110e0Safresh1    if (! $param->getValue('minimal')) {
32491f110e0Safresh1        if ($param->parsed('mtime'))
325b39c5158Smillert        {
32691f110e0Safresh1            $extra .= mkExtendedTime($param->getValue('mtime'),
32791f110e0Safresh1                                    $param->getValue('atime'),
32891f110e0Safresh1                                    $param->getValue('ctime'));
329b39c5158Smillert
33091f110e0Safresh1            $ctlExtra .= mkExtendedTime($param->getValue('mtime'));
331b39c5158Smillert        }
332b39c5158Smillert
333898184e3Ssthen        if ( $osCode == ZIP_OS_CODE_UNIX )
334b39c5158Smillert        {
33591f110e0Safresh1            if ( $param->getValue('want_exunixn') )
336898184e3Ssthen            {
33791f110e0Safresh1                    my $ux3 = mkUnixNExtra( @{ $param->getValue('want_exunixn') });
338898184e3Ssthen                    $extra    .= $ux3;
339898184e3Ssthen                    $ctlExtra .= $ux3;
340898184e3Ssthen            }
341898184e3Ssthen
34291f110e0Safresh1            if ( $param->getValue('exunix2') )
343898184e3Ssthen            {
34491f110e0Safresh1                    $extra    .= mkUnix2Extra( @{ $param->getValue('exunix2') });
345b39c5158Smillert                    $ctlExtra .= mkUnix2Extra();
346b39c5158Smillert            }
347898184e3Ssthen        }
348b39c5158Smillert
34991f110e0Safresh1        $extFileAttr = $param->getValue('extattr')
35091f110e0Safresh1            if defined $param->getValue('extattr') ;
351b39c5158Smillert
35291f110e0Safresh1        $extra .= $param->getValue('extrafieldlocal')
35391f110e0Safresh1            if defined $param->getValue('extrafieldlocal');
354b39c5158Smillert
35591f110e0Safresh1        $ctlExtra .= $param->getValue('extrafieldcentral')
35691f110e0Safresh1            if defined $param->getValue('extrafieldcentral');
357b39c5158Smillert    }
358b39c5158Smillert
359898184e3Ssthen    my $method = *$self->{ZipData}{Method} ;
360b39c5158Smillert    my $gpFlag = 0 ;
361b39c5158Smillert    $gpFlag |= ZIP_GP_FLAG_STREAMING_MASK
362b39c5158Smillert        if *$self->{ZipData}{Stream} ;
363b39c5158Smillert
364898184e3Ssthen    $gpFlag |= ZIP_GP_FLAG_LZMA_EOS_PRESENT
365898184e3Ssthen        if $method == ZIP_CM_LZMA ;
366898184e3Ssthen
36756d68f1eSafresh1    $gpFlag |= ZIP_GP_FLAG_LANGUAGE_ENCODING
36856d68f1eSafresh1        if  $param->getValue('efs') && (length($filename) || length($comment));
369b39c5158Smillert
370b39c5158Smillert    my $version = $ZIP_CM_MIN_VERSIONS{$method};
371b39c5158Smillert    $version = ZIP64_MIN_VERSION
372b39c5158Smillert        if ZIP64_MIN_VERSION > $version && *$self->{ZipData}{Zip64};
373898184e3Ssthen
37491f110e0Safresh1    my $madeBy = ($param->getValue('os_code') << 8) + $version;
375b39c5158Smillert    my $extract = $version;
376b39c5158Smillert
377b39c5158Smillert    *$self->{ZipData}{Version} = $version;
378b39c5158Smillert    *$self->{ZipData}{MadeBy} = $madeBy;
379b39c5158Smillert
380b39c5158Smillert    my $ifa = 0;
381b39c5158Smillert    $ifa |= ZIP_IFA_TEXT_MASK
38291f110e0Safresh1        if $param->getValue('textflag');
383b39c5158Smillert
384b39c5158Smillert    $hdr .= pack "V", ZIP_LOCAL_HDR_SIG ; # signature
385b39c5158Smillert    $hdr .= pack 'v', $extract   ; # extract Version & OS
386b39c5158Smillert    $hdr .= pack 'v', $gpFlag    ; # general purpose flag (set streaming mode)
387b39c5158Smillert    $hdr .= pack 'v', $method    ; # compression method (deflate)
388b39c5158Smillert    $hdr .= pack 'V', $time      ; # last mod date/time
389b39c5158Smillert    $hdr .= pack 'V', 0          ; # crc32               - 0 when streaming
390b39c5158Smillert    $hdr .= pack 'V', $empty     ; # compressed length   - 0 when streaming
391b39c5158Smillert    $hdr .= pack 'V', $empty     ; # uncompressed length - 0 when streaming
392b39c5158Smillert    $hdr .= pack 'v', length $filename ; # filename length
393b39c5158Smillert    $hdr .= pack 'v', length $extra ; # extra length
394b39c5158Smillert
395b39c5158Smillert    $hdr .= $filename ;
396b39c5158Smillert
397b39c5158Smillert    # Remember the offset for the compressed & uncompressed lengths in the
398b39c5158Smillert    # local header.
399b39c5158Smillert    if (*$self->{ZipData}{Zip64}) {
400b39c5158Smillert        *$self->{ZipData}{SizesOffset} = *$self->{ZipData}{Offset}->get64bit()
401b39c5158Smillert            + length($hdr) + 4 ;
402b39c5158Smillert    }
403b39c5158Smillert    else {
404b39c5158Smillert        *$self->{ZipData}{SizesOffset} = *$self->{ZipData}{Offset}->get64bit()
405b39c5158Smillert                                            + 18;
406b39c5158Smillert    }
407b39c5158Smillert
408b39c5158Smillert    $hdr .= $extra ;
409b39c5158Smillert
410b39c5158Smillert
411b39c5158Smillert    my $ctl = '';
412b39c5158Smillert
413b39c5158Smillert    $ctl .= pack "V", ZIP_CENTRAL_HDR_SIG ; # signature
414b39c5158Smillert    $ctl .= pack 'v', $madeBy    ; # version made by
415b39c5158Smillert    $ctl .= pack 'v', $extract   ; # extract Version
416b39c5158Smillert    $ctl .= pack 'v', $gpFlag    ; # general purpose flag (streaming mode)
417b39c5158Smillert    $ctl .= pack 'v', $method    ; # compression method (deflate)
418b39c5158Smillert    $ctl .= pack 'V', $time      ; # last mod date/time
419b39c5158Smillert    $ctl .= pack 'V', 0          ; # crc32
420b39c5158Smillert    $ctl .= pack 'V', $empty     ; # compressed length
421b39c5158Smillert    $ctl .= pack 'V', $empty     ; # uncompressed length
422b39c5158Smillert    $ctl .= pack 'v', length $filename ; # filename length
423b39c5158Smillert
424b39c5158Smillert    *$self->{ZipData}{ExtraOffset} = length $ctl;
425b39c5158Smillert    *$self->{ZipData}{ExtraSize} = length $ctlExtra ;
426b39c5158Smillert
427b39c5158Smillert    $ctl .= pack 'v', length $ctlExtra ; # extra length
428b39c5158Smillert    $ctl .= pack 'v', length $comment ;  # file comment length
429b39c5158Smillert    $ctl .= pack 'v', 0          ; # disk number start
430b39c5158Smillert    $ctl .= pack 'v', $ifa       ; # internal file attributes
431b39c5158Smillert    $ctl .= pack 'V', $extFileAttr   ; # external file attributes
432b39c5158Smillert
433b39c5158Smillert    # offset to local hdr
434b39c5158Smillert    if (*$self->{ZipData}{LocalHdrOffset}->is64bit() ) {
43591f110e0Safresh1        $ctl .= pack 'V', IO::Compress::Base::Common::MAX32 ;
436b39c5158Smillert    }
437b39c5158Smillert    else {
438b39c5158Smillert        $ctl .= *$self->{ZipData}{LocalHdrOffset}->getPacked_V32() ;
439b39c5158Smillert    }
440b39c5158Smillert
441b39c5158Smillert    $ctl .= $filename ;
442b39c5158Smillert
44391f110e0Safresh1    *$self->{ZipData}{Offset}->add32(length $hdr) ;
444b39c5158Smillert
445b8851fccSafresh1    *$self->{ZipData}{CentralHeader} = [ $ctl, $ctlExtra, $comment];
446898184e3Ssthen
447b39c5158Smillert    return $hdr;
448b39c5158Smillert}
449b39c5158Smillert
450b39c5158Smillertsub mkTrailer
451b39c5158Smillert{
452b39c5158Smillert    my $self = shift ;
453b39c5158Smillert
454b39c5158Smillert    my $crc32 ;
455b39c5158Smillert    if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) {
456b39c5158Smillert        $crc32 = pack "V", *$self->{Compress}->crc32();
457b39c5158Smillert    }
458b39c5158Smillert    else {
459b39c5158Smillert        $crc32 = pack "V", *$self->{ZipData}{CRC32};
460b39c5158Smillert    }
461b39c5158Smillert
462b8851fccSafresh1    my ($ctl, $ctlExtra, $comment) = @{ *$self->{ZipData}{CentralHeader} };
463b39c5158Smillert
464b39c5158Smillert    my $sizes ;
465b39c5158Smillert    if (! *$self->{ZipData}{Zip64}) {
466b39c5158Smillert        $sizes .= *$self->{CompSize}->getPacked_V32() ;   # Compressed size
467b39c5158Smillert        $sizes .= *$self->{UnCompSize}->getPacked_V32() ; # Uncompressed size
468b39c5158Smillert    }
469b39c5158Smillert    else {
470b39c5158Smillert        $sizes .= *$self->{CompSize}->getPacked_V64() ;   # Compressed size
471b39c5158Smillert        $sizes .= *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size
472b39c5158Smillert    }
473b39c5158Smillert
474b39c5158Smillert    my $data = $crc32 . $sizes ;
475b39c5158Smillert
476b39c5158Smillert    my $xtrasize  = *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size
477b39c5158Smillert       $xtrasize .= *$self->{CompSize}->getPacked_V64() ;   # Compressed size
478b39c5158Smillert
479b39c5158Smillert    my $hdr = '';
480b39c5158Smillert
481b39c5158Smillert    if (*$self->{ZipData}{Stream}) {
482b39c5158Smillert        $hdr  = pack "V", ZIP_DATA_HDR_SIG ;                       # signature
483b39c5158Smillert        $hdr .= $data ;
484b39c5158Smillert    }
485b39c5158Smillert    else {
486b39c5158Smillert        $self->writeAt(*$self->{ZipData}{LocalHdrOffset}->get64bit() + 14,  $crc32)
487b39c5158Smillert            or return undef;
488b39c5158Smillert        $self->writeAt(*$self->{ZipData}{SizesOffset},
489b39c5158Smillert                *$self->{ZipData}{Zip64} ? $xtrasize : $sizes)
490b39c5158Smillert            or return undef;
491b39c5158Smillert    }
492b39c5158Smillert
493b39c5158Smillert    # Central Header Record/Zip64 extended field
494b39c5158Smillert
495b39c5158Smillert    substr($ctl, 16, length $crc32) = $crc32 ;
496b39c5158Smillert
497b8851fccSafresh1    my $zip64Payload = '';
498b39c5158Smillert
499b8851fccSafresh1    # uncompressed length - only set zip64 if needed
500b8851fccSafresh1    if (*$self->{UnCompSize}->isAlmost64bit()) { #  || *$self->{ZipData}{Zip64}) {
501b8851fccSafresh1        $zip64Payload .= *$self->{UnCompSize}->getPacked_V64() ;
502b39c5158Smillert    } else {
503b39c5158Smillert        substr($ctl, 24, 4) = *$self->{UnCompSize}->getPacked_V32() ;
504b39c5158Smillert    }
505b39c5158Smillert
506b8851fccSafresh1    # compressed length - only set zip64 if needed
507b8851fccSafresh1    if (*$self->{CompSize}->isAlmost64bit()) { # || *$self->{ZipData}{Zip64}) {
508b8851fccSafresh1        $zip64Payload .= *$self->{CompSize}->getPacked_V64() ;
509b39c5158Smillert    } else {
510b39c5158Smillert        substr($ctl, 20, 4) = *$self->{CompSize}->getPacked_V32() ;
511b39c5158Smillert    }
512b39c5158Smillert
513b39c5158Smillert    # Local Header offset
514b8851fccSafresh1    $zip64Payload .= *$self->{ZipData}{LocalHdrOffset}->getPacked_V64()
515b39c5158Smillert        if *$self->{ZipData}{LocalHdrOffset}->is64bit() ;
516b39c5158Smillert
517b8851fccSafresh1    # disk no - always zero, so don't need to include it.
518b8851fccSafresh1    #$zip64Payload .= pack "V", 0    ;
519b39c5158Smillert
520b8851fccSafresh1    my $zip64Xtra = '';
521b8851fccSafresh1
522b8851fccSafresh1    if (length $zip64Payload) {
523b8851fccSafresh1        $zip64Xtra = IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $zip64Payload);
524b8851fccSafresh1
525b39c5158Smillert        substr($ctl, *$self->{ZipData}{ExtraOffset}, 2) =
526b8851fccSafresh1             pack 'v', *$self->{ZipData}{ExtraSize} + length $zip64Xtra;
527b39c5158Smillert
528b39c5158Smillert        *$self->{ZipData}{AnyZip64} = 1;
529b39c5158Smillert    }
530b39c5158Smillert
531b8851fccSafresh1    # Zip64 needs to be first in extra field to workaround a Windows Explorer Bug
532b8851fccSafresh1    # See http://www.info-zip.org/phpBB3/viewtopic.php?f=3&t=440 for details
533b8851fccSafresh1    $ctl .= $zip64Xtra . $ctlExtra . $comment;
534b8851fccSafresh1
53591f110e0Safresh1    *$self->{ZipData}{Offset}->add32(length($hdr));
536b39c5158Smillert    *$self->{ZipData}{Offset}->add( *$self->{CompSize} );
537b39c5158Smillert    push @{ *$self->{ZipData}{CentralDir} }, $ctl ;
538b39c5158Smillert
539b39c5158Smillert    return $hdr;
540b39c5158Smillert}
541b39c5158Smillert
542b39c5158Smillertsub mkFinalTrailer
543b39c5158Smillert{
544b39c5158Smillert    my $self = shift ;
545b39c5158Smillert
546b39c5158Smillert    my $comment = '';
547b39c5158Smillert    $comment = *$self->{ZipData}{ZipComment} ;
548b39c5158Smillert
549b39c5158Smillert    my $cd_offset = *$self->{ZipData}{Offset}->get32bit() ; # offset to start central dir
550b39c5158Smillert
551b39c5158Smillert    my $entries = @{ *$self->{ZipData}{CentralDir} };
55291f110e0Safresh1
55391f110e0Safresh1    *$self->{ZipData}{AnyZip64} = 1
55491f110e0Safresh1        if *$self->{ZipData}{Offset}->is64bit || $entries >= 0xFFFF ;
55591f110e0Safresh1
556b39c5158Smillert    my $cd = join '', @{ *$self->{ZipData}{CentralDir} };
557b39c5158Smillert    my $cd_len = length $cd ;
558b39c5158Smillert
559b39c5158Smillert    my $z64e = '';
560b39c5158Smillert
561b39c5158Smillert    if ( *$self->{ZipData}{AnyZip64} ) {
562b39c5158Smillert
563b39c5158Smillert        my $v  = *$self->{ZipData}{Version} ;
564b39c5158Smillert        my $mb = *$self->{ZipData}{MadeBy} ;
565b39c5158Smillert        $z64e .= pack 'v', $mb            ; # Version made by
566b39c5158Smillert        $z64e .= pack 'v', $v             ; # Version to extract
567b39c5158Smillert        $z64e .= pack 'V', 0              ; # number of disk
568b39c5158Smillert        $z64e .= pack 'V', 0              ; # number of disk with central dir
569b39c5158Smillert        $z64e .= U64::pack_V64 $entries   ; # entries in central dir on this disk
570b39c5158Smillert        $z64e .= U64::pack_V64 $entries   ; # entries in central dir
571b39c5158Smillert        $z64e .= U64::pack_V64 $cd_len    ; # size of central dir
572b39c5158Smillert        $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to start central dir
573e0680481Safresh1        $z64e .= *$self->{ZipData}{extrafieldzip64}  # otional extra field
574e0680481Safresh1            if defined *$self->{ZipData}{extrafieldzip64} ;
575b39c5158Smillert
576b39c5158Smillert        $z64e  = pack("V", ZIP64_END_CENTRAL_REC_HDR_SIG) # signature
577b39c5158Smillert              .  U64::pack_V64(length $z64e)
578b39c5158Smillert              .  $z64e ;
579b39c5158Smillert
58091f110e0Safresh1        *$self->{ZipData}{Offset}->add32(length $cd) ;
581b39c5158Smillert
582b39c5158Smillert        $z64e .= pack "V", ZIP64_END_CENTRAL_LOC_HDR_SIG; # signature
583b39c5158Smillert        $z64e .= pack 'V', 0              ; # number of disk with central dir
584b39c5158Smillert        $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to end zip64 central dir
585b39c5158Smillert        $z64e .= pack 'V', 1              ; # Total number of disks
586b39c5158Smillert
58791f110e0Safresh1        $cd_offset = IO::Compress::Base::Common::MAX32 ;
58891f110e0Safresh1        $cd_len = IO::Compress::Base::Common::MAX32 if IO::Compress::Base::Common::isGeMax32 $cd_len ;
589b39c5158Smillert        $entries = 0xFFFF if $entries >= 0xFFFF ;
590b39c5158Smillert    }
591b39c5158Smillert
592b39c5158Smillert    my $ecd = '';
593b39c5158Smillert    $ecd .= pack "V", ZIP_END_CENTRAL_HDR_SIG ; # signature
594b39c5158Smillert    $ecd .= pack 'v', 0          ; # number of disk
595b39c5158Smillert    $ecd .= pack 'v', 0          ; # number of disk with central dir
596b39c5158Smillert    $ecd .= pack 'v', $entries   ; # entries in central dir on this disk
597b39c5158Smillert    $ecd .= pack 'v', $entries   ; # entries in central dir
598b39c5158Smillert    $ecd .= pack 'V', $cd_len    ; # size of central dir
599b39c5158Smillert    $ecd .= pack 'V', $cd_offset ; # offset to start central dir
600b39c5158Smillert    $ecd .= pack 'v', length $comment ; # zipfile comment length
601b39c5158Smillert    $ecd .= $comment;
602b39c5158Smillert
603b39c5158Smillert    return $cd . $z64e . $ecd ;
604b39c5158Smillert}
605b39c5158Smillert
606b39c5158Smillertsub ckParams
607b39c5158Smillert{
608b39c5158Smillert    my $self = shift ;
609b39c5158Smillert    my $got = shift;
610b39c5158Smillert
61191f110e0Safresh1    $got->setValue('crc32' => 1);
612b39c5158Smillert
61391f110e0Safresh1    if (! $got->parsed('time') ) {
614b39c5158Smillert        # Modification time defaults to now.
61591f110e0Safresh1        $got->setValue('time' => time) ;
616b39c5158Smillert    }
617b39c5158Smillert
61891f110e0Safresh1    if ($got->parsed('extime') ) {
61991f110e0Safresh1        my $timeRef = $got->getValue('extime');
620b39c5158Smillert        if ( defined $timeRef) {
621b39c5158Smillert            return $self->saveErrorString(undef, "exTime not a 3-element array ref")
622b39c5158Smillert                if ref $timeRef ne 'ARRAY' || @$timeRef != 3;
623b39c5158Smillert        }
624b39c5158Smillert
62591f110e0Safresh1        $got->setValue("mtime", $timeRef->[1]);
62691f110e0Safresh1        $got->setValue("atime", $timeRef->[0]);
62791f110e0Safresh1        $got->setValue("ctime", $timeRef->[2]);
628b39c5158Smillert    }
629b39c5158Smillert
630898184e3Ssthen    # Unix2/3 Extended Attribute
63191f110e0Safresh1    for my $name (qw(exunix2 exunixn))
632898184e3Ssthen    {
633898184e3Ssthen        if ($got->parsed($name) ) {
63491f110e0Safresh1            my $idRef = $got->getValue($name);
635898184e3Ssthen            if ( defined $idRef) {
636898184e3Ssthen                return $self->saveErrorString(undef, "$name not a 2-element array ref")
637898184e3Ssthen                    if ref $idRef ne 'ARRAY' || @$idRef != 2;
638b39c5158Smillert            }
639b39c5158Smillert
64091f110e0Safresh1            $got->setValue("uid", $idRef->[0]);
64191f110e0Safresh1            $got->setValue("gid", $idRef->[1]);
64291f110e0Safresh1            $got->setValue("want_$name", $idRef);
643898184e3Ssthen        }
644b39c5158Smillert    }
645b39c5158Smillert
646b39c5158Smillert    *$self->{ZipData}{AnyZip64} = 1
647e0680481Safresh1        if $got->getValue('zip64') || $got->getValue('extrafieldzip64') ;
64891f110e0Safresh1    *$self->{ZipData}{Zip64} = $got->getValue('zip64');
64991f110e0Safresh1    *$self->{ZipData}{Stream} = $got->getValue('stream');
650b39c5158Smillert
65191f110e0Safresh1    my $method = $got->getValue('method');
652b39c5158Smillert    return $self->saveErrorString(undef, "Unknown Method '$method'")
653b39c5158Smillert        if ! defined $ZIP_CM_MIN_VERSIONS{$method};
654b39c5158Smillert
655b39c5158Smillert    return $self->saveErrorString(undef, "Bzip2 not available")
656b39c5158Smillert        if $method == ZIP_CM_BZIP2 and
657b39c5158Smillert           ! defined $IO::Compress::Adapter::Bzip2::VERSION;
658b39c5158Smillert
659b39c5158Smillert    return $self->saveErrorString(undef, "Lzma not available")
660898184e3Ssthen        if $method == ZIP_CM_LZMA
661898184e3Ssthen        and ! defined $IO::Compress::Adapter::Lzma::VERSION;
662b39c5158Smillert
663b39c5158Smillert    *$self->{ZipData}{Method} = $method;
664b39c5158Smillert
66591f110e0Safresh1    *$self->{ZipData}{ZipComment} = $got->getValue('zipcomment') ;
666b39c5158Smillert
667e0680481Safresh1    for my $name (qw( extrafieldlocal extrafieldcentral extrafieldzip64))
668b39c5158Smillert    {
66991f110e0Safresh1        my $data = $got->getValue($name) ;
670b39c5158Smillert        if (defined $data) {
671b39c5158Smillert            my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, 1, 0) ;
672b39c5158Smillert            return $self->saveErrorString(undef, "Error with $name Parameter: $bad")
673b39c5158Smillert                if $bad ;
674b39c5158Smillert
67591f110e0Safresh1            $got->setValue($name, $data) ;
676e0680481Safresh1            *$self->{ZipData}{$name} = $data;
677b39c5158Smillert        }
678b39c5158Smillert    }
679b39c5158Smillert
680b39c5158Smillert    return undef
681b39c5158Smillert        if defined $IO::Compress::Bzip2::VERSION
682b39c5158Smillert            and ! IO::Compress::Bzip2::ckParams($self, $got);
683b39c5158Smillert
68491f110e0Safresh1    if ($got->parsed('sparse') ) {
68591f110e0Safresh1        *$self->{ZipData}{Sparse} = $got->getValue('sparse') ;
686898184e3Ssthen        *$self->{ZipData}{Method} = ZIP_CM_STORE;
687898184e3Ssthen    }
688898184e3Ssthen
68991f110e0Safresh1    if ($got->parsed('filtername')) {
69091f110e0Safresh1        my $v = $got->getValue('filtername') ;
691898184e3Ssthen        *$self->{ZipData}{FilterName} = $v
692898184e3Ssthen            if ref $v eq 'CODE' ;
693898184e3Ssthen    }
694898184e3Ssthen
695b39c5158Smillert    return 1 ;
696b39c5158Smillert}
697b39c5158Smillert
698898184e3Ssthensub outputPayload
699898184e3Ssthen{
700898184e3Ssthen    my $self = shift ;
701898184e3Ssthen    return 1 if *$self->{ZipData}{Sparse} ;
702898184e3Ssthen    return $self->output(@_);
703898184e3Ssthen}
704898184e3Ssthen
705898184e3Ssthen
706b39c5158Smillert#sub newHeader
707b39c5158Smillert#{
708b39c5158Smillert#    my $self = shift ;
709b39c5158Smillert#
710b39c5158Smillert#    return $self->mkHeader(*$self->{Got});
711b39c5158Smillert#}
712b39c5158Smillert
713b39c5158Smillert
71491f110e0Safresh1our %PARAMS = (
71591f110e0Safresh1            'stream'    => [IO::Compress::Base::Common::Parse_boolean,   1],
71691f110e0Safresh1           #'store'     => [IO::Compress::Base::Common::Parse_boolean,   0],
71791f110e0Safresh1            'method'    => [IO::Compress::Base::Common::Parse_unsigned,  ZIP_CM_DEFLATE],
718b39c5158Smillert
719b39c5158Smillert#            # Zip header fields
72091f110e0Safresh1            'minimal'   => [IO::Compress::Base::Common::Parse_boolean,   0],
72191f110e0Safresh1            'zip64'     => [IO::Compress::Base::Common::Parse_boolean,   0],
72291f110e0Safresh1            'comment'   => [IO::Compress::Base::Common::Parse_any,       ''],
72391f110e0Safresh1            'zipcomment'=> [IO::Compress::Base::Common::Parse_any,       ''],
72491f110e0Safresh1            'name'      => [IO::Compress::Base::Common::Parse_any,       ''],
72591f110e0Safresh1            'filtername'=> [IO::Compress::Base::Common::Parse_code,      undef],
72691f110e0Safresh1            'canonicalname'=> [IO::Compress::Base::Common::Parse_boolean,   0],
72756d68f1eSafresh1            'efs'       => [IO::Compress::Base::Common::Parse_boolean,   0],
72891f110e0Safresh1            'time'      => [IO::Compress::Base::Common::Parse_any,       undef],
72991f110e0Safresh1            'extime'    => [IO::Compress::Base::Common::Parse_any,       undef],
73091f110e0Safresh1            'exunix2'   => [IO::Compress::Base::Common::Parse_any,       undef],
73191f110e0Safresh1            'exunixn'   => [IO::Compress::Base::Common::Parse_any,       undef],
73291f110e0Safresh1            'extattr'   => [IO::Compress::Base::Common::Parse_any,
733898184e3Ssthen                    $Compress::Raw::Zlib::gzip_os_code == 3
734898184e3Ssthen                        ? 0100644 << 16
735898184e3Ssthen                        : 0],
73691f110e0Safresh1            'os_code'   => [IO::Compress::Base::Common::Parse_unsigned,  $Compress::Raw::Zlib::gzip_os_code],
737b39c5158Smillert
73891f110e0Safresh1            'textflag'  => [IO::Compress::Base::Common::Parse_boolean,   0],
73991f110e0Safresh1            'extrafieldlocal'  => [IO::Compress::Base::Common::Parse_any,    undef],
74091f110e0Safresh1            'extrafieldcentral'=> [IO::Compress::Base::Common::Parse_any,    undef],
741e0680481Safresh1            'extrafieldzip64'  => [IO::Compress::Base::Common::Parse_any,    undef],
742b39c5158Smillert
743898184e3Ssthen            # Lzma
74491f110e0Safresh1            'preset'   => [IO::Compress::Base::Common::Parse_unsigned, 6],
74591f110e0Safresh1            'extreme'  => [IO::Compress::Base::Common::Parse_boolean,  0],
746898184e3Ssthen
747898184e3Ssthen            # For internal use only
74891f110e0Safresh1            'sparse'    => [IO::Compress::Base::Common::Parse_unsigned,  0],
749898184e3Ssthen
75091f110e0Safresh1            IO::Compress::RawDeflate::getZlibParams(),
75191f110e0Safresh1            defined $IO::Compress::Bzip2::VERSION
75291f110e0Safresh1                ? IO::Compress::Bzip2::getExtraParams()
75391f110e0Safresh1                : ()
75491f110e0Safresh1
75591f110e0Safresh1
756b39c5158Smillert                );
75791f110e0Safresh1
75891f110e0Safresh1sub getExtraParams
75991f110e0Safresh1{
76091f110e0Safresh1    return %PARAMS ;
761b39c5158Smillert}
762b39c5158Smillert
763b39c5158Smillertsub getInverseClass
764b39c5158Smillert{
765eac174f2Safresh1    no warnings 'once';
766b39c5158Smillert    return ('IO::Uncompress::Unzip',
767b39c5158Smillert                \$IO::Uncompress::Unzip::UnzipError);
768b39c5158Smillert}
769b39c5158Smillert
770b39c5158Smillertsub getFileInfo
771b39c5158Smillert{
772b39c5158Smillert    my $self = shift ;
773b39c5158Smillert    my $params = shift;
774b39c5158Smillert    my $filename = shift ;
775b39c5158Smillert
77691f110e0Safresh1    if (IO::Compress::Base::Common::isaScalar($filename))
777898184e3Ssthen    {
77891f110e0Safresh1        $params->setValue(zip64 => 1)
77991f110e0Safresh1            if IO::Compress::Base::Common::isGeMax32 length (${ $filename }) ;
780898184e3Ssthen
781898184e3Ssthen        return ;
782898184e3Ssthen    }
783898184e3Ssthen
784898184e3Ssthen    my ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) ;
78591f110e0Safresh1    if ( $params->parsed('storelinks') )
786898184e3Ssthen    {
787898184e3Ssthen        ($mode, $uid, $gid, $size, $atime, $mtime, $ctime)
788898184e3Ssthen                = (lstat($filename))[2, 4,5,7, 8,9,10] ;
789898184e3Ssthen    }
790898184e3Ssthen    else
791898184e3Ssthen    {
792898184e3Ssthen        ($mode, $uid, $gid, $size, $atime, $mtime, $ctime)
793898184e3Ssthen                = (stat($filename))[2, 4,5,7, 8,9,10] ;
794898184e3Ssthen    }
795898184e3Ssthen
79691f110e0Safresh1    $params->setValue(textflag => -T $filename )
79791f110e0Safresh1        if ! $params->parsed('textflag');
798898184e3Ssthen
79991f110e0Safresh1    $params->setValue(zip64 => 1)
80091f110e0Safresh1        if IO::Compress::Base::Common::isGeMax32 $size ;
801b39c5158Smillert
80291f110e0Safresh1    $params->setValue('name' => $filename)
80391f110e0Safresh1        if ! $params->parsed('name') ;
804b39c5158Smillert
80591f110e0Safresh1    $params->setValue('time' => $mtime)
80691f110e0Safresh1        if ! $params->parsed('time') ;
807b39c5158Smillert
80891f110e0Safresh1    if ( ! $params->parsed('extime'))
809b39c5158Smillert    {
81091f110e0Safresh1        $params->setValue('mtime' => $mtime) ;
81191f110e0Safresh1        $params->setValue('atime' => $atime) ;
81291f110e0Safresh1        $params->setValue('ctime' => undef) ; # No Creation time
813898184e3Ssthen        # TODO - see if can fillout creation time on non-Unix
814b39c5158Smillert    }
815b39c5158Smillert
816b39c5158Smillert    # NOTE - Unix specific code alert
81791f110e0Safresh1    if (! $params->parsed('extattr'))
818898184e3Ssthen    {
819898184e3Ssthen        use Fcntl qw(:mode) ;
820898184e3Ssthen        my $attr = $mode << 16;
821898184e3Ssthen        $attr |= ZIP_A_RONLY if ($mode & S_IWRITE) == 0 ;
822898184e3Ssthen        $attr |= ZIP_A_DIR   if ($mode & S_IFMT  ) == S_IFDIR ;
823b39c5158Smillert
82491f110e0Safresh1        $params->setValue('extattr' => $attr);
825898184e3Ssthen    }
826898184e3Ssthen
82791f110e0Safresh1    $params->setValue('want_exunixn', [$uid, $gid]);
82891f110e0Safresh1    $params->setValue('uid' => $uid) ;
82991f110e0Safresh1    $params->setValue('gid' => $gid) ;
830b39c5158Smillert
831b39c5158Smillert}
832b39c5158Smillert
833b39c5158Smillertsub mkExtendedTime
834b39c5158Smillert{
835b39c5158Smillert    # order expected is m, a, c
836b39c5158Smillert
837b39c5158Smillert    my $times = '';
838b39c5158Smillert    my $bit = 1 ;
839b39c5158Smillert    my $flags = 0;
840b39c5158Smillert
841b39c5158Smillert    for my $time (@_)
842b39c5158Smillert    {
843b39c5158Smillert        if (defined $time)
844b39c5158Smillert        {
845b39c5158Smillert            $flags |= $bit;
846b39c5158Smillert            $times .= pack("V", $time);
847b39c5158Smillert        }
848b39c5158Smillert
849b39c5158Smillert        $bit <<= 1 ;
850b39c5158Smillert    }
851b39c5158Smillert
852b39c5158Smillert    return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_EXT_TIMESTAMP,
853b39c5158Smillert                                                 pack("C", $flags) .  $times);
854b39c5158Smillert}
855b39c5158Smillert
856b39c5158Smillertsub mkUnix2Extra
857b39c5158Smillert{
858b39c5158Smillert    my $ids = '';
859b39c5158Smillert    for my $id (@_)
860b39c5158Smillert    {
861b39c5158Smillert        $ids .= pack("v", $id);
862b39c5158Smillert    }
863b39c5158Smillert
864b39c5158Smillert    return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIX2,
865b39c5158Smillert                                                 $ids);
866b39c5158Smillert}
867b39c5158Smillert
868898184e3Ssthensub mkUnixNExtra
869898184e3Ssthen{
870898184e3Ssthen    my $uid = shift;
871898184e3Ssthen    my $gid = shift;
872898184e3Ssthen
873898184e3Ssthen    # Assumes UID/GID are 32-bit
874898184e3Ssthen    my $ids ;
875898184e3Ssthen    $ids .= pack "C", 1; # version
876898184e3Ssthen    $ids .= pack "C", $Config{uidsize};
877898184e3Ssthen    $ids .= pack "V", $uid;
878898184e3Ssthen    $ids .= pack "C", $Config{gidsize};
879898184e3Ssthen    $ids .= pack "V", $gid;
880898184e3Ssthen
881898184e3Ssthen    return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIXN,
882898184e3Ssthen                                                 $ids);
883898184e3Ssthen}
884898184e3Ssthen
885b39c5158Smillert
886b39c5158Smillert# from Archive::Zip
887b39c5158Smillertsub _unixToDosTime    # Archive::Zip::Member
888b39c5158Smillert{
889b39c5158Smillert	my $time_t = shift;
890898184e3Ssthen
891b39c5158Smillert    # TODO - add something to cope with unix time < 1980
892b39c5158Smillert	my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime($time_t);
893b39c5158Smillert	my $dt = 0;
894b39c5158Smillert	$dt += ( $sec >> 1 );
895b39c5158Smillert	$dt += ( $min << 5 );
896b39c5158Smillert	$dt += ( $hour << 11 );
897b39c5158Smillert	$dt += ( $mday << 16 );
898b39c5158Smillert	$dt += ( ( $mon + 1 ) << 21 );
899b39c5158Smillert	$dt += ( ( $year - 80 ) << 25 );
900b39c5158Smillert	return $dt;
901b39c5158Smillert}
902b39c5158Smillert
903b39c5158Smillert1;
904b39c5158Smillert
905b39c5158Smillert__END__
906b39c5158Smillert
907b39c5158Smillert=head1 NAME
908b39c5158Smillert
909b39c5158SmillertIO::Compress::Zip - Write zip files/buffers
910b39c5158Smillert
911b39c5158Smillert=head1 SYNOPSIS
912b39c5158Smillert
913b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError) ;
914b39c5158Smillert
915b39c5158Smillert    my $status = zip $input => $output [,OPTS]
916b39c5158Smillert        or die "zip failed: $ZipError\n";
917b39c5158Smillert
918eac174f2Safresh1    my $z = IO::Compress::Zip->new( $output [,OPTS] )
919b39c5158Smillert        or die "zip failed: $ZipError\n";
920b39c5158Smillert
921b39c5158Smillert    $z->print($string);
922b39c5158Smillert    $z->printf($format, $string);
923b39c5158Smillert    $z->write($string);
924b39c5158Smillert    $z->syswrite($string [, $length, $offset]);
925b39c5158Smillert    $z->flush();
926b39c5158Smillert    $z->tell();
927b39c5158Smillert    $z->eof();
928b39c5158Smillert    $z->seek($position, $whence);
929b39c5158Smillert    $z->binmode();
930b39c5158Smillert    $z->fileno();
931b39c5158Smillert    $z->opened();
932b39c5158Smillert    $z->autoflush();
933b39c5158Smillert    $z->input_line_number();
934b39c5158Smillert    $z->newStream( [OPTS] );
935b39c5158Smillert
936b39c5158Smillert    $z->deflateParams();
937b39c5158Smillert
938b39c5158Smillert    $z->close() ;
939b39c5158Smillert
940b39c5158Smillert    $ZipError ;
941b39c5158Smillert
942b39c5158Smillert    # IO::File mode
943b39c5158Smillert
944b39c5158Smillert    print $z $string;
945b39c5158Smillert    printf $z $format, $string;
946b39c5158Smillert    tell $z
947b39c5158Smillert    eof $z
948b39c5158Smillert    seek $z, $position, $whence
949b39c5158Smillert    binmode $z
950b39c5158Smillert    fileno $z
951b39c5158Smillert    close $z ;
952b39c5158Smillert
953b39c5158Smillert=head1 DESCRIPTION
954b39c5158Smillert
955b39c5158SmillertThis module provides a Perl interface that allows writing zip
956b39c5158Smillertcompressed data to files or buffer.
957b39c5158Smillert
958b39c5158SmillertThe primary purpose of this module is to provide streaming write access to
959eac174f2Safresh1zip files and buffers.
960b39c5158Smillert
961eac174f2Safresh1At present the following compression methods are supported by IO::Compress::Zip
962b39c5158Smillert
96356d68f1eSafresh1=over 5
96456d68f1eSafresh1
965eac174f2Safresh1=item Store (0)
96656d68f1eSafresh1
967eac174f2Safresh1=item Deflate (8)
968eac174f2Safresh1
969eac174f2Safresh1=item Bzip2 (12)
970eac174f2Safresh1
971eac174f2Safresh1To write Bzip2 content, the module C<IO::Uncompress::Bunzip2> must
972eac174f2Safresh1be installed.
973eac174f2Safresh1
974eac174f2Safresh1=item Lzma (14)
975eac174f2Safresh1
976eac174f2Safresh1To write LZMA content, the module C<IO::Uncompress::UnLzma> must
977eac174f2Safresh1be installed.
978eac174f2Safresh1
979eac174f2Safresh1=item Zstandard (93)
980eac174f2Safresh1
981eac174f2Safresh1To write Zstandard content, the module C<IO::Compress::Zstd> must
982eac174f2Safresh1be installed.
983eac174f2Safresh1
984eac174f2Safresh1=item Xz (95)
985eac174f2Safresh1
986eac174f2Safresh1To write Xz content, the module C<IO::Uncompress::UnXz> must
987eac174f2Safresh1be installed.
98856d68f1eSafresh1
98956d68f1eSafresh1=back
990898184e3Ssthen
991b39c5158SmillertFor reading zip files/buffers, see the companion module
992b39c5158SmillertL<IO::Uncompress::Unzip|IO::Uncompress::Unzip>.
993b39c5158Smillert
994b39c5158Smillert=head1 Functional Interface
995b39c5158Smillert
996b39c5158SmillertA top-level function, C<zip>, is provided to carry out
997b39c5158Smillert"one-shot" compression between buffers and/or files. For finer
998b39c5158Smillertcontrol over the compression process, see the L</"OO Interface">
999b39c5158Smillertsection.
1000b39c5158Smillert
1001b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError) ;
1002b39c5158Smillert
100391f110e0Safresh1    zip $input_filename_or_reference => $output_filename_or_reference [,OPTS]
1004b39c5158Smillert        or die "zip failed: $ZipError\n";
1005b39c5158Smillert
1006b39c5158SmillertThe functional interface needs Perl5.005 or better.
1007b39c5158Smillert
10086fb12b70Safresh1=head2 zip $input_filename_or_reference => $output_filename_or_reference [, OPTS]
1009b39c5158Smillert
101091f110e0Safresh1C<zip> expects at least two parameters,
101156d68f1eSafresh1C<$input_filename_or_reference> and C<$output_filename_or_reference>
101256d68f1eSafresh1and zero or more optional parameters (see L</Optional Parameters>)
1013b39c5158Smillert
101491f110e0Safresh1=head3 The C<$input_filename_or_reference> parameter
1015b39c5158Smillert
101691f110e0Safresh1The parameter, C<$input_filename_or_reference>, is used to define the
101791f110e0Safresh1source of the uncompressed data.
1018b39c5158Smillert
1019b39c5158SmillertIt can take one of the following forms:
1020b39c5158Smillert
1021b39c5158Smillert=over 5
1022b39c5158Smillert
1023b39c5158Smillert=item A filename
1024b39c5158Smillert
102556d68f1eSafresh1If the C<$input_filename_or_reference> parameter is a simple scalar, it is
102691f110e0Safresh1assumed to be a filename. This file will be opened for reading and the
102791f110e0Safresh1input data will be read from it.
1028b39c5158Smillert
1029b39c5158Smillert=item A filehandle
1030b39c5158Smillert
103191f110e0Safresh1If the C<$input_filename_or_reference> parameter is a filehandle, the input
103291f110e0Safresh1data will be read from it.  The string '-' can be used as an alias for
103391f110e0Safresh1standard input.
1034b39c5158Smillert
1035b39c5158Smillert=item A scalar reference
1036b39c5158Smillert
103791f110e0Safresh1If C<$input_filename_or_reference> is a scalar reference, the input data
103891f110e0Safresh1will be read from C<$$input_filename_or_reference>.
1039b39c5158Smillert
1040b39c5158Smillert=item An array reference
1041b39c5158Smillert
104291f110e0Safresh1If C<$input_filename_or_reference> is an array reference, each element in
104391f110e0Safresh1the array must be a filename.
1044b39c5158Smillert
1045b39c5158SmillertThe input data will be read from each file in turn.
1046b39c5158Smillert
1047b39c5158SmillertThe complete array will be walked to ensure that it only
1048b39c5158Smillertcontains valid filenames before any data is compressed.
1049b39c5158Smillert
1050b39c5158Smillert=item An Input FileGlob string
1051b39c5158Smillert
105291f110e0Safresh1If C<$input_filename_or_reference> is a string that is delimited by the
105391f110e0Safresh1characters "<" and ">" C<zip> will assume that it is an
105491f110e0Safresh1I<input fileglob string>. The input is the list of files that match the
105591f110e0Safresh1fileglob.
1056b39c5158Smillert
1057b39c5158SmillertSee L<File::GlobMapper|File::GlobMapper> for more details.
1058b39c5158Smillert
1059b39c5158Smillert=back
1060b39c5158Smillert
106191f110e0Safresh1If the C<$input_filename_or_reference> parameter is any other type,
106291f110e0Safresh1C<undef> will be returned.
1063b39c5158Smillert
1064e0680481Safresh1In addition, if C<$input_filename_or_reference> corresponds to a filename
1065e0680481Safresh1from the filesystem, a number of zip file header fields will be populated by default
1066e0680481Safresh1using the following attributes from the input file
1067e0680481Safresh1
1068e0680481Safresh1=over 5
1069e0680481Safresh1
1070e0680481Safresh1=item * the full filename contained in C<$input_filename_or_reference>
1071e0680481Safresh1
1072e0680481Safresh1=item * the file protection attributes
1073e0680481Safresh1
1074e0680481Safresh1=item * the UID/GID for the file
1075e0680481Safresh1
1076e0680481Safresh1=item * the file timestamps
1077e0680481Safresh1
1078e0680481Safresh1=back
1079b39c5158Smillert
1080b39c5158SmillertIf you do not want to use these defaults they can be overridden by
1081e0680481Safresh1explicitly setting one, or more, of the C<Name>, C<Time>, C<TextFlag>, C<ExtAttr>, C<exUnixN> and C<exTime> options or by setting the
1082b39c5158SmillertC<Minimal> parameter.
1083b39c5158Smillert
108491f110e0Safresh1=head3 The C<$output_filename_or_reference> parameter
1085b39c5158Smillert
108691f110e0Safresh1The parameter C<$output_filename_or_reference> is used to control the
108791f110e0Safresh1destination of the compressed data. This parameter can take one of
108891f110e0Safresh1these forms.
1089b39c5158Smillert
1090b39c5158Smillert=over 5
1091b39c5158Smillert
1092b39c5158Smillert=item A filename
1093b39c5158Smillert
109491f110e0Safresh1If the C<$output_filename_or_reference> parameter is a simple scalar, it is
109591f110e0Safresh1assumed to be a filename.  This file will be opened for writing and the
109691f110e0Safresh1compressed data will be written to it.
1097b39c5158Smillert
1098b39c5158Smillert=item A filehandle
1099b39c5158Smillert
110091f110e0Safresh1If the C<$output_filename_or_reference> parameter is a filehandle, the
110191f110e0Safresh1compressed data will be written to it.  The string '-' can be used as
110291f110e0Safresh1an alias for standard output.
1103b39c5158Smillert
1104b39c5158Smillert=item A scalar reference
1105b39c5158Smillert
110691f110e0Safresh1If C<$output_filename_or_reference> is a scalar reference, the
110791f110e0Safresh1compressed data will be stored in C<$$output_filename_or_reference>.
1108b39c5158Smillert
1109b39c5158Smillert=item An Array Reference
1110b39c5158Smillert
111191f110e0Safresh1If C<$output_filename_or_reference> is an array reference,
111291f110e0Safresh1the compressed data will be pushed onto the array.
1113b39c5158Smillert
1114b39c5158Smillert=item An Output FileGlob
1115b39c5158Smillert
111691f110e0Safresh1If C<$output_filename_or_reference> is a string that is delimited by the
111791f110e0Safresh1characters "<" and ">" C<zip> will assume that it is an
111891f110e0Safresh1I<output fileglob string>. The output is the list of files that match the
111991f110e0Safresh1fileglob.
1120b39c5158Smillert
112191f110e0Safresh1When C<$output_filename_or_reference> is an fileglob string,
112291f110e0Safresh1C<$input_filename_or_reference> must also be a fileglob string. Anything
112391f110e0Safresh1else is an error.
1124b39c5158Smillert
1125898184e3SsthenSee L<File::GlobMapper|File::GlobMapper> for more details.
1126898184e3Ssthen
1127b39c5158Smillert=back
1128b39c5158Smillert
112991f110e0Safresh1If the C<$output_filename_or_reference> parameter is any other type,
113091f110e0Safresh1C<undef> will be returned.
1131b39c5158Smillert
1132b39c5158Smillert=head2 Notes
1133b39c5158Smillert
113491f110e0Safresh1When C<$input_filename_or_reference> maps to multiple files/buffers and
113591f110e0Safresh1C<$output_filename_or_reference> is a single
1136b39c5158Smillertfile/buffer the input files/buffers will each be stored
113791f110e0Safresh1in C<$output_filename_or_reference> as a distinct entry.
1138b39c5158Smillert
1139b39c5158Smillert=head2 Optional Parameters
1140b39c5158Smillert
114156d68f1eSafresh1The optional parameters for the one-shot function C<zip>
114256d68f1eSafresh1are (for the most part) identical to those used with the OO interface defined in the
114356d68f1eSafresh1L</"Constructor Options"> section. The exceptions are listed below
1144b39c5158Smillert
1145b39c5158Smillert=over 5
1146b39c5158Smillert
1147b39c5158Smillert=item C<< AutoClose => 0|1 >>
1148b39c5158Smillert
1149b39c5158SmillertThis option applies to any input or output data streams to
1150b39c5158SmillertC<zip> that are filehandles.
1151b39c5158Smillert
1152b39c5158SmillertIf C<AutoClose> is specified, and the value is true, it will result in all
1153b39c5158Smillertinput and/or output filehandles being closed once C<zip> has
1154b39c5158Smillertcompleted.
1155b39c5158Smillert
1156b39c5158SmillertThis parameter defaults to 0.
1157b39c5158Smillert
1158b39c5158Smillert=item C<< BinModeIn => 0|1 >>
1159b39c5158Smillert
1160b46d8ef2Safresh1This option is now a no-op. All files will be read in binmode.
1161b39c5158Smillert
1162b39c5158Smillert=item C<< Append => 0|1 >>
1163b39c5158Smillert
1164b39c5158SmillertThe behaviour of this option is dependent on the type of output data
1165b39c5158Smillertstream.
1166b39c5158Smillert
1167b39c5158Smillert=over 5
1168b39c5158Smillert
1169b39c5158Smillert=item * A Buffer
1170b39c5158Smillert
1171b39c5158SmillertIf C<Append> is enabled, all compressed data will be append to the end of
1172b39c5158Smillertthe output buffer. Otherwise the output buffer will be cleared before any
1173b39c5158Smillertcompressed data is written to it.
1174b39c5158Smillert
1175b39c5158Smillert=item * A Filename
1176b39c5158Smillert
1177b39c5158SmillertIf C<Append> is enabled, the file will be opened in append mode. Otherwise
1178b39c5158Smillertthe contents of the file, if any, will be truncated before any compressed
1179b39c5158Smillertdata is written to it.
1180b39c5158Smillert
1181b39c5158Smillert=item * A Filehandle
1182b39c5158Smillert
1183b39c5158SmillertIf C<Append> is enabled, the filehandle will be positioned to the end of
1184b39c5158Smillertthe file via a call to C<seek> before any compressed data is
1185b39c5158Smillertwritten to it.  Otherwise the file pointer will not be moved.
1186b39c5158Smillert
1187b39c5158Smillert=back
1188b39c5158Smillert
1189b39c5158SmillertWhen C<Append> is specified, and set to true, it will I<append> all compressed
1190b39c5158Smillertdata to the output data stream.
1191b39c5158Smillert
1192b39c5158SmillertSo when the output is a filehandle it will carry out a seek to the eof
1193b39c5158Smillertbefore writing any compressed data. If the output is a filename, it will be opened for
1194898184e3Ssthenappending. If the output is a buffer, all compressed data will be
1195898184e3Ssthenappended to the existing buffer.
1196b39c5158Smillert
1197b39c5158SmillertConversely when C<Append> is not specified, or it is present and is set to
1198b39c5158Smillertfalse, it will operate as follows.
1199b39c5158Smillert
1200b39c5158SmillertWhen the output is a filename, it will truncate the contents of the file
1201b39c5158Smillertbefore writing any compressed data. If the output is a filehandle
1202b39c5158Smillertits position will not be changed. If the output is a buffer, it will be
1203b39c5158Smillertwiped before any compressed data is output.
1204b39c5158Smillert
1205b39c5158SmillertDefaults to 0.
1206b39c5158Smillert
1207b39c5158Smillert=back
1208b39c5158Smillert
1209*3d61058aSafresh1=head2 Oneshot Examples
1210b39c5158Smillert
121156d68f1eSafresh1Here are a few example that show the capabilities of the module.
121256d68f1eSafresh1
121356d68f1eSafresh1=head3 Streaming
121456d68f1eSafresh1
121556d68f1eSafresh1This very simple command line example demonstrates the streaming capabilities of the module.
121656d68f1eSafresh1The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT.
121756d68f1eSafresh1
121856d68f1eSafresh1    $ echo hello world | perl -MIO::Compress::Zip=zip -e 'zip \*STDIN => \*STDOUT' >output.zip
121956d68f1eSafresh1
122056d68f1eSafresh1The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>,
122156d68f1eSafresh1so the above can be rewritten as
122256d68f1eSafresh1
122356d68f1eSafresh1    $ echo hello world | perl -MIO::Compress::Zip=zip -e 'zip "-" => "-"' >output.zip
122456d68f1eSafresh1
122556d68f1eSafresh1One problem with creating a zip archive directly from STDIN can be demonstrated by looking at
122656d68f1eSafresh1the contents of the zip file, output.zip, that we have just created.
122756d68f1eSafresh1
122856d68f1eSafresh1    $ unzip -l output.zip
122956d68f1eSafresh1    Archive:  output.zip
123056d68f1eSafresh1    Length      Date    Time    Name
123156d68f1eSafresh1    ---------  ---------- -----   ----
123256d68f1eSafresh1        12  2019-08-16 22:21
123356d68f1eSafresh1    ---------                     -------
123456d68f1eSafresh1        12                     1 file
123556d68f1eSafresh1
123656d68f1eSafresh1The archive member (filename) used is the empty string.
123756d68f1eSafresh1
123856d68f1eSafresh1If that doesn't suit your needs, you can explicitly set the filename used
123956d68f1eSafresh1in the zip archive by specifying the L<Name|"File Naming Options"> option, like so
124056d68f1eSafresh1
124156d68f1eSafresh1    echo hello world | perl -MIO::Compress::Zip=zip -e 'zip "-" => "-", Name => "hello.txt"' >output.zip
124256d68f1eSafresh1
124356d68f1eSafresh1Now the contents of the zip file looks like this
124456d68f1eSafresh1
124556d68f1eSafresh1    $ unzip -l output.zip
124656d68f1eSafresh1    Archive:  output.zip
124756d68f1eSafresh1    Length      Date    Time    Name
124856d68f1eSafresh1    ---------  ---------- -----   ----
124956d68f1eSafresh1        12  2019-08-16 22:22   hello.txt
125056d68f1eSafresh1    ---------                     -------
125156d68f1eSafresh1        12                     1 file
125256d68f1eSafresh1
125356d68f1eSafresh1=head3 Compressing a file from the filesystem
125456d68f1eSafresh1
1255b39c5158SmillertTo read the contents of the file C<file1.txt> and write the compressed
1256b39c5158Smillertdata to the file C<file1.txt.zip>.
1257b39c5158Smillert
1258b39c5158Smillert    use strict ;
1259b39c5158Smillert    use warnings ;
1260b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError) ;
1261b39c5158Smillert
1262b39c5158Smillert    my $input = "file1.txt";
1263b39c5158Smillert    zip $input => "$input.zip"
1264b39c5158Smillert        or die "zip failed: $ZipError\n";
1265b39c5158Smillert
126656d68f1eSafresh1=head3 Reading from a Filehandle and writing to an in-memory buffer
126756d68f1eSafresh1
1268b39c5158SmillertTo read from an existing Perl filehandle, C<$input>, and write the
1269b39c5158Smillertcompressed data to a buffer, C<$buffer>.
1270b39c5158Smillert
1271b39c5158Smillert    use strict ;
1272b39c5158Smillert    use warnings ;
1273b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError) ;
1274b39c5158Smillert    use IO::File ;
1275b39c5158Smillert
1276eac174f2Safresh1    my $input = IO::File->new( "<file1.txt" )
1277b39c5158Smillert        or die "Cannot open 'file1.txt': $!\n" ;
1278b39c5158Smillert    my $buffer ;
1279b39c5158Smillert    zip $input => \$buffer
1280b39c5158Smillert        or die "zip failed: $ZipError\n";
1281b39c5158Smillert
128256d68f1eSafresh1=head3 Compressing multiple files
128356d68f1eSafresh1
1284898184e3SsthenTo create a zip file, C<output.zip>, that contains the compressed contents
1285898184e3Ssthenof the files C<alpha.txt> and C<beta.txt>
1286b39c5158Smillert
1287b39c5158Smillert    use strict ;
1288b39c5158Smillert    use warnings ;
1289b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError) ;
1290b39c5158Smillert
1291898184e3Ssthen    zip [ 'alpha.txt', 'beta.txt' ] => 'output.zip'
1292b39c5158Smillert        or die "zip failed: $ZipError\n";
1293b39c5158Smillert
1294898184e3SsthenAlternatively, rather than having to explicitly name each of the files that
1295898184e3Ssthenyou want to compress, you could use a fileglob to select all the C<txt>
1296898184e3Ssthenfiles in the current directory, as follows
1297b39c5158Smillert
1298b39c5158Smillert    use strict ;
1299b39c5158Smillert    use warnings ;
1300b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError) ;
1301b39c5158Smillert
1302898184e3Ssthen    my @files = <*.txt>;
1303898184e3Ssthen    zip \@files => 'output.zip'
1304898184e3Ssthen        or die "zip failed: $ZipError\n";
1305898184e3Ssthen
1306898184e3Ssthenor more succinctly
1307898184e3Ssthen
1308898184e3Ssthen    zip [ <*.txt> ] => 'output.zip'
1309898184e3Ssthen        or die "zip failed: $ZipError\n";
1310b39c5158Smillert
1311b39c5158Smillert=head1 OO Interface
1312b39c5158Smillert
1313b39c5158Smillert=head2 Constructor
1314b39c5158Smillert
1315b39c5158SmillertThe format of the constructor for C<IO::Compress::Zip> is shown below
1316b39c5158Smillert
1317eac174f2Safresh1    my $z = IO::Compress::Zip->new( $output [,OPTS] )
1318b39c5158Smillert        or die "IO::Compress::Zip failed: $ZipError\n";
1319b39c5158Smillert
1320*3d61058aSafresh1The constructor takes one mandatory parameter, C<$output>, defined below and
1321*3d61058aSafresh1zero or more C<OPTS>, defined in L<Constructor Options>.
1322*3d61058aSafresh1
1323*3d61058aSafresh1It returns an C<IO::Compress::Zip> object on success and C<undef> on failure.
1324b39c5158SmillertThe variable C<$ZipError> will contain an error message on failure.
1325b39c5158Smillert
1326b39c5158SmillertIf you are running Perl 5.005 or better the object, C<$z>, returned from
1327b39c5158SmillertIO::Compress::Zip can be used exactly like an L<IO::File|IO::File> filehandle.
1328b39c5158SmillertThis means that all normal output file operations can be carried out
1329b39c5158Smillertwith C<$z>.
1330b39c5158SmillertFor example, to write to a compressed file/buffer you can use either of
1331b39c5158Smillertthese forms
1332b39c5158Smillert
1333b39c5158Smillert    $z->print("hello world\n");
1334b39c5158Smillert    print $z "hello world\n";
1335b39c5158Smillert
1336*3d61058aSafresh1Below is a simple exaple of using the OO interface to create an output file
1337*3d61058aSafresh1C<myfile.zip> and write some data to it.
1338*3d61058aSafresh1
1339*3d61058aSafresh1    my $filename = "myfile.zip";
1340*3d61058aSafresh1    my $z = IO::Compress::Zip->new($filename)
1341*3d61058aSafresh1        or die "IO::Compress::Zip failed: $ZipError\n";
1342*3d61058aSafresh1
1343*3d61058aSafresh1    $z->print("abcde");
1344*3d61058aSafresh1    $z->close();
1345*3d61058aSafresh1
1346*3d61058aSafresh1See the L</Examples> for more.
1347*3d61058aSafresh1
1348b39c5158SmillertThe mandatory parameter C<$output> is used to control the destination
1349b39c5158Smillertof the compressed data. This parameter can take one of these forms.
1350b39c5158Smillert
1351b39c5158Smillert=over 5
1352b39c5158Smillert
1353b39c5158Smillert=item A filename
1354b39c5158Smillert
1355b39c5158SmillertIf the C<$output> parameter is a simple scalar, it is assumed to be a
1356b39c5158Smillertfilename. This file will be opened for writing and the compressed data
1357b39c5158Smillertwill be written to it.
1358b39c5158Smillert
1359b39c5158Smillert=item A filehandle
1360b39c5158Smillert
1361b39c5158SmillertIf the C<$output> parameter is a filehandle, the compressed data will be
1362b39c5158Smillertwritten to it.
1363b39c5158SmillertThe string '-' can be used as an alias for standard output.
1364b39c5158Smillert
1365b39c5158Smillert=item A scalar reference
1366b39c5158Smillert
1367b39c5158SmillertIf C<$output> is a scalar reference, the compressed data will be stored
1368b39c5158Smillertin C<$$output>.
1369b39c5158Smillert
1370b39c5158Smillert=back
1371b39c5158Smillert
1372b39c5158SmillertIf the C<$output> parameter is any other type, C<IO::Compress::Zip>::new will
1373b39c5158Smillertreturn undef.
1374b39c5158Smillert
1375b39c5158Smillert=head2 Constructor Options
1376b39c5158Smillert
137756d68f1eSafresh1C<OPTS> is any combination of zero or more the following options:
1378b39c5158Smillert
1379b39c5158Smillert=over 5
1380b39c5158Smillert
1381b39c5158Smillert=item C<< AutoClose => 0|1 >>
1382b39c5158Smillert
1383b39c5158SmillertThis option is only valid when the C<$output> parameter is a filehandle. If
1384b39c5158Smillertspecified, and the value is true, it will result in the C<$output> being
1385b39c5158Smillertclosed once either the C<close> method is called or the C<IO::Compress::Zip>
1386b39c5158Smillertobject is destroyed.
1387b39c5158Smillert
1388b39c5158SmillertThis parameter defaults to 0.
1389b39c5158Smillert
1390b39c5158Smillert=item C<< Append => 0|1 >>
1391b39c5158Smillert
1392b39c5158SmillertOpens C<$output> in append mode.
1393b39c5158Smillert
1394b39c5158SmillertThe behaviour of this option is dependent on the type of C<$output>.
1395b39c5158Smillert
1396b39c5158Smillert=over 5
1397b39c5158Smillert
1398b39c5158Smillert=item * A Buffer
1399b39c5158Smillert
1400b39c5158SmillertIf C<$output> is a buffer and C<Append> is enabled, all compressed data
1401b39c5158Smillertwill be append to the end of C<$output>. Otherwise C<$output> will be
1402b39c5158Smillertcleared before any data is written to it.
1403b39c5158Smillert
1404b39c5158Smillert=item * A Filename
1405b39c5158Smillert
1406b39c5158SmillertIf C<$output> is a filename and C<Append> is enabled, the file will be
1407b39c5158Smillertopened in append mode. Otherwise the contents of the file, if any, will be
1408b39c5158Smillerttruncated before any compressed data is written to it.
1409b39c5158Smillert
1410b39c5158Smillert=item * A Filehandle
1411b39c5158Smillert
1412b39c5158SmillertIf C<$output> is a filehandle, the file pointer will be positioned to the
1413b39c5158Smillertend of the file via a call to C<seek> before any compressed data is written
1414b39c5158Smillertto it.  Otherwise the file pointer will not be moved.
1415b39c5158Smillert
1416b39c5158Smillert=back
1417b39c5158Smillert
1418b39c5158SmillertThis parameter defaults to 0.
1419b39c5158Smillert
142056d68f1eSafresh1=back
142156d68f1eSafresh1
142256d68f1eSafresh1=head3 File Naming Options
142356d68f1eSafresh1
142456d68f1eSafresh1A quick bit of zip file terminology -- A zip archive consists of one or more I<archive members>, where each member has an associated
142556d68f1eSafresh1filename, known as the I<archive member name>.
142656d68f1eSafresh1
142756d68f1eSafresh1The options listed in this section control how the I<archive member name> (or filename) is stored the zip archive.
142856d68f1eSafresh1
142956d68f1eSafresh1=over 5
143056d68f1eSafresh1
1431b39c5158Smillert=item C<< Name => $string >>
1432b39c5158Smillert
143356d68f1eSafresh1This option is used to explicitly set the I<archive member name> in
143456d68f1eSafresh1the zip archive to C<$string>.
143556d68f1eSafresh1Most of the time you don't need to make use of this option.
143656d68f1eSafresh1By default when adding a filename to the zip archive, the I<archive member name> will match the filename.
1437898184e3Ssthen
143856d68f1eSafresh1You should only need to use this option if you want the I<archive member name>
143956d68f1eSafresh1to be different from the uncompressed filename or when the input is a filehandle or a buffer.
1440898184e3Ssthen
144156d68f1eSafresh1The default behaviour for what I<archive member name> is used when the C<Name> option
144256d68f1eSafresh1is I<not> specified depends on the form of the C<$input> parameter:
144356d68f1eSafresh1
144456d68f1eSafresh1=over 5
144556d68f1eSafresh1
144656d68f1eSafresh1=item *
144756d68f1eSafresh1
144856d68f1eSafresh1If the C<$input> parameter is a filename, the
144956d68f1eSafresh1value of C<$input> will be used for the I<archive member name> .
145056d68f1eSafresh1
145156d68f1eSafresh1=item *
145256d68f1eSafresh1If the C<$input> parameter is not a filename,
145356d68f1eSafresh1the I<archive member name> will be an empty string.
145456d68f1eSafresh1
145556d68f1eSafresh1=back
1456898184e3Ssthen
1457898184e3SsthenNote that both the C<CanonicalName> and C<FilterName> options
145856d68f1eSafresh1can modify the value used for the I<archive member name>.
145956d68f1eSafresh1
146056d68f1eSafresh1Also note that you should set the C<Efs> option to true if you are working
146156d68f1eSafresh1with UTF8 filenames.
1462898184e3Ssthen
1463898184e3Ssthen=item C<< CanonicalName => 0|1 >>
1464898184e3Ssthen
146556d68f1eSafresh1This option controls whether the I<archive member name> is
1466898184e3SsthenI<normalized> into Unix format before being written to the zip file.
1467898184e3Ssthen
1468898184e3SsthenIt is recommended that you enable this option unless you really need
1469898184e3Ssthento create a non-standard Zip file.
1470898184e3Ssthen
1471898184e3SsthenThis is what APPNOTE.TXT has to say on what should be stored in the zip
1472898184e3Ssthenfilename header field.
1473898184e3Ssthen
1474898184e3Ssthen    The name of the file, with optional relative path.
1475898184e3Ssthen    The path stored should not contain a drive or
1476898184e3Ssthen    device letter, or a leading slash.  All slashes
1477898184e3Ssthen    should be forward slashes '/' as opposed to
1478898184e3Ssthen    backwards slashes '\' for compatibility with Amiga
1479898184e3Ssthen    and UNIX file systems etc.
1480898184e3Ssthen
1481898184e3SsthenThis option defaults to B<false>.
1482898184e3Ssthen
1483898184e3Ssthen=item C<< FilterName => sub { ... }  >>
1484898184e3Ssthen
148556d68f1eSafresh1This option allow the I<archive member> name to be modified
1486898184e3Ssthenbefore it is written to the zip file.
1487898184e3Ssthen
1488898184e3SsthenThis option takes a parameter that must be a reference to a sub.  On entry
1489898184e3Ssthento the sub the C<$_> variable will contain the name to be filtered. If no
1490898184e3Ssthenfilename is available C<$_> will contain an empty string.
1491898184e3Ssthen
149256d68f1eSafresh1The value of C<$_> when the sub returns will be  used as the I<archive member name>.
1493898184e3Ssthen
1494898184e3SsthenNote that if C<CanonicalName> is enabled, a
1495898184e3Ssthennormalized filename will be passed to the sub.
1496898184e3Ssthen
1497898184e3SsthenIf you use C<FilterName> to modify the filename, it is your responsibility
1498898184e3Ssthento keep the filename in Unix format.
1499898184e3Ssthen
15006fb12b70Safresh1Although this option can be used with the OO interface, it is of most use
1501898184e3Ssthenwith the one-shot interface. For example, the code below shows how
1502898184e3SsthenC<FilterName> can be used to remove the path component from a series of
1503898184e3Ssthenfilenames before they are stored in C<$zipfile>.
1504898184e3Ssthen
1505898184e3Ssthen    sub compressTxtFiles
1506898184e3Ssthen    {
1507898184e3Ssthen        my $zipfile = shift ;
1508898184e3Ssthen        my $dir     = shift ;
1509898184e3Ssthen
1510898184e3Ssthen        zip [ <$dir/*.txt> ] => $zipfile,
1511898184e3Ssthen            FilterName => sub { s[^$dir/][] } ;
1512898184e3Ssthen    }
1513b39c5158Smillert
151456d68f1eSafresh1=item C<< Efs => 0|1 >>
151556d68f1eSafresh1
151656d68f1eSafresh1This option controls setting of the "Language Encoding Flag" (EFS) in the zip
151756d68f1eSafresh1archive. When set, the filename and comment fields for the zip archive MUST
151856d68f1eSafresh1be valid UTF-8.
151956d68f1eSafresh1
152056d68f1eSafresh1If the string used for the filename and/or comment is not valid UTF-8 when this option
152156d68f1eSafresh1is true, the script will die with a "wide character" error.
152256d68f1eSafresh1
152356d68f1eSafresh1Note that this option only works with Perl 5.8.4 or better.
152456d68f1eSafresh1
152556d68f1eSafresh1This option defaults to B<false>.
152656d68f1eSafresh1
152756d68f1eSafresh1=back
152856d68f1eSafresh1
152956d68f1eSafresh1=head3 Overall Zip Archive Structure
153056d68f1eSafresh1
153156d68f1eSafresh1=over 5
153256d68f1eSafresh1
153356d68f1eSafresh1=item C<< Minimal => 1|0 >>
153456d68f1eSafresh1
153556d68f1eSafresh1If specified, this option will disable the creation of all extra fields
153656d68f1eSafresh1in the zip local and central headers. So the C<exTime>, C<exUnix2>,
153756d68f1eSafresh1C<exUnixN>, C<ExtraFieldLocal> and C<ExtraFieldCentral> options will
153856d68f1eSafresh1be ignored.
153956d68f1eSafresh1
154056d68f1eSafresh1This parameter defaults to 0.
154156d68f1eSafresh1
154256d68f1eSafresh1=item C<< Stream => 0|1 >>
154356d68f1eSafresh1
154456d68f1eSafresh1This option controls whether the zip file/buffer output is created in
154556d68f1eSafresh1streaming mode.
154656d68f1eSafresh1
154756d68f1eSafresh1Note that when outputting to a file with streaming mode disabled (C<Stream>
154856d68f1eSafresh1is 0), the output file must be seekable.
154956d68f1eSafresh1
155056d68f1eSafresh1The default is 1.
155156d68f1eSafresh1
155256d68f1eSafresh1=item C<< Zip64 => 0|1 >>
155356d68f1eSafresh1
155456d68f1eSafresh1Create a Zip64 zip file/buffer. This option is used if you want
155556d68f1eSafresh1to store files larger than 4 Gig or store more than 64K files in a single
155656d68f1eSafresh1zip archive.
155756d68f1eSafresh1
155856d68f1eSafresh1C<Zip64> will be automatically set, as needed, if working with the one-shot
155956d68f1eSafresh1interface when the input is either a filename or a scalar reference.
156056d68f1eSafresh1
156156d68f1eSafresh1If you intend to manipulate the Zip64 zip files created with this module
156256d68f1eSafresh1using an external zip/unzip, make sure that it supports Zip64.
156356d68f1eSafresh1
156456d68f1eSafresh1In particular, if you are using Info-Zip you need to have zip version 3.x
156556d68f1eSafresh1or better to update a Zip64 archive and unzip version 6.x to read a zip64
156656d68f1eSafresh1archive.
156756d68f1eSafresh1
156856d68f1eSafresh1The default is 0.
156956d68f1eSafresh1
157056d68f1eSafresh1=back
157156d68f1eSafresh1
157256d68f1eSafresh1=head3 Deflate Compression Options
157356d68f1eSafresh1
157456d68f1eSafresh1=over 5
157556d68f1eSafresh1
157656d68f1eSafresh1=item -Level
157756d68f1eSafresh1
157856d68f1eSafresh1Defines the compression level used by zlib. The value should either be
157956d68f1eSafresh1a number between 0 and 9 (0 means no compression and 9 is maximum
158056d68f1eSafresh1compression), or one of the symbolic constants defined below.
158156d68f1eSafresh1
158256d68f1eSafresh1   Z_NO_COMPRESSION
158356d68f1eSafresh1   Z_BEST_SPEED
158456d68f1eSafresh1   Z_BEST_COMPRESSION
158556d68f1eSafresh1   Z_DEFAULT_COMPRESSION
158656d68f1eSafresh1
158756d68f1eSafresh1The default is Z_DEFAULT_COMPRESSION.
158856d68f1eSafresh1
158956d68f1eSafresh1Note, these constants are not imported by C<IO::Compress::Zip> by default.
159056d68f1eSafresh1
159156d68f1eSafresh1    use IO::Compress::Zip qw(:strategy);
159256d68f1eSafresh1    use IO::Compress::Zip qw(:constants);
159356d68f1eSafresh1    use IO::Compress::Zip qw(:all);
159456d68f1eSafresh1
159556d68f1eSafresh1=item -Strategy
159656d68f1eSafresh1
159756d68f1eSafresh1Defines the strategy used to tune the compression. Use one of the symbolic
159856d68f1eSafresh1constants defined below.
159956d68f1eSafresh1
160056d68f1eSafresh1   Z_FILTERED
160156d68f1eSafresh1   Z_HUFFMAN_ONLY
160256d68f1eSafresh1   Z_RLE
160356d68f1eSafresh1   Z_FIXED
160456d68f1eSafresh1   Z_DEFAULT_STRATEGY
160556d68f1eSafresh1
160656d68f1eSafresh1The default is Z_DEFAULT_STRATEGY.
160756d68f1eSafresh1
160856d68f1eSafresh1=back
160956d68f1eSafresh1
161056d68f1eSafresh1=head3 Bzip2 Compression Options
161156d68f1eSafresh1
161256d68f1eSafresh1=over 5
161356d68f1eSafresh1
161456d68f1eSafresh1=item C<< BlockSize100K => number >>
161556d68f1eSafresh1
161656d68f1eSafresh1Specify the number of 100K blocks bzip2 uses during compression.
161756d68f1eSafresh1
161856d68f1eSafresh1Valid values are from 1 to 9, where 9 is best compression.
161956d68f1eSafresh1
162056d68f1eSafresh1This option is only valid if the C<Method> is ZIP_CM_BZIP2. It is ignored
162156d68f1eSafresh1otherwise.
162256d68f1eSafresh1
162356d68f1eSafresh1The default is 1.
162456d68f1eSafresh1
162556d68f1eSafresh1=item C<< WorkFactor => number >>
162656d68f1eSafresh1
162756d68f1eSafresh1Specifies how much effort bzip2 should take before resorting to a slower
162856d68f1eSafresh1fallback compression algorithm.
162956d68f1eSafresh1
163056d68f1eSafresh1Valid values range from 0 to 250, where 0 means use the default value 30.
163156d68f1eSafresh1
163256d68f1eSafresh1This option is only valid if the C<Method> is ZIP_CM_BZIP2. It is ignored
163356d68f1eSafresh1otherwise.
163456d68f1eSafresh1
163556d68f1eSafresh1The default is 0.
163656d68f1eSafresh1
163756d68f1eSafresh1=back
163856d68f1eSafresh1
1639eac174f2Safresh1=head3 Lzma and Xz Compression Options
164056d68f1eSafresh1
164156d68f1eSafresh1=over 5
164256d68f1eSafresh1
164356d68f1eSafresh1=item C<< Preset => number >>
164456d68f1eSafresh1
164556d68f1eSafresh1Used to choose the LZMA compression preset.
164656d68f1eSafresh1
164756d68f1eSafresh1Valid values are 0-9 and C<LZMA_PRESET_DEFAULT>.
164856d68f1eSafresh1
164956d68f1eSafresh10 is the fastest compression with the lowest memory usage and the lowest
165056d68f1eSafresh1compression.
165156d68f1eSafresh1
165256d68f1eSafresh19 is the slowest compression with the highest memory usage but with the best
165356d68f1eSafresh1compression.
165456d68f1eSafresh1
165556d68f1eSafresh1This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored
165656d68f1eSafresh1otherwise.
165756d68f1eSafresh1
165856d68f1eSafresh1Defaults to C<LZMA_PRESET_DEFAULT> (6).
165956d68f1eSafresh1
166056d68f1eSafresh1=item C<< Extreme => 0|1 >>
166156d68f1eSafresh1
166256d68f1eSafresh1Makes LZMA compression a lot slower, but a small compression gain.
166356d68f1eSafresh1
166456d68f1eSafresh1This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored
166556d68f1eSafresh1otherwise.
166656d68f1eSafresh1
166756d68f1eSafresh1Defaults to 0.
166856d68f1eSafresh1
166956d68f1eSafresh1=back
167056d68f1eSafresh1
167156d68f1eSafresh1=head3 Other Options
167256d68f1eSafresh1
167356d68f1eSafresh1=over 5
167456d68f1eSafresh1
1675b39c5158Smillert=item C<< Time => $number >>
1676b39c5158Smillert
1677b39c5158SmillertSets the last modified time field in the zip header to $number.
1678b39c5158Smillert
1679b39c5158SmillertThis field defaults to the time the C<IO::Compress::Zip> object was created
1680898184e3Ssthenif this option is not specified and the C<$input> parameter is not a
1681898184e3Ssthenfilename.
1682b39c5158Smillert
1683b39c5158Smillert=item C<< ExtAttr => $attr >>
1684b39c5158Smillert
1685b39c5158SmillertThis option controls the "external file attributes" field in the central
1686b39c5158Smillertheader of the zip file. This is a 4 byte field.
1687b39c5158Smillert
1688b39c5158SmillertIf you are running a Unix derivative this value defaults to
1689b39c5158Smillert
1690898184e3Ssthen    0100644 << 16
1691b39c5158Smillert
1692b39c5158SmillertThis should allow read/write access to any files that are extracted from
1693898184e3Ssthenthe zip file/buffer`.
1694b39c5158Smillert
1695b39c5158SmillertFor all other systems it defaults to 0.
1696b39c5158Smillert
1697b39c5158Smillert=item C<< exTime => [$atime, $mtime, $ctime] >>
1698b39c5158Smillert
1699b39c5158SmillertThis option expects an array reference with exactly three elements:
1700b39c5158SmillertC<$atime>, C<mtime> and C<$ctime>. These correspond to the last access
1701b39c5158Smillerttime, last modification time and creation time respectively.
1702b39c5158Smillert
1703b39c5158SmillertIt uses these values to set the extended timestamp field (ID is "UT") in
1704b39c5158Smillertthe local zip header using the three values, $atime, $mtime, $ctime. In
1705b39c5158Smillertaddition it sets the extended timestamp field in the central zip header
1706b39c5158Smillertusing C<$mtime>.
1707b39c5158Smillert
1708b39c5158SmillertIf any of the three values is C<undef> that time value will not be used.
1709b39c5158SmillertSo, for example, to set only the C<$mtime> you would use this
1710b39c5158Smillert
1711b39c5158Smillert    exTime => [undef, $mtime, undef]
1712b39c5158Smillert
1713b39c5158SmillertIf the C<Minimal> option is set to true, this option will be ignored.
1714b39c5158Smillert
1715b39c5158SmillertBy default no extended time field is created.
1716b39c5158Smillert
1717b39c5158Smillert=item C<< exUnix2 => [$uid, $gid] >>
1718b39c5158Smillert
1719b39c5158SmillertThis option expects an array reference with exactly two elements: C<$uid>
1720898184e3Ssthenand C<$gid>. These values correspond to the numeric User ID (UID) and Group ID
1721898184e3Ssthen(GID) of the owner of the files respectively.
1722b39c5158Smillert
1723b39c5158SmillertWhen the C<exUnix2> option is present it will trigger the creation of a
1724898184e3SsthenUnix2 extra field (ID is "Ux") in the local zip header. This will be populated
1725898184e3Ssthenwith C<$uid> and C<$gid>. An empty Unix2 extra field will also
1726898184e3Ssthenbe created in the central zip header.
1727898184e3Ssthen
1728898184e3SsthenNote - The UID & GID are stored as 16-bit
1729898184e3Ssthenintegers in the "Ux" field. Use C<< exUnixN >> if your UID or GID are
1730898184e3Ssthen32-bit.
1731b39c5158Smillert
1732b39c5158SmillertIf the C<Minimal> option is set to true, this option will be ignored.
1733b39c5158Smillert
1734b39c5158SmillertBy default no Unix2 extra field is created.
1735b39c5158Smillert
1736898184e3Ssthen=item C<< exUnixN => [$uid, $gid] >>
1737898184e3Ssthen
1738898184e3SsthenThis option expects an array reference with exactly two elements: C<$uid>
1739898184e3Ssthenand C<$gid>. These values correspond to the numeric User ID (UID) and Group ID
1740898184e3Ssthen(GID) of the owner of the files respectively.
1741898184e3Ssthen
1742898184e3SsthenWhen the C<exUnixN> option is present it will trigger the creation of a
17436fb12b70Safresh1UnixN extra field (ID is "ux") in both the local and central zip headers.
1744898184e3SsthenThis will be populated with C<$uid> and C<$gid>.
1745898184e3SsthenThe UID & GID are stored as 32-bit integers.
1746898184e3Ssthen
1747898184e3SsthenIf the C<Minimal> option is set to true, this option will be ignored.
1748898184e3Ssthen
1749898184e3SsthenBy default no UnixN extra field is created.
1750898184e3Ssthen
1751b39c5158Smillert=item C<< Comment => $comment >>
1752b39c5158Smillert
1753b39c5158SmillertStores the contents of C<$comment> in the Central File Header of
1754b39c5158Smillertthe zip file.
1755b39c5158Smillert
175656d68f1eSafresh1Set the C<Efs> option to true if you want to store a UTF8 comment.
175756d68f1eSafresh1
1758b39c5158SmillertBy default, no comment field is written to the zip file.
1759b39c5158Smillert
1760b39c5158Smillert=item C<< ZipComment => $comment >>
1761b39c5158Smillert
1762b39c5158SmillertStores the contents of C<$comment> in the End of Central Directory record
1763b39c5158Smillertof the zip file.
1764b39c5158Smillert
1765b39c5158SmillertBy default, no comment field is written to the zip file.
1766b39c5158Smillert
1767b39c5158Smillert=item C<< Method => $method >>
1768b39c5158Smillert
1769eac174f2Safresh1Controls which compression method is used. At present the compression
1770eac174f2Safresh1methods supported are: Store (no compression at all), Deflate,
1771eac174f2Safresh1Bzip2, Zstd, Xz and Lzma.
1772b39c5158Smillert
1773eac174f2Safresh1The symbols ZIP_CM_STORE, ZIP_CM_DEFLATE, ZIP_CM_BZIP2, ZIP_CM_ZSTD, ZIP_CM_XZ and ZIP_CM_LZMA
1774898184e3Ssthenare used to select the compression method.
1775b39c5158Smillert
1776b39c5158SmillertThese constants are not imported by C<IO::Compress::Zip> by default.
1777b39c5158Smillert
1778b39c5158Smillert    use IO::Compress::Zip qw(:zip_method);
1779b39c5158Smillert    use IO::Compress::Zip qw(:constants);
1780b39c5158Smillert    use IO::Compress::Zip qw(:all);
1781b39c5158Smillert
1782b39c5158SmillertNote that to create Bzip2 content, the module C<IO::Compress::Bzip2> must
1783b39c5158Smillertbe installed. A fatal error will be thrown if you attempt to create Bzip2
1784b39c5158Smillertcontent when C<IO::Compress::Bzip2> is not available.
1785b39c5158Smillert
1786898184e3SsthenNote that to create Lzma content, the module C<IO::Compress::Lzma> must
1787898184e3Ssthenbe installed. A fatal error will be thrown if you attempt to create Lzma
1788898184e3Ssthencontent when C<IO::Compress::Lzma> is not available.
1789898184e3Ssthen
1790eac174f2Safresh1Note that to create Xz content, the module C<IO::Compress::Xz> must
1791eac174f2Safresh1be installed. A fatal error will be thrown if you attempt to create Xz
1792eac174f2Safresh1content when C<IO::Compress::Xz> is not available.
1793eac174f2Safresh1
1794eac174f2Safresh1Note that to create Zstd content, the module C<IO::Compress::Zstd> must
1795eac174f2Safresh1be installed. A fatal error will be thrown if you attempt to create Zstd
1796eac174f2Safresh1content when C<IO::Compress::Zstd> is not available.
1797eac174f2Safresh1
1798b39c5158SmillertThe default method is ZIP_CM_DEFLATE.
1799b39c5158Smillert
1800b39c5158Smillert=item C<< TextFlag => 0|1 >>
1801b39c5158Smillert
1802b39c5158SmillertThis parameter controls the setting of a bit in the zip central header. It
1803b39c5158Smillertis used to signal that the data stored in the zip file/buffer is probably
1804b39c5158Smillerttext.
1805b39c5158Smillert
1806898184e3SsthenIn one-shot mode this flag will be set to true if the Perl C<-T> operator thinks
1807898184e3Ssthenthe file contains text.
1808898184e3Ssthen
1809b39c5158SmillertThe default is 0.
1810b39c5158Smillert
1811b39c5158Smillert=item C<< ExtraFieldLocal => $data >>
181291f110e0Safresh1
1813b39c5158Smillert=item C<< ExtraFieldCentral => $data >>
1814b39c5158Smillert
1815b39c5158SmillertThe C<ExtraFieldLocal> option is used to store additional metadata in the
1816b39c5158Smillertlocal header for the zip file/buffer. The C<ExtraFieldCentral> does the
1817b39c5158Smillertsame for the matching central header.
1818b39c5158Smillert
1819b39c5158SmillertAn extra field consists of zero or more subfields. Each subfield consists
1820b39c5158Smillertof a two byte header followed by the subfield data.
1821b39c5158Smillert
1822b39c5158SmillertThe list of subfields can be supplied in any of the following formats
1823b39c5158Smillert
1824b39c5158Smillert    ExtraFieldLocal => [$id1, $data1,
1825b39c5158Smillert                        $id2, $data2,
1826b39c5158Smillert                         ...
1827b39c5158Smillert                       ]
1828b39c5158Smillert
1829b39c5158Smillert    ExtraFieldLocal => [ [$id1 => $data1],
1830b39c5158Smillert                         [$id2 => $data2],
1831b39c5158Smillert                         ...
1832b39c5158Smillert                       ]
1833b39c5158Smillert
1834b39c5158Smillert    ExtraFieldLocal => { $id1 => $data1,
1835b39c5158Smillert                         $id2 => $data2,
1836b39c5158Smillert                         ...
1837b39c5158Smillert                       }
1838b39c5158Smillert
1839b39c5158SmillertWhere C<$id1>, C<$id2> are two byte subfield ID's.
1840b39c5158Smillert
1841b39c5158SmillertIf you use the hash syntax, you have no control over the order in which
1842b39c5158Smillertthe ExtraSubFields are stored, plus you cannot have SubFields with
1843b39c5158Smillertduplicate ID.
1844b39c5158Smillert
1845b39c5158SmillertAlternatively the list of subfields can by supplied as a scalar, thus
1846b39c5158Smillert
1847b39c5158Smillert    ExtraField => $rawdata
1848b39c5158Smillert
1849898184e3SsthenIn this case C<IO::Compress::Zip> will check that C<$rawdata> consists of
1850898184e3Ssthenzero or more conformant sub-fields.
1851898184e3Ssthen
1852b39c5158SmillertThe Extended Time field (ID "UT"), set using the C<exTime> option, and the
1853b39c5158SmillertUnix2 extra field (ID "Ux), set using the C<exUnix2> option, are examples
1854b39c5158Smillertof extra fields.
1855b39c5158Smillert
1856b39c5158SmillertIf the C<Minimal> option is set to true, this option will be ignored.
1857b39c5158Smillert
1858b39c5158SmillertThe maximum size of an extra field 65535 bytes.
1859b39c5158Smillert
1860b39c5158Smillert=item C<< Strict => 0|1 >>
1861b39c5158Smillert
1862b39c5158SmillertThis is a placeholder option.
1863b39c5158Smillert
1864b39c5158Smillert=back
1865b39c5158Smillert
1866b39c5158Smillert=head2 Examples
1867b39c5158Smillert
1868*3d61058aSafresh1=head3 Streaming
1869*3d61058aSafresh1
1870*3d61058aSafresh1This very simple command line example demonstrates the streaming capabilities
1871*3d61058aSafresh1of the module. The code reads data from STDIN or all the files given on the
1872*3d61058aSafresh1commandline, compresses it, and writes the compressed data to STDOUT.
1873*3d61058aSafresh1
1874*3d61058aSafresh1    use strict ;
1875*3d61058aSafresh1    use warnings ;
1876*3d61058aSafresh1    use IO::Compress::Zip qw(zip $ZipError) ;
1877*3d61058aSafresh1
1878*3d61058aSafresh1    my $z = IO::Compress::Zip->new("-", Stream => 1)
1879*3d61058aSafresh1        or die "IO::Compress::Zip failed: $ZipError\n";
1880*3d61058aSafresh1
1881*3d61058aSafresh1    while (<>) {
1882*3d61058aSafresh1        $z->print("abcde");
1883*3d61058aSafresh1    }
1884*3d61058aSafresh1    $z->close();
1885*3d61058aSafresh1
1886*3d61058aSafresh1Note the use of C<"-"> to means C<STDOUT>. Alternatively you can use C<\*STDOUT>.
1887*3d61058aSafresh1
1888*3d61058aSafresh1One problem with creating a zip archive directly from STDIN can be demonstrated by looking at
1889*3d61058aSafresh1the contents of the zip file, output.zip, that we have just created
1890*3d61058aSafresh1(assumg you have redirected it to a file called C<output.zip>).
1891*3d61058aSafresh1
1892*3d61058aSafresh1    $ unzip -l output.zip
1893*3d61058aSafresh1    Archive:  output.zip
1894*3d61058aSafresh1    Length      Date    Time    Name
1895*3d61058aSafresh1    ---------  ---------- -----   ----
1896*3d61058aSafresh1        12  2019-08-16 22:21
1897*3d61058aSafresh1    ---------                     -------
1898*3d61058aSafresh1        12                     1 file
1899*3d61058aSafresh1
1900*3d61058aSafresh1The archive member (filename) used is the empty string.
1901*3d61058aSafresh1
1902*3d61058aSafresh1If that doesn't suit your needs, you can explicitly set the filename used
1903*3d61058aSafresh1in the zip archive by specifying the L<Name|"File Naming Options"> option, like so
1904*3d61058aSafresh1
1905*3d61058aSafresh1    my $z = IO::Compress::Zip->new("-", Name => "hello.txt", Stream => 1)
1906*3d61058aSafresh1
1907*3d61058aSafresh1Now the contents of the zip file looks like this
1908*3d61058aSafresh1
1909*3d61058aSafresh1    $ unzip -l output.zip
1910*3d61058aSafresh1    Archive:  output.zip
1911*3d61058aSafresh1    Length      Date    Time    Name
1912*3d61058aSafresh1    ---------  ---------- -----   ----
1913*3d61058aSafresh1        12  2019-08-16 22:22   hello.txt
1914*3d61058aSafresh1    ---------                     -------
1915*3d61058aSafresh1        12                     1 file
1916*3d61058aSafresh1
1917*3d61058aSafresh1=head3 Compressing a file from the filesystem
1918*3d61058aSafresh1
1919*3d61058aSafresh1To read the contents of the file C<file1.txt> and write the compressed
1920*3d61058aSafresh1data to the file C<file1.txt.zip> there are a few options
1921*3d61058aSafresh1
1922*3d61058aSafresh1Start by creating the compression object and opening the input file
1923*3d61058aSafresh1
1924*3d61058aSafresh1    use strict ;
1925*3d61058aSafresh1    use warnings ;
1926*3d61058aSafresh1    use IO::Compress::Zip qw(zip $ZipError) ;
1927*3d61058aSafresh1
1928*3d61058aSafresh1    my $input = "file1.txt";
1929*3d61058aSafresh1    my $z = IO::Compress::Zip->new("file1.txt.zip")
1930*3d61058aSafresh1        or die "IO::Compress::Zip failed: $ZipError\n";
1931*3d61058aSafresh1
1932*3d61058aSafresh1    # open the input file
1933*3d61058aSafresh1    open my $fh, "<", "file1.txt"
1934*3d61058aSafresh1        or die "Cannot open file1.txt: $!\n";
1935*3d61058aSafresh1
1936*3d61058aSafresh1    # loop through the input file & write to the compressed file
1937*3d61058aSafresh1    while (<$fh>) {
1938*3d61058aSafresh1        $z->print($_);
1939*3d61058aSafresh1    }
1940*3d61058aSafresh1
1941*3d61058aSafresh1    # not forgetting to close the compressed file
1942*3d61058aSafresh1    $z->close();
1943*3d61058aSafresh1
1944*3d61058aSafresh1=head3 Compressing multiple files
1945*3d61058aSafresh1
1946*3d61058aSafresh1To create a zip file, C<output.zip>, that contains the compressed contents
1947*3d61058aSafresh1of the files C<alpha.txt> and C<beta.txt>
1948*3d61058aSafresh1
1949*3d61058aSafresh1    use strict ;
1950*3d61058aSafresh1    use warnings ;
1951*3d61058aSafresh1    use IO::Compress::Zip qw(zip $ZipError) ;
1952*3d61058aSafresh1
1953*3d61058aSafresh1    my $z = IO::Compress::Zip->new("output.zip", Name => "alpha.txt")
1954*3d61058aSafresh1        or die "IO::Compress::Zip failed: $ZipError\n";
1955*3d61058aSafresh1
1956*3d61058aSafresh1    # open the input file
1957*3d61058aSafresh1    open my $fh, "<", "file1.txt"
1958*3d61058aSafresh1        or die "Cannot open file1.txt: $!\n";
1959*3d61058aSafresh1
1960*3d61058aSafresh1    # loop through the input file & write to the compressed file
1961*3d61058aSafresh1    while (<$fh>) {
1962*3d61058aSafresh1        $z->print($_);
1963*3d61058aSafresh1    }
1964*3d61058aSafresh1
1965*3d61058aSafresh1    # move to next file
1966*3d61058aSafresh1    $z->newStream(Name => "beta.txt")
1967*3d61058aSafresh1
1968*3d61058aSafresh1    while (<$fh>) {
1969*3d61058aSafresh1        $z->print($_);
1970*3d61058aSafresh1    }
1971*3d61058aSafresh1
1972*3d61058aSafresh1    $z->close();
1973b39c5158Smillert
1974b39c5158Smillert=head1 Methods
1975b39c5158Smillert
1976b39c5158Smillert=head2 print
1977b39c5158Smillert
1978b39c5158SmillertUsage is
1979b39c5158Smillert
1980b39c5158Smillert    $z->print($data)
1981b39c5158Smillert    print $z $data
1982b39c5158Smillert
1983b39c5158SmillertCompresses and outputs the contents of the C<$data> parameter. This
1984b39c5158Smillerthas the same behaviour as the C<print> built-in.
1985b39c5158Smillert
1986b39c5158SmillertReturns true if successful.
1987b39c5158Smillert
1988b39c5158Smillert=head2 printf
1989b39c5158Smillert
1990b39c5158SmillertUsage is
1991b39c5158Smillert
1992b39c5158Smillert    $z->printf($format, $data)
1993b39c5158Smillert    printf $z $format, $data
1994b39c5158Smillert
1995b39c5158SmillertCompresses and outputs the contents of the C<$data> parameter.
1996b39c5158Smillert
1997b39c5158SmillertReturns true if successful.
1998b39c5158Smillert
1999b39c5158Smillert=head2 syswrite
2000b39c5158Smillert
2001b39c5158SmillertUsage is
2002b39c5158Smillert
2003b39c5158Smillert    $z->syswrite $data
2004b39c5158Smillert    $z->syswrite $data, $length
2005b39c5158Smillert    $z->syswrite $data, $length, $offset
2006b39c5158Smillert
2007b39c5158SmillertCompresses and outputs the contents of the C<$data> parameter.
2008b39c5158Smillert
2009b39c5158SmillertReturns the number of uncompressed bytes written, or C<undef> if
2010b39c5158Smillertunsuccessful.
2011b39c5158Smillert
2012b39c5158Smillert=head2 write
2013b39c5158Smillert
2014b39c5158SmillertUsage is
2015b39c5158Smillert
2016b39c5158Smillert    $z->write $data
2017b39c5158Smillert    $z->write $data, $length
2018b39c5158Smillert    $z->write $data, $length, $offset
2019b39c5158Smillert
2020b39c5158SmillertCompresses and outputs the contents of the C<$data> parameter.
2021b39c5158Smillert
2022b39c5158SmillertReturns the number of uncompressed bytes written, or C<undef> if
2023b39c5158Smillertunsuccessful.
2024b39c5158Smillert
2025b39c5158Smillert=head2 flush
2026b39c5158Smillert
2027b39c5158SmillertUsage is
2028b39c5158Smillert
2029b39c5158Smillert    $z->flush;
2030b39c5158Smillert    $z->flush($flush_type);
2031b39c5158Smillert
2032b39c5158SmillertFlushes any pending compressed data to the output file/buffer.
2033b39c5158Smillert
2034b39c5158SmillertThis method takes an optional parameter, C<$flush_type>, that controls
2035b39c5158Smillerthow the flushing will be carried out. By default the C<$flush_type>
2036b39c5158Smillertused is C<Z_FINISH>. Other valid values for C<$flush_type> are
2037b39c5158SmillertC<Z_NO_FLUSH>, C<Z_SYNC_FLUSH>, C<Z_FULL_FLUSH> and C<Z_BLOCK>. It is
2038b39c5158Smillertstrongly recommended that you only set the C<flush_type> parameter if
2039b39c5158Smillertyou fully understand the implications of what it does - overuse of C<flush>
2040b39c5158Smillertcan seriously degrade the level of compression achieved. See the C<zlib>
2041b39c5158Smillertdocumentation for details.
2042b39c5158Smillert
2043b39c5158SmillertReturns true on success.
2044b39c5158Smillert
2045b39c5158Smillert=head2 tell
2046b39c5158Smillert
2047b39c5158SmillertUsage is
2048b39c5158Smillert
2049b39c5158Smillert    $z->tell()
2050b39c5158Smillert    tell $z
2051b39c5158Smillert
2052b39c5158SmillertReturns the uncompressed file offset.
2053b39c5158Smillert
2054b39c5158Smillert=head2 eof
2055b39c5158Smillert
2056b39c5158SmillertUsage is
2057b39c5158Smillert
2058b39c5158Smillert    $z->eof();
2059b39c5158Smillert    eof($z);
2060b39c5158Smillert
2061b39c5158SmillertReturns true if the C<close> method has been called.
2062b39c5158Smillert
2063b39c5158Smillert=head2 seek
2064b39c5158Smillert
2065b39c5158Smillert    $z->seek($position, $whence);
2066b39c5158Smillert    seek($z, $position, $whence);
2067b39c5158Smillert
2068b39c5158SmillertProvides a sub-set of the C<seek> functionality, with the restriction
2069b39c5158Smillertthat it is only legal to seek forward in the output file/buffer.
2070b39c5158SmillertIt is a fatal error to attempt to seek backward.
2071b39c5158Smillert
2072b39c5158SmillertEmpty parts of the file/buffer will have NULL (0x00) bytes written to them.
2073b39c5158Smillert
2074b39c5158SmillertThe C<$whence> parameter takes one the usual values, namely SEEK_SET,
2075b39c5158SmillertSEEK_CUR or SEEK_END.
2076b39c5158Smillert
2077b39c5158SmillertReturns 1 on success, 0 on failure.
2078b39c5158Smillert
2079b39c5158Smillert=head2 binmode
2080b39c5158Smillert
2081b39c5158SmillertUsage is
2082b39c5158Smillert
2083b39c5158Smillert    $z->binmode
2084b39c5158Smillert    binmode $z ;
2085b39c5158Smillert
2086b39c5158SmillertThis is a noop provided for completeness.
2087b39c5158Smillert
2088b39c5158Smillert=head2 opened
2089b39c5158Smillert
2090b39c5158Smillert    $z->opened()
2091b39c5158Smillert
2092b39c5158SmillertReturns true if the object currently refers to a opened file/buffer.
2093b39c5158Smillert
2094b39c5158Smillert=head2 autoflush
2095b39c5158Smillert
2096b39c5158Smillert    my $prev = $z->autoflush()
2097b39c5158Smillert    my $prev = $z->autoflush(EXPR)
2098b39c5158Smillert
2099b39c5158SmillertIf the C<$z> object is associated with a file or a filehandle, this method
2100b39c5158Smillertreturns the current autoflush setting for the underlying filehandle. If
2101b39c5158SmillertC<EXPR> is present, and is non-zero, it will enable flushing after every
2102b39c5158Smillertwrite/print operation.
2103b39c5158Smillert
2104b39c5158SmillertIf C<$z> is associated with a buffer, this method has no effect and always
2105b39c5158Smillertreturns C<undef>.
2106b39c5158Smillert
2107b39c5158SmillertB<Note> that the special variable C<$|> B<cannot> be used to set or
2108b39c5158Smillertretrieve the autoflush setting.
2109b39c5158Smillert
2110b39c5158Smillert=head2 input_line_number
2111b39c5158Smillert
2112b39c5158Smillert    $z->input_line_number()
2113b39c5158Smillert    $z->input_line_number(EXPR)
2114b39c5158Smillert
2115b39c5158SmillertThis method always returns C<undef> when compressing.
2116b39c5158Smillert
2117b39c5158Smillert=head2 fileno
2118b39c5158Smillert
2119b39c5158Smillert    $z->fileno()
2120b39c5158Smillert    fileno($z)
2121b39c5158Smillert
2122b39c5158SmillertIf the C<$z> object is associated with a file or a filehandle, C<fileno>
2123b39c5158Smillertwill return the underlying file descriptor. Once the C<close> method is
2124b39c5158Smillertcalled C<fileno> will return C<undef>.
2125b39c5158Smillert
2126898184e3SsthenIf the C<$z> object is associated with a buffer, this method will return
2127b39c5158SmillertC<undef>.
2128b39c5158Smillert
2129b39c5158Smillert=head2 close
2130b39c5158Smillert
2131b39c5158Smillert    $z->close() ;
2132b39c5158Smillert    close $z ;
2133b39c5158Smillert
2134b39c5158SmillertFlushes any pending compressed data and then closes the output file/buffer.
2135b39c5158Smillert
2136b39c5158SmillertFor most versions of Perl this method will be automatically invoked if
2137b39c5158Smillertthe IO::Compress::Zip object is destroyed (either explicitly or by the
2138b39c5158Smillertvariable with the reference to the object going out of scope). The
2139b39c5158Smillertexceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
2140b39c5158Smillertthese cases, the C<close> method will be called automatically, but
2141b39c5158Smillertnot until global destruction of all live objects when the program is
2142b39c5158Smillertterminating.
2143b39c5158Smillert
2144b39c5158SmillertTherefore, if you want your scripts to be able to run on all versions
2145b39c5158Smillertof Perl, you should call C<close> explicitly and not rely on automatic
2146b39c5158Smillertclosing.
2147b39c5158Smillert
2148b39c5158SmillertReturns true on success, otherwise 0.
2149b39c5158Smillert
2150b39c5158SmillertIf the C<AutoClose> option has been enabled when the IO::Compress::Zip
2151b39c5158Smillertobject was created, and the object is associated with a file, the
2152b39c5158Smillertunderlying file will also be closed.
2153b39c5158Smillert
2154b39c5158Smillert=head2 newStream([OPTS])
2155b39c5158Smillert
2156b39c5158SmillertUsage is
2157b39c5158Smillert
2158b39c5158Smillert    $z->newStream( [OPTS] )
2159b39c5158Smillert
2160b39c5158SmillertCloses the current compressed data stream and starts a new one.
2161b39c5158Smillert
21626fb12b70Safresh1OPTS consists of any of the options that are available when creating
2163b39c5158Smillertthe C<$z> object.
2164b39c5158Smillert
2165b39c5158SmillertSee the L</"Constructor Options"> section for more details.
2166b39c5158Smillert
2167b39c5158Smillert=head2 deflateParams
2168b39c5158Smillert
2169b39c5158SmillertUsage is
2170b39c5158Smillert
2171b39c5158Smillert    $z->deflateParams
2172b39c5158Smillert
2173b39c5158SmillertTODO
2174b39c5158Smillert
2175b39c5158Smillert=head1 Importing
2176b39c5158Smillert
2177b39c5158SmillertA number of symbolic constants are required by some methods in
2178b39c5158SmillertC<IO::Compress::Zip>. None are imported by default.
2179b39c5158Smillert
2180b39c5158Smillert=over 5
2181b39c5158Smillert
2182b39c5158Smillert=item :all
2183b39c5158Smillert
2184b39c5158SmillertImports C<zip>, C<$ZipError> and all symbolic
2185b39c5158Smillertconstants that can be used by C<IO::Compress::Zip>. Same as doing this
2186b39c5158Smillert
2187b39c5158Smillert    use IO::Compress::Zip qw(zip $ZipError :constants) ;
2188b39c5158Smillert
2189b39c5158Smillert=item :constants
2190b39c5158Smillert
2191b39c5158SmillertImport all symbolic constants. Same as doing this
2192b39c5158Smillert
2193b39c5158Smillert    use IO::Compress::Zip qw(:flush :level :strategy :zip_method) ;
2194b39c5158Smillert
2195b39c5158Smillert=item :flush
2196b39c5158Smillert
2197b39c5158SmillertThese symbolic constants are used by the C<flush> method.
2198b39c5158Smillert
2199b39c5158Smillert    Z_NO_FLUSH
2200b39c5158Smillert    Z_PARTIAL_FLUSH
2201b39c5158Smillert    Z_SYNC_FLUSH
2202b39c5158Smillert    Z_FULL_FLUSH
2203b39c5158Smillert    Z_FINISH
2204b39c5158Smillert    Z_BLOCK
2205b39c5158Smillert
2206b39c5158Smillert=item :level
2207b39c5158Smillert
2208b39c5158SmillertThese symbolic constants are used by the C<Level> option in the constructor.
2209b39c5158Smillert
2210b39c5158Smillert    Z_NO_COMPRESSION
2211b39c5158Smillert    Z_BEST_SPEED
2212b39c5158Smillert    Z_BEST_COMPRESSION
2213b39c5158Smillert    Z_DEFAULT_COMPRESSION
2214b39c5158Smillert
2215b39c5158Smillert=item :strategy
2216b39c5158Smillert
2217b39c5158SmillertThese symbolic constants are used by the C<Strategy> option in the constructor.
2218b39c5158Smillert
2219b39c5158Smillert    Z_FILTERED
2220b39c5158Smillert    Z_HUFFMAN_ONLY
2221b39c5158Smillert    Z_RLE
2222b39c5158Smillert    Z_FIXED
2223b39c5158Smillert    Z_DEFAULT_STRATEGY
2224b39c5158Smillert
2225b39c5158Smillert=item :zip_method
2226b39c5158Smillert
2227b39c5158SmillertThese symbolic constants are used by the C<Method> option in the
2228b39c5158Smillertconstructor.
2229b39c5158Smillert
2230b39c5158Smillert    ZIP_CM_STORE
2231b39c5158Smillert    ZIP_CM_DEFLATE
2232b39c5158Smillert    ZIP_CM_BZIP2
2233b39c5158Smillert
2234b39c5158Smillert=back
2235b39c5158Smillert
2236b39c5158Smillert=head1 EXAMPLES
2237b39c5158Smillert
2238b39c5158Smillert=head2 Apache::GZip Revisited
2239b39c5158Smillert
2240b39c5158SmillertSee L<IO::Compress::FAQ|IO::Compress::FAQ/"Apache::GZip Revisited">
2241b39c5158Smillert
2242b39c5158Smillert=head2 Working with Net::FTP
2243b39c5158Smillert
2244b39c5158SmillertSee L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP">
2245b39c5158Smillert
224656d68f1eSafresh1=head1 SUPPORT
224756d68f1eSafresh1
224856d68f1eSafresh1General feedback/questions/bug reports should be sent to
224956d68f1eSafresh1L<https://github.com/pmqs/IO-Compress/issues> (preferred) or
225056d68f1eSafresh1L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>.
225156d68f1eSafresh1
2252b39c5158Smillert=head1 SEE ALSO
2253b39c5158Smillert
2254b46d8ef2Safresh1L<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>
2255b39c5158Smillert
2256898184e3SsthenL<IO::Compress::FAQ|IO::Compress::FAQ>
2257b39c5158Smillert
2258b39c5158SmillertL<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
2259b39c5158SmillertL<Archive::Tar|Archive::Tar>,
2260b39c5158SmillertL<IO::Zlib|IO::Zlib>
2261b39c5158Smillert
2262b39c5158SmillertFor RFC 1950, 1951 and 1952 see
2263eac174f2Safresh1L<https://datatracker.ietf.org/doc/html/rfc1950>,
2264eac174f2Safresh1L<https://datatracker.ietf.org/doc/html/rfc1951> and
2265eac174f2Safresh1L<https://datatracker.ietf.org/doc/html/rfc1952>
2266b39c5158Smillert
2267b39c5158SmillertThe I<zlib> compression library was written by Jean-loup Gailly
22689f11ffb7Safresh1C<gzip@prep.ai.mit.edu> and Mark Adler C<madler@alumni.caltech.edu>.
2269b39c5158Smillert
2270b39c5158SmillertThe primary site for the I<zlib> compression library is
22719f11ffb7Safresh1L<http://www.zlib.org>.
2272b39c5158Smillert
2273e0680481Safresh1The primary site for the I<zlib-ng> compression library is
2274e0680481Safresh1L<https://github.com/zlib-ng/zlib-ng>.
2275e0680481Safresh1
22769f11ffb7Safresh1The primary site for gzip is L<http://www.gzip.org>.
2277b39c5158Smillert
2278b39c5158Smillert=head1 AUTHOR
2279b39c5158Smillert
22809f11ffb7Safresh1This module was written by Paul Marquess, C<pmqs@cpan.org>.
2281b39c5158Smillert
2282b39c5158Smillert=head1 MODIFICATION HISTORY
2283b39c5158Smillert
2284b39c5158SmillertSee the Changes file.
2285b39c5158Smillert
2286b39c5158Smillert=head1 COPYRIGHT AND LICENSE
2287b39c5158Smillert
2288*3d61058aSafresh1Copyright (c) 2005-2024 Paul Marquess. All rights reserved.
2289b39c5158Smillert
2290b39c5158SmillertThis program is free software; you can redistribute it and/or
2291b39c5158Smillertmodify it under the same terms as Perl itself.
2292