1package IO::Uncompress::Unzip;
2
3require 5.006 ;
4
5# for RFC1952
6
7use strict ;
8use warnings;
9#use bytes;
10
11use IO::File;
12use IO::Uncompress::RawInflate  2.064 ;
13use IO::Compress::Base::Common  2.064 qw(:Status );
14use IO::Uncompress::Adapter::Inflate  2.064 ;
15use IO::Uncompress::Adapter::Identity 2.064 ;
16use IO::Compress::Zlib::Extra 2.064 ;
17use IO::Compress::Zip::Constants 2.064 ;
18
19use Compress::Raw::Zlib  2.064 () ;
20
21BEGIN
22{
23    eval{ require IO::Uncompress::Adapter::Bunzip2 ;
24           import  IO::Uncompress::Adapter::Bunzip2 } ;
25    eval{ require IO::Uncompress::Adapter::UnLzma ;
26          import  IO::Uncompress::Adapter::UnLzma } ;
27}
28
29
30require Exporter ;
31
32our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
33
34$VERSION = '2.064_01';
35$UnzipError = '';
36
37@ISA    = qw(Exporter IO::Uncompress::RawInflate);
38@EXPORT_OK = qw( $UnzipError unzip );
39%EXPORT_TAGS = %IO::Uncompress::RawInflate::EXPORT_TAGS ;
40push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
41Exporter::export_ok_tags('all');
42
43%headerLookup = (
44        ZIP_CENTRAL_HDR_SIG,            \&skipCentralDirectory,
45        ZIP_END_CENTRAL_HDR_SIG,        \&skipEndCentralDirectory,
46        ZIP64_END_CENTRAL_REC_HDR_SIG,  \&skipCentralDirectory64Rec,
47        ZIP64_END_CENTRAL_LOC_HDR_SIG,  \&skipCentralDirectory64Loc,
48        ZIP64_ARCHIVE_EXTRA_SIG,        \&skipArchiveExtra,
49        ZIP64_DIGITAL_SIGNATURE_SIG,    \&skipDigitalSignature,
50        );
51
52sub new
53{
54    my $class = shift ;
55    my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$UnzipError);
56    $obj->_create(undef, 0, @_);
57}
58
59sub unzip
60{
61    my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$UnzipError);
62    return $obj->_inf(@_) ;
63}
64
65sub getExtraParams
66{
67
68    return (
69#            # Zip header fields
70            'name'    => [IO::Compress::Base::Common::Parse_any,       undef],
71
72            'stream'  => [IO::Compress::Base::Common::Parse_boolean,   0],
73
74            # TODO - This means reading the central directory to get
75            # 1. the local header offsets
76            # 2. The compressed data length
77        );
78}
79
80sub ckParams
81{
82    my $self = shift ;
83    my $got = shift ;
84
85    # unzip always needs crc32
86    $got->setValue('crc32' => 1);
87
88    *$self->{UnzipData}{Name} = $got->getValue('name');
89
90    return 1;
91}
92
93sub mkUncomp
94{
95    my $self = shift ;
96    my $got = shift ;
97
98     my $magic = $self->ckMagic()
99        or return 0;
100
101    *$self->{Info} = $self->readHeader($magic)
102        or return undef ;
103
104    return 1;
105
106}
107
108sub ckMagic
109{
110    my $self = shift;
111
112    my $magic ;
113    $self->smartReadExact(\$magic, 4);
114
115    *$self->{HeaderPending} = $magic ;
116
117    return $self->HeaderError("Minimum header size is " .
118                              4 . " bytes")
119        if length $magic != 4 ;
120
121    return $self->HeaderError("Bad Magic")
122        if ! _isZipMagic($magic) ;
123
124    *$self->{Type} = 'zip';
125
126    return $magic ;
127}
128
129
130sub fastForward
131{
132    my $self = shift;
133    my $offset = shift;
134
135    # TODO - if Stream isn't enabled & reading from file, use seek
136
137    my $buffer = '';
138    my $c = 1024 * 16;
139
140    while ($offset > 0)
141    {
142        $c = length $offset
143            if length $offset < $c ;
144
145        $offset -= $c;
146
147        $self->smartReadExact(\$buffer, $c)
148            or return 0;
149    }
150
151    return 1;
152}
153
154
155sub readHeader
156{
157    my $self = shift;
158    my $magic = shift ;
159
160    my $name =  *$self->{UnzipData}{Name} ;
161    my $hdr = $self->_readZipHeader($magic) ;
162
163    while (defined $hdr)
164    {
165        if (! defined $name || $hdr->{Name} eq $name)
166        {
167            return $hdr ;
168        }
169
170        # skip the data
171        # TODO - when Stream is off, use seek
172        my $buffer;
173        if (*$self->{ZipData}{Streaming}) {
174
175            while (1) {
176
177                my $b;
178                my $status = $self->smartRead(\$b, 1024 * 16);
179                return undef
180                    if $status <= 0 ;
181
182                my $temp_buf;
183                my $out;
184                $status = *$self->{Uncomp}->uncompr(\$b, \$temp_buf, 0, $out);
185
186                return $self->saveErrorString(undef, *$self->{Uncomp}{Error},
187                                                     *$self->{Uncomp}{ErrorNo})
188                    if $self->saveStatus($status) == STATUS_ERROR;
189
190                if ($status == STATUS_ENDSTREAM) {
191                    *$self->{Uncomp}->reset();
192                    $self->pushBack($b)  ;
193                    last;
194                }
195            }
196
197            # skip the trailer
198            $self->smartReadExact(\$buffer, $hdr->{TrailerLength})
199                or return $self->saveErrorString(undef, "Truncated file");
200        }
201        else {
202            my $c = $hdr->{CompressedLength}->get64bit();
203            $self->fastForward($c)
204                or return $self->saveErrorString(undef, "Truncated file");
205            $buffer = '';
206        }
207
208        $self->chkTrailer($buffer) == STATUS_OK
209            or return $self->saveErrorString(undef, "Truncated file");
210
211        $hdr = $self->_readFullZipHeader();
212
213        return $self->saveErrorString(undef, "Cannot find '$name'")
214            if $self->smartEof();
215    }
216
217    return undef;
218}
219
220sub chkTrailer
221{
222    my $self = shift;
223    my $trailer = shift;
224
225    my ($sig, $CRC32, $cSize, $uSize) ;
226    my ($cSizeHi, $uSizeHi) = (0, 0);
227    if (*$self->{ZipData}{Streaming}) {
228        $sig   = unpack ("V", substr($trailer, 0, 4));
229        $CRC32 = unpack ("V", substr($trailer, 4, 4));
230
231        if (*$self->{ZipData}{Zip64} ) {
232            $cSize = U64::newUnpack_V64 substr($trailer,  8, 8);
233            $uSize = U64::newUnpack_V64 substr($trailer, 16, 8);
234        }
235        else {
236            $cSize = U64::newUnpack_V32 substr($trailer,  8, 4);
237            $uSize = U64::newUnpack_V32 substr($trailer, 12, 4);
238        }
239
240        return $self->TrailerError("Data Descriptor signature, got $sig")
241            if $sig != ZIP_DATA_HDR_SIG;
242    }
243    else {
244        ($CRC32, $cSize, $uSize) =
245            (*$self->{ZipData}{Crc32},
246             *$self->{ZipData}{CompressedLen},
247             *$self->{ZipData}{UnCompressedLen});
248    }
249
250    *$self->{Info}{CRC32} = *$self->{ZipData}{CRC32} ;
251    *$self->{Info}{CompressedLength} = $cSize->get64bit();
252    *$self->{Info}{UncompressedLength} = $uSize->get64bit();
253
254    if (*$self->{Strict}) {
255        return $self->TrailerError("CRC mismatch")
256            if $CRC32  != *$self->{ZipData}{CRC32} ;
257
258        return $self->TrailerError("CSIZE mismatch.")
259            if ! $cSize->equal(*$self->{CompSize});
260
261        return $self->TrailerError("USIZE mismatch.")
262            if ! $uSize->equal(*$self->{UnCompSize});
263    }
264
265    my $reachedEnd = STATUS_ERROR ;
266    # check for central directory or end of central directory
267    while (1)
268    {
269        my $magic ;
270        my $got = $self->smartRead(\$magic, 4);
271
272        return $self->saveErrorString(STATUS_ERROR, "Truncated file")
273            if $got != 4 && *$self->{Strict};
274
275        if ($got == 0) {
276            return STATUS_EOF ;
277        }
278        elsif ($got < 0) {
279            return STATUS_ERROR ;
280        }
281        elsif ($got < 4) {
282            $self->pushBack($magic)  ;
283            return STATUS_OK ;
284        }
285
286        my $sig = unpack("V", $magic) ;
287
288        my $hdr;
289        if ($hdr = $headerLookup{$sig})
290        {
291            if (&$hdr($self, $magic) != STATUS_OK ) {
292                if (*$self->{Strict}) {
293                    return STATUS_ERROR ;
294                }
295                else {
296                    $self->clearError();
297                    return STATUS_OK ;
298                }
299            }
300
301            if ($sig == ZIP_END_CENTRAL_HDR_SIG)
302            {
303                return STATUS_OK ;
304                last;
305            }
306        }
307        elsif ($sig == ZIP_LOCAL_HDR_SIG)
308        {
309            $self->pushBack($magic)  ;
310            return STATUS_OK ;
311        }
312        else
313        {
314            # put the data back
315            $self->pushBack($magic)  ;
316            last;
317        }
318    }
319
320    return $reachedEnd ;
321}
322
323sub skipCentralDirectory
324{
325    my $self = shift;
326    my $magic = shift ;
327
328    my $buffer;
329    $self->smartReadExact(\$buffer, 46 - 4)
330        or return $self->TrailerError("Minimum header size is " .
331                                     46 . " bytes") ;
332
333    my $keep = $magic . $buffer ;
334    *$self->{HeaderPending} = $keep ;
335
336   #my $versionMadeBy      = unpack ("v", substr($buffer, 4-4,  2));
337   #my $extractVersion     = unpack ("v", substr($buffer, 6-4,  2));
338   #my $gpFlag             = unpack ("v", substr($buffer, 8-4,  2));
339   #my $compressedMethod   = unpack ("v", substr($buffer, 10-4, 2));
340   #my $lastModTime        = unpack ("V", substr($buffer, 12-4, 4));
341   #my $crc32              = unpack ("V", substr($buffer, 16-4, 4));
342    my $compressedLength   = unpack ("V", substr($buffer, 20-4, 4));
343    my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4));
344    my $filename_length    = unpack ("v", substr($buffer, 28-4, 2));
345    my $extra_length       = unpack ("v", substr($buffer, 30-4, 2));
346    my $comment_length     = unpack ("v", substr($buffer, 32-4, 2));
347   #my $disk_start         = unpack ("v", substr($buffer, 34-4, 2));
348   #my $int_file_attrib    = unpack ("v", substr($buffer, 36-4, 2));
349   #my $ext_file_attrib    = unpack ("V", substr($buffer, 38-4, 2));
350   #my $lcl_hdr_offset     = unpack ("V", substr($buffer, 42-4, 2));
351
352
353    my $filename;
354    my $extraField;
355    my $comment ;
356    if ($filename_length)
357    {
358        $self->smartReadExact(\$filename, $filename_length)
359            or return $self->TruncatedTrailer("filename");
360        $keep .= $filename ;
361    }
362
363    if ($extra_length)
364    {
365        $self->smartReadExact(\$extraField, $extra_length)
366            or return $self->TruncatedTrailer("extra");
367        $keep .= $extraField ;
368    }
369
370    if ($comment_length)
371    {
372        $self->smartReadExact(\$comment, $comment_length)
373            or return $self->TruncatedTrailer("comment");
374        $keep .= $comment ;
375    }
376
377    return STATUS_OK ;
378}
379
380sub skipArchiveExtra
381{
382    my $self = shift;
383    my $magic = shift ;
384
385    my $buffer;
386    $self->smartReadExact(\$buffer, 4)
387        or return $self->TrailerError("Minimum header size is " .
388                                     4 . " bytes") ;
389
390    my $keep = $magic . $buffer ;
391
392    my $size = unpack ("V", $buffer);
393
394    $self->smartReadExact(\$buffer, $size)
395        or return $self->TrailerError("Minimum header size is " .
396                                     $size . " bytes") ;
397
398    $keep .= $buffer ;
399    *$self->{HeaderPending} = $keep ;
400
401    return STATUS_OK ;
402}
403
404
405sub skipCentralDirectory64Rec
406{
407    my $self = shift;
408    my $magic = shift ;
409
410    my $buffer;
411    $self->smartReadExact(\$buffer, 8)
412        or return $self->TrailerError("Minimum header size is " .
413                                     8 . " bytes") ;
414
415    my $keep = $magic . $buffer ;
416
417    my ($sizeLo, $sizeHi)  = unpack ("V V", $buffer);
418    my $size = $sizeHi * U64::MAX32 + $sizeLo;
419
420    $self->fastForward($size)
421        or return $self->TrailerError("Minimum header size is " .
422                                     $size . " bytes") ;
423
424   #$keep .= $buffer ;
425   #*$self->{HeaderPending} = $keep ;
426
427   #my $versionMadeBy      = unpack ("v",   substr($buffer,  0, 2));
428   #my $extractVersion     = unpack ("v",   substr($buffer,  2, 2));
429   #my $diskNumber         = unpack ("V",   substr($buffer,  4, 4));
430   #my $cntrlDirDiskNo     = unpack ("V",   substr($buffer,  8, 4));
431   #my $entriesInThisCD    = unpack ("V V", substr($buffer, 12, 8));
432   #my $entriesInCD        = unpack ("V V", substr($buffer, 20, 8));
433   #my $sizeOfCD           = unpack ("V V", substr($buffer, 28, 8));
434   #my $offsetToCD         = unpack ("V V", substr($buffer, 36, 8));
435
436    return STATUS_OK ;
437}
438
439sub skipCentralDirectory64Loc
440{
441    my $self = shift;
442    my $magic = shift ;
443
444    my $buffer;
445    $self->smartReadExact(\$buffer, 20 - 4)
446        or return $self->TrailerError("Minimum header size is " .
447                                     20 . " bytes") ;
448
449    my $keep = $magic . $buffer ;
450    *$self->{HeaderPending} = $keep ;
451
452   #my $startCdDisk        = unpack ("V",   substr($buffer,  4-4, 4));
453   #my $offsetToCD         = unpack ("V V", substr($buffer,  8-4, 8));
454   #my $diskCount          = unpack ("V",   substr($buffer, 16-4, 4));
455
456    return STATUS_OK ;
457}
458
459sub skipEndCentralDirectory
460{
461    my $self = shift;
462    my $magic = shift ;
463
464    my $buffer;
465    $self->smartReadExact(\$buffer, 22 - 4)
466        or return $self->TrailerError("Minimum header size is " .
467                                     22 . " bytes") ;
468
469    my $keep = $magic . $buffer ;
470    *$self->{HeaderPending} = $keep ;
471
472   #my $diskNumber         = unpack ("v", substr($buffer, 4-4,  2));
473   #my $cntrlDirDiskNo     = unpack ("v", substr($buffer, 6-4,  2));
474   #my $entriesInThisCD    = unpack ("v", substr($buffer, 8-4,  2));
475   #my $entriesInCD        = unpack ("v", substr($buffer, 10-4, 2));
476   #my $sizeOfCD           = unpack ("V", substr($buffer, 12-4, 4));
477   #my $offsetToCD         = unpack ("V", substr($buffer, 16-4, 4));
478    my $comment_length     = unpack ("v", substr($buffer, 20-4, 2));
479
480
481    my $comment ;
482    if ($comment_length)
483    {
484        $self->smartReadExact(\$comment, $comment_length)
485            or return $self->TruncatedTrailer("comment");
486        $keep .= $comment ;
487    }
488
489    return STATUS_OK ;
490}
491
492
493sub _isZipMagic
494{
495    my $buffer = shift ;
496    return 0 if length $buffer < 4 ;
497    my $sig = unpack("V", $buffer) ;
498    return $sig == ZIP_LOCAL_HDR_SIG ;
499}
500
501
502sub _readFullZipHeader($)
503{
504    my ($self) = @_ ;
505    my $magic = '' ;
506
507    $self->smartReadExact(\$magic, 4);
508
509    *$self->{HeaderPending} = $magic ;
510
511    return $self->HeaderError("Minimum header size is " .
512                              30 . " bytes")
513        if length $magic != 4 ;
514
515
516    return $self->HeaderError("Bad Magic")
517        if ! _isZipMagic($magic) ;
518
519    my $status = $self->_readZipHeader($magic);
520    delete *$self->{Transparent} if ! defined $status ;
521    return $status ;
522}
523
524sub _readZipHeader($)
525{
526    my ($self, $magic) = @_ ;
527    my ($HeaderCRC) ;
528    my ($buffer) = '' ;
529
530    $self->smartReadExact(\$buffer, 30 - 4)
531        or return $self->HeaderError("Minimum header size is " .
532                                     30 . " bytes") ;
533
534    my $keep = $magic . $buffer ;
535    *$self->{HeaderPending} = $keep ;
536
537    my $extractVersion     = unpack ("v", substr($buffer, 4-4,  2));
538    my $gpFlag             = unpack ("v", substr($buffer, 6-4,  2));
539    my $compressedMethod   = unpack ("v", substr($buffer, 8-4,  2));
540    my $lastModTime        = unpack ("V", substr($buffer, 10-4, 4));
541    my $crc32              = unpack ("V", substr($buffer, 14-4, 4));
542    my $compressedLength   = U64::newUnpack_V32 substr($buffer, 18-4, 4);
543    my $uncompressedLength = U64::newUnpack_V32 substr($buffer, 22-4, 4);
544    my $filename_length    = unpack ("v", substr($buffer, 26-4, 2));
545    my $extra_length       = unpack ("v", substr($buffer, 28-4, 2));
546
547    my $filename;
548    my $extraField;
549    my @EXTRA = ();
550    my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ;
551
552    return $self->HeaderError("Encrypted content not supported")
553        if $gpFlag & (ZIP_GP_FLAG_ENCRYPTED_MASK|ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK);
554
555    return $self->HeaderError("Patch content not supported")
556        if $gpFlag & ZIP_GP_FLAG_PATCHED_MASK;
557
558    *$self->{ZipData}{Streaming} = $streamingMode;
559
560
561    if ($filename_length)
562    {
563        $self->smartReadExact(\$filename, $filename_length)
564            or return $self->TruncatedHeader("Filename");
565        $keep .= $filename ;
566    }
567
568    my $zip64 = 0 ;
569
570    if ($extra_length)
571    {
572        $self->smartReadExact(\$extraField, $extra_length)
573            or return $self->TruncatedHeader("Extra Field");
574
575        my $bad = IO::Compress::Zlib::Extra::parseRawExtra($extraField,
576                                                \@EXTRA, 1, 0);
577        return $self->HeaderError($bad)
578            if defined $bad;
579
580        $keep .= $extraField ;
581
582        my %Extra ;
583        for (@EXTRA)
584        {
585            $Extra{$_->[0]} = \$_->[1];
586        }
587
588        if (defined $Extra{ZIP_EXTRA_ID_ZIP64()})
589        {
590            $zip64 = 1 ;
591
592            my $buff = ${ $Extra{ZIP_EXTRA_ID_ZIP64()} };
593
594            # This code assumes that all the fields in the Zip64
595            # extra field aren't necessarily present. The spec says that
596            # they only exist if the equivalent local headers are -1.
597
598            if (! $streamingMode) {
599                my $offset = 0 ;
600
601                if (U64::full32 $uncompressedLength->get32bit() ) {
602                    $uncompressedLength
603                            = U64::newUnpack_V64 substr($buff, 0, 8);
604
605                    $offset += 8 ;
606                }
607
608                if (U64::full32 $compressedLength->get32bit() ) {
609
610                    $compressedLength
611                        = U64::newUnpack_V64 substr($buff, $offset, 8);
612
613                    $offset += 8 ;
614                }
615           }
616        }
617    }
618
619    *$self->{ZipData}{Zip64} = $zip64;
620
621    if (! $streamingMode) {
622        *$self->{ZipData}{Streaming} = 0;
623        *$self->{ZipData}{Crc32} = $crc32;
624        *$self->{ZipData}{CompressedLen} = $compressedLength;
625        *$self->{ZipData}{UnCompressedLen} = $uncompressedLength;
626        *$self->{CompressedInputLengthRemaining} =
627            *$self->{CompressedInputLength} = $compressedLength->get64bit();
628    }
629
630    *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef);
631    *$self->{ZipData}{Method} = $compressedMethod;
632    if ($compressedMethod == ZIP_CM_DEFLATE)
633    {
634        *$self->{Type} = 'zip-deflate';
635        my $obj = IO::Uncompress::Adapter::Inflate::mkUncompObject(1,0,0);
636
637        *$self->{Uncomp} = $obj;
638    }
639    elsif ($compressedMethod == ZIP_CM_BZIP2)
640    {
641        return $self->HeaderError("Unsupported Compression format $compressedMethod")
642            if ! defined $IO::Uncompress::Adapter::Bunzip2::VERSION ;
643
644        *$self->{Type} = 'zip-bzip2';
645
646        my $obj = IO::Uncompress::Adapter::Bunzip2::mkUncompObject();
647
648        *$self->{Uncomp} = $obj;
649    }
650    elsif ($compressedMethod == ZIP_CM_LZMA)
651    {
652        return $self->HeaderError("Unsupported Compression format $compressedMethod")
653            if ! defined $IO::Uncompress::Adapter::UnLzma::VERSION ;
654
655        *$self->{Type} = 'zip-lzma';
656        my $LzmaHeader;
657        $self->smartReadExact(\$LzmaHeader, 4)
658                or return $self->saveErrorString(undef, "Truncated file");
659        my ($verHi, $verLo)   = unpack ("CC", substr($LzmaHeader, 0, 2));
660        my $LzmaPropertiesSize   = unpack ("v", substr($LzmaHeader, 2, 2));
661
662
663        my $LzmaPropertyData;
664        $self->smartReadExact(\$LzmaPropertyData, $LzmaPropertiesSize)
665                or return $self->saveErrorString(undef, "Truncated file");
666
667        if (! $streamingMode) {
668            *$self->{ZipData}{CompressedLen}->subtract(4 + $LzmaPropertiesSize) ;
669            *$self->{CompressedInputLengthRemaining} =
670                *$self->{CompressedInputLength} = *$self->{ZipData}{CompressedLen}->get64bit();
671        }
672
673        my $obj =
674            IO::Uncompress::Adapter::UnLzma::mkUncompZipObject($LzmaPropertyData);
675
676        *$self->{Uncomp} = $obj;
677    }
678    elsif ($compressedMethod == ZIP_CM_STORE)
679    {
680        *$self->{Type} = 'zip-stored';
681
682        my $obj =
683        IO::Uncompress::Adapter::Identity::mkUncompObject($streamingMode,
684                                                          $zip64);
685
686        *$self->{Uncomp} = $obj;
687    }
688    else
689    {
690        return $self->HeaderError("Unsupported Compression format $compressedMethod");
691    }
692
693    return {
694        'Type'               => 'zip',
695        'FingerprintLength'  => 4,
696        #'HeaderLength'       => $compressedMethod == 8 ? length $keep : 0,
697        'HeaderLength'       => length $keep,
698        'Zip64'              => $zip64,
699        'TrailerLength'      => ! $streamingMode ? 0 : $zip64 ? 24 : 16,
700        'Header'             => $keep,
701        'CompressedLength'   => $compressedLength ,
702        'UncompressedLength' => $uncompressedLength ,
703        'CRC32'              => $crc32 ,
704        'Name'               => $filename,
705        'Time'               => _dosToUnixTime($lastModTime),
706        'Stream'             => $streamingMode,
707
708        'MethodID'           => $compressedMethod,
709        'MethodName'         => $compressedMethod == ZIP_CM_DEFLATE
710                                 ? "Deflated"
711                                 : $compressedMethod == ZIP_CM_BZIP2
712                                     ? "Bzip2"
713                                     : $compressedMethod == ZIP_CM_LZMA
714                                         ? "Lzma"
715                                         : $compressedMethod == ZIP_CM_STORE
716                                             ? "Stored"
717                                             : "Unknown" ,
718
719#        'TextFlag'      => $flag & GZIP_FLG_FTEXT ? 1 : 0,
720#        'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
721#        'NameFlag'      => $flag & GZIP_FLG_FNAME ? 1 : 0,
722#        'CommentFlag'   => $flag & GZIP_FLG_FCOMMENT ? 1 : 0,
723#        'ExtraFlag'     => $flag & GZIP_FLG_FEXTRA ? 1 : 0,
724#        'Comment'       => $comment,
725#        'OsID'          => $os,
726#        'OsName'        => defined $GZIP_OS_Names{$os}
727#                                 ? $GZIP_OS_Names{$os} : "Unknown",
728#        'HeaderCRC'     => $HeaderCRC,
729#        'Flags'         => $flag,
730#        'ExtraFlags'    => $xfl,
731        'ExtraFieldRaw' => $extraField,
732        'ExtraField'    => [ @EXTRA ],
733
734
735      }
736}
737
738sub filterUncompressed
739{
740    my $self = shift ;
741
742    if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) {
743        *$self->{ZipData}{CRC32} = *$self->{Uncomp}->crc32() ;
744    }
745    else {
746        *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(${$_[0]}, *$self->{ZipData}{CRC32}, $_[1]);
747    }
748}
749
750
751# from Archive::Zip & info-zip
752sub _dosToUnixTime
753{
754	my $dt = shift;
755
756	my $year = ( ( $dt >> 25 ) & 0x7f ) + 80;
757	my $mon  = ( ( $dt >> 21 ) & 0x0f ) - 1;
758	my $mday = ( ( $dt >> 16 ) & 0x1f );
759
760	my $hour = ( ( $dt >> 11 ) & 0x1f );
761	my $min  = ( ( $dt >> 5 ) & 0x3f );
762	my $sec  = ( ( $dt << 1 ) & 0x3e );
763
764
765    use POSIX 'mktime';
766
767    my $time_t = mktime( $sec, $min, $hour, $mday, $mon, $year, 0, 0, -1 );
768    return 0 if ! defined $time_t;
769	return $time_t;
770}
771
772#sub scanCentralDirectory
773#{
774#    # Use cases
775#    # 1 32-bit CD
776#    # 2 64-bit CD
777#
778#    my $self = shift ;
779#
780#    my @CD = ();
781#    my $offset = $self->findCentralDirectoryOffset();
782#
783#    return 0
784#        if ! defined $offset;
785#
786#    $self->smarkSeek($offset, 0, SEEK_SET) ;
787#
788#    # Now walk the Central Directory Records
789#    my $buffer ;
790#    while ($self->smartReadExact(\$buffer, 46) &&
791#           unpack("V", $buffer) == ZIP_CENTRAL_HDR_SIG) {
792#
793#        my $compressedLength   = unpack ("V", substr($buffer, 20, 4));
794#        my $filename_length    = unpack ("v", substr($buffer, 28, 2));
795#        my $extra_length       = unpack ("v", substr($buffer, 30, 2));
796#        my $comment_length     = unpack ("v", substr($buffer, 32, 2));
797#
798#        $self->smarkSeek($filename_length + $extra_length + $comment_length, 0, SEEK_CUR)
799#            if $extra_length || $comment_length || $filename_length;
800#        push @CD, $compressedLength ;
801#    }
802#
803#}
804#
805#sub findCentralDirectoryOffset
806#{
807#    my $self = shift ;
808#
809#    # Most common use-case is where there is no comment, so
810#    # know exactly where the end of central directory record
811#    # should be.
812#
813#    $self->smarkSeek(-22, 0, SEEK_END) ;
814#
815#    my $buffer;
816#    $self->smartReadExact(\$buffer, 22) ;
817#
818#    my $zip64 = 0;
819#    my $centralDirOffset ;
820#    if ( unpack("V", $buffer) == ZIP_END_CENTRAL_HDR_SIG ) {
821#        $centralDirOffset = unpack ("V", substr($buffer, 16, 2));
822#    }
823#    else {
824#        die "xxxx";
825#    }
826#
827#    return $centralDirOffset ;
828#}
829#
830#sub is84BitCD
831#{
832#    # TODO
833#    my $self = shift ;
834#}
835
836
837sub skip
838{
839    my $self = shift;
840    my $size = shift;
841
842    use Fcntl qw(SEEK_CUR);
843    if (ref $size eq 'U64') {
844        $self->smartSeek($size->get64bit(), SEEK_CUR);
845    }
846    else {
847        $self->smartSeek($size, SEEK_CUR);
848    }
849
850}
851
852
853sub scanCentralDirectory
854{
855    my $self = shift;
856
857    my $here = $self->tell();
858
859    # Use cases
860    # 1 32-bit CD
861    # 2 64-bit CD
862
863    my @CD = ();
864    my $offset = $self->findCentralDirectoryOffset();
865
866    return ()
867        if ! defined $offset;
868
869    $self->smarkSeek($offset, 0, SEEK_SET) ;
870
871    # Now walk the Central Directory Records
872    my $buffer ;
873    while ($self->smartReadExact(\$buffer, 46) &&
874           unpack("V", $buffer) == ZIP_CENTRAL_HDR_SIG) {
875
876        my $compressedLength   = unpack("V", substr($buffer, 20, 4));
877        my $uncompressedLength = unpack("V", substr($buffer, 24, 4));
878        my $filename_length    = unpack("v", substr($buffer, 28, 2));
879        my $extra_length       = unpack("v", substr($buffer, 30, 2));
880        my $comment_length     = unpack("v", substr($buffer, 32, 2));
881
882        $self->skip($filename_length ) ;
883
884        my $v64 = new U64 $compressedLength ;
885
886        if (U64::full32 $compressedLength ) {
887            $self->smartReadExact(\$buffer, $extra_length) ;
888            die "xxx $offset $comment_length $filename_length $extra_length" . length($buffer)
889                if length($buffer) != $extra_length;
890            my $got = $self->get64Extra($buffer, U64::full32 $uncompressedLength);
891
892            # If not Zip64 extra field, assume size is 0xFFFFFFFF
893            $v64 = $got if defined $got;
894        }
895        else {
896            $self->skip($extra_length) ;
897        }
898
899        $self->skip($comment_length ) ;
900
901        push @CD, $v64 ;
902    }
903
904    $self->smartSeek($here, 0, SEEK_SET) ;
905
906    return @CD;
907}
908
909sub get64Extra
910{
911    my $self = shift ;
912
913    my $buffer = shift;
914    my $is_uncomp = shift ;
915
916    my $extra = IO::Compress::Zlib::Extra::findID(0x0001, $buffer);
917
918    if (! defined $extra)
919    {
920        return undef;
921    }
922    else
923    {
924        my $u64 = U64::newUnpack_V64(substr($extra,  $is_uncomp ? 8 : 0)) ;
925        return $u64;
926    }
927}
928
929sub offsetFromZip64
930{
931    my $self = shift ;
932    my $here = shift;
933
934    $self->smartSeek($here - 20, 0, SEEK_SET)
935        or die "xx $!" ;
936
937    my $buffer;
938    my $got = 0;
939    $self->smartReadExact(\$buffer, 20)
940        or die "xxx $here $got $!" ;
941
942    if ( unpack("V", $buffer) == ZIP64_END_CENTRAL_LOC_HDR_SIG ) {
943        my $cd64 = U64::Value_VV64 substr($buffer,  8, 8);
944
945        $self->smartSeek($cd64, 0, SEEK_SET) ;
946
947        $self->smartReadExact(\$buffer, 4)
948            or die "xxx" ;
949
950        if ( unpack("V", $buffer) == ZIP64_END_CENTRAL_REC_HDR_SIG ) {
951
952            $self->smartReadExact(\$buffer, 8)
953                or die "xxx" ;
954            my $size  = U64::Value_VV64($buffer);
955            $self->smartReadExact(\$buffer, $size)
956                or die "xxx" ;
957
958            my $cd64 =  U64::Value_VV64 substr($buffer,  36, 8);
959
960            return $cd64 ;
961        }
962
963        die "zzz";
964    }
965
966    die "zzz";
967}
968
969use constant Pack_ZIP_END_CENTRAL_HDR_SIG => pack("V", ZIP_END_CENTRAL_HDR_SIG);
970
971sub findCentralDirectoryOffset
972{
973    my $self = shift ;
974
975    # Most common use-case is where there is no comment, so
976    # know exactly where the end of central directory record
977    # should be.
978
979    $self->smartSeek(-22, 0, SEEK_END) ;
980    my $here = $self->tell();
981
982    my $buffer;
983    $self->smartReadExact(\$buffer, 22)
984        or die "xxx" ;
985
986    my $zip64 = 0;
987    my $centralDirOffset ;
988    if ( unpack("V", $buffer) == ZIP_END_CENTRAL_HDR_SIG ) {
989        $centralDirOffset = unpack("V", substr($buffer, 16,  4));
990    }
991    else {
992        $self->smartSeek(0, 0, SEEK_END) ;
993
994        my $fileLen = $self->tell();
995        my $want = 0 ;
996
997        while(1) {
998            $want += 1024;
999            my $seekTo = $fileLen - $want;
1000            if ($seekTo < 0 ) {
1001                $seekTo = 0;
1002                $want = $fileLen ;
1003            }
1004            $self->smartSeek( $seekTo, 0, SEEK_SET)
1005                or die "xxx $!" ;
1006            my $got;
1007            $self->smartReadExact($buffer, $want)
1008                or die "xxx " ;
1009            my $pos = rindex( $buffer, Pack_ZIP_END_CENTRAL_HDR_SIG);
1010
1011            if ($pos >= 0) {
1012                #$here = $self->tell();
1013                $here = $seekTo + $pos ;
1014                $centralDirOffset = unpack("V", substr($buffer, $pos + 16,  4));
1015                last ;
1016            }
1017
1018            return undef
1019                if $want == $fileLen;
1020        }
1021    }
1022
1023    $centralDirOffset = $self->offsetFromZip64($here)
1024        if U64::full32 $centralDirOffset ;
1025
1026    return $centralDirOffset ;
1027}
1028
10291;
1030
1031__END__
1032
1033
1034=head1 NAME
1035
1036IO::Uncompress::Unzip - Read zip files/buffers
1037
1038=head1 SYNOPSIS
1039
1040    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1041
1042    my $status = unzip $input => $output [,OPTS]
1043        or die "unzip failed: $UnzipError\n";
1044
1045    my $z = new IO::Uncompress::Unzip $input [OPTS]
1046        or die "unzip failed: $UnzipError\n";
1047
1048    $status = $z->read($buffer)
1049    $status = $z->read($buffer, $length)
1050    $status = $z->read($buffer, $length, $offset)
1051    $line = $z->getline()
1052    $char = $z->getc()
1053    $char = $z->ungetc()
1054    $char = $z->opened()
1055
1056    $status = $z->inflateSync()
1057
1058    $data = $z->trailingData()
1059    $status = $z->nextStream()
1060    $data = $z->getHeaderInfo()
1061    $z->tell()
1062    $z->seek($position, $whence)
1063    $z->binmode()
1064    $z->fileno()
1065    $z->eof()
1066    $z->close()
1067
1068    $UnzipError ;
1069
1070    # IO::File mode
1071
1072    <$z>
1073    read($z, $buffer);
1074    read($z, $buffer, $length);
1075    read($z, $buffer, $length, $offset);
1076    tell($z)
1077    seek($z, $position, $whence)
1078    binmode($z)
1079    fileno($z)
1080    eof($z)
1081    close($z)
1082
1083=head1 DESCRIPTION
1084
1085This module provides a Perl interface that allows the reading of
1086zlib files/buffers.
1087
1088For writing zip files/buffers, see the companion module IO::Compress::Zip.
1089
1090=head1 Functional Interface
1091
1092A top-level function, C<unzip>, is provided to carry out
1093"one-shot" uncompression between buffers and/or files. For finer
1094control over the uncompression process, see the L</"OO Interface">
1095section.
1096
1097    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1098
1099    unzip $input_filename_or_reference => $output_filename_or_reference [,OPTS]
1100        or die "unzip failed: $UnzipError\n";
1101
1102The functional interface needs Perl5.005 or better.
1103
1104=head2 unzip $input_filename_or_reference => $output_filename_or_reference [, OPTS]
1105
1106C<unzip> expects at least two parameters,
1107C<$input_filename_or_reference> and C<$output_filename_or_reference>.
1108
1109=head3 The C<$input_filename_or_reference> parameter
1110
1111The parameter, C<$input_filename_or_reference>, is used to define the
1112source of the compressed data.
1113
1114It can take one of the following forms:
1115
1116=over 5
1117
1118=item A filename
1119
1120If the <$input_filename_or_reference> parameter is a simple scalar, it is
1121assumed to be a filename. This file will be opened for reading and the
1122input data will be read from it.
1123
1124=item A filehandle
1125
1126If the C<$input_filename_or_reference> parameter is a filehandle, the input
1127data will be read from it.  The string '-' can be used as an alias for
1128standard input.
1129
1130=item A scalar reference
1131
1132If C<$input_filename_or_reference> is a scalar reference, the input data
1133will be read from C<$$input_filename_or_reference>.
1134
1135=item An array reference
1136
1137If C<$input_filename_or_reference> is an array reference, each element in
1138the array must be a filename.
1139
1140The input data will be read from each file in turn.
1141
1142The complete array will be walked to ensure that it only
1143contains valid filenames before any data is uncompressed.
1144
1145=item An Input FileGlob string
1146
1147If C<$input_filename_or_reference> is a string that is delimited by the
1148characters "<" and ">" C<unzip> will assume that it is an
1149I<input fileglob string>. The input is the list of files that match the
1150fileglob.
1151
1152See L<File::GlobMapper|File::GlobMapper> for more details.
1153
1154=back
1155
1156If the C<$input_filename_or_reference> parameter is any other type,
1157C<undef> will be returned.
1158
1159=head3 The C<$output_filename_or_reference> parameter
1160
1161The parameter C<$output_filename_or_reference> is used to control the
1162destination of the uncompressed data. This parameter can take one of
1163these forms.
1164
1165=over 5
1166
1167=item A filename
1168
1169If the C<$output_filename_or_reference> parameter is a simple scalar, it is
1170assumed to be a filename.  This file will be opened for writing and the
1171uncompressed data will be written to it.
1172
1173=item A filehandle
1174
1175If the C<$output_filename_or_reference> parameter is a filehandle, the
1176uncompressed data will be written to it.  The string '-' can be used as
1177an alias for standard output.
1178
1179=item A scalar reference
1180
1181If C<$output_filename_or_reference> is a scalar reference, the
1182uncompressed data will be stored in C<$$output_filename_or_reference>.
1183
1184=item An Array Reference
1185
1186If C<$output_filename_or_reference> is an array reference,
1187the uncompressed data will be pushed onto the array.
1188
1189=item An Output FileGlob
1190
1191If C<$output_filename_or_reference> is a string that is delimited by the
1192characters "<" and ">" C<unzip> will assume that it is an
1193I<output fileglob string>. The output is the list of files that match the
1194fileglob.
1195
1196When C<$output_filename_or_reference> is an fileglob string,
1197C<$input_filename_or_reference> must also be a fileglob string. Anything
1198else is an error.
1199
1200See L<File::GlobMapper|File::GlobMapper> for more details.
1201
1202=back
1203
1204If the C<$output_filename_or_reference> parameter is any other type,
1205C<undef> will be returned.
1206
1207=head2 Notes
1208
1209When C<$input_filename_or_reference> maps to multiple compressed
1210files/buffers and C<$output_filename_or_reference> is
1211a single file/buffer, after uncompression C<$output_filename_or_reference> will contain a
1212concatenation of all the uncompressed data from each of the input
1213files/buffers.
1214
1215=head2 Optional Parameters
1216
1217Unless specified below, the optional parameters for C<unzip>,
1218C<OPTS>, are the same as those used with the OO interface defined in the
1219L</"Constructor Options"> section below.
1220
1221=over 5
1222
1223=item C<< AutoClose => 0|1 >>
1224
1225This option applies to any input or output data streams to
1226C<unzip> that are filehandles.
1227
1228If C<AutoClose> is specified, and the value is true, it will result in all
1229input and/or output filehandles being closed once C<unzip> has
1230completed.
1231
1232This parameter defaults to 0.
1233
1234=item C<< BinModeOut => 0|1 >>
1235
1236When writing to a file or filehandle, set C<binmode> before writing to the
1237file.
1238
1239Defaults to 0.
1240
1241=item C<< Append => 0|1 >>
1242
1243The behaviour of this option is dependent on the type of output data
1244stream.
1245
1246=over 5
1247
1248=item * A Buffer
1249
1250If C<Append> is enabled, all uncompressed data will be append to the end of
1251the output buffer. Otherwise the output buffer will be cleared before any
1252uncompressed data is written to it.
1253
1254=item * A Filename
1255
1256If C<Append> is enabled, the file will be opened in append mode. Otherwise
1257the contents of the file, if any, will be truncated before any uncompressed
1258data is written to it.
1259
1260=item * A Filehandle
1261
1262If C<Append> is enabled, the filehandle will be positioned to the end of
1263the file via a call to C<seek> before any uncompressed data is
1264written to it.  Otherwise the file pointer will not be moved.
1265
1266=back
1267
1268When C<Append> is specified, and set to true, it will I<append> all uncompressed
1269data to the output data stream.
1270
1271So when the output is a filehandle it will carry out a seek to the eof
1272before writing any uncompressed data. If the output is a filename, it will be opened for
1273appending. If the output is a buffer, all uncompressed data will be
1274appended to the existing buffer.
1275
1276Conversely when C<Append> is not specified, or it is present and is set to
1277false, it will operate as follows.
1278
1279When the output is a filename, it will truncate the contents of the file
1280before writing any uncompressed data. If the output is a filehandle
1281its position will not be changed. If the output is a buffer, it will be
1282wiped before any uncompressed data is output.
1283
1284Defaults to 0.
1285
1286=item C<< MultiStream => 0|1 >>
1287
1288If the input file/buffer contains multiple compressed data streams, this
1289option will uncompress the whole lot as a single data stream.
1290
1291Defaults to 0.
1292
1293=item C<< TrailingData => $scalar >>
1294
1295Returns the data, if any, that is present immediately after the compressed
1296data stream once uncompression is complete.
1297
1298This option can be used when there is useful information immediately
1299following the compressed data stream, and you don't know the length of the
1300compressed data stream.
1301
1302If the input is a buffer, C<trailingData> will return everything from the
1303end of the compressed data stream to the end of the buffer.
1304
1305If the input is a filehandle, C<trailingData> will return the data that is
1306left in the filehandle input buffer once the end of the compressed data
1307stream has been reached. You can then use the filehandle to read the rest
1308of the input file.
1309
1310Don't bother using C<trailingData> if the input is a filename.
1311
1312If you know the length of the compressed data stream before you start
1313uncompressing, you can avoid having to use C<trailingData> by setting the
1314C<InputLength> option.
1315
1316=back
1317
1318=head2 Examples
1319
1320Say you have a zip file, C<file1.zip>, that only contains a
1321single member, you can read it and write the uncompressed data to the
1322file C<file1.txt> like this.
1323
1324    use strict ;
1325    use warnings ;
1326    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1327
1328    my $input = "file1.zip";
1329    my $output = "file1.txt";
1330    unzip $input => $output
1331        or die "unzip failed: $UnzipError\n";
1332
1333If you have a zip file that contains multiple members and want to read a
1334specific member from the file, say C<"data1">, use the C<Name> option
1335
1336    use strict ;
1337    use warnings ;
1338    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1339
1340    my $input = "file1.zip";
1341    my $output = "file1.txt";
1342    unzip $input => $output, Name => "data1"
1343        or die "unzip failed: $UnzipError\n";
1344
1345Alternatively, if you want to read the  C<"data1"> member into memory, use
1346a scalar reference for the C<output> parameter.
1347
1348    use strict ;
1349    use warnings ;
1350    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1351
1352    my $input = "file1.zip";
1353    my $output ;
1354    unzip $input => \$output, Name => "data1"
1355        or die "unzip failed: $UnzipError\n";
1356    # $output now contains the uncompressed data
1357
1358To read from an existing Perl filehandle, C<$input>, and write the
1359uncompressed data to a buffer, C<$buffer>.
1360
1361    use strict ;
1362    use warnings ;
1363    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1364    use IO::File ;
1365
1366    my $input = new IO::File "<file1.zip"
1367        or die "Cannot open 'file1.zip': $!\n" ;
1368    my $buffer ;
1369    unzip $input => \$buffer
1370        or die "unzip failed: $UnzipError\n";
1371
1372=head1 OO Interface
1373
1374=head2 Constructor
1375
1376The format of the constructor for IO::Uncompress::Unzip is shown below
1377
1378    my $z = new IO::Uncompress::Unzip $input [OPTS]
1379        or die "IO::Uncompress::Unzip failed: $UnzipError\n";
1380
1381Returns an C<IO::Uncompress::Unzip> object on success and undef on failure.
1382The variable C<$UnzipError> will contain an error message on failure.
1383
1384If you are running Perl 5.005 or better the object, C<$z>, returned from
1385IO::Uncompress::Unzip can be used exactly like an L<IO::File|IO::File> filehandle.
1386This means that all normal input file operations can be carried out with
1387C<$z>.  For example, to read a line from a compressed file/buffer you can
1388use either of these forms
1389
1390    $line = $z->getline();
1391    $line = <$z>;
1392
1393The mandatory parameter C<$input> is used to determine the source of the
1394compressed data. This parameter can take one of three forms.
1395
1396=over 5
1397
1398=item A filename
1399
1400If the C<$input> parameter is a scalar, it is assumed to be a filename. This
1401file will be opened for reading and the compressed data will be read from it.
1402
1403=item A filehandle
1404
1405If the C<$input> parameter is a filehandle, the compressed data will be
1406read from it.
1407The string '-' can be used as an alias for standard input.
1408
1409=item A scalar reference
1410
1411If C<$input> is a scalar reference, the compressed data will be read from
1412C<$$input>.
1413
1414=back
1415
1416=head2 Constructor Options
1417
1418The option names defined below are case insensitive and can be optionally
1419prefixed by a '-'.  So all of the following are valid
1420
1421    -AutoClose
1422    -autoclose
1423    AUTOCLOSE
1424    autoclose
1425
1426OPTS is a combination of the following options:
1427
1428=over 5
1429
1430=item C<< Name => "membername" >>
1431
1432Open "membername" from the zip file for reading.
1433
1434=item C<< AutoClose => 0|1 >>
1435
1436This option is only valid when the C<$input> parameter is a filehandle. If
1437specified, and the value is true, it will result in the file being closed once
1438either the C<close> method is called or the IO::Uncompress::Unzip object is
1439destroyed.
1440
1441This parameter defaults to 0.
1442
1443=item C<< MultiStream => 0|1 >>
1444
1445Treats the complete zip file/buffer as a single compressed data
1446stream. When reading in multi-stream mode each member of the zip
1447file/buffer will be uncompressed in turn until the end of the file/buffer
1448is encountered.
1449
1450This parameter defaults to 0.
1451
1452=item C<< Prime => $string >>
1453
1454This option will uncompress the contents of C<$string> before processing the
1455input file/buffer.
1456
1457This option can be useful when the compressed data is embedded in another
1458file/data structure and it is not possible to work out where the compressed
1459data begins without having to read the first few bytes. If this is the
1460case, the uncompression can be I<primed> with these bytes using this
1461option.
1462
1463=item C<< Transparent => 0|1 >>
1464
1465If this option is set and the input file/buffer is not compressed data,
1466the module will allow reading of it anyway.
1467
1468In addition, if the input file/buffer does contain compressed data and
1469there is non-compressed data immediately following it, setting this option
1470will make this module treat the whole file/buffer as a single data stream.
1471
1472This option defaults to 1.
1473
1474=item C<< BlockSize => $num >>
1475
1476When reading the compressed input data, IO::Uncompress::Unzip will read it in
1477blocks of C<$num> bytes.
1478
1479This option defaults to 4096.
1480
1481=item C<< InputLength => $size >>
1482
1483When present this option will limit the number of compressed bytes read
1484from the input file/buffer to C<$size>. This option can be used in the
1485situation where there is useful data directly after the compressed data
1486stream and you know beforehand the exact length of the compressed data
1487stream.
1488
1489This option is mostly used when reading from a filehandle, in which case
1490the file pointer will be left pointing to the first byte directly after the
1491compressed data stream.
1492
1493This option defaults to off.
1494
1495=item C<< Append => 0|1 >>
1496
1497This option controls what the C<read> method does with uncompressed data.
1498
1499If set to 1, all uncompressed data will be appended to the output parameter
1500of the C<read> method.
1501
1502If set to 0, the contents of the output parameter of the C<read> method
1503will be overwritten by the uncompressed data.
1504
1505Defaults to 0.
1506
1507=item C<< Strict => 0|1 >>
1508
1509This option controls whether the extra checks defined below are used when
1510carrying out the decompression. When Strict is on, the extra tests are
1511carried out, when Strict is off they are not.
1512
1513The default for this option is off.
1514
1515=back
1516
1517=head2 Examples
1518
1519TODO
1520
1521=head1 Methods
1522
1523=head2 read
1524
1525Usage is
1526
1527    $status = $z->read($buffer)
1528
1529Reads a block of compressed data (the size of the compressed block is
1530determined by the C<Buffer> option in the constructor), uncompresses it and
1531writes any uncompressed data into C<$buffer>. If the C<Append> parameter is
1532set in the constructor, the uncompressed data will be appended to the
1533C<$buffer> parameter. Otherwise C<$buffer> will be overwritten.
1534
1535Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1536or a negative number on error.
1537
1538=head2 read
1539
1540Usage is
1541
1542    $status = $z->read($buffer, $length)
1543    $status = $z->read($buffer, $length, $offset)
1544
1545    $status = read($z, $buffer, $length)
1546    $status = read($z, $buffer, $length, $offset)
1547
1548Attempt to read C<$length> bytes of uncompressed data into C<$buffer>.
1549
1550The main difference between this form of the C<read> method and the
1551previous one, is that this one will attempt to return I<exactly> C<$length>
1552bytes. The only circumstances that this function will not is if end-of-file
1553or an IO error is encountered.
1554
1555Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1556or a negative number on error.
1557
1558=head2 getline
1559
1560Usage is
1561
1562    $line = $z->getline()
1563    $line = <$z>
1564
1565Reads a single line.
1566
1567This method fully supports the use of the variable C<$/> (or
1568C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use) to
1569determine what constitutes an end of line. Paragraph mode, record mode and
1570file slurp mode are all supported.
1571
1572=head2 getc
1573
1574Usage is
1575
1576    $char = $z->getc()
1577
1578Read a single character.
1579
1580=head2 ungetc
1581
1582Usage is
1583
1584    $char = $z->ungetc($string)
1585
1586=head2 inflateSync
1587
1588Usage is
1589
1590    $status = $z->inflateSync()
1591
1592TODO
1593
1594=head2 getHeaderInfo
1595
1596Usage is
1597
1598    $hdr  = $z->getHeaderInfo();
1599    @hdrs = $z->getHeaderInfo();
1600
1601This method returns either a hash reference (in scalar context) or a list
1602or hash references (in array context) that contains information about each
1603of the header fields in the compressed data stream(s).
1604
1605=head2 tell
1606
1607Usage is
1608
1609    $z->tell()
1610    tell $z
1611
1612Returns the uncompressed file offset.
1613
1614=head2 eof
1615
1616Usage is
1617
1618    $z->eof();
1619    eof($z);
1620
1621Returns true if the end of the compressed input stream has been reached.
1622
1623=head2 seek
1624
1625    $z->seek($position, $whence);
1626    seek($z, $position, $whence);
1627
1628Provides a sub-set of the C<seek> functionality, with the restriction
1629that it is only legal to seek forward in the input file/buffer.
1630It is a fatal error to attempt to seek backward.
1631
1632Note that the implementation of C<seek> in this module does not provide
1633true random access to a compressed file/buffer. It  works by uncompressing
1634data from the current offset in the file/buffer until it reaches the
1635uncompressed offset specified in the parameters to C<seek>. For very small
1636files this may be acceptable behaviour. For large files it may cause an
1637unacceptable delay.
1638
1639The C<$whence> parameter takes one the usual values, namely SEEK_SET,
1640SEEK_CUR or SEEK_END.
1641
1642Returns 1 on success, 0 on failure.
1643
1644=head2 binmode
1645
1646Usage is
1647
1648    $z->binmode
1649    binmode $z ;
1650
1651This is a noop provided for completeness.
1652
1653=head2 opened
1654
1655    $z->opened()
1656
1657Returns true if the object currently refers to a opened file/buffer.
1658
1659=head2 autoflush
1660
1661    my $prev = $z->autoflush()
1662    my $prev = $z->autoflush(EXPR)
1663
1664If the C<$z> object is associated with a file or a filehandle, this method
1665returns the current autoflush setting for the underlying filehandle. If
1666C<EXPR> is present, and is non-zero, it will enable flushing after every
1667write/print operation.
1668
1669If C<$z> is associated with a buffer, this method has no effect and always
1670returns C<undef>.
1671
1672B<Note> that the special variable C<$|> B<cannot> be used to set or
1673retrieve the autoflush setting.
1674
1675=head2 input_line_number
1676
1677    $z->input_line_number()
1678    $z->input_line_number(EXPR)
1679
1680Returns the current uncompressed line number. If C<EXPR> is present it has
1681the effect of setting the line number. Note that setting the line number
1682does not change the current position within the file/buffer being read.
1683
1684The contents of C<$/> are used to determine what constitutes a line
1685terminator.
1686
1687=head2 fileno
1688
1689    $z->fileno()
1690    fileno($z)
1691
1692If the C<$z> object is associated with a file or a filehandle, C<fileno>
1693will return the underlying file descriptor. Once the C<close> method is
1694called C<fileno> will return C<undef>.
1695
1696If the C<$z> object is associated with a buffer, this method will return
1697C<undef>.
1698
1699=head2 close
1700
1701    $z->close() ;
1702    close $z ;
1703
1704Closes the output file/buffer.
1705
1706For most versions of Perl this method will be automatically invoked if
1707the IO::Uncompress::Unzip object is destroyed (either explicitly or by the
1708variable with the reference to the object going out of scope). The
1709exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
1710these cases, the C<close> method will be called automatically, but
1711not until global destruction of all live objects when the program is
1712terminating.
1713
1714Therefore, if you want your scripts to be able to run on all versions
1715of Perl, you should call C<close> explicitly and not rely on automatic
1716closing.
1717
1718Returns true on success, otherwise 0.
1719
1720If the C<AutoClose> option has been enabled when the IO::Uncompress::Unzip
1721object was created, and the object is associated with a file, the
1722underlying file will also be closed.
1723
1724=head2 nextStream
1725
1726Usage is
1727
1728    my $status = $z->nextStream();
1729
1730Skips to the next compressed data stream in the input file/buffer. If a new
1731compressed data stream is found, the eof marker will be cleared and C<$.>
1732will be reset to 0.
1733
1734Returns 1 if a new stream was found, 0 if none was found, and -1 if an
1735error was encountered.
1736
1737=head2 trailingData
1738
1739Usage is
1740
1741    my $data = $z->trailingData();
1742
1743Returns the data, if any, that is present immediately after the compressed
1744data stream once uncompression is complete. It only makes sense to call
1745this method once the end of the compressed data stream has been
1746encountered.
1747
1748This option can be used when there is useful information immediately
1749following the compressed data stream, and you don't know the length of the
1750compressed data stream.
1751
1752If the input is a buffer, C<trailingData> will return everything from the
1753end of the compressed data stream to the end of the buffer.
1754
1755If the input is a filehandle, C<trailingData> will return the data that is
1756left in the filehandle input buffer once the end of the compressed data
1757stream has been reached. You can then use the filehandle to read the rest
1758of the input file.
1759
1760Don't bother using C<trailingData> if the input is a filename.
1761
1762If you know the length of the compressed data stream before you start
1763uncompressing, you can avoid having to use C<trailingData> by setting the
1764C<InputLength> option in the constructor.
1765
1766=head1 Importing
1767
1768No symbolic constants are required by this IO::Uncompress::Unzip at present.
1769
1770=over 5
1771
1772=item :all
1773
1774Imports C<unzip> and C<$UnzipError>.
1775Same as doing this
1776
1777    use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1778
1779=back
1780
1781=head1 EXAMPLES
1782
1783=head2 Working with Net::FTP
1784
1785See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP">
1786
1787=head2 Walking through a zip file
1788
1789The code below can be used to traverse a zip file, one compressed data
1790stream at a time.
1791
1792    use IO::Uncompress::Unzip qw($UnzipError);
1793
1794    my $zipfile = "somefile.zip";
1795    my $u = new IO::Uncompress::Unzip $zipfile
1796        or die "Cannot open $zipfile: $UnzipError";
1797
1798    my $status;
1799    for ($status = 1; $status > 0; $status = $u->nextStream())
1800    {
1801
1802        my $name = $u->getHeaderInfo()->{Name};
1803        warn "Processing member $name\n" ;
1804
1805        my $buff;
1806        while (($status = $u->read($buff)) > 0) {
1807            # Do something here
1808        }
1809
1810        last if $status < 0;
1811    }
1812
1813    die "Error processing $zipfile: $!\n"
1814        if $status < 0 ;
1815
1816Each individual compressed data stream is read until the logical
1817end-of-file is reached. Then C<nextStream> is called. This will skip to the
1818start of the next compressed data stream and clear the end-of-file flag.
1819
1820It is also worth noting that C<nextStream> can be called at any time -- you
1821don't have to wait until you have exhausted a compressed data stream before
1822skipping to the next one.
1823
1824=head2 Unzipping a complete zip file to disk
1825
1826Daniel S. Sterling has written a script that uses C<IO::Uncompress::UnZip>
1827to read a zip file and unzip its contents to disk.
1828
1829The script is available from L<https://gist.github.com/eqhmcow/5389877>
1830
1831=head1 SEE ALSO
1832
1833L<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::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
1834
1835L<IO::Compress::FAQ|IO::Compress::FAQ>
1836
1837L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
1838L<Archive::Tar|Archive::Tar>,
1839L<IO::Zlib|IO::Zlib>
1840
1841For RFC 1950, 1951 and 1952 see
1842F<http://www.faqs.org/rfcs/rfc1950.html>,
1843F<http://www.faqs.org/rfcs/rfc1951.html> and
1844F<http://www.faqs.org/rfcs/rfc1952.html>
1845
1846The I<zlib> compression library was written by Jean-loup Gailly
1847F<gzip@prep.ai.mit.edu> and Mark Adler F<madler@alumni.caltech.edu>.
1848
1849The primary site for the I<zlib> compression library is
1850F<http://www.zlib.org>.
1851
1852The primary site for gzip is F<http://www.gzip.org>.
1853
1854=head1 AUTHOR
1855
1856This module was written by Paul Marquess, F<pmqs@cpan.org>.
1857
1858=head1 MODIFICATION HISTORY
1859
1860See the Changes file.
1861
1862=head1 COPYRIGHT AND LICENSE
1863
1864Copyright (c) 2005-2014 Paul Marquess. All rights reserved.
1865
1866This program is free software; you can redistribute it and/or
1867modify it under the same terms as Perl itself.
1868
1869