2 package IO::Uncompress::Base ;
8 our (@ISA, $VERSION, @EXPORT_OK, %EXPORT_TAGS);
9 #@ISA = qw(Exporter IO::File);
13 $VERSION = '2.000_13';
15 use constant G_EOF => 0 ;
16 use constant G_ERR => -1 ;
18 use IO::Compress::Base::Common;
19 #use Parse::Parameters ;
23 use Scalar::Util qw(readonly);
24 use List::Util qw(min);
28 push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
29 #Exporter::export_ok_tags('all') ;
42 if (defined *$self->{InputLength}) {
44 if *$self->{InputLengthRemaining} <= 0 ;
45 $size = min($size, *$self->{InputLengthRemaining});
48 if ( length *$self->{Prime} ) {
49 #$$out = substr(*$self->{Prime}, 0, $size, '') ;
50 $$out = substr(*$self->{Prime}, 0, $size) ;
51 substr(*$self->{Prime}, 0, $size) = '' ;
52 if (length $$out == $size) {
53 *$self->{InputLengthRemaining} -= length $$out
54 if defined *$self->{InputLength};
58 $offset = length $$out ;
61 my $get_size = $size - $offset ;
63 #if ( defined *$self->{InputLength} ) {
64 # $get_size = min($get_size, *$self->{InputLengthRemaining});
67 if (defined *$self->{FH})
68 { *$self->{FH}->read($$out, $get_size, $offset) }
69 elsif (defined *$self->{InputEvent}) {
71 while (length $$out < $size) {
73 if ($got = *$self->{InputEvent}->($$out, $get_size)) <= 0;
76 if (length $$out > $size ) {
77 #*$self->{Prime} = substr($$out, $size, length($$out), '');
78 *$self->{Prime} = substr($$out, $size, length($$out));
79 substr($$out, $size, length($$out)) = '';
82 *$self->{EventEof} = 1 if $got <= 0 ;
85 no warnings 'uninitialized';
86 my $buf = *$self->{Buffer} ;
87 $$buf = '' unless defined $$buf ;
88 #$$out = '' unless defined $$out ;
89 substr($$out, $offset) = substr($$buf, *$self->{BufferOffset}, $get_size);
90 if (*$self->{ConsumeInput})
91 { substr($$buf, 0, $get_size) = '' }
93 { *$self->{BufferOffset} += length($$out) - $offset }
96 *$self->{InputLengthRemaining} -= length($$out) #- $offset
97 if defined *$self->{InputLength};
99 $self->saveStatus(length $$out < 0 ? STATUS_ERROR : STATUS_OK) ;
108 return if ! defined $_[0] || length $_[0] == 0 ;
110 if (defined *$self->{FH} || defined *$self->{InputEvent} ) {
111 *$self->{Prime} = $_[0] . *$self->{Prime} ;
112 *$self->{InputLengthRemaining} += length($_[0]);
115 my $len = length $_[0];
117 if($len > *$self->{BufferOffset}) {
118 *$self->{Prime} = substr($_[0], 0, $len - *$self->{BufferOffset}) . *$self->{Prime} ;
119 *$self->{InputLengthRemaining} = *$self->{InputLength};
120 *$self->{BufferOffset} = 0
123 *$self->{InputLengthRemaining} += length($_[0]);
124 *$self->{BufferOffset} -= length($_[0]) ;
133 my $truncate = shift;
134 #print "smartSeek to $offset\n";
136 # TODO -- need to take prime into account
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];
175 return 0 if length *$self->{Prime} || *$self->{PushMode};
177 if (defined *$self->{FH})
178 { *$self->{FH}->eof() }
179 elsif (defined *$self->{InputEvent})
180 { *$self->{EventEof} }
182 { *$self->{BufferOffset} >= length(${ *$self->{Buffer} }) }
189 *$self->{ErrorNo} = 0 ;
190 ${ *$self->{Error} } = '' ;
196 my $errno = shift() + 0 ;
197 #return $errno unless $errno || ! defined *$self->{ErrorNo};
198 #return $errno unless $errno ;
200 *$self->{ErrorNo} = $errno;
201 ${ *$self->{Error} } = '' ;
203 return *$self->{ErrorNo} ;
212 #return $retval if ${ *$self->{Error} };
214 ${ *$self->{Error} } = shift ;
215 *$self->{ErrorNo} = shift() + 0 if @_ ;
217 #warn "saveErrorString: " . ${ *$self->{Error} } . " " . *$self->{Error} . "\n" ;
224 $self->saveErrorString(0, $_[0]);
234 my $errno = *$self->{ErrorNo};
235 my $error = ${ *$self->{Error} };
239 *$self->{ErrorNo} = $errno ;
240 ${ *$self->{Error} } = $error ;
248 return ${ *$self->{Error} } ;
254 return *$self->{ErrorNo};
260 return $self->saveErrorString(undef, "Header Error: $_[0]", STATUS_ERROR);
266 return $self->saveErrorString(G_ERR, "Trailer Error: $_[0]", STATUS_ERROR);
272 return $self->HeaderError("Truncated in $_[0] Section");
278 return $self->TrailerError("Truncated in $_[0] Section");
286 my $got = shift || IO::Compress::Base::Parameters::new();
289 'BlockSize' => [1, 1, Parse_unsigned, 16 * 1024],
290 'AutoClose' => [1, 1, Parse_boolean, 0],
291 'Strict' => [1, 1, Parse_boolean, 0],
292 #'Lax' => [1, 1, Parse_boolean, 1],
293 'Append' => [1, 1, Parse_boolean, 0],
294 'Prime' => [1, 1, Parse_any, undef],
295 'MultiStream' => [1, 1, Parse_boolean, 0],
296 'Transparent' => [1, 1, Parse_any, 1],
297 'Scan' => [1, 1, Parse_boolean, 0],
298 'InputLength' => [1, 1, Parse_unsigned, undef],
299 'BinModeOut' => [1, 1, Parse_boolean, 0],
300 #'ConsumeInput' => [1, 1, Parse_boolean, 0],
302 $self->getExtraParams(),
305 #'Todo - Revert to ordinary file on end Z_STREAM_END'=> 0,
310 $got->parse($Valid, @_ )
311 or $self->croakError("${class}: $got->{Error}") ;
321 my $append_mode = shift ;
323 my $class = ref $obj;
324 $obj->croakError("$class: Missing Input parameter")
327 my $inValue = shift ;
331 $got = $obj->checkParams($class, undef, @_)
335 my $inType = whatIsInput($inValue, 1);
337 $obj->ckInputParam($class, $inValue, 1)
343 or $obj->croakError("${class}: $obj->{Error}");
345 if ($inType eq 'buffer' || $inType eq 'code') {
346 *$obj->{Buffer} = $inValue ;
347 *$obj->{InputEvent} = $inValue
348 if $inType eq 'code' ;
351 if ($inType eq 'handle') {
352 *$obj->{FH} = $inValue ;
353 *$obj->{Handle} = 1 ;
354 # Need to rewind for Scan
355 #seek(*$obj->{FH}, 0, SEEK_SET) if $got->value('Scan');
356 *$obj->{FH}->seek(0, SEEK_SET) if $got->value('Scan');
360 $mode = '+<' if $got->value('Scan');
361 *$obj->{StdIO} = ($inValue eq '-');
362 *$obj->{FH} = new IO::File "$mode $inValue"
363 or return $obj->saveErrorString(undef, "cannot open file '$inValue': $!", $!) ;
366 *$obj->{LineNo} = $. = 0;
367 setBinModeInput(*$obj->{FH}) ;
370 *$obj->{Buffer} = \$buff ;
374 *$obj->{InputLength} = $got->parsed('InputLength')
375 ? $got->value('InputLength')
377 *$obj->{InputLengthRemaining} = $got->value('InputLength');
378 *$obj->{BufferOffset} = 0 ;
379 *$obj->{AutoClose} = $got->value('AutoClose');
380 *$obj->{Strict} = $got->value('Strict');
381 *$obj->{BlockSize} = $got->value('BlockSize');
382 *$obj->{Append} = $got->value('Append');
383 *$obj->{AppendOutput} = $append_mode || $got->value('Append');
384 *$obj->{ConsumeInput} = $got->value('ConsumeInput');
385 *$obj->{Transparent} = $got->value('Transparent');
386 *$obj->{MultiStream} = $got->value('MultiStream');
388 # TODO - move these two into RawDeflate
389 *$obj->{Scan} = $got->value('Scan');
390 *$obj->{ParseExtra} = $got->value('ParseExtra')
391 || $got->value('Strict') ;
393 *$obj->{Prime} = $got->value('Prime') || '' ;
394 *$obj->{Pending} = '';
396 *$obj->{PlainBytesRead} = 0;
397 *$obj->{InflatedBytesRead} = 0;
398 *$obj->{UnCompSize} = new U64;
399 *$obj->{CompSize} = new U64;
400 *$obj->{TotalInflatedBytesRead} = 0;
401 *$obj->{NewStream} = 0 ;
402 *$obj->{EventEof} = 0 ;
403 *$obj->{ClassName} = $class ;
404 *$obj->{Params} = $got ;
406 if (*$obj->{ConsumeInput}) {
412 my $status = $obj->mkUncomp($class, $got);
415 unless defined $status;
419 unless *$obj->{Transparent};
422 *$obj->{Type} = 'plain';
424 #$status = $obj->mkIdentityUncomp($class, $got);
425 $obj->pushBack(*$obj->{HeaderPending}) ;
428 push @{ *$obj->{InfoList} }, *$obj->{Info} ;
430 $obj->saveStatus(STATUS_OK) ;
441 my $inType = whatIsInput($_[0], $_[1]);
443 $self->croakError("$from: input parameter not a filename, filehandle, array ref or scalar ref")
446 if ($inType eq 'filename' )
448 $self->croakError("$from: input filename is undef or null string")
449 if ! defined $_[0] || $_[0] eq '' ;
451 if ($_[0] ne '-' && ! -e $_[0] )
453 return $self->saveErrorString(undef,
454 "input file '$_[0]' does not exist", STATUS_ERROR);
466 my $class = (caller)[0] ;
467 my $name = (caller(1))[3] ;
469 $obj->croakError("$name: expected at least 1 parameters\n")
477 my $x = new Validator($class, *$obj->{Error}, $name, $input, $output)
480 push @_, $output if $haveOut && $x->{Hash};
482 my $got = $obj->checkParams($name, undef, @_)
485 *$obj->{MultiStream} = $got->value('MultiStream');
486 $got->value('MultiStream', 0);
492 # while (my($k, $v) = each %$input)
495 # unless defined $v ;
497 # $obj->_singleTarget($x, $k, $v, @_)
501 # return keys %$input ;
507 foreach my $pair (@{ $x->{Pairs} })
509 my ($from, $to) = @$pair ;
510 $obj->_singleTarget($x, $from, $to, @_)
514 return scalar @{ $x->{Pairs} } ;
517 if (! $x->{oneOutput} )
519 my $inFile = ($x->{inType} eq 'filenames'
520 || $x->{inType} eq 'filename');
522 $x->{inType} = $inFile ? 'filename' : 'buffer';
524 foreach my $in ($x->{oneInput} ? $input : @$input)
529 $obj->_singleTarget($x, $in, $output, @_)
536 # finally the 1 to 1 and n to 1
537 return $obj->_singleTarget($x, $input, $output, @_);
539 croak "should not be here" ;
547 ${ $x->{Error} } = $string ;
560 $x->{buff} = \$buff ;
563 if ($x->{outType} eq 'filename') {
566 if $x->{Got}->value('Append') ;
567 $x->{fh} = new IO::File "$mode $output"
568 or return retErr($x, "cannot open file '$output': $!") ;
569 binmode $x->{fh} if $x->{Got}->valueOrDefault('BinModeOut');
573 elsif ($x->{outType} eq 'handle') {
575 binmode $x->{fh} if $x->{Got}->valueOrDefault('BinModeOut');
576 if ($x->{Got}->value('Append')) {
577 seek($x->{fh}, 0, SEEK_END)
578 or return retErr($x, "Cannot seek to end of output filehandle: $!") ;
583 elsif ($x->{outType} eq 'buffer' )
586 unless $x->{Got}->value('Append');
587 $x->{buff} = $output ;
592 defined $self->_rd2($x, $input, $output)
597 for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input)
599 defined $self->_rd2($x, $element, $output)
605 if ( ($x->{outType} eq 'filename' && $output ne '-') ||
606 ($x->{outType} eq 'handle' && $x->{Got}->value('AutoClose'))) {
608 or return retErr($x, $!);
622 my $z = createSelfTiedObject($x->{Class}, *$self->{Error});
624 $z->_create($x->{Got}, 1, $input, @_)
632 while (($status = $z->read($x->{buff})) > 0) {
634 print $fh ${ $x->{buff} }
635 or return $z->saveErrorString(undef, "Error writing to output file: $!", $!);
636 ${ $x->{buff} } = '' ;
640 if (! $x->{oneOutput} ) {
641 my $ot = $x->{outType} ;
644 { push @$output, $x->{buff} }
645 elsif ($ot eq 'hash')
646 { $output->{$input} = $x->{buff} }
653 unless *$self->{MultiStream};
655 $status = $z->nextStream();
658 unless $status == 1 ;
661 return $z->closeError(undef)
672 return $_[0] if ref($_[0]);
686 wantarray ? @{ *$self->{InfoList} } : *$self->{Info};
695 if (defined *$self->{CompressedInputLength}) {
696 if (*$self->{CompressedInputLengthRemaining} == 0) {
697 delete *$self->{CompressedInputLength};
698 *$self->{CompressedInputLengthDone} = 1;
701 $size = min($size, *$self->{CompressedInputLengthRemaining} );
702 *$self->{CompressedInputLengthRemaining} -= $size ;
705 my $status = $self->smartRead($buff, $size) ;
706 return $self->saveErrorString(STATUS_ERROR, "Error Reading Data")
710 *$self->{Closed} = 1 ;
711 *$self->{EndStream} = 1 ;
712 return $self->saveErrorString(STATUS_ERROR, "unexpected end of file", STATUS_ERROR);
726 # >0 - ok, number of bytes read
732 return G_EOF if *$self->{Closed} ;
733 #return G_EOF if !length *$self->{Pending} && *$self->{EndStream} ;
734 return G_EOF if *$self->{EndStream} ;
737 my $scan_mode = shift ;
739 if (*$self->{Plain}) {
741 my $len = $self->smartRead(\$tmp_buff, *$self->{BlockSize}) ;
743 return $self->saveErrorString(G_ERR, "Error reading data: $!", $!)
747 *$self->{EndStream} = 1 ;
750 *$self->{PlainBytesRead} += $len ;
751 $$buffer .= $tmp_buff;
757 if (*$self->{NewStream}) {
759 $self->gotoNextStream() > 0
762 # For the headers that actually uncompressed data, put the
763 # uncompressed data into the output buffer.
764 $$buffer .= *$self->{Pending} ;
765 my $len = length *$self->{Pending} ;
766 *$self->{Pending} = '';
772 my $status = $self->readBlock(\$temp_buf, *$self->{BlockSize}, $outSize) ;
774 if $status == STATUS_ERROR ;
778 if ($status == STATUS_OK) {
779 my $beforeC_len = length $temp_buf;
780 my $before_len = defined $$buffer ? length $$buffer : 0 ;
781 $status = *$self->{Uncomp}->uncompr(\$temp_buf, $buffer,
782 defined *$self->{CompressedInputLengthDone} ||
783 $self->smartEof(), $outSize);
785 return $self->saveErrorString(G_ERR, *$self->{Uncomp}{Error}, *$self->{Uncomp}{ErrorNo})
786 if $self->saveStatus($status) == STATUS_ERROR;
788 $self->postBlockChk($buffer) == STATUS_OK
791 $self->filterUncompressed($buffer);
793 $buf_len = length($$buffer) - $before_len;
796 *$self->{CompSize}->add($beforeC_len - length $temp_buf) ;
798 *$self->{InflatedBytesRead} += $buf_len ;
799 *$self->{TotalInflatedBytesRead} += $buf_len ;
800 *$self->{UnCompSize}->add($buf_len) ;
803 if ($status == STATUS_ENDSTREAM) {
805 *$self->{EndStream} = 1 ;
806 $self->pushBack($temp_buf) ;
810 my $trailer_size = *$self->{Info}{TrailerLength} ;
812 if (*$self->{Info}{TrailerLength})
814 $got = $self->smartRead(\$trailer, $trailer_size) ;
817 if ($got == $trailer_size) {
818 $self->chkTrailer($trailer) == STATUS_OK
822 return $self->TrailerError("trailer truncated. Expected " .
823 "$trailer_size bytes, got $got")
825 $self->pushBack($trailer) ;
828 if (! $self->smartEof()) {
829 *$self->{NewStream} = 1 ;
831 if (*$self->{MultiStream}) {
832 *$self->{EndStream} = 0 ;
840 # return the number of uncompressed bytes read
848 return *$self->{Uncomp}->reset();
851 sub filterUncompressed
858 # return *$self->{NewStream} ||
859 # *$self->{EndStream} ;
866 my $status = $self->gotoNextStream();
870 *$self->{TotalInflatedBytesRead} = 0 ;
871 *$self->{LineNo} = $. = 0;
880 if (! *$self->{NewStream}) {
884 # TODO - make this more efficient if know the offset for the end of
885 # the stream and seekable
886 $status = $self->read($buffer)
893 *$self->{NewStream} = 0 ;
894 *$self->{EndStream} = 0 ;
896 *$self->{UnCompSize}->reset();
897 *$self->{CompSize}->reset();
899 my $magic = $self->ckMagic();
902 *$self->{EndStream} = 1 ;
906 *$self->{Info} = $self->readHeader($magic);
908 if ( ! defined *$self->{Info} ) {
909 *$self->{EndStream} = 1 ;
913 push @{ *$self->{InfoList} }, *$self->{Info} ;
921 return 1 if ! defined *$self->{InfoList};
922 return scalar @{ *$self->{InfoList} } ;
928 # >0 - ok, number of bytes read
934 return G_EOF if *$self->{Closed} ;
935 return G_EOF if !length *$self->{Pending} && *$self->{EndStream} ;
939 #$self->croakError(*$self->{ClassName} .
940 # "::read: buffer parameter is read-only")
941 # if Compress::Raw::Zlib::_readonly_ref($_[0]);
944 $self->croakError(*$self->{ClassName} . "::read: buffer parameter is read-only")
945 if readonly(${ $_[0] });
947 $self->croakError(*$self->{ClassName} . "::read: not a scalar reference $_[0]" )
948 unless ref $_[0] eq 'SCALAR' ;
952 $self->croakError(*$self->{ClassName} . "::read: buffer parameter is read-only")
959 my $offset = $_[2] || 0;
961 # the core read will return 0 if asked for 0 bytes
962 return 0 if defined $length && $length == 0 ;
964 $length = $length || 0;
966 $self->croakError(*$self->{ClassName} . "::read: length parameter is negative")
969 $$buffer = '' unless *$self->{AppendOutput} || $offset ;
971 # Short-circuit if this is a simple read, with no length
972 # or offset specified.
973 unless ( $length || $offset) {
974 if (length *$self->{Pending}) {
975 $$buffer .= *$self->{Pending} ;
976 my $len = length *$self->{Pending};
977 *$self->{Pending} = '' ;
982 $len = $self->_raw_read($buffer)
983 while ! *$self->{EndStream} && $len == 0 ;
988 # Need to jump through more hoops - either length or offset
989 # or both are specified.
990 my $out_buffer = \*$self->{Pending} ;
992 while (! *$self->{EndStream} && length($$out_buffer) < $length)
994 my $buf_len = $self->_raw_read($out_buffer);
999 $length = length $$out_buffer
1000 if length($$out_buffer) < $length ;
1003 $$buffer .= "\x00" x ($offset - length($$buffer))
1004 if $offset > length($$buffer) ;
1005 #substr($$buffer, $offset) = substr($$out_buffer, 0, $length, '') ;
1006 substr($$buffer, $offset) = substr($$out_buffer, 0, $length) ;
1007 substr($$out_buffer, 0, $length) = '' ;
1010 #$$buffer .= substr($$out_buffer, 0, $length, '') ;
1011 $$buffer .= substr($$out_buffer, 0, $length) ;
1012 substr($$out_buffer, 0, $length) = '' ;
1023 if ( ! defined $/ ) {
1025 1 while $self->read($data) > 0 ;
1026 $. = ++ *$self->{LineNo} if defined($data);
1031 if ( ! length $/ ) {
1033 while ($self->read($paragraph) > 0 ) {
1034 if ($paragraph =~ s/^(.*?\n\n+)//s) {
1035 *$self->{Pending} = $paragraph ;
1037 $. = ++ *$self->{LineNo} ;
1041 $. = ++ *$self->{LineNo} if defined($paragraph);
1048 my $endl = quotemeta($/); # quote in case $/ contains RE meta chars
1049 while ($self->read($line) > 0 ) {
1050 if ($line =~ s/^(.*?$endl)//s) {
1051 *$self->{Pending} = $line ;
1052 $. = ++ *$self->{LineNo} ;
1057 $. = ++ *$self->{LineNo} if defined($line);
1065 my $current_append = *$self->{AppendOutput} ;
1066 *$self->{AppendOutput} = 1;
1067 my $lineref = $self->_getline();
1068 *$self->{AppendOutput} = $current_append;
1075 $self->croakError(*$self->{ClassName} .
1076 "::getlines: called in scalar context\n") unless wantarray;
1078 push(@lines, $line) while defined($line = $self->getline);
1084 goto &getlines if wantarray;
1092 return $buf if $self->read($buf, 1);
1099 *$self->{Pending} = "" unless defined *$self->{Pending} ;
1100 *$self->{Pending} = $_[0] . *$self->{Pending} ;
1107 #return \"" if ! defined *$self->{Trailing} ;
1108 #return \*$self->{Trailing} ;
1110 if (defined *$self->{FH} || defined *$self->{InputEvent} ) {
1111 return *$self->{Prime} ;
1114 my $buf = *$self->{Buffer} ;
1115 my $offset = *$self->{BufferOffset} ;
1116 return substr($$buf, $offset, -1) ;
1125 return (*$self->{Closed} ||
1126 (!length *$self->{Pending}
1127 && ( $self->smartEof() || *$self->{EndStream}))) ;
1135 if (*$self->{Plain}) {
1136 $in = *$self->{PlainBytesRead} ;
1139 $in = *$self->{TotalInflatedBytesRead} ;
1142 my $pending = length *$self->{Pending} ;
1144 return 0 if $pending > $in ;
1145 return $in - $pending ;
1150 # todo - what to do if close is called before the end of the gzip file
1151 # do we remember any trailing data?
1154 return 1 if *$self->{Closed} ;
1161 if (defined *$self->{FH}) {
1162 if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) {
1163 #if ( *$self->{AutoClose}) {
1166 $status = *$self->{FH}->close();
1167 return $self->saveErrorString(0, $!, $!)
1168 if !*$self->{InNew} && $self->saveStatus($!) != 0 ;
1170 delete *$self->{FH} ;
1173 *$self->{Closed} = 1 ;
1187 my $position = shift;
1188 my $whence = shift ;
1190 my $here = $self->tell() ;
1194 if ($whence == SEEK_SET) {
1195 $target = $position ;
1197 elsif ($whence == SEEK_CUR) {
1198 $target = $here + $position ;
1200 elsif ($whence == SEEK_END) {
1201 $target = $position ;
1202 $self->croakError(*$self->{ClassName} . "::seek: SEEK_END not allowed") ;
1205 $self->croakError(*$self->{ClassName} ."::seek: unknown value, $whence, for whence parameter");
1208 # short circuit if seeking to current offset
1209 return 1 if $target == $here ;
1211 # Outlaw any attempt to seek backwards
1212 $self->croakError( *$self->{ClassName} ."::seek: cannot seek backwards")
1213 if $target < $here ;
1215 # Walk the file to the new offset
1216 my $offset = $target - $here ;
1219 $self->read($buffer, $offset) == $offset
1228 return defined *$self->{FH}
1229 ? fileno *$self->{FH}
1236 # my $self = shift ;
1237 # return defined *$self->{FH}
1238 # ? binmode *$self->{FH}
1245 return ! *$self->{Closed} ;
1251 return defined *$self->{FH}
1252 ? *$self->{FH}->autoflush(@_)
1256 sub input_line_number
1259 my $last = *$self->{LineNo};
1260 $. = *$self->{LineNo} = $_[1] if @_ ;
1265 *BINMODE = \&binmode;
1278 #return sub { croak "$name Not Available" ; } ;
1279 return sub { croak "$name Not Available: File opened only for intput" ; } ;
1283 *print = _notAvailable('print');
1284 *PRINT = _notAvailable('print');
1285 *printf = _notAvailable('printf');
1286 *PRINTF = _notAvailable('printf');
1287 *write = _notAvailable('write');
1288 *WRITE = _notAvailable('write');
1291 #*syswrite = \&_notAvailable;
1295 package IO::Uncompress::Base ;
1304 IO::Uncompress::Base - Base Class for IO::Uncompress modules
1309 use IO::Uncompress::Base ;
1314 This module is not intended for direct use in application code. Its sole
1315 purpose if to to be sub-classed by IO::Unompress modules.
1322 L<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::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
1324 L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
1326 L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
1327 L<Archive::Tar|Archive::Tar>,
1328 L<IO::Zlib|IO::Zlib>
1336 This module was written by Paul Marquess, F<pmqs@cpan.org>.
1340 =head1 MODIFICATION HISTORY
1342 See the Changes file.
1344 =head1 COPYRIGHT AND LICENSE
1346 Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
1348 This program is free software; you can redistribute it and/or
1349 modify it under the same terms as Perl itself.