2 package IO::Uncompress::Gunzip ;
13 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $GunzipError);
15 @ISA = qw(Exporter IO::BaseInflate);
16 @EXPORT_OK = qw( $GunzipError gunzip );
17 %EXPORT_TAGS = %IO::BaseInflate::EXPORT_TAGS ;
18 push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
19 Exporter::export_ok_tags('all');
24 $VERSION = '2.000_05';
29 return IO::BaseInflate::new($pkg, 'rfc1952', undef, \$GunzipError, 0, @_);
34 return IO::BaseInflate::_inf(__PACKAGE__, 'rfc1952', \$GunzipError, @_) ;
37 package IO::BaseInflate ;
43 our ($VERSION, @EXPORT_OK, %EXPORT_TAGS);
45 $VERSION = '2.000_03';
47 use Compress::Zlib 2 ;
48 use Compress::Zlib::Common ;
49 use Compress::Zlib::ParseParameters ;
50 use Compress::Gzip::Constants;
51 use Compress::Zlib::FileConstants;
55 use Scalar::Util qw(readonly);
56 use List::Util qw(min);
60 push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
61 #Exporter::export_ok_tags('all') ;
64 use constant G_EOF => 0 ;
65 use constant G_ERR => -1 ;
77 if ( length *$self->{Prime} ) {
78 #$$out = substr(*$self->{Prime}, 0, $size, '') ;
79 $$out = substr(*$self->{Prime}, 0, $size) ;
80 substr(*$self->{Prime}, 0, $size) = '' ;
81 if (length $$out == $size) {
82 #*$self->{InputLengthRemaining} -= length $$out;
85 $offset = length $$out ;
88 my $get_size = $size - $offset ;
90 if ( defined *$self->{InputLength} ) {
91 #*$self->{InputLengthRemaining} += length *$self->{Prime} ;
92 #*$self->{InputLengthRemaining} = *$self->{InputLength}
93 # if *$self->{InputLengthRemaining} > *$self->{InputLength};
94 $get_size = min($get_size, *$self->{InputLengthRemaining});
97 if (defined *$self->{FH})
98 { *$self->{FH}->read($$out, $get_size, $offset) }
99 elsif (defined *$self->{InputEvent}) {
101 while (length $$out < $size) {
103 if ($got = *$self->{InputEvent}->($$out, $get_size)) <= 0;
106 if (length $$out > $size ) {
107 #*$self->{Prime} = substr($$out, $size, length($$out), '');
108 *$self->{Prime} = substr($$out, $size, length($$out));
109 substr($$out, $size, length($$out)) = '';
112 *$self->{EventEof} = 1 if $got <= 0 ;
115 no warnings 'uninitialized';
116 my $buf = *$self->{Buffer} ;
117 $$buf = '' unless defined $$buf ;
118 #$$out = '' unless defined $$out ;
119 substr($$out, $offset) = substr($$buf, *$self->{BufferOffset}, $get_size);
120 *$self->{BufferOffset} += length($$out) - $offset ;
123 *$self->{InputLengthRemaining} -= length $$out;
125 $self->saveStatus(length $$out < 0 ? Z_DATA_ERROR : 0) ;
134 my $truncate = shift;
135 #print "smartSeek to $offset\n";
137 if (defined *$self->{FH})
138 { *$self->{FH}->seek($offset, SEEK_SET) }
140 *$self->{BufferOffset} = $offset ;
141 substr(${ *$self->{Buffer} }, *$self->{BufferOffset}) = ''
150 my $out_data = shift ;
152 if (defined *$self->{FH}) {
153 # flush needed for 5.8.0
154 defined *$self->{FH}->write($out_data, length $out_data) &&
155 defined *$self->{FH}->flush() ;
158 my $buf = *$self->{Buffer} ;
159 substr($$buf, *$self->{BufferOffset}, length $out_data) = $out_data ;
160 *$self->{BufferOffset} += length($out_data) ;
167 return $_[0]->smartRead($_[1], $_[2]) == $_[2];
170 sub getTrailingBuffer
173 return "" if defined *$self->{FH} || defined *$self->{InputEvent} ;
175 my $buf = *$self->{Buffer} ;
176 my $offset = *$self->{BufferOffset} ;
177 return substr($$buf, $offset, -1) ;
183 if (defined *$self->{FH})
184 { *$self->{FH}->eof() }
185 elsif (defined *$self->{InputEvent})
186 { *$self->{EventEof} }
188 { *$self->{BufferOffset} >= length(${ *$self->{Buffer} }) }
194 *$self->{ErrorNo} = shift() + 0 ;
195 ${ *$self->{Error} } = '' ;
197 return *$self->{ErrorNo} ;
205 ${ *$self->{Error} } = shift ;
206 *$self->{ErrorNo} = shift() + 0 if @_ ;
208 #print "saveErrorString: " . ${ *$self->{Error} } . "\n" ;
215 return ${ *$self->{Error} } ;
221 return *$self->{ErrorNo};
227 return $self->saveErrorString(undef, "Header Error: $_[0]", Z_DATA_ERROR);
233 return $self->saveErrorString(G_ERR, "Trailer Error: $_[0]", Z_DATA_ERROR);
239 return $self->HeaderError("Truncated in $_[0] Section");
245 return 0 if length $buffer < 4 ;
246 my $sig = unpack("V", $buffer) ;
247 return $sig == 0x04034b50 ;
253 return 0 if length $buffer < GZIP_ID_SIZE ;
254 my ($id1, $id2) = unpack("C C", $buffer) ;
255 return $id1 == GZIP_ID1 && $id2 == GZIP_ID2 ;
261 return 0 if length $buffer < ZLIB_HEADER_SIZE ;
262 my $hdr = unpack("n", $buffer) ;
263 return $hdr % 31 == 0 ;
271 $magic = '' unless defined $magic ;
275 $self->smartRead(\$buffer, *$self->{BlockSize}) >= 0
276 or return $self->saveErrorString(undef, "No data to read");
278 my $temp_buf = $magic . $buffer ;
279 *$self->{HeaderPending} = $temp_buf ;
281 my $status = *$self->{Inflate}->inflate($temp_buf, $buffer) ;
282 my $buf_len = *$self->{Inflate}->inflateCount();
284 # zlib before 1.2 needs an extra byte after the compressed data
286 if ($status == Z_OK && $self->smartEof()) {
288 $status = *$self->{Inflate}->inflate(\$byte, $buffer) ;
289 return $self->saveErrorString(undef, "Inflation Error: $status", $status)
290 unless $self->saveStatus($status) == Z_OK || $status == Z_STREAM_END ;
291 $buf_len += *$self->{Inflate}->inflateCount();
294 return $self->saveErrorString(undef, "unexpected end of file", Z_DATA_ERROR)
295 if $self->saveStatus($status) != Z_STREAM_END && $self->smartEof() ;
297 return $self->saveErrorString(undef, "Inflation Error: $status", $status)
298 unless $status == Z_OK || $status == Z_STREAM_END ;
300 if ($status == Z_STREAM_END) {
301 if (*$self->{MultiStream}
302 && (length $temp_buf || ! $self->smartEof())){
303 *$self->{NewStream} = 1 ;
304 *$self->{EndStream} = 0 ;
305 *$self->{Prime} = $temp_buf . *$self->{Prime} ;
308 *$self->{EndStream} = 1 ;
309 *$self->{Trailing} = $temp_buf . $self->getTrailingBuffer();
312 *$self->{HeaderPending} = $buffer ;
313 *$self->{InflatedBytesRead} = $buf_len ;
314 *$self->{TotalInflatedBytesRead} += $buf_len ;
315 *$self->{Type} = 'rfc1951';
317 $self->saveStatus(Z_OK);
322 'TrailerLength' => 0,
327 sub _guessCompression
331 # Check raw first in case the first few bytes happen to match
332 # the signatures of gzip/deflate.
333 my $got = $self->_isRaw() ;
334 return $got if defined $got ;
336 *$self->{Prime} = *$self->{HeaderPending} . *$self->{Prime} ;
337 *$self->{HeaderPending} = '';
338 *$self->{Inflate}->inflateReset();
342 $self->smartReadExact(\$magic, GZIP_ID_SIZE)
343 or return $self->HeaderError("Minimum header size is " .
344 GZIP_ID_SIZE . " bytes") ;
346 if (isGzipMagic($magic)) {
347 $status = $self->_readGzipHeader($magic);
348 delete *$self->{Transparent} if ! defined $status ;
351 elsif ( $status = $self->_readDeflateHeader($magic) ) {
355 *$self->{Prime} = $magic . *$self->{HeaderPending} . *$self->{Prime} ;
356 *$self->{HeaderPending} = '';
357 $self->saveErrorString(undef, "unknown compression format", Z_DATA_ERROR);
360 sub _readFullGzipHeader($)
365 $self->smartReadExact(\$magic, GZIP_ID_SIZE);
367 *$self->{HeaderPending} = $magic ;
369 return $self->HeaderError("Minimum header size is " .
370 GZIP_MIN_HEADER_SIZE . " bytes")
371 if length $magic != GZIP_ID_SIZE ;
374 return $self->HeaderError("Bad Magic")
375 if ! isGzipMagic($magic) ;
377 my $status = $self->_readGzipHeader($magic);
378 delete *$self->{Transparent} if ! defined $status ;
382 sub _readGzipHeader($)
384 my ($self, $magic) = @_ ;
388 $self->smartReadExact(\$buffer, GZIP_MIN_HEADER_SIZE - GZIP_ID_SIZE)
389 or return $self->HeaderError("Minimum header size is " .
390 GZIP_MIN_HEADER_SIZE . " bytes") ;
392 my $keep = $magic . $buffer ;
393 *$self->{HeaderPending} = $keep ;
395 # now split out the various parts
396 my ($cm, $flag, $mtime, $xfl, $os) = unpack("C C V C C", $buffer) ;
398 $cm == GZIP_CM_DEFLATED
399 or return $self->HeaderError("Not Deflate (CM is $cm)") ;
401 # check for use of reserved bits
402 return $self->HeaderError("Use of Reserved Bits in FLG field.")
403 if $flag & GZIP_FLG_RESERVED ;
407 if ($flag & GZIP_FLG_FEXTRA) {
409 $self->smartReadExact(\$buffer, GZIP_FEXTRA_HEADER_SIZE)
410 or return $self->TruncatedHeader("FEXTRA Length") ;
412 my ($XLEN) = unpack("v", $buffer) ;
413 $self->smartReadExact(\$EXTRA, $XLEN)
414 or return $self->TruncatedHeader("FEXTRA Body");
415 $keep .= $buffer . $EXTRA ;
417 if ($XLEN && *$self->{'ParseExtra'}) {
419 while ($offset < $XLEN) {
421 return $self->TruncatedHeader("FEXTRA Body")
422 if $offset + GZIP_FEXTRA_SUBFIELD_HEADER_SIZE > $XLEN ;
424 my $id = substr($EXTRA, $offset, GZIP_FEXTRA_SUBFIELD_ID_SIZE);
425 $offset += GZIP_FEXTRA_SUBFIELD_ID_SIZE ;
427 return $self->HeaderError("SubField ID 2nd byte is 0x00")
428 if *$self->{Strict} && substr($id, 1, 1) eq "\x00" ;
430 my ($subLen) = unpack("v", substr($EXTRA, $offset,
431 GZIP_FEXTRA_SUBFIELD_LEN_SIZE)) ;
432 $offset += GZIP_FEXTRA_SUBFIELD_LEN_SIZE ;
434 return $self->TruncatedHeader("FEXTRA Body")
435 if $offset + $subLen > $XLEN ;
437 push @EXTRA, [$id => substr($EXTRA, $offset, $subLen)];
444 if ($flag & GZIP_FLG_FNAME) {
447 $self->smartReadExact(\$buffer, 1)
448 or return $self->TruncatedHeader("FNAME");
449 last if $buffer eq GZIP_NULL_BYTE ;
452 $keep .= $origname . GZIP_NULL_BYTE ;
454 return $self->HeaderError("Non ISO 8859-1 Character found in Name")
455 if *$self->{Strict} && $origname =~ /$GZIP_FNAME_INVALID_CHAR_RE/o ;
459 if ($flag & GZIP_FLG_FCOMMENT) {
462 $self->smartReadExact(\$buffer, 1)
463 or return $self->TruncatedHeader("FCOMMENT");
464 last if $buffer eq GZIP_NULL_BYTE ;
467 $keep .= $comment . GZIP_NULL_BYTE ;
469 return $self->HeaderError("Non ISO 8859-1 Character found in Comment")
470 if *$self->{Strict} && $comment =~ /$GZIP_FCOMMENT_INVALID_CHAR_RE/o ;
473 if ($flag & GZIP_FLG_FHCRC) {
474 $self->smartReadExact(\$buffer, GZIP_FHCRC_SIZE)
475 or return $self->TruncatedHeader("FHCRC");
477 $HeaderCRC = unpack("v", $buffer) ;
478 my $crc16 = crc32($keep) & 0xFF ;
480 return $self->HeaderError("CRC16 mismatch.")
481 if *$self->{Strict} && $crc16 != $HeaderCRC;
486 # Assume compression method is deflated for xfl tests
490 *$self->{Type} = 'rfc1952';
494 'HeaderLength' => length $keep,
495 'TrailerLength' => GZIP_TRAILER_SIZE,
497 'isMinimalHeader' => $keep eq GZIP_MINIMUM_HEADER ? 1 : 0,
500 'MethodName' => $cm == GZIP_CM_DEFLATED ? "Deflated" : "Unknown" ,
501 'TextFlag' => $flag & GZIP_FLG_FTEXT ? 1 : 0,
502 'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
503 'NameFlag' => $flag & GZIP_FLG_FNAME ? 1 : 0,
504 'CommentFlag' => $flag & GZIP_FLG_FCOMMENT ? 1 : 0,
505 'ExtraFlag' => $flag & GZIP_FLG_FEXTRA ? 1 : 0,
507 'Comment' => $comment,
510 'OsName' => defined $GZIP_OS_Names{$os}
511 ? $GZIP_OS_Names{$os} : "Unknown",
512 'HeaderCRC' => $HeaderCRC,
514 'ExtraFlags' => $xfl,
515 'ExtraFieldRaw' => $EXTRA,
516 'ExtraField' => [ @EXTRA ],
519 #'CompSize'=> $compsize,
521 #'OrigSize'=> $ISIZE,
525 sub _readFullZipHeader($)
530 $self->smartReadExact(\$magic, 4);
532 *$self->{HeaderPending} = $magic ;
534 return $self->HeaderError("Minimum header size is " .
536 if length $magic != 4 ;
539 return $self->HeaderError("Bad Magic")
540 if ! isZipMagic($magic) ;
542 my $status = $self->_readZipHeader($magic);
543 delete *$self->{Transparent} if ! defined $status ;
547 sub _readZipHeader($)
549 my ($self, $magic) = @_ ;
553 $self->smartReadExact(\$buffer, 30 - 4)
554 or return $self->HeaderError("Minimum header size is " .
557 my $keep = $magic . $buffer ;
558 *$self->{HeaderPending} = $keep ;
560 my $extractVersion = unpack ("v", substr($buffer, 4-4, 2));
561 my $gpFlag = unpack ("v", substr($buffer, 6-4, 2));
562 my $compressedMethod = unpack ("v", substr($buffer, 8-4, 2));
563 my $lastModTime = unpack ("v", substr($buffer, 10-4, 2));
564 my $lastModDate = unpack ("v", substr($buffer, 12-4, 2));
565 my $crc32 = unpack ("v", substr($buffer, 14-4, 4));
566 my $compressedLength = unpack ("V", substr($buffer, 18-4, 4));
567 my $uncompressedLength = unpack ("V", substr($buffer, 22-4, 4));
568 my $filename_length = unpack ("v", substr($buffer, 26-4, 2));
569 my $extra_length = unpack ("v", substr($buffer, 28-4, 2));
574 if ($filename_length)
576 $self->smartReadExact(\$filename, $filename_length)
577 or return $self->HeaderError("xxx");
583 $self->smartReadExact(\$extraField, $extra_length)
584 or return $self->HeaderError("xxx");
585 $keep .= $extraField ;
588 *$self->{Type} = 'zip';
592 'HeaderLength' => length $keep,
593 'TrailerLength' => $gpFlag & 0x08 ? 16 : 0,
597 # 'MethodName' => $cm == GZIP_CM_DEFLATED ? "Deflated" : "Unknown" ,
598 # 'TextFlag' => $flag & GZIP_FLG_FTEXT ? 1 : 0,
599 # 'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
600 # 'NameFlag' => $flag & GZIP_FLG_FNAME ? 1 : 0,
601 # 'CommentFlag' => $flag & GZIP_FLG_FCOMMENT ? 1 : 0,
602 # 'ExtraFlag' => $flag & GZIP_FLG_FEXTRA ? 1 : 0,
603 # 'Name' => $origname,
604 # 'Comment' => $comment,
607 # 'OsName' => defined $GZIP_OS_Names{$os}
608 # ? $GZIP_OS_Names{$os} : "Unknown",
609 # 'HeaderCRC' => $HeaderCRC,
611 # 'ExtraFlags' => $xfl,
612 # 'ExtraFieldRaw' => $EXTRA,
613 # 'ExtraField' => [ @EXTRA ],
616 #'CompSize'=> $compsize,
618 #'OrigSize'=> $ISIZE,
628 ($data >> $offset ) & $mask & 0xFF ;
632 sub _readDeflateHeader
634 my ($self, $buffer) = @_ ;
637 $self->smartReadExact(\$buffer, ZLIB_HEADER_SIZE);
639 *$self->{HeaderPending} = $buffer ;
641 return $self->HeaderError("Header size is " .
642 ZLIB_HEADER_SIZE . " bytes")
643 if length $buffer != ZLIB_HEADER_SIZE;
645 return $self->HeaderError("CRC mismatch.")
646 if ! isZlibMagic($buffer) ;
649 my ($CMF, $FLG) = unpack "C C", $buffer;
650 my $FDICT = bits($FLG, ZLIB_FLG_FDICT_OFFSET, ZLIB_FLG_FDICT_BITS ),
652 my $cm = bits($CMF, ZLIB_CMF_CM_OFFSET, ZLIB_CMF_CM_BITS) ;
653 $cm == ZLIB_CMF_CM_DEFLATED
654 or return $self->HeaderError("Not Deflate (CM is $cm)") ;
658 $self->smartReadExact(\$buffer, ZLIB_FDICT_SIZE)
659 or return $self->TruncatedHeader("FDICT");
661 $DICTID = unpack("N", $buffer) ;
664 *$self->{Type} = 'rfc1950';
668 'HeaderLength' => ZLIB_HEADER_SIZE,
669 'TrailerLength' => ZLIB_TRAILER_SIZE,
673 CM => bits($CMF, ZLIB_CMF_CM_OFFSET, ZLIB_CMF_CM_BITS ),
674 CINFO => bits($CMF, ZLIB_CMF_CINFO_OFFSET, ZLIB_CMF_CINFO_BITS ),
676 FCHECK => bits($FLG, ZLIB_FLG_FCHECK_OFFSET, ZLIB_FLG_FCHECK_BITS),
677 FDICT => bits($FLG, ZLIB_FLG_FDICT_OFFSET, ZLIB_FLG_FDICT_BITS ),
678 FLEVEL => bits($FLG, ZLIB_FLG_LEVEL_OFFSET, ZLIB_FLG_LEVEL_BITS ),
692 #'Input' => [Parse_store_ref, undef],
694 'BlockSize' => [Parse_unsigned, 16 * 1024],
695 'AutoClose' => [Parse_boolean, 0],
696 'Strict' => [Parse_boolean, 0],
697 #'Lax' => [Parse_boolean, 1],
698 'Append' => [Parse_boolean, 0],
699 'Prime' => [Parse_any, undef],
700 'MultiStream' => [Parse_boolean, 0],
701 'Transparent' => [Parse_any, 1],
702 'Scan' => [Parse_boolean, 0],
703 'InputLength' => [Parse_unsigned, undef],
705 #'Todo - Revert to ordinary file on end Z_STREAM_END'=> 0,
709 $Valid->{'ParseExtra'} = [Parse_boolean, 0]
710 if $type eq 'rfc1952' ;
712 my $got = Compress::Zlib::ParseParameters::new();
714 $got->parse($Valid, @_ )
715 or croak "$class: $got->{Error}" ;
725 my $error_ref = shift ;
726 my $append_mode = shift ;
728 croak("$class: Missing Input parameter")
731 my $inValue = shift ;
735 $got = checkParams($class, $type, @_)
739 my $inType = whatIsInput($inValue, 1);
741 ckInputParam($class, $inValue, $error_ref, 1)
744 my $obj = bless Symbol::gensym(), ref($class) || $class;
745 tie *$obj, $obj if $] >= 5.005;
749 *$obj->{Error} = $error_ref ;
752 if ($inType eq 'buffer' || $inType eq 'code') {
753 *$obj->{Buffer} = $inValue ;
754 *$obj->{InputEvent} = $inValue
755 if $inType eq 'code' ;
758 if ($inType eq 'handle') {
759 *$obj->{FH} = $inValue ;
760 *$obj->{Handle} = 1 ;
761 # Need to rewind for Scan
762 #seek(*$obj->{FH}, 0, SEEK_SET) if $got->value('Scan');
763 *$obj->{FH}->seek(0, SEEK_SET) if $got->value('Scan');
767 $mode = '+<' if $got->value('Scan');
768 *$obj->{StdIO} = ($inValue eq '-');
769 *$obj->{FH} = new IO::File "$mode $inValue"
770 or return $obj->saveErrorString(undef, "cannot open file '$inValue': $!", $!) ;
773 # Setting STDIN to binmode causes grief
774 setBinModeInput(*$obj->{FH}) ;
777 *$obj->{Buffer} = \$buff ;
781 *$obj->{InputLength} = $got->parsed('InputLength')
782 ? $got->value('InputLength')
784 *$obj->{InputLengthRemaining} = $got->value('InputLength');
785 *$obj->{BufferOffset} = 0 ;
786 *$obj->{AutoClose} = $got->value('AutoClose');
787 *$obj->{Strict} = $got->value('Strict');
788 #*$obj->{Strict} = ! $got->value('Lax');
789 *$obj->{BlockSize} = $got->value('BlockSize');
790 *$obj->{Append} = $got->value('Append');
791 *$obj->{AppendOutput} = $append_mode || $got->value('Append');
792 *$obj->{Transparent} = $got->value('Transparent');
793 *$obj->{MultiStream} = $got->value('MultiStream');
794 *$obj->{Scan} = $got->value('Scan');
795 *$obj->{ParseExtra} = $got->value('ParseExtra')
796 || $got->value('Strict') ;
797 #|| ! $got->value('Lax') ;
798 *$obj->{Type} = $type;
799 *$obj->{Prime} = $got->value('Prime') || '' ;
800 *$obj->{Pending} = '';
802 *$obj->{PlainBytesRead} = 0;
803 *$obj->{InflatedBytesRead} = 0;
805 *$obj->{TotalInflatedBytesRead} = 0;
806 *$obj->{NewStream} = 0 ;
807 *$obj->{EventEof} = 0 ;
808 *$obj->{ClassName} = $class ;
814 (*$obj->{Inflate}, $status) = new Compress::Zlib::InflateScan
815 -CRC32 => $type eq 'rfc1952' ||
817 -ADLER32 => $type eq 'rfc1950' ||
819 -WindowBits => - MAX_WBITS ;
823 (*$obj->{Inflate}, $status) = new Compress::Zlib::Inflate
825 -CRC32 => $type eq 'rfc1952' ||
827 -ADLER32 => $type eq 'rfc1950' ||
829 -WindowBits => - MAX_WBITS ;
832 return $obj->saveErrorString(undef, "Could not create Inflation object: $status")
833 if $obj->saveStatus($status) != Z_OK ;
835 if ($type eq 'rfc1952')
837 *$obj->{Info} = $obj->_readFullGzipHeader() ;
839 elsif ($type eq 'zip')
841 *$obj->{Info} = $obj->_readFullZipHeader() ;
843 elsif ($type eq 'rfc1950')
845 *$obj->{Info} = $obj->_readDeflateHeader() ;
847 elsif ($type eq 'rfc1951')
849 *$obj->{Info} = $obj->_isRaw() ;
851 elsif ($type eq 'any')
853 *$obj->{Info} = $obj->_guessCompression() ;
856 if (! defined *$obj->{Info})
858 return undef unless *$obj->{Transparent};
860 *$obj->{Type} = 'plain';
862 *$obj->{PlainBytesRead} = length *$obj->{HeaderPending} ;
865 push @{ *$obj->{InfoList} }, *$obj->{Info} ;
866 *$obj->{Pending} = *$obj->{HeaderPending}
867 if *$obj->{Plain} || *$obj->{Type} eq 'rfc1951';
869 $obj->saveStatus(0) ;
877 # my $class = shift ;
879 # my $error_ref = shift ;
881 # my $name = (caller(1))[3] ;
883 # croak "$name: expected at least 2 parameters\n"
886 # my $input = shift ;
887 # my $output = shift ;
889 # ckInOutParams($name, $input, $output, $error_ref)
892 # my $outType = whatIs($output);
894 # my $gunzip = new($class, $type, $error_ref, 1, $input, @_)
898 # if ($outType eq 'filename') {
901 # if *$gunzip->{Append} ;
902 # $fh = new IO::File "$mode $output"
903 # or return $gunzip->saveErrorString(undef, "cannot open file '$output': $!", $!) ;
906 # if ($outType eq 'handle') {
908 # if (*$gunzip->{Append}) {
909 # seek($fh, 0, SEEK_END)
910 # or return $gunzip->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ;
915 # $buff = $output if $outType eq 'buffer' ;
917 # while (($status = $gunzip->read($buff)) > 0) {
920 # or return $gunzip->saveErrorString(undef, "Error writing to output file: $!", $!);
930 # if ( $outType eq 'filename' ||
931 # ($outType eq 'handle' && *$gunzip->{AutoClose})) {
933 # or return $gunzip->saveErrorString(undef, $!, $!);
943 my $error_ref = shift ;
945 my $name = (caller(1))[3] ;
947 croak "$name: expected at least 1 parameters\n"
954 my $x = new Validator($class, $type, $error_ref, $name, $input, $output)
957 push @_, $output if $haveOut && $x->{Hash};
959 my $got = checkParams($name, $type, @_)
966 while (my($k, $v) = each %$input)
971 _singleTarget($x, 1, $k, $v, @_)
975 return keys %$input ;
981 foreach my $pair (@{ $x->{Pairs} })
983 my ($from, $to) = @$pair ;
984 _singleTarget($x, 1, $from, $to, @_)
988 return scalar @{ $x->{Pairs} } ;
991 #if ($x->{outType} eq 'array' || $x->{outType} eq 'hash')
992 if (! $x->{oneOutput} )
994 my $inFile = ($x->{inType} eq 'filenames'
995 || $x->{inType} eq 'filename');
997 $x->{inType} = $inFile ? 'filename' : 'buffer';
998 my $ot = $x->{outType} ;
999 $x->{outType} = 'buffer';
1001 foreach my $in ($x->{oneInput} ? $input : @$input)
1004 $x->{oneInput} = 1 ;
1006 _singleTarget($x, $inFile, $in, \$out, @_)
1010 { push @$output, \$out }
1012 { $output->{$in} = \$out }
1018 # finally the 1 to 1 and n to 1
1019 return _singleTarget($x, 1, $input, $output, @_);
1021 croak "should not be here" ;
1027 my $string = shift ;
1029 ${ $x->{Error} } = $string ;
1037 my $inputIsFilename = shift;
1044 if ($x->{outType} eq 'filename') {
1047 if $x->{Got}->value('Append') ;
1048 $x->{fh} = new IO::File "$mode $output"
1049 or return retErr($x, "cannot open file '$output': $!") ;
1050 setBinModeOutput($x->{fh});
1054 elsif ($x->{outType} eq 'handle') {
1056 setBinModeOutput($x->{fh});
1057 if ($x->{Got}->value('Append')) {
1058 seek($x->{fh}, 0, SEEK_END)
1059 or return retErr($x, "Cannot seek to end of output filehandle: $!") ;
1064 elsif ($x->{outType} eq 'buffer' )
1067 unless $x->{Got}->value('Append');
1068 $x->{buff} = $output ;
1073 defined _rd2($x, $input, $inputIsFilename)
1078 my $inputIsFilename = ($x->{inType} ne 'array');
1080 for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input)
1082 defined _rd2($x, $element, $inputIsFilename)
1088 if ( ($x->{outType} eq 'filename' && $output ne '-') ||
1089 ($x->{outType} eq 'handle' && $x->{Got}->value('AutoClose'))) {
1091 or return retErr($x, $!);
1092 #or return $gunzip->saveErrorString(undef, $!, $!);
1103 my $inputIsFilename = shift;
1105 my $gunzip = new($x->{Class}, $x->{Type}, $x->{Got}, $x->{Error}, 1, $input, @_)
1111 while (($status = $gunzip->read($x->{buff})) > 0) {
1113 print $fh $x->{buff}
1114 or return $gunzip->saveErrorString(undef, "Error writing to output file: $!", $!);
1130 return $_[0] if ref($_[0]);
1144 return *$self->{Info};
1150 # >0 - ok, number of bytes read
1156 return G_EOF if *$self->{Closed} ;
1157 #return G_EOF if !length *$self->{Pending} && *$self->{EndStream} ;
1158 return G_EOF if *$self->{EndStream} ;
1160 my $buffer = shift ;
1161 my $scan_mode = shift ;
1163 if (*$self->{Plain}) {
1165 my $len = $self->smartRead(\$tmp_buff, *$self->{BlockSize}) ;
1167 return $self->saveErrorString(G_ERR, "Error reading data: $!", $!)
1171 *$self->{EndStream} = 1 ;
1174 *$self->{PlainBytesRead} += $len ;
1175 $$buffer .= $tmp_buff;
1181 if (*$self->{NewStream}) {
1182 *$self->{NewStream} = 0 ;
1183 *$self->{EndStream} = 0 ;
1184 *$self->{Inflate}->inflateReset();
1186 if (*$self->{Type} eq 'rfc1952')
1188 *$self->{Info} = $self->_readFullGzipHeader() ;
1190 elsif (*$self->{Type} eq 'zip')
1192 *$self->{Info} = $self->_readFullZipHeader() ;
1194 elsif (*$self->{Type} eq 'rfc1950')
1196 *$self->{Info} = $self->_readDeflateHeader() ;
1198 elsif (*$self->{Type} eq 'rfc1951')
1200 *$self->{Info} = $self->_isRaw() ;
1201 *$self->{Pending} = *$self->{HeaderPending}
1202 if defined *$self->{Info} ;
1205 return G_ERR unless defined *$self->{Info} ;
1207 push @{ *$self->{InfoList} }, *$self->{Info} ;
1209 if (*$self->{Type} eq 'rfc1951') {
1210 $$buffer .= *$self->{Pending} ;
1211 my $len = length *$self->{Pending} ;
1212 *$self->{Pending} = '';
1218 my $status = $self->smartRead(\$temp_buf, *$self->{BlockSize}) ;
1219 return $self->saveErrorString(G_ERR, "Error Reading Data")
1222 if ($status == 0 ) {
1223 *$self->{Closed} = 1 ;
1224 *$self->{EndStream} = 1 ;
1225 return $self->saveErrorString(G_ERR, "unexpected end of file", Z_DATA_ERROR);
1228 my $before_len = defined $$buffer ? length $$buffer : 0 ;
1229 $status = *$self->{Inflate}->inflate(\$temp_buf, $buffer) ;
1231 return $self->saveErrorString(G_ERR, "Inflation Error: $status")
1232 unless $self->saveStatus($status) == Z_OK || $status == Z_STREAM_END ;
1234 my $buf_len = *$self->{Inflate}->inflateCount();
1236 # zlib before 1.2 needs an extra byte after the compressed data
1238 if ($status == Z_OK && *$self->{Type} eq 'rfc1951' && $self->smartEof()) {
1240 $status = *$self->{Inflate}->inflate(\$byte, $buffer) ;
1242 $buf_len += *$self->{Inflate}->inflateCount();
1244 return $self->saveErrorString(G_ERR, "Inflation Error: $status")
1245 unless $self->saveStatus($status) == Z_OK || $status == Z_STREAM_END ;
1249 return $self->saveErrorString(G_ERR, "unexpected end of file", Z_DATA_ERROR)
1250 if $status != Z_STREAM_END && $self->smartEof() ;
1252 *$self->{InflatedBytesRead} += $buf_len ;
1253 *$self->{TotalInflatedBytesRead} += $buf_len ;
1254 my $rest = GZIP_ISIZE_MAX - *$self->{ISize} ;
1255 if ($buf_len > $rest) {
1256 *$self->{ISize} = $buf_len - $rest - 1;
1259 *$self->{ISize} += $buf_len ;
1262 if ($status == Z_STREAM_END) {
1264 *$self->{EndStream} = 1 ;
1266 if (*$self->{Type} eq 'rfc1951' || ! *$self->{Info}{TrailerLength})
1268 *$self->{Trailing} = $temp_buf . $self->getTrailingBuffer();
1272 # Only rfc1950 & 1952 have a trailer
1274 my $trailer_size = *$self->{Info}{TrailerLength} ;
1277 # my $offset = *$self->{Inflate}->getLastBufferOffset();
1278 # substr($temp_buf, 0, $offset) = '' ;
1281 if (length $temp_buf < $trailer_size) {
1283 my $want = $trailer_size - length $temp_buf;
1284 my $got = $self->smartRead(\$buff, $want) ;
1285 if ($got != $want && *$self->{Strict} ) {
1286 my $len = length($temp_buf) + length($buff);
1287 return $self->TrailerError("trailer truncated. Expected " .
1288 "$trailer_size bytes, got $len");
1293 if (length $temp_buf >= $trailer_size) {
1295 #my $trailer = substr($temp_buf, 0, $trailer_size, '') ;
1296 my $trailer = substr($temp_buf, 0, $trailer_size) ;
1297 substr($temp_buf, 0, $trailer_size) = '' ;
1299 if (*$self->{Type} eq 'rfc1952') {
1301 my ($CRC32, $ISIZE) = unpack("V V", $trailer) ;
1302 *$self->{Info}{CRC32} = $CRC32;
1303 *$self->{Info}{ISIZE} = $ISIZE;
1305 if (*$self->{Strict}) {
1306 return $self->TrailerError("CRC mismatch")
1307 if $CRC32 != *$self->{Inflate}->crc32() ;
1309 my $exp_isize = *$self->{ISize};
1310 return $self->TrailerError("ISIZE mismatch. Got $ISIZE"
1311 . ", expected $exp_isize")
1312 if $ISIZE != $exp_isize ;
1315 elsif (*$self->{Type} eq 'zip') {
1317 my ($sig, $CRC32, $cSize, $uSize) = unpack("V V V V", $trailer) ;
1318 return $self->TrailerError("Data Descriptor signature")
1319 if $sig != 0x08074b50;
1321 if (*$self->{Strict}) {
1322 return $self->TrailerError("CRC mismatch")
1323 if $CRC32 != *$self->{Inflate}->crc32() ;
1327 elsif (*$self->{Type} eq 'rfc1950') {
1328 my $ADLER32 = unpack("N", $trailer) ;
1329 *$self->{Info}{ADLER32} = $ADLER32;
1330 return $self->TrailerError("CRC mismatch")
1331 if *$self->{Strict} && $ADLER32 != *$self->{Inflate}->adler32() ;
1335 if (*$self->{MultiStream}
1336 && (length $temp_buf || ! $self->smartEof())){
1337 *$self->{NewStream} = 1 ;
1338 *$self->{EndStream} = 0 ;
1339 *$self->{Prime} = $temp_buf . *$self->{Prime} ;
1344 *$self->{Trailing} = $temp_buf .$self->getTrailingBuffer();
1349 # return the number of uncompressed bytes read
1355 # my $self = shift ;
1356 # return *$self->{NewStream} ||
1357 # *$self->{EndStream} ;
1363 return 1 if ! defined *$self->{InfoList};
1364 return scalar @{ *$self->{InfoList} } ;
1370 # >0 - ok, number of bytes read
1376 return G_EOF if *$self->{Closed} ;
1377 return G_EOF if !length *$self->{Pending} && *$self->{EndStream} ;
1381 #croak(*$self->{ClassName} . "::read: buffer parameter is read-only")
1382 # if Compress::Zlib::_readonly_ref($_[0]);
1385 croak(*$self->{ClassName} . "::read: buffer parameter is read-only")
1386 if readonly(${ $_[0] });
1388 croak *$self->{ClassName} . "::read: not a scalar reference $_[0]"
1389 unless ref $_[0] eq 'SCALAR' ;
1393 croak(*$self->{ClassName} . "::read: buffer parameter is read-only")
1399 my $length = $_[1] ;
1400 my $offset = $_[2] || 0;
1402 # the core read will return 0 if asked for 0 bytes
1403 return 0 if defined $length && $length == 0 ;
1405 $length = $length || 0;
1407 croak(*$self->{ClassName} . "::read: length parameter is negative")
1410 $$buffer = '' unless *$self->{AppendOutput} || $offset ;
1412 # Short-circuit if this is a simple read, with no length
1413 # or offset specified.
1414 unless ( $length || $offset) {
1415 if (length *$self->{Pending}) {
1416 $$buffer .= *$self->{Pending} ;
1417 my $len = length *$self->{Pending};
1418 *$self->{Pending} = '' ;
1423 $len = $self->_raw_read($buffer)
1424 while ! *$self->{EndStream} && $len == 0 ;
1429 # Need to jump through more hoops - either length or offset
1430 # or both are specified.
1431 #*$self->{Pending} = '' if ! length *$self->{Pending} ;
1432 my $out_buffer = \*$self->{Pending} ;
1434 while (! *$self->{EndStream} && length($$out_buffer) < $length)
1436 my $buf_len = $self->_raw_read($out_buffer);
1441 $length = length $$out_buffer
1442 if length($$out_buffer) < $length ;
1445 $$buffer .= "\x00" x ($offset - length($$buffer))
1446 if $offset > length($$buffer) ;
1447 #substr($$buffer, $offset) = substr($$out_buffer, 0, $length, '') ;
1448 substr($$buffer, $offset) = substr($$out_buffer, 0, $length) ;
1449 substr($$out_buffer, 0, $length) = '' ;
1452 #$$buffer .= substr($$out_buffer, 0, $length, '') ;
1453 $$buffer .= substr($$out_buffer, 0, $length) ;
1454 substr($$out_buffer, 0, $length) = '' ;
1465 if ( ! defined $/ ) {
1467 1 while $self->read($data) > 0 ;
1472 if ( ! length $/ ) {
1474 while ($self->read($paragraph) > 0 ) {
1475 if ($paragraph =~ s/^(.*?\n\n+)//s) {
1476 *$self->{Pending} = $paragraph ;
1487 my $endl = quotemeta($/); # quote in case $/ contains RE meta chars
1488 while ($self->read($line) > 0 ) {
1489 if ($line =~ s/^(.*?$endl)//s) {
1490 *$self->{Pending} = $line ;
1491 $. = ++ *$self->{LineNo} ;
1496 $. = ++ *$self->{LineNo} if defined($line);
1504 my $current_append = *$self->{AppendOutput} ;
1505 *$self->{AppendOutput} = 1;
1506 my $lineref = $self->_getline();
1507 *$self->{AppendOutput} = $current_append;
1514 croak *$self->{ClassName} . "::getlines: called in scalar context\n" unless wantarray;
1516 push(@lines, $line) while defined($line = $self->getline);
1522 goto &getlines if wantarray;
1530 return $buf if $self->read($buf, 1);
1537 *$self->{Pending} = "" unless defined *$self->{Pending} ;
1538 *$self->{Pending} = $_[0] . *$self->{Pending} ;
1545 return \"" if ! defined *$self->{Trailing} ;
1546 return \*$self->{Trailing} ;
1553 # inflateSync is a no-op in Plain mode
1555 if *$self->{Plain} ;
1557 return 0 if *$self->{Closed} ;
1558 #return G_EOF if !length *$self->{Pending} && *$self->{EndStream} ;
1559 return 0 if ! length *$self->{Pending} && *$self->{EndStream} ;
1562 *$self->{Strict} = 0 ;
1569 if (length *$self->{Pending} )
1571 $temp_buf = *$self->{Pending} ;
1572 *$self->{Pending} = '';
1576 $status = $self->smartRead(\$temp_buf, *$self->{BlockSize}) ;
1577 return $self->saveErrorString(0, "Error Reading Data")
1580 if ($status == 0 ) {
1581 *$self->{EndStream} = 1 ;
1582 return $self->saveErrorString(0, "unexpected end of file", Z_DATA_ERROR);
1586 $status = *$self->{Inflate}->inflateSync($temp_buf) ;
1588 if ($status == Z_OK)
1590 *$self->{Pending} .= $temp_buf ;
1594 last unless $status = Z_DATA_ERROR ;
1604 return (*$self->{Closed} ||
1605 (!length *$self->{Pending}
1606 && ( $self->smartEof() || *$self->{EndStream}))) ;
1614 if (*$self->{Plain}) {
1615 $in = *$self->{PlainBytesRead} ;
1618 $in = *$self->{TotalInflatedBytesRead} ;
1621 my $pending = length *$self->{Pending} ;
1623 return 0 if $pending > $in ;
1624 return $in - $pending ;
1629 # todo - what to do if close is called before the end of the gzip file
1630 # do we remember any trailing data?
1633 return 1 if *$self->{Closed} ;
1640 if (defined *$self->{FH}) {
1641 if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) {
1642 #if ( *$self->{AutoClose}) {
1644 $status = *$self->{FH}->close();
1645 return $self->saveErrorString(0, $!, $!)
1646 if !*$self->{InNew} && $self->saveStatus($!) != 0 ;
1648 delete *$self->{FH} ;
1651 *$self->{Closed} = 1 ;
1665 my $position = shift;
1666 my $whence = shift ;
1668 my $here = $self->tell() ;
1672 if ($whence == SEEK_SET) {
1673 $target = $position ;
1675 elsif ($whence == SEEK_CUR) {
1676 $target = $here + $position ;
1678 elsif ($whence == SEEK_END) {
1679 $target = $position ;
1680 croak *$self->{ClassName} . "::seek: SEEK_END not allowed" ;
1683 croak *$self->{ClassName} ."::seek: unknown value, $whence, for whence parameter";
1686 # short circuit if seeking to current offset
1687 return 1 if $target == $here ;
1689 # Outlaw any attempt to seek backwards
1690 croak *$self->{ClassName} ."::seek: cannot seek backwards"
1691 if $target < $here ;
1693 # Walk the file to the new offset
1694 my $offset = $target - $here ;
1697 $self->read($buffer, $offset) == $offset
1706 return defined *$self->{FH}
1707 ? fileno *$self->{FH}
1714 # my $self = shift ;
1715 # return defined *$self->{FH}
1716 # ? binmode *$self->{FH}
1720 *BINMODE = \&binmode;
1733 #return sub { croak "$name Not Available" ; } ;
1734 return sub { croak "$name Not Available: File opened only for intput" ; } ;
1738 *print = _notAvailable('print');
1739 *PRINT = _notAvailable('print');
1740 *printf = _notAvailable('printf');
1741 *PRINTF = _notAvailable('printf');
1742 *write = _notAvailable('write');
1743 *WRITE = _notAvailable('write');
1746 #*syswrite = \&_notAvailable;
1748 #package IO::_infScan ;
1750 #*_raw_read = \&IO::BaseInflate::_raw_read ;
1751 #*smartRead = \&IO::BaseInflate::smartRead ;
1752 #*smartWrite = \&IO::BaseInflate::smartWrite ;
1753 #*smartSeek = \&IO::BaseInflate::smartSeek ;
1759 return 1 if *$self->{Closed} ;
1760 return 1 if !length *$self->{Pending} && *$self->{EndStream} ;
1765 $len = $self->_raw_read(\$buffer, 1)
1766 while ! *$self->{EndStream} && $len >= 0 ;
1768 #return $len if $len < 0 ? $len : 0 ;
1769 return $len < 0 ? 0 : 1 ;
1776 my $headerLength = *$self->{Info}{HeaderLength};
1777 my $block_offset = $headerLength + *$self->{Inflate}->getLastBlockOffset();
1778 $_[0] = $headerLength + *$self->{Inflate}->getEndOffset();
1779 #printf "# End $_[0], headerlen $headerLength \n";;
1781 #printf "# block_offset $block_offset %x\n", $block_offset;
1783 ( $self->smartSeek($block_offset) &&
1784 $self->smartRead(\$byte, 1) )
1785 or return $self->saveErrorString(0, $!, $!);
1787 #printf "#byte is %x\n", unpack('C*',$byte);
1788 *$self->{Inflate}->resetLastBlockByte($byte);
1789 #printf "#to byte is %x\n", unpack('C*',$byte);
1791 ( $self->smartSeek($block_offset) &&
1792 $self->smartWrite($byte) )
1793 or return $self->saveErrorString(0, $!, $!);
1795 #$self->smartSeek($end_offset, 1);
1803 my ($status, $def) = *$self->{Inflate}->createDeflateStream(
1805 -WindowBits => - MAX_WBITS,
1806 -CRC32 => *$self->{Type} eq 'rfc1952'
1807 || *$self->{Type} eq 'zip',
1808 -ADLER32 => *$self->{Type} eq 'rfc1950',
1811 return wantarray ? ($status, $def) : $def ;
1815 package IO::Uncompress::Gunzip ;
1823 IO::Uncompress::Gunzip - Perl interface to read RFC 1952 files/buffers
1827 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
1829 my $status = gunzip $input => $output [,OPTS]
1830 or die "gunzip failed: $GunzipError\n";
1832 my $z = new IO::Uncompress::Gunzip $input [OPTS]
1833 or die "gunzip failed: $GunzipError\n";
1835 $status = $z->read($buffer)
1836 $status = $z->read($buffer, $length)
1837 $status = $z->read($buffer, $length, $offset)
1838 $line = $z->getline()
1840 $char = $z->ungetc()
1841 $status = $z->inflateSync()
1843 $data = $z->getHeaderInfo()
1845 $z->seek($position, $whence)
1857 read($z, $buffer, $length);
1858 read($z, $buffer, $length, $offset);
1860 seek($z, $position, $whence)
1871 B<WARNING -- This is a Beta release>.
1875 =item * DO NOT use in production code.
1877 =item * The documentation is incomplete in places.
1879 =item * Parts of the interface defined here are tentative.
1881 =item * Please report any problems you find.
1889 This module provides a Perl interface that allows the reading of
1890 files/buffers that conform to RFC 1952.
1892 For writing RFC 1952 files/buffers, see the companion module
1897 =head1 Functional Interface
1899 A top-level function, C<gunzip>, is provided to carry out "one-shot"
1900 uncompression between buffers and/or files. For finer control over the uncompression process, see the L</"OO Interface"> section.
1902 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
1904 gunzip $input => $output [,OPTS]
1905 or die "gunzip failed: $GunzipError\n";
1907 gunzip \%hash [,OPTS]
1908 or die "gunzip failed: $GunzipError\n";
1910 The functional interface needs Perl5.005 or better.
1913 =head2 gunzip $input => $output [, OPTS]
1915 If the first parameter is not a hash reference C<gunzip> expects
1916 at least two parameters, C<$input> and C<$output>.
1918 =head3 The C<$input> parameter
1920 The parameter, C<$input>, is used to define the source of
1921 the compressed data.
1923 It can take one of the following forms:
1929 If the C<$input> parameter is a simple scalar, it is assumed to be a
1930 filename. This file will be opened for reading and the input data
1931 will be read from it.
1935 If the C<$input> parameter is a filehandle, the input data will be
1937 The string '-' can be used as an alias for standard input.
1939 =item A scalar reference
1941 If C<$input> is a scalar reference, the input data will be read
1944 =item An array reference
1946 If C<$input> is an array reference, the input data will be read from each
1947 element of the array in turn. The action taken by C<gunzip> with
1948 each element of the array will depend on the type of data stored
1949 in it. You can mix and match any of the types defined in this list,
1950 excluding other array or hash references.
1951 The complete array will be walked to ensure that it only
1952 contains valid data types before any data is uncompressed.
1954 =item An Input FileGlob string
1956 If C<$input> is a string that is delimited by the characters "<" and ">"
1957 C<gunzip> will assume that it is an I<input fileglob string>. The
1958 input is the list of files that match the fileglob.
1960 If the fileglob does not match any files ...
1962 See L<File::GlobMapper|File::GlobMapper> for more details.
1967 If the C<$input> parameter is any other type, C<undef> will be returned.
1971 =head3 The C<$output> parameter
1973 The parameter C<$output> is used to control the destination of the
1974 uncompressed data. This parameter can take one of these forms.
1980 If the C<$output> parameter is a simple scalar, it is assumed to be a filename.
1981 This file will be opened for writing and the uncompressed data will be
1986 If the C<$output> parameter is a filehandle, the uncompressed data will
1988 The string '-' can be used as an alias for standard output.
1991 =item A scalar reference
1993 If C<$output> is a scalar reference, the uncompressed data will be stored
1997 =item A Hash Reference
1999 If C<$output> is a hash reference, the uncompressed data will be written
2000 to C<$output{$input}> as a scalar reference.
2002 When C<$output> is a hash reference, C<$input> must be either a filename or
2003 list of filenames. Anything else is an error.
2006 =item An Array Reference
2008 If C<$output> is an array reference, the uncompressed data will be pushed
2011 =item An Output FileGlob
2013 If C<$output> is a string that is delimited by the characters "<" and ">"
2014 C<gunzip> will assume that it is an I<output fileglob string>. The
2015 output is the list of files that match the fileglob.
2017 When C<$output> is an fileglob string, C<$input> must also be a fileglob
2018 string. Anything else is an error.
2022 If the C<$output> parameter is any other type, C<undef> will be returned.
2024 =head2 gunzip \%hash [, OPTS]
2026 If the first parameter is a hash reference, C<\%hash>, this will be used to
2027 define both the source of compressed data and to control where the
2028 uncompressed data is output. Each key/value pair in the hash defines a
2029 mapping between an input filename, stored in the key, and an output
2030 file/buffer, stored in the value. Although the input can only be a filename,
2031 there is more flexibility to control the destination of the uncompressed
2032 data. This is determined by the type of the value. Valid types are
2038 If the value is C<undef> the uncompressed data will be written to the
2039 value as a scalar reference.
2043 If the value is a simple scalar, it is assumed to be a filename. This file will
2044 be opened for writing and the uncompressed data will be written to it.
2048 If the value is a filehandle, the uncompressed data will be
2050 The string '-' can be used as an alias for standard output.
2053 =item A scalar reference
2055 If the value is a scalar reference, the uncompressed data will be stored
2056 in the buffer that is referenced by the scalar.
2059 =item A Hash Reference
2061 If the value is a hash reference, the uncompressed data will be written
2062 to C<$hash{$input}> as a scalar reference.
2064 =item An Array Reference
2066 If C<$output> is an array reference, the uncompressed data will be pushed
2071 Any other type is a error.
2075 When C<$input> maps to multiple files/buffers and C<$output> is a single
2076 file/buffer the uncompressed input files/buffers will all be stored in
2077 C<$output> as a single uncompressed stream.
2081 =head2 Optional Parameters
2083 Unless specified below, the optional parameters for C<gunzip>,
2084 C<OPTS>, are the same as those used with the OO interface defined in the
2085 L</"Constructor Options"> section below.
2089 =item AutoClose =E<gt> 0|1
2091 This option applies to any input or output data streams to C<gunzip>
2092 that are filehandles.
2094 If C<AutoClose> is specified, and the value is true, it will result in all
2095 input and/or output filehandles being closed once C<gunzip> has
2098 This parameter defaults to 0.
2102 =item -Append =E<gt> 0|1
2115 To read the contents of the file C<file1.txt.gz> and write the
2116 compressed data to the file C<file1.txt>.
2120 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
2122 my $input = "file1.txt.gz";
2123 my $output = "file1.txt";
2124 gunzip $input => $output
2125 or die "gunzip failed: $GunzipError\n";
2128 To read from an existing Perl filehandle, C<$input>, and write the
2129 uncompressed data to a buffer, C<$buffer>.
2133 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
2136 my $input = new IO::File "<file1.txt.gz"
2137 or die "Cannot open 'file1.txt.gz': $!\n" ;
2139 gunzip $input => \$buffer
2140 or die "gunzip failed: $GunzipError\n";
2142 To uncompress all files in the directory "/my/home" that match "*.txt.gz" and store the compressed data in the same directory
2146 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
2148 gunzip '</my/home/*.txt.gz>' => '</my/home/#1.txt>'
2149 or die "gunzip failed: $GunzipError\n";
2151 and if you want to compress each file one at a time, this will do the trick
2155 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
2157 for my $input ( glob "/my/home/*.txt.gz" )
2159 my $output = $input;
2160 $output =~ s/.gz// ;
2161 gunzip $input => $output
2162 or die "Error compressing '$input': $GunzipError\n";
2169 The format of the constructor for IO::Uncompress::Gunzip is shown below
2172 my $z = new IO::Uncompress::Gunzip $input [OPTS]
2173 or die "IO::Uncompress::Gunzip failed: $GunzipError\n";
2175 Returns an C<IO::Uncompress::Gunzip> object on success and undef on failure.
2176 The variable C<$GunzipError> will contain an error message on failure.
2178 If you are running Perl 5.005 or better the object, C<$z>, returned from
2179 IO::Uncompress::Gunzip can be used exactly like an L<IO::File|IO::File> filehandle.
2180 This means that all normal input file operations can be carried out with C<$z>.
2181 For example, to read a line from a compressed file/buffer you can use either
2184 $line = $z->getline();
2187 The mandatory parameter C<$input> is used to determine the source of the
2188 compressed data. This parameter can take one of three forms.
2194 If the C<$input> parameter is a scalar, it is assumed to be a filename. This
2195 file will be opened for reading and the compressed data will be read from it.
2199 If the C<$input> parameter is a filehandle, the compressed data will be
2201 The string '-' can be used as an alias for standard input.
2204 =item A scalar reference
2206 If C<$input> is a scalar reference, the compressed data will be read from
2211 =head2 Constructor Options
2214 The option names defined below are case insensitive and can be optionally
2215 prefixed by a '-'. So all of the following are valid
2222 OPTS is a combination of the following options:
2226 =item -AutoClose =E<gt> 0|1
2228 This option is only valid when the C<$input> parameter is a filehandle. If
2229 specified, and the value is true, it will result in the file being closed once
2230 either the C<close> method is called or the IO::Uncompress::Gunzip object is
2233 This parameter defaults to 0.
2235 =item -MultiStream =E<gt> 0|1
2239 Allows multiple concatenated compressed streams to be treated as a single
2240 compressed stream. Decompression will stop once either the end of the
2241 file/buffer is reached, an error is encountered (premature eof, corrupt
2242 compressed data) or the end of a stream is not immediately followed by the
2243 start of another stream.
2245 This parameter defaults to 0.
2249 =item -Prime =E<gt> $string
2251 This option will uncompress the contents of C<$string> before processing the
2254 This option can be useful when the compressed data is embedded in another
2255 file/data structure and it is not possible to work out where the compressed
2256 data begins without having to read the first few bytes. If this is the case,
2257 the uncompression can be I<primed> with these bytes using this option.
2259 =item -Transparent =E<gt> 0|1
2261 If this option is set and the input file or buffer is not compressed data,
2262 the module will allow reading of it anyway.
2264 This option defaults to 1.
2266 =item -BlockSize =E<gt> $num
2268 When reading the compressed input data, IO::Uncompress::Gunzip will read it in blocks
2271 This option defaults to 4096.
2273 =item -InputLength =E<gt> $size
2275 When present this option will limit the number of compressed bytes read from
2276 the input file/buffer to C<$size>. This option can be used in the situation
2277 where there is useful data directly after the compressed data stream and you
2278 know beforehand the exact length of the compressed data stream.
2280 This option is mostly used when reading from a filehandle, in which case the
2281 file pointer will be left pointing to the first byte directly after the
2282 compressed data stream.
2286 This option defaults to off.
2288 =item -Append =E<gt> 0|1
2290 This option controls what the C<read> method does with uncompressed data.
2292 If set to 1, all uncompressed data will be appended to the output parameter of
2295 If set to 0, the contents of the output parameter of the C<read> method will be
2296 overwritten by the uncompressed data.
2300 =item -Strict =E<gt> 0|1
2304 This option controls whether the extra checks defined below are used when
2305 carrying out the decompression. When Strict is on, the extra tests are carried
2306 out, when Strict is off they are not.
2308 The default for this option is off.
2322 If the FHCRC bit is set in the gzip FLG header byte, the CRC16 bytes in the
2323 header must match the crc16 value of the gzip header actually read.
2327 If the gzip header contains a name field (FNAME) it consists solely of ISO
2332 If the gzip header contains a comment field (FCOMMENT) it consists solely of
2333 ISO 8859-1 characters plus line-feed.
2337 If the gzip FEXTRA header field is present it must conform to the sub-field
2338 structure as defined in RFC1952.
2342 The CRC32 and ISIZE trailer fields must be present.
2346 The value of the CRC32 field read must match the crc32 value of the
2347 uncompressed data actually contained in the gzip file.
2351 The value of the ISIZE fields read must match the length of the uncompressed
2352 data actually read from the file.
2361 =item -ParseExtra =E<gt> 0|1
2363 If the gzip FEXTRA header field is present and this option is set, it will
2364 force the module to check that it conforms to the sub-field structure as
2367 If the C<Strict> is on it will automatically enable this option.
2385 $status = $z->read($buffer)
2387 Reads a block of compressed data (the size the the compressed block is
2388 determined by the C<Buffer> option in the constructor), uncompresses it and
2389 writes any uncompressed data into C<$buffer>. If the C<Append> parameter is set
2390 in the constructor, the uncompressed data will be appended to the C<$buffer>
2391 parameter. Otherwise C<$buffer> will be overwritten.
2393 Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or
2394 a negative number on error.
2400 $status = $z->read($buffer, $length)
2401 $status = $z->read($buffer, $length, $offset)
2403 $status = read($z, $buffer, $length)
2404 $status = read($z, $buffer, $length, $offset)
2406 Attempt to read C<$length> bytes of uncompressed data into C<$buffer>.
2408 The main difference between this form of the C<read> method and the previous
2409 one, is that this one will attempt to return I<exactly> C<$length> bytes. The
2410 only circumstances that this function will not is if end-of-file or an IO error
2413 Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or
2414 a negative number on error.
2421 $line = $z->getline()
2424 Reads a single line.
2426 This method fully supports the use of of the variable C<$/>
2427 (or C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use) to
2428 determine what constitutes an end of line. Both paragraph mode and file
2429 slurp mode are supported.
2438 Read a single character.
2444 $char = $z->ungetc($string)
2451 $status = $z->inflateSync()
2455 =head2 getHeaderInfo
2459 $hdr = $z->getHeaderInfo()
2467 This method returns a hash reference that contains the contents of each of the
2468 header fields defined in RFC1952.
2479 The contents of the Comment header field, if present. If no comment is present,
2480 the value will be undef. Note this is different from a zero length comment,
2481 which will return an empty string.
2495 Returns the uncompressed file offset.
2506 Returns true if the end of the compressed input stream has been reached.
2512 $z->seek($position, $whence);
2513 seek($z, $position, $whence);
2518 Provides a sub-set of the C<seek> functionality, with the restriction
2519 that it is only legal to seek forward in the input file/buffer.
2520 It is a fatal error to attempt to seek backward.
2524 The C<$whence> parameter takes one the usual values, namely SEEK_SET,
2525 SEEK_CUR or SEEK_END.
2527 Returns 1 on success, 0 on failure.
2536 This is a noop provided for completeness.
2543 If the C<$z> object is associated with a file, this method will return
2544 the underlying filehandle.
2546 If the C<$z> object is is associated with a buffer, this method will
2556 Closes the output file/buffer.
2560 For most versions of Perl this method will be automatically invoked if
2561 the IO::Uncompress::Gunzip object is destroyed (either explicitly or by the
2562 variable with the reference to the object going out of scope). The
2563 exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
2564 these cases, the C<close> method will be called automatically, but
2565 not until global destruction of all live objects when the program is
2568 Therefore, if you want your scripts to be able to run on all versions
2569 of Perl, you should call C<close> explicitly and not rely on automatic
2572 Returns true on success, otherwise 0.
2574 If the C<AutoClose> option has been enabled when the IO::Uncompress::Gunzip
2575 object was created, and the object is associated with a file, the
2576 underlying file will also be closed.
2583 No symbolic constants are required by this IO::Uncompress::Gunzip at present.
2589 Imports C<gunzip> and C<$GunzipError>.
2592 use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
2603 L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Uncompress::AnyInflate>
2605 L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
2607 L<File::GlobMapper|File::GlobMapper>, L<Archive::Tar|Archive::Zip>,
2608 L<IO::Zlib|IO::Zlib>
2610 For RFC 1950, 1951 and 1952 see
2611 F<http://www.faqs.org/rfcs/rfc1950.html>,
2612 F<http://www.faqs.org/rfcs/rfc1951.html> and
2613 F<http://www.faqs.org/rfcs/rfc1952.html>
2615 The primary site for the gzip program is F<http://www.gzip.org>.
2619 The I<IO::Uncompress::Gunzip> module was written by Paul Marquess,
2620 F<pmqs@cpan.org>. The latest copy of the module can be
2621 found on CPAN in F<modules/by-module/Compress/Compress-Zlib-x.x.tar.gz>.
2623 The I<zlib> compression library was written by Jean-loup Gailly
2624 F<gzip@prep.ai.mit.edu> and Mark Adler F<madler@alumni.caltech.edu>.
2626 The primary site for the I<zlib> compression library is
2627 F<http://www.zlib.org>.
2629 =head1 MODIFICATION HISTORY
2631 See the Changes file.
2633 =head1 COPYRIGHT AND LICENSE
2636 Copyright (c) 2005 Paul Marquess. All rights reserved.
2637 This program is free software; you can redistribute it and/or
2638 modify it under the same terms as Perl itself.