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