Document when as a syntax modifier
[p5sagit/p5-mst-13.2.git] / ext / IO-Compress / lib / IO / Uncompress / Unzip.pm
CommitLineData
a02d0f6f 1package IO::Uncompress::Unzip;
2
3require 5.004 ;
4
5# for RFC1952
6
7use strict ;
8use warnings;
9use bytes;
10
319fab50 11use IO::Uncompress::RawInflate 2.017 ;
12use IO::Compress::Base::Common 2.017 qw(:Status createSelfTiedObject);
13use IO::Uncompress::Adapter::Inflate 2.017 ;
14use IO::Uncompress::Adapter::Identity 2.017 ;
15use IO::Compress::Zlib::Extra 2.017 ;
16use IO::Compress::Zip::Constants 2.017 ;
a02d0f6f 17
319fab50 18use Compress::Raw::Zlib 2.017 qw(crc32) ;
c70c1701 19
2b4e0969 20BEGIN
21{
c70c1701 22 eval { require IO::Uncompress::Adapter::Bunzip2 ;
23 import IO::Uncompress::Adapter::Bunzip2 } ;
319fab50 24 #eval { require IO::Uncompress::Adapter::UnLzma ;
25 # import IO::Uncompress::Adapter::UnLzma } ;
2b4e0969 26}
27
28
a02d0f6f 29require Exporter ;
30
e7d45986 31our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
a02d0f6f 32
319fab50 33$VERSION = '2.017';
a02d0f6f 34$UnzipError = '';
35
36@ISA = qw(Exporter IO::Uncompress::RawInflate);
37@EXPORT_OK = qw( $UnzipError unzip );
38%EXPORT_TAGS = %IO::Uncompress::RawInflate::EXPORT_TAGS ;
39push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
40Exporter::export_ok_tags('all');
41
e7d45986 42%headerLookup = (
43 ZIP_CENTRAL_HDR_SIG, \&skipCentralDirectory,
44 ZIP_END_CENTRAL_HDR_SIG, \&skipEndCentralDirectory,
45 ZIP64_END_CENTRAL_REC_HDR_SIG, \&skipCentralDirectory64Rec,
46 ZIP64_END_CENTRAL_LOC_HDR_SIG, \&skipCentralDirectory64Loc,
47 ZIP64_ARCHIVE_EXTRA_SIG, \&skipArchiveExtra,
48 ZIP64_DIGITAL_SIGNATURE_SIG, \&skipDigitalSignature,
49 );
50
a02d0f6f 51sub new
52{
53 my $class = shift ;
54 my $obj = createSelfTiedObject($class, \$UnzipError);
55 $obj->_create(undef, 0, @_);
56}
57
58sub unzip
59{
60 my $obj = createSelfTiedObject(undef, \$UnzipError);
61 return $obj->_inf(@_) ;
62}
63
64sub getExtraParams
65{
319fab50 66 use IO::Compress::Base::Common 2.017 qw(:Parse);
a02d0f6f 67
68
69 return (
70# # Zip header fields
71 'Name' => [1, 1, Parse_any, undef],
72
73# 'Streaming' => [1, 1, Parse_boolean, 1],
74 );
75}
76
77sub ckParams
78{
79 my $self = shift ;
80 my $got = shift ;
81
82 # unzip always needs crc32
83 $got->value('CRC32' => 1);
84
85 *$self->{UnzipData}{Name} = $got->value('Name');
86
87 return 1;
88}
89
a1787f24 90sub mkUncomp
91{
92 my $self = shift ;
93 my $got = shift ;
94
95 my $magic = $self->ckMagic()
96 or return 0;
97
98 *$self->{Info} = $self->readHeader($magic)
99 or return undef ;
100
101 return 1;
102
103}
a02d0f6f 104
105sub ckMagic
106{
107 my $self = shift;
108
109 my $magic ;
110 $self->smartReadExact(\$magic, 4);
111
112 *$self->{HeaderPending} = $magic ;
113
114 return $self->HeaderError("Minimum header size is " .
115 4 . " bytes")
116 if length $magic != 4 ;
117
118 return $self->HeaderError("Bad Magic")
119 if ! _isZipMagic($magic) ;
120
121 *$self->{Type} = 'zip';
122
123 return $magic ;
124}
125
126
127
128sub readHeader
129{
130 my $self = shift;
131 my $magic = shift ;
132
133 my $name = *$self->{UnzipData}{Name} ;
134 my $hdr = $self->_readZipHeader($magic) ;
135
136 while (defined $hdr)
137 {
138 if (! defined $name || $hdr->{Name} eq $name)
139 {
140 return $hdr ;
141 }
142
143 # skip the data
144 my $buffer;
145 if (*$self->{ZipData}{Streaming}) {
146
147 while (1) {
148
149 my $b;
150 my $status = $self->smartRead(\$b, 1024 * 16);
151 return undef
152 if $status <= 0 ;
153
154 my $temp_buf;
155 my $out;
156 $status = *$self->{Uncomp}->uncompr(\$b, \$temp_buf, 0, $out);
157
158 return $self->saveErrorString(undef, *$self->{Uncomp}{Error},
159 *$self->{Uncomp}{ErrorNo})
160 if $self->saveStatus($status) == STATUS_ERROR;
161
162 if ($status == STATUS_ENDSTREAM) {
163 *$self->{Uncomp}->reset();
164 $self->pushBack($b) ;
165 last;
166 }
167 }
168
169 # skip the trailer
170 $self->smartReadExact(\$buffer, $hdr->{TrailerLength})
171 or return $self->saveErrorString(undef, "Truncated file");
172 }
173 else {
e7d45986 174 my $c = $hdr->{CompressedLength}->get32bit();
a02d0f6f 175 $self->smartReadExact(\$buffer, $c)
176 or return $self->saveErrorString(undef, "Truncated file");
177 $buffer = '';
178 }
179
180 $self->chkTrailer($buffer) == STATUS_OK
181 or return $self->saveErrorString(undef, "Truncated file");
182
183 $hdr = $self->_readFullZipHeader();
184
185 return $self->saveErrorString(undef, "Cannot find '$name'")
186 if $self->smartEof();
187 }
188
189 return undef;
190}
191
192sub chkTrailer
193{
194 my $self = shift;
195 my $trailer = shift;
196
197 my ($sig, $CRC32, $cSize, $uSize) ;
e7d45986 198 my ($cSizeHi, $uSizeHi) = (0, 0);
a02d0f6f 199 if (*$self->{ZipData}{Streaming}) {
e7d45986 200 $sig = unpack ("V", substr($trailer, 0, 4));
201 $CRC32 = unpack ("V", substr($trailer, 4, 4));
202
203 if (*$self->{ZipData}{Zip64} ) {
204 $cSize = U64::newUnpack_V64 substr($trailer, 8, 8);
205 $uSize = U64::newUnpack_V64 substr($trailer, 16, 8);
206 }
207 else {
208 $cSize = U64::newUnpack_V32 substr($trailer, 8, 4);
209 $uSize = U64::newUnpack_V32 substr($trailer, 12, 4);
210 }
211
a02d0f6f 212 return $self->TrailerError("Data Descriptor signature, got $sig")
c70c1701 213 if $sig != ZIP_DATA_HDR_SIG;
a02d0f6f 214 }
215 else {
216 ($CRC32, $cSize, $uSize) =
217 (*$self->{ZipData}{Crc32},
218 *$self->{ZipData}{CompressedLen},
219 *$self->{ZipData}{UnCompressedLen});
220 }
221
222 if (*$self->{Strict}) {
2b4e0969 223 return $self->TrailerError("CRC mismatch")
224 if $CRC32 != *$self->{ZipData}{CRC32} ;
a02d0f6f 225
e7d45986 226 return $self->TrailerError("CSIZE mismatch.")
227 if ! $cSize->equal(*$self->{CompSize});
a02d0f6f 228
e7d45986 229 return $self->TrailerError("USIZE mismatch.")
230 if ! $uSize->equal(*$self->{UnCompSize});
a02d0f6f 231 }
232
233 my $reachedEnd = STATUS_ERROR ;
234 # check for central directory or end of central directory
235 while (1)
236 {
237 my $magic ;
238 my $got = $self->smartRead(\$magic, 4);
239
240 return $self->saveErrorString(STATUS_ERROR, "Truncated file")
241 if $got != 4 && *$self->{Strict};
242
243 if ($got == 0) {
244 return STATUS_EOF ;
245 }
246 elsif ($got < 0) {
247 return STATUS_ERROR ;
248 }
249 elsif ($got < 4) {
250 $self->pushBack($magic) ;
251 return STATUS_OK ;
252 }
253
254 my $sig = unpack("V", $magic) ;
255
258133d1 256 my $hdr;
257 if ($hdr = $headerLookup{$sig})
a02d0f6f 258 {
258133d1 259 if (&$hdr($self, $magic) != STATUS_OK ) {
a02d0f6f 260 if (*$self->{Strict}) {
261 return STATUS_ERROR ;
262 }
263 else {
264 $self->clearError();
265 return STATUS_OK ;
266 }
267 }
e7d45986 268
269 if ($sig == ZIP_END_CENTRAL_HDR_SIG)
270 {
271 return STATUS_OK ;
272 last;
a02d0f6f 273 }
a02d0f6f 274 }
c70c1701 275 elsif ($sig == ZIP_LOCAL_HDR_SIG)
a02d0f6f 276 {
277 $self->pushBack($magic) ;
278 return STATUS_OK ;
279 }
280 else
281 {
282 # put the data back
283 $self->pushBack($magic) ;
284 last;
285 }
286 }
287
288 return $reachedEnd ;
289}
290
291sub skipCentralDirectory
292{
293 my $self = shift;
294 my $magic = shift ;
295
296 my $buffer;
297 $self->smartReadExact(\$buffer, 46 - 4)
298 or return $self->TrailerError("Minimum header size is " .
299 46 . " bytes") ;
300
301 my $keep = $magic . $buffer ;
302 *$self->{HeaderPending} = $keep ;
303
304 #my $versionMadeBy = unpack ("v", substr($buffer, 4-4, 2));
305 #my $extractVersion = unpack ("v", substr($buffer, 6-4, 2));
306 #my $gpFlag = unpack ("v", substr($buffer, 8-4, 2));
307 #my $compressedMethod = unpack ("v", substr($buffer, 10-4, 2));
308 #my $lastModTime = unpack ("V", substr($buffer, 12-4, 4));
309 #my $crc32 = unpack ("V", substr($buffer, 16-4, 4));
e7d45986 310 my $compressedLength = unpack ("V", substr($buffer, 20-4, 4));
311 my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4));
a02d0f6f 312 my $filename_length = unpack ("v", substr($buffer, 28-4, 2));
313 my $extra_length = unpack ("v", substr($buffer, 30-4, 2));
314 my $comment_length = unpack ("v", substr($buffer, 32-4, 2));
315 #my $disk_start = unpack ("v", substr($buffer, 34-4, 2));
316 #my $int_file_attrib = unpack ("v", substr($buffer, 36-4, 2));
317 #my $ext_file_attrib = unpack ("V", substr($buffer, 38-4, 2));
318 #my $lcl_hdr_offset = unpack ("V", substr($buffer, 42-4, 2));
319
320
321 my $filename;
322 my $extraField;
323 my $comment ;
324 if ($filename_length)
325 {
326 $self->smartReadExact(\$filename, $filename_length)
2b4e0969 327 or return $self->TruncatedTrailer("filename");
a02d0f6f 328 $keep .= $filename ;
329 }
330
331 if ($extra_length)
332 {
333 $self->smartReadExact(\$extraField, $extra_length)
2b4e0969 334 or return $self->TruncatedTrailer("extra");
a02d0f6f 335 $keep .= $extraField ;
336 }
337
338 if ($comment_length)
339 {
340 $self->smartReadExact(\$comment, $comment_length)
2b4e0969 341 or return $self->TruncatedTrailer("comment");
a02d0f6f 342 $keep .= $comment ;
343 }
344
345 return STATUS_OK ;
346}
347
e7d45986 348sub skipArchiveExtra
349{
350 my $self = shift;
351 my $magic = shift ;
352
353 my $buffer;
354 $self->smartReadExact(\$buffer, 4)
355 or return $self->TrailerError("Minimum header size is " .
356 4 . " bytes") ;
357
358 my $keep = $magic . $buffer ;
359
360 my $size = unpack ("V", $buffer);
361
362 $self->smartReadExact(\$buffer, $size)
363 or return $self->TrailerError("Minimum header size is " .
364 $size . " bytes") ;
365
366 $keep .= $buffer ;
367 *$self->{HeaderPending} = $keep ;
368
369 return STATUS_OK ;
370}
371
372
373sub skipCentralDirectory64Rec
374{
375 my $self = shift;
376 my $magic = shift ;
377
378 my $buffer;
379 $self->smartReadExact(\$buffer, 8)
380 or return $self->TrailerError("Minimum header size is " .
381 8 . " bytes") ;
382
383 my $keep = $magic . $buffer ;
384
385 my ($sizeLo, $sizeHi) = unpack ("V V", $buffer);
386
387 # TODO - take SizeHi into account
388 $self->smartReadExact(\$buffer, $sizeLo)
389 or return $self->TrailerError("Minimum header size is " .
390 $sizeLo . " bytes") ;
391
392 $keep .= $buffer ;
393 *$self->{HeaderPending} = $keep ;
394
395 #my $versionMadeBy = unpack ("v", substr($buffer, 0, 2));
396 #my $extractVersion = unpack ("v", substr($buffer, 2, 2));
397 #my $diskNumber = unpack ("V", substr($buffer, 4, 4));
398 #my $cntrlDirDiskNo = unpack ("V", substr($buffer, 8, 4));
399 #my $entriesInThisCD = unpack ("V V", substr($buffer, 12, 8));
400 #my $entriesInCD = unpack ("V V", substr($buffer, 20, 8));
401 #my $sizeOfCD = unpack ("V V", substr($buffer, 28, 8));
402 #my $offsetToCD = unpack ("V V", substr($buffer, 36, 8));
403
404 return STATUS_OK ;
405}
406
407sub skipCentralDirectory64Loc
408{
409 my $self = shift;
410 my $magic = shift ;
411
412 my $buffer;
413 $self->smartReadExact(\$buffer, 20 - 4)
414 or return $self->TrailerError("Minimum header size is " .
415 20 . " bytes") ;
416
417 my $keep = $magic . $buffer ;
418 *$self->{HeaderPending} = $keep ;
419
420 #my $startCdDisk = unpack ("V", substr($buffer, 4-4, 4));
421 #my $offsetToCD = unpack ("V V", substr($buffer, 8-4, 8));
422 #my $diskCount = unpack ("V", substr($buffer, 16-4, 4));
423
424 return STATUS_OK ;
425}
426
a02d0f6f 427sub skipEndCentralDirectory
428{
429 my $self = shift;
430 my $magic = shift ;
431
432 my $buffer;
433 $self->smartReadExact(\$buffer, 22 - 4)
434 or return $self->TrailerError("Minimum header size is " .
435 22 . " bytes") ;
436
437 my $keep = $magic . $buffer ;
438 *$self->{HeaderPending} = $keep ;
439
440 #my $diskNumber = unpack ("v", substr($buffer, 4-4, 2));
441 #my $cntrlDirDiskNo = unpack ("v", substr($buffer, 6-4, 2));
442 #my $entriesInThisCD = unpack ("v", substr($buffer, 8-4, 2));
443 #my $entriesInCD = unpack ("v", substr($buffer, 10-4, 2));
444 #my $sizeOfCD = unpack ("V", substr($buffer, 12-4, 2));
445 #my $offsetToCD = unpack ("V", substr($buffer, 16-4, 2));
446 my $comment_length = unpack ("v", substr($buffer, 20-4, 2));
447
448
449 my $comment ;
450 if ($comment_length)
451 {
452 $self->smartReadExact(\$comment, $comment_length)
2b4e0969 453 or return $self->TruncatedTrailer("comment");
a02d0f6f 454 $keep .= $comment ;
455 }
456
457 return STATUS_OK ;
458}
459
460
a02d0f6f 461sub _isZipMagic
462{
463 my $buffer = shift ;
464 return 0 if length $buffer < 4 ;
465 my $sig = unpack("V", $buffer) ;
c70c1701 466 return $sig == ZIP_LOCAL_HDR_SIG ;
a02d0f6f 467}
468
469
470sub _readFullZipHeader($)
471{
472 my ($self) = @_ ;
473 my $magic = '' ;
474
475 $self->smartReadExact(\$magic, 4);
476
477 *$self->{HeaderPending} = $magic ;
478
479 return $self->HeaderError("Minimum header size is " .
480 30 . " bytes")
481 if length $magic != 4 ;
482
483
484 return $self->HeaderError("Bad Magic")
485 if ! _isZipMagic($magic) ;
486
487 my $status = $self->_readZipHeader($magic);
488 delete *$self->{Transparent} if ! defined $status ;
489 return $status ;
490}
491
492sub _readZipHeader($)
493{
494 my ($self, $magic) = @_ ;
495 my ($HeaderCRC) ;
496 my ($buffer) = '' ;
497
498 $self->smartReadExact(\$buffer, 30 - 4)
499 or return $self->HeaderError("Minimum header size is " .
500 30 . " bytes") ;
501
502 my $keep = $magic . $buffer ;
503 *$self->{HeaderPending} = $keep ;
504
505 my $extractVersion = unpack ("v", substr($buffer, 4-4, 2));
506 my $gpFlag = unpack ("v", substr($buffer, 6-4, 2));
507 my $compressedMethod = unpack ("v", substr($buffer, 8-4, 2));
508 my $lastModTime = unpack ("V", substr($buffer, 10-4, 4));
509 my $crc32 = unpack ("V", substr($buffer, 14-4, 4));
e7d45986 510 my $compressedLength = new U64 unpack ("V", substr($buffer, 18-4, 4));
511 my $uncompressedLength = new U64 unpack ("V", substr($buffer, 22-4, 4));
a02d0f6f 512 my $filename_length = unpack ("v", substr($buffer, 26-4, 2));
513 my $extra_length = unpack ("v", substr($buffer, 28-4, 2));
514
515 my $filename;
516 my $extraField;
c70c1701 517 my @EXTRA = ();
518 my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ;
a02d0f6f 519
520 return $self->HeaderError("Streamed Stored content not supported")
521 if $streamingMode && $compressedMethod == 0 ;
522
258133d1 523 return $self->HeaderError("Encrypted content not supported")
524 if $gpFlag & (ZIP_GP_FLAG_ENCRYPTED_MASK|ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK);
525
526 return $self->HeaderError("Patch content not supported")
527 if $gpFlag & ZIP_GP_FLAG_PATCHED_MASK;
528
a02d0f6f 529 *$self->{ZipData}{Streaming} = $streamingMode;
530
a02d0f6f 531
532 if ($filename_length)
533 {
534 $self->smartReadExact(\$filename, $filename_length)
c70c1701 535 or return $self->TruncatedHeader("Filename");
a02d0f6f 536 $keep .= $filename ;
537 }
538
e7d45986 539 my $zip64 = 0 ;
540
a02d0f6f 541 if ($extra_length)
542 {
543 $self->smartReadExact(\$extraField, $extra_length)
c70c1701 544 or return $self->TruncatedHeader("Extra Field");
545
546 my $bad = IO::Compress::Zlib::Extra::parseRawExtra($extraField,
547 \@EXTRA, 1, 0);
548 return $self->HeaderError($bad)
549 if defined $bad;
550
a02d0f6f 551 $keep .= $extraField ;
e7d45986 552
553 my %Extra ;
554 for (@EXTRA)
555 {
556 $Extra{$_->[0]} = \$_->[1];
557 }
558
559 if (defined $Extra{ZIP_EXTRA_ID_ZIP64()})
560 {
561 $zip64 = 1 ;
562
563 my $buff = ${ $Extra{ZIP_EXTRA_ID_ZIP64()} };
564
258133d1 565 # TODO - This code assumes that all the fields in the Zip64
566 # extra field aren't necessarily present. The spec says that
567 # they only exist if the equivalent local headers are -1.
568 # Need to check that info-zip fills out -1 in the local header
569 # correctly.
570
571 if (! $streamingMode) {
572 my $offset = 0 ;
573
574 $uncompressedLength = U64::newUnpack_V64 substr($buff, 0, 8)
575 if $uncompressedLength == 0xFFFF ;
576
577 $offset += 8 ;
578
579 $compressedLength = U64::newUnpack_V64 substr($buff, $offset, 8)
580 if $compressedLength == 0xFFFF ;
581
582 $offset += 8 ;
583
584 #my $cheaderOffset = U64::newUnpack_V64 substr($buff, 16, 8);
585 #my $diskNumber = unpack ("V", substr($buff, 24, 4));
586 }
e7d45986 587 }
588 }
589
590 *$self->{ZipData}{Zip64} = $zip64;
591
592 if (! $streamingMode) {
593 *$self->{ZipData}{Streaming} = 0;
594 *$self->{ZipData}{Crc32} = $crc32;
595 *$self->{ZipData}{CompressedLen} = $compressedLength;
596 *$self->{ZipData}{UnCompressedLen} = $uncompressedLength;
597 *$self->{CompressedInputLengthRemaining} =
598 *$self->{CompressedInputLength} = $compressedLength->get32bit();
a02d0f6f 599 }
600
2b4e0969 601 *$self->{ZipData}{Method} = $compressedMethod;
c70c1701 602 if ($compressedMethod == ZIP_CM_DEFLATE)
a02d0f6f 603 {
2b4e0969 604 *$self->{Type} = 'zip-deflate';
a1787f24 605 my $obj = IO::Uncompress::Adapter::Inflate::mkUncompObject(1,0,0);
606
607 *$self->{Uncomp} = $obj;
608 *$self->{ZipData}{CRC32} = crc32(undef);
2b4e0969 609 }
c70c1701 610 elsif ($compressedMethod == ZIP_CM_BZIP2)
2b4e0969 611 {
a1787f24 612 return $self->HeaderError("Unsupported Compression format $compressedMethod")
613 if ! defined $IO::Uncompress::Adapter::Bunzip2::VERSION ;
2b4e0969 614
615 *$self->{Type} = 'zip-bzip2';
616
a1787f24 617 my $obj = IO::Uncompress::Adapter::Bunzip2::mkUncompObject();
2b4e0969 618
619 *$self->{Uncomp} = $obj;
620 *$self->{ZipData}{CRC32} = crc32(undef);
a02d0f6f 621 }
319fab50 622# elsif ($compressedMethod == ZIP_CM_LZMA)
623# {
624# return $self->HeaderError("Unsupported Compression format $compressedMethod")
625# if ! defined $IO::Uncompress::Adapter::UnLzma::VERSION ;
626#
627# *$self->{Type} = 'zip-lzma';
628#
629# my $obj = IO::Uncompress::Adapter::UnLzma::mkUncompObject();
630#
631# *$self->{Uncomp} = $obj;
632# *$self->{ZipData}{CRC32} = crc32(undef);
633# }
c70c1701 634 elsif ($compressedMethod == ZIP_CM_STORE)
a02d0f6f 635 {
636 # TODO -- add support for reading uncompressed
637
2b4e0969 638 *$self->{Type} = 'zip-stored';
a02d0f6f 639
a1787f24 640 my $obj = IO::Uncompress::Adapter::Identity::mkUncompObject();
a02d0f6f 641
642 *$self->{Uncomp} = $obj;
a02d0f6f 643 }
644 else
645 {
646 return $self->HeaderError("Unsupported Compression format $compressedMethod");
647 }
648
649 return {
650 'Type' => 'zip',
651 'FingerprintLength' => 4,
652 #'HeaderLength' => $compressedMethod == 8 ? length $keep : 0,
653 'HeaderLength' => length $keep,
e7d45986 654 'Zip64' => $zip64,
655 'TrailerLength' => ! $streamingMode ? 0 : $zip64 ? 24 : 16,
a02d0f6f 656 'Header' => $keep,
657 'CompressedLength' => $compressedLength ,
658 'UncompressedLength' => $uncompressedLength ,
659 'CRC32' => $crc32 ,
660 'Name' => $filename,
661 'Time' => _dosToUnixTime($lastModTime),
662 'Stream' => $streamingMode,
663
664 'MethodID' => $compressedMethod,
c70c1701 665 'MethodName' => $compressedMethod == ZIP_CM_DEFLATE
a02d0f6f 666 ? "Deflated"
c70c1701 667 : $compressedMethod == ZIP_CM_BZIP2
668 ? "Bzip2"
669 : $compressedMethod == ZIP_CM_STORE
670 ? "Stored"
671 : "Unknown" ,
a02d0f6f 672
673# 'TextFlag' => $flag & GZIP_FLG_FTEXT ? 1 : 0,
674# 'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
675# 'NameFlag' => $flag & GZIP_FLG_FNAME ? 1 : 0,
676# 'CommentFlag' => $flag & GZIP_FLG_FCOMMENT ? 1 : 0,
677# 'ExtraFlag' => $flag & GZIP_FLG_FEXTRA ? 1 : 0,
678# 'Comment' => $comment,
679# 'OsID' => $os,
680# 'OsName' => defined $GZIP_OS_Names{$os}
681# ? $GZIP_OS_Names{$os} : "Unknown",
682# 'HeaderCRC' => $HeaderCRC,
683# 'Flags' => $flag,
684# 'ExtraFlags' => $xfl,
c70c1701 685 'ExtraFieldRaw' => $extraField,
686 'ExtraField' => [ @EXTRA ],
a02d0f6f 687
688
689 }
690}
691
2b4e0969 692sub filterUncompressed
693{
694 my $self = shift ;
695
696 if (*$self->{ZipData}{Method} == 12) {
697 *$self->{ZipData}{CRC32} = crc32(${$_[0]}, *$self->{ZipData}{CRC32});
698 }
699 else {
700 *$self->{ZipData}{CRC32} = *$self->{Uncomp}->crc32() ;
701 }
702}
703
704
a02d0f6f 705# from Archive::Zip
706sub _dosToUnixTime
707{
708 #use Time::Local 'timelocal_nocheck';
709 use Time::Local 'timelocal';
710
711 my $dt = shift;
712
713 my $year = ( ( $dt >> 25 ) & 0x7f ) + 80;
714 my $mon = ( ( $dt >> 21 ) & 0x0f ) - 1;
715 my $mday = ( ( $dt >> 16 ) & 0x1f );
716
717 my $hour = ( ( $dt >> 11 ) & 0x1f );
718 my $min = ( ( $dt >> 5 ) & 0x3f );
719 my $sec = ( ( $dt << 1 ) & 0x3e );
720
721 # catch errors
722 my $time_t =
723 eval { timelocal( $sec, $min, $hour, $mday, $mon, $year ); };
724 return 0
725 if $@;
726 return $time_t;
727}
728
729
7301;
731
732__END__
733
734
735=head1 NAME
736
cb7abd7f 737IO::Uncompress::Unzip - Read zip files/buffers
738
a02d0f6f 739=head1 SYNOPSIS
740
741 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
742
743 my $status = unzip $input => $output [,OPTS]
744 or die "unzip failed: $UnzipError\n";
745
746 my $z = new IO::Uncompress::Unzip $input [OPTS]
747 or die "unzip failed: $UnzipError\n";
748
749 $status = $z->read($buffer)
750 $status = $z->read($buffer, $length)
751 $status = $z->read($buffer, $length, $offset)
752 $line = $z->getline()
753 $char = $z->getc()
754 $char = $z->ungetc()
755 $char = $z->opened()
756
757 $status = $z->inflateSync()
758
e7d45986 759 $data = $z->trailingData()
760 $status = $z->nextStream()
a02d0f6f 761 $data = $z->getHeaderInfo()
762 $z->tell()
763 $z->seek($position, $whence)
764 $z->binmode()
765 $z->fileno()
766 $z->eof()
767 $z->close()
768
769 $UnzipError ;
770
771 # IO::File mode
772
773 <$z>
774 read($z, $buffer);
775 read($z, $buffer, $length);
776 read($z, $buffer, $length, $offset);
777 tell($z)
778 seek($z, $position, $whence)
779 binmode($z)
780 fileno($z)
781 eof($z)
782 close($z)
783
a02d0f6f 784=head1 DESCRIPTION
785
a02d0f6f 786This module provides a Perl interface that allows the reading of
787zlib files/buffers.
788
789For writing zip files/buffers, see the companion module IO::Compress::Zip.
790
a02d0f6f 791=head1 Functional Interface
792
793A top-level function, C<unzip>, is provided to carry out
794"one-shot" uncompression between buffers and/or files. For finer
795control over the uncompression process, see the L</"OO Interface">
796section.
797
798 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
799
800 unzip $input => $output [,OPTS]
801 or die "unzip failed: $UnzipError\n";
802
a02d0f6f 803The functional interface needs Perl5.005 or better.
804
a02d0f6f 805=head2 unzip $input => $output [, OPTS]
806
a02d0f6f 807C<unzip> expects at least two parameters, C<$input> and C<$output>.
808
809=head3 The C<$input> parameter
810
811The parameter, C<$input>, is used to define the source of
812the compressed data.
813
814It can take one of the following forms:
815
816=over 5
817
818=item A filename
819
820If the C<$input> parameter is a simple scalar, it is assumed to be a
821filename. This file will be opened for reading and the input data
822will be read from it.
823
824=item A filehandle
825
826If the C<$input> parameter is a filehandle, the input data will be
827read from it.
828The string '-' can be used as an alias for standard input.
829
830=item A scalar reference
831
832If C<$input> is a scalar reference, the input data will be read
833from C<$$input>.
834
835=item An array reference
836
837If C<$input> is an array reference, each element in the array must be a
838filename.
839
840The input data will be read from each file in turn.
841
842The complete array will be walked to ensure that it only
843contains valid filenames before any data is uncompressed.
844
a02d0f6f 845=item An Input FileGlob string
846
847If C<$input> is a string that is delimited by the characters "<" and ">"
848C<unzip> will assume that it is an I<input fileglob string>. The
849input is the list of files that match the fileglob.
850
851If the fileglob does not match any files ...
852
853See L<File::GlobMapper|File::GlobMapper> for more details.
854
a02d0f6f 855=back
856
857If the C<$input> parameter is any other type, C<undef> will be returned.
858
a02d0f6f 859=head3 The C<$output> parameter
860
861The parameter C<$output> is used to control the destination of the
862uncompressed data. This parameter can take one of these forms.
863
864=over 5
865
866=item A filename
867
868If the C<$output> parameter is a simple scalar, it is assumed to be a
869filename. This file will be opened for writing and the uncompressed
870data will be written to it.
871
872=item A filehandle
873
874If the C<$output> parameter is a filehandle, the uncompressed data
875will be written to it.
876The string '-' can be used as an alias for standard output.
877
a02d0f6f 878=item A scalar reference
879
880If C<$output> is a scalar reference, the uncompressed data will be
881stored in C<$$output>.
882
a02d0f6f 883=item An Array Reference
884
885If C<$output> is an array reference, the uncompressed data will be
886pushed onto the array.
887
888=item An Output FileGlob
889
890If C<$output> is a string that is delimited by the characters "<" and ">"
891C<unzip> will assume that it is an I<output fileglob string>. The
892output is the list of files that match the fileglob.
893
894When C<$output> is an fileglob string, C<$input> must also be a fileglob
895string. Anything else is an error.
896
897=back
898
899If the C<$output> parameter is any other type, C<undef> will be returned.
900
a02d0f6f 901=head2 Notes
902
c70c1701 903When C<$input> maps to multiple compressed files/buffers and C<$output> is
904a single file/buffer, after uncompression C<$output> will contain a
905concatenation of all the uncompressed data from each of the input
906files/buffers.
907
a02d0f6f 908=head2 Optional Parameters
909
910Unless specified below, the optional parameters for C<unzip>,
911C<OPTS>, are the same as those used with the OO interface defined in the
912L</"Constructor Options"> section below.
913
914=over 5
915
e7d45986 916=item C<< AutoClose => 0|1 >>
a02d0f6f 917
918This option applies to any input or output data streams to
919C<unzip> that are filehandles.
920
921If C<AutoClose> is specified, and the value is true, it will result in all
922input and/or output filehandles being closed once C<unzip> has
923completed.
924
925This parameter defaults to 0.
926
e7d45986 927=item C<< BinModeOut => 0|1 >>
a02d0f6f 928
929When writing to a file or filehandle, set C<binmode> before writing to the
930file.
931
932Defaults to 0.
933
e7d45986 934=item C<< Append => 0|1 >>
a02d0f6f 935
936TODO
937
e7d45986 938=item C<< MultiStream => 0|1 >>
a02d0f6f 939
e7d45986 940If the input file/buffer contains multiple compressed data streams, this
941option will uncompress the whole lot as a single data stream.
a02d0f6f 942
e7d45986 943Defaults to 0.
a02d0f6f 944
258133d1 945=item C<< TrailingData => $scalar >>
946
947Returns the data, if any, that is present immediately after the compressed
948data stream once uncompression is complete.
949
950This option can be used when there is useful information immediately
951following the compressed data stream, and you don't know the length of the
952compressed data stream.
953
954If the input is a buffer, C<trailingData> will return everything from the
955end of the compressed data stream to the end of the buffer.
956
957If the input is a filehandle, C<trailingData> will return the data that is
958left in the filehandle input buffer once the end of the compressed data
959stream has been reached. You can then use the filehandle to read the rest
960of the input file.
961
962Don't bother using C<trailingData> if the input is a filename.
963
258133d1 964If you know the length of the compressed data stream before you start
965uncompressing, you can avoid having to use C<trailingData> by setting the
966C<InputLength> option.
967
a02d0f6f 968=back
969
a02d0f6f 970=head2 Examples
971
972To read the contents of the file C<file1.txt.zip> and write the
973compressed data to the file C<file1.txt>.
974
975 use strict ;
976 use warnings ;
977 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
978
979 my $input = "file1.txt.zip";
980 my $output = "file1.txt";
981 unzip $input => $output
982 or die "unzip failed: $UnzipError\n";
983
a02d0f6f 984To read from an existing Perl filehandle, C<$input>, and write the
985uncompressed data to a buffer, C<$buffer>.
986
987 use strict ;
988 use warnings ;
989 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
990 use IO::File ;
991
992 my $input = new IO::File "<file1.txt.zip"
993 or die "Cannot open 'file1.txt.zip': $!\n" ;
994 my $buffer ;
995 unzip $input => \$buffer
996 or die "unzip failed: $UnzipError\n";
997
998To uncompress all files in the directory "/my/home" that match "*.txt.zip" and store the compressed data in the same directory
999
1000 use strict ;
1001 use warnings ;
1002 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1003
1004 unzip '</my/home/*.txt.zip>' => '</my/home/#1.txt>'
1005 or die "unzip failed: $UnzipError\n";
1006
1007and if you want to compress each file one at a time, this will do the trick
1008
1009 use strict ;
1010 use warnings ;
1011 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1012
1013 for my $input ( glob "/my/home/*.txt.zip" )
1014 {
1015 my $output = $input;
1016 $output =~ s/.zip// ;
1017 unzip $input => $output
1018 or die "Error compressing '$input': $UnzipError\n";
1019 }
1020
1021=head1 OO Interface
1022
1023=head2 Constructor
1024
1025The format of the constructor for IO::Uncompress::Unzip is shown below
1026
a02d0f6f 1027 my $z = new IO::Uncompress::Unzip $input [OPTS]
1028 or die "IO::Uncompress::Unzip failed: $UnzipError\n";
1029
1030Returns an C<IO::Uncompress::Unzip> object on success and undef on failure.
1031The variable C<$UnzipError> will contain an error message on failure.
1032
1033If you are running Perl 5.005 or better the object, C<$z>, returned from
1034IO::Uncompress::Unzip can be used exactly like an L<IO::File|IO::File> filehandle.
1035This means that all normal input file operations can be carried out with
1036C<$z>. For example, to read a line from a compressed file/buffer you can
1037use either of these forms
1038
1039 $line = $z->getline();
1040 $line = <$z>;
1041
1042The mandatory parameter C<$input> is used to determine the source of the
1043compressed data. This parameter can take one of three forms.
1044
1045=over 5
1046
1047=item A filename
1048
1049If the C<$input> parameter is a scalar, it is assumed to be a filename. This
1050file will be opened for reading and the compressed data will be read from it.
1051
1052=item A filehandle
1053
1054If the C<$input> parameter is a filehandle, the compressed data will be
1055read from it.
1056The string '-' can be used as an alias for standard input.
1057
a02d0f6f 1058=item A scalar reference
1059
1060If C<$input> is a scalar reference, the compressed data will be read from
1061C<$$output>.
1062
1063=back
1064
1065=head2 Constructor Options
1066
a02d0f6f 1067The option names defined below are case insensitive and can be optionally
1068prefixed by a '-'. So all of the following are valid
1069
1070 -AutoClose
1071 -autoclose
1072 AUTOCLOSE
1073 autoclose
1074
1075OPTS is a combination of the following options:
1076
1077=over 5
1078
e7d45986 1079=item C<< AutoClose => 0|1 >>
a02d0f6f 1080
1081This option is only valid when the C<$input> parameter is a filehandle. If
1082specified, and the value is true, it will result in the file being closed once
1083either the C<close> method is called or the IO::Uncompress::Unzip object is
1084destroyed.
1085
1086This parameter defaults to 0.
1087
e7d45986 1088=item C<< MultiStream => 0|1 >>
a02d0f6f 1089
e7d45986 1090Treats the complete zip file/buffer as a single compressed data
1091stream. When reading in multi-stream mode each member of the zip
1092file/buffer will be uncompressed in turn until the end of the file/buffer
1093is encountered.
a02d0f6f 1094
1095This parameter defaults to 0.
1096
e7d45986 1097=item C<< Prime => $string >>
a02d0f6f 1098
1099This option will uncompress the contents of C<$string> before processing the
1100input file/buffer.
1101
1102This option can be useful when the compressed data is embedded in another
1103file/data structure and it is not possible to work out where the compressed
1104data begins without having to read the first few bytes. If this is the
1105case, the uncompression can be I<primed> with these bytes using this
1106option.
1107
e7d45986 1108=item C<< Transparent => 0|1 >>
a02d0f6f 1109
f6fd7794 1110If this option is set and the input file/buffer is not compressed data,
a02d0f6f 1111the module will allow reading of it anyway.
1112
f6fd7794 1113In addition, if the input file/buffer does contain compressed data and
1114there is non-compressed data immediately following it, setting this option
1115will make this module treat the whole file/bufffer as a single data stream.
1116
a02d0f6f 1117This option defaults to 1.
1118
e7d45986 1119=item C<< BlockSize => $num >>
a02d0f6f 1120
1121When reading the compressed input data, IO::Uncompress::Unzip will read it in
1122blocks of C<$num> bytes.
1123
1124This option defaults to 4096.
1125
e7d45986 1126=item C<< InputLength => $size >>
a02d0f6f 1127
1128When present this option will limit the number of compressed bytes read
1129from the input file/buffer to C<$size>. This option can be used in the
1130situation where there is useful data directly after the compressed data
1131stream and you know beforehand the exact length of the compressed data
1132stream.
1133
1134This option is mostly used when reading from a filehandle, in which case
1135the file pointer will be left pointing to the first byte directly after the
1136compressed data stream.
1137
a02d0f6f 1138This option defaults to off.
1139
e7d45986 1140=item C<< Append => 0|1 >>
a02d0f6f 1141
1142This option controls what the C<read> method does with uncompressed data.
1143
1144If set to 1, all uncompressed data will be appended to the output parameter
1145of the C<read> method.
1146
1147If set to 0, the contents of the output parameter of the C<read> method
1148will be overwritten by the uncompressed data.
1149
1150Defaults to 0.
1151
e7d45986 1152=item C<< Strict => 0|1 >>
a02d0f6f 1153
a02d0f6f 1154This option controls whether the extra checks defined below are used when
1155carrying out the decompression. When Strict is on, the extra tests are
1156carried out, when Strict is off they are not.
1157
1158The default for this option is off.
1159
a02d0f6f 1160=back
1161
1162=head2 Examples
1163
1164TODO
1165
1166=head1 Methods
1167
1168=head2 read
1169
1170Usage is
1171
1172 $status = $z->read($buffer)
1173
1174Reads a block of compressed data (the size the the compressed block is
1175determined by the C<Buffer> option in the constructor), uncompresses it and
1176writes any uncompressed data into C<$buffer>. If the C<Append> parameter is
1177set in the constructor, the uncompressed data will be appended to the
1178C<$buffer> parameter. Otherwise C<$buffer> will be overwritten.
1179
1180Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1181or a negative number on error.
1182
1183=head2 read
1184
1185Usage is
1186
1187 $status = $z->read($buffer, $length)
1188 $status = $z->read($buffer, $length, $offset)
1189
1190 $status = read($z, $buffer, $length)
1191 $status = read($z, $buffer, $length, $offset)
1192
1193Attempt to read C<$length> bytes of uncompressed data into C<$buffer>.
1194
1195The main difference between this form of the C<read> method and the
1196previous one, is that this one will attempt to return I<exactly> C<$length>
1197bytes. The only circumstances that this function will not is if end-of-file
1198or an IO error is encountered.
1199
1200Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1201or a negative number on error.
1202
a02d0f6f 1203=head2 getline
1204
1205Usage is
1206
1207 $line = $z->getline()
1208 $line = <$z>
1209
1210Reads a single line.
1211
258133d1 1212This method fully supports the use of of the variable C<$/> (or
1213C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use) to
1214determine what constitutes an end of line. Paragraph mode, record mode and
1215file slurp mode are all supported.
a02d0f6f 1216
a02d0f6f 1217=head2 getc
1218
1219Usage is
1220
1221 $char = $z->getc()
1222
1223Read a single character.
1224
1225=head2 ungetc
1226
1227Usage is
1228
1229 $char = $z->ungetc($string)
1230
a02d0f6f 1231=head2 inflateSync
1232
1233Usage is
1234
1235 $status = $z->inflateSync()
1236
1237TODO
1238
a02d0f6f 1239=head2 getHeaderInfo
1240
1241Usage is
1242
1243 $hdr = $z->getHeaderInfo();
1244 @hdrs = $z->getHeaderInfo();
1245
1246This method returns either a hash reference (in scalar context) or a list
1247or hash references (in array context) that contains information about each
1248of the header fields in the compressed data stream(s).
1249
a02d0f6f 1250=head2 tell
1251
1252Usage is
1253
1254 $z->tell()
1255 tell $z
1256
1257Returns the uncompressed file offset.
1258
1259=head2 eof
1260
1261Usage is
1262
1263 $z->eof();
1264 eof($z);
1265
a02d0f6f 1266Returns true if the end of the compressed input stream has been reached.
1267
a02d0f6f 1268=head2 seek
1269
1270 $z->seek($position, $whence);
1271 seek($z, $position, $whence);
1272
a02d0f6f 1273Provides a sub-set of the C<seek> functionality, with the restriction
1274that it is only legal to seek forward in the input file/buffer.
1275It is a fatal error to attempt to seek backward.
1276
a02d0f6f 1277The C<$whence> parameter takes one the usual values, namely SEEK_SET,
1278SEEK_CUR or SEEK_END.
1279
1280Returns 1 on success, 0 on failure.
1281
1282=head2 binmode
1283
1284Usage is
1285
1286 $z->binmode
1287 binmode $z ;
1288
1289This is a noop provided for completeness.
1290
1291=head2 opened
1292
1293 $z->opened()
1294
1295Returns true if the object currently refers to a opened file/buffer.
1296
1297=head2 autoflush
1298
1299 my $prev = $z->autoflush()
1300 my $prev = $z->autoflush(EXPR)
1301
1302If the C<$z> object is associated with a file or a filehandle, this method
1303returns the current autoflush setting for the underlying filehandle. If
1304C<EXPR> is present, and is non-zero, it will enable flushing after every
1305write/print operation.
1306
1307If C<$z> is associated with a buffer, this method has no effect and always
1308returns C<undef>.
1309
1310B<Note> that the special variable C<$|> B<cannot> be used to set or
1311retrieve the autoflush setting.
1312
1313=head2 input_line_number
1314
1315 $z->input_line_number()
1316 $z->input_line_number(EXPR)
1317
a02d0f6f 1318Returns the current uncompressed line number. If C<EXPR> is present it has
1319the effect of setting the line number. Note that setting the line number
1320does not change the current position within the file/buffer being read.
1321
1322The contents of C<$/> are used to to determine what constitutes a line
1323terminator.
1324
a02d0f6f 1325=head2 fileno
1326
1327 $z->fileno()
1328 fileno($z)
1329
d54256af 1330If the C<$z> object is associated with a file or a filehandle, C<fileno>
1331will return the underlying file descriptor. Once the C<close> method is
1332called C<fileno> will return C<undef>.
a02d0f6f 1333
d54256af 1334If the C<$z> object is is associated with a buffer, this method will return
1335C<undef>.
a02d0f6f 1336
1337=head2 close
1338
1339 $z->close() ;
1340 close $z ;
1341
a02d0f6f 1342Closes the output file/buffer.
1343
a02d0f6f 1344For most versions of Perl this method will be automatically invoked if
1345the IO::Uncompress::Unzip object is destroyed (either explicitly or by the
1346variable with the reference to the object going out of scope). The
1347exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
1348these cases, the C<close> method will be called automatically, but
1349not until global destruction of all live objects when the program is
1350terminating.
1351
1352Therefore, if you want your scripts to be able to run on all versions
1353of Perl, you should call C<close> explicitly and not rely on automatic
1354closing.
1355
1356Returns true on success, otherwise 0.
1357
1358If the C<AutoClose> option has been enabled when the IO::Uncompress::Unzip
1359object was created, and the object is associated with a file, the
1360underlying file will also be closed.
1361
e7d45986 1362=head2 nextStream
1363
1364Usage is
1365
1366 my $status = $z->nextStream();
1367
1368Skips to the next compressed data stream in the input file/buffer. If a new
258133d1 1369compressed data stream is found, the eof marker will be cleared and C<$.>
1370will be reset to 0.
e7d45986 1371
1372Returns 1 if a new stream was found, 0 if none was found, and -1 if an
1373error was encountered.
1374
1375=head2 trailingData
1376
1377Usage is
1378
1379 my $data = $z->trailingData();
1380
258133d1 1381Returns the data, if any, that is present immediately after the compressed
1382data stream once uncompression is complete. It only makes sense to call
1383this method once the end of the compressed data stream has been
1384encountered.
1385
1386This option can be used when there is useful information immediately
1387following the compressed data stream, and you don't know the length of the
1388compressed data stream.
1389
1390If the input is a buffer, C<trailingData> will return everything from the
1391end of the compressed data stream to the end of the buffer.
1392
1393If the input is a filehandle, C<trailingData> will return the data that is
1394left in the filehandle input buffer once the end of the compressed data
1395stream has been reached. You can then use the filehandle to read the rest
1396of the input file.
1397
1398Don't bother using C<trailingData> if the input is a filename.
1399
258133d1 1400If you know the length of the compressed data stream before you start
1401uncompressing, you can avoid having to use C<trailingData> by setting the
1402C<InputLength> option in the constructor.
e7d45986 1403
a02d0f6f 1404=head1 Importing
1405
1406No symbolic constants are required by this IO::Uncompress::Unzip at present.
1407
1408=over 5
1409
1410=item :all
1411
1412Imports C<unzip> and C<$UnzipError>.
1413Same as doing this
1414
1415 use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1416
1417=back
1418
1419=head1 EXAMPLES
1420
d54256af 1421=head2 Working with Net::FTP
1422
1423See L<IO::Uncompress::Unzip::FAQ|IO::Uncompress::Unzip::FAQ/"Compressed files and Net::FTP">
1424
a02d0f6f 1425=head1 SEE ALSO
1426
258133d1 1427L<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::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
a02d0f6f 1428
1429L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
1430
1431L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
1432L<Archive::Tar|Archive::Tar>,
1433L<IO::Zlib|IO::Zlib>
1434
a02d0f6f 1435For RFC 1950, 1951 and 1952 see
1436F<http://www.faqs.org/rfcs/rfc1950.html>,
1437F<http://www.faqs.org/rfcs/rfc1951.html> and
1438F<http://www.faqs.org/rfcs/rfc1952.html>
1439
1440The I<zlib> compression library was written by Jean-loup Gailly
1441F<gzip@prep.ai.mit.edu> and Mark Adler F<madler@alumni.caltech.edu>.
1442
1443The primary site for the I<zlib> compression library is
1444F<http://www.zlib.org>.
1445
1446The primary site for gzip is F<http://www.gzip.org>.
1447
a02d0f6f 1448=head1 AUTHOR
1449
cb7abd7f 1450This module was written by Paul Marquess, F<pmqs@cpan.org>.
a02d0f6f 1451
a02d0f6f 1452=head1 MODIFICATION HISTORY
1453
1454See the Changes file.
1455
1456=head1 COPYRIGHT AND LICENSE
a02d0f6f 1457
319fab50 1458Copyright (c) 2005-2009 Paul Marquess. All rights reserved.
a02d0f6f 1459
1460This program is free software; you can redistribute it and/or
1461modify it under the same terms as Perl itself.
1462