1b39c5158Smillert 2b39c5158Smillertpackage IO::Uncompress::Base ; 3b39c5158Smillert 4b39c5158Smillertuse strict ; 5b39c5158Smillertuse warnings; 69f11ffb7Safresh1use bytes; 7b39c5158Smillert 8b39c5158Smillertour (@ISA, $VERSION, @EXPORT_OK, %EXPORT_TAGS); 99f11ffb7Safresh1@ISA = qw(IO::File Exporter); 10b39c5158Smillert 11b39c5158Smillert 12*3d61058aSafresh1$VERSION = '2.212'; 13b39c5158Smillert 14b39c5158Smillertuse constant G_EOF => 0 ; 15b39c5158Smillertuse constant G_ERR => -1 ; 16b39c5158Smillert 17*3d61058aSafresh1use IO::Compress::Base::Common 2.212 ; 18b39c5158Smillert 19b39c5158Smillertuse IO::File ; 20b39c5158Smillertuse Symbol; 2191f110e0Safresh1use Scalar::Util (); 2291f110e0Safresh1use List::Util (); 23b39c5158Smillertuse Carp ; 24b39c5158Smillert 25b39c5158Smillert%EXPORT_TAGS = ( ); 26b39c5158Smillertpush @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; 27b39c5158Smillert 28b39c5158Smillertsub smartRead 29b39c5158Smillert{ 30b39c5158Smillert my $self = $_[0]; 31b39c5158Smillert my $out = $_[1]; 32b39c5158Smillert my $size = $_[2]; 33b39c5158Smillert $$out = "" ; 34b39c5158Smillert 35b39c5158Smillert my $offset = 0 ; 36898184e3Ssthen my $status = 1; 37b39c5158Smillert 38b39c5158Smillert 39b39c5158Smillert if (defined *$self->{InputLength}) { 40b39c5158Smillert return 0 41b39c5158Smillert if *$self->{InputLengthRemaining} <= 0 ; 4291f110e0Safresh1 $size = List::Util::min($size, *$self->{InputLengthRemaining}); 43b39c5158Smillert } 44b39c5158Smillert 45b39c5158Smillert if ( length *$self->{Prime} ) { 46b39c5158Smillert $$out = substr(*$self->{Prime}, 0, $size) ; 47b39c5158Smillert substr(*$self->{Prime}, 0, $size) = '' ; 48b39c5158Smillert if (length $$out == $size) { 49b39c5158Smillert *$self->{InputLengthRemaining} -= length $$out 50b39c5158Smillert if defined *$self->{InputLength}; 51b39c5158Smillert 52b39c5158Smillert return length $$out ; 53b39c5158Smillert } 54b39c5158Smillert $offset = length $$out ; 55b39c5158Smillert } 56b39c5158Smillert 57b39c5158Smillert my $get_size = $size - $offset ; 58b39c5158Smillert 59b39c5158Smillert if (defined *$self->{FH}) { 60b39c5158Smillert if ($offset) { 61b39c5158Smillert # Not using this 62b39c5158Smillert # 63b39c5158Smillert # *$self->{FH}->read($$out, $get_size, $offset); 64b39c5158Smillert # 65b39c5158Smillert # because the filehandle may not support the offset parameter 66b39c5158Smillert # An example is Net::FTP 67b39c5158Smillert my $tmp = ''; 68898184e3Ssthen $status = *$self->{FH}->read($tmp, $get_size) ; 69898184e3Ssthen substr($$out, $offset) = $tmp 70898184e3Ssthen if defined $status && $status > 0 ; 71b39c5158Smillert } 72b39c5158Smillert else 73898184e3Ssthen { $status = *$self->{FH}->read($$out, $get_size) } 74b39c5158Smillert } 75b39c5158Smillert elsif (defined *$self->{InputEvent}) { 76b39c5158Smillert my $got = 1 ; 77b39c5158Smillert while (length $$out < $size) { 78b39c5158Smillert last 79b39c5158Smillert if ($got = *$self->{InputEvent}->($$out, $get_size)) <= 0; 80b39c5158Smillert } 81b39c5158Smillert 82b39c5158Smillert if (length $$out > $size ) { 83b39c5158Smillert *$self->{Prime} = substr($$out, $size, length($$out)); 84b39c5158Smillert substr($$out, $size, length($$out)) = ''; 85b39c5158Smillert } 86b39c5158Smillert 87b39c5158Smillert *$self->{EventEof} = 1 if $got <= 0 ; 88b39c5158Smillert } 89b39c5158Smillert else { 90b39c5158Smillert no warnings 'uninitialized'; 91b39c5158Smillert my $buf = *$self->{Buffer} ; 92b39c5158Smillert $$buf = '' unless defined $$buf ; 93b39c5158Smillert substr($$out, $offset) = substr($$buf, *$self->{BufferOffset}, $get_size); 94b39c5158Smillert if (*$self->{ConsumeInput}) 95b39c5158Smillert { substr($$buf, 0, $get_size) = '' } 96b39c5158Smillert else 97b39c5158Smillert { *$self->{BufferOffset} += length($$out) - $offset } 98b39c5158Smillert } 99b39c5158Smillert 100b39c5158Smillert *$self->{InputLengthRemaining} -= length($$out) #- $offset 101b39c5158Smillert if defined *$self->{InputLength}; 102b39c5158Smillert 103898184e3Ssthen if (! defined $status) { 104898184e3Ssthen $self->saveStatus($!) ; 105898184e3Ssthen return STATUS_ERROR; 106898184e3Ssthen } 107898184e3Ssthen 108b39c5158Smillert $self->saveStatus(length $$out < 0 ? STATUS_ERROR : STATUS_OK) ; 109b39c5158Smillert 110b39c5158Smillert return length $$out; 111b39c5158Smillert} 112b39c5158Smillert 113b39c5158Smillertsub pushBack 114b39c5158Smillert{ 115b39c5158Smillert my $self = shift ; 116b39c5158Smillert 117b39c5158Smillert return if ! defined $_[0] || length $_[0] == 0 ; 118b39c5158Smillert 119b39c5158Smillert if (defined *$self->{FH} || defined *$self->{InputEvent} ) { 120b39c5158Smillert *$self->{Prime} = $_[0] . *$self->{Prime} ; 121b39c5158Smillert *$self->{InputLengthRemaining} += length($_[0]); 122b39c5158Smillert } 123b39c5158Smillert else { 124b39c5158Smillert my $len = length $_[0]; 125b39c5158Smillert 126b39c5158Smillert if($len > *$self->{BufferOffset}) { 127b39c5158Smillert *$self->{Prime} = substr($_[0], 0, $len - *$self->{BufferOffset}) . *$self->{Prime} ; 128b39c5158Smillert *$self->{InputLengthRemaining} = *$self->{InputLength}; 129b39c5158Smillert *$self->{BufferOffset} = 0 130b39c5158Smillert } 131b39c5158Smillert else { 132b39c5158Smillert *$self->{InputLengthRemaining} += length($_[0]); 133b39c5158Smillert *$self->{BufferOffset} -= length($_[0]) ; 134b39c5158Smillert } 135b39c5158Smillert } 136b39c5158Smillert} 137b39c5158Smillert 138b39c5158Smillertsub smartSeek 139b39c5158Smillert{ 140b39c5158Smillert my $self = shift ; 141b39c5158Smillert my $offset = shift ; 142b39c5158Smillert my $truncate = shift; 143898184e3Ssthen my $position = shift || SEEK_SET; 144b39c5158Smillert 145b39c5158Smillert # TODO -- need to take prime into account 146b46d8ef2Safresh1 *$self->{Prime} = ''; 147b39c5158Smillert if (defined *$self->{FH}) 148898184e3Ssthen { *$self->{FH}->seek($offset, $position) } 149898184e3Ssthen else { 150898184e3Ssthen if ($position == SEEK_END) { 151b46d8ef2Safresh1 *$self->{BufferOffset} = length(${ *$self->{Buffer} }) + $offset ; 152898184e3Ssthen } 153898184e3Ssthen elsif ($position == SEEK_CUR) { 154898184e3Ssthen *$self->{BufferOffset} += $offset ; 155898184e3Ssthen } 156b39c5158Smillert else { 157b39c5158Smillert *$self->{BufferOffset} = $offset ; 158898184e3Ssthen } 159898184e3Ssthen 160b39c5158Smillert substr(${ *$self->{Buffer} }, *$self->{BufferOffset}) = '' 161b39c5158Smillert if $truncate; 162b39c5158Smillert return 1; 163b39c5158Smillert } 164b39c5158Smillert} 165b39c5158Smillert 166898184e3Ssthensub smartTell 167898184e3Ssthen{ 168898184e3Ssthen my $self = shift ; 169898184e3Ssthen 170898184e3Ssthen if (defined *$self->{FH}) 171898184e3Ssthen { return *$self->{FH}->tell() } 172898184e3Ssthen else 173898184e3Ssthen { return *$self->{BufferOffset} } 174898184e3Ssthen} 175898184e3Ssthen 176b39c5158Smillertsub smartWrite 177b39c5158Smillert{ 178b39c5158Smillert my $self = shift ; 179b39c5158Smillert my $out_data = shift ; 180b39c5158Smillert 181b39c5158Smillert if (defined *$self->{FH}) { 182b39c5158Smillert # flush needed for 5.8.0 183b39c5158Smillert defined *$self->{FH}->write($out_data, length $out_data) && 184b39c5158Smillert defined *$self->{FH}->flush() ; 185b39c5158Smillert } 186b39c5158Smillert else { 187b39c5158Smillert my $buf = *$self->{Buffer} ; 188b39c5158Smillert substr($$buf, *$self->{BufferOffset}, length $out_data) = $out_data ; 189b39c5158Smillert *$self->{BufferOffset} += length($out_data) ; 190b39c5158Smillert return 1; 191b39c5158Smillert } 192b39c5158Smillert} 193b39c5158Smillert 194b39c5158Smillertsub smartReadExact 195b39c5158Smillert{ 196b39c5158Smillert return $_[0]->smartRead($_[1], $_[2]) == $_[2]; 197b39c5158Smillert} 198b39c5158Smillert 199b39c5158Smillertsub smartEof 200b39c5158Smillert{ 201b39c5158Smillert my ($self) = $_[0]; 202b39c5158Smillert local $.; 203b39c5158Smillert 204b39c5158Smillert return 0 if length *$self->{Prime} || *$self->{PushMode}; 205b39c5158Smillert 206b39c5158Smillert if (defined *$self->{FH}) 207b39c5158Smillert { 208b39c5158Smillert # Could use 209b39c5158Smillert # 210b39c5158Smillert # *$self->{FH}->eof() 211b39c5158Smillert # 212b39c5158Smillert # here, but this can cause trouble if 213b39c5158Smillert # the filehandle is itself a tied handle, but it uses sysread. 214898184e3Ssthen # Then we get into mixing buffered & non-buffered IO, 215898184e3Ssthen # which will cause trouble 216b39c5158Smillert 217b39c5158Smillert my $info = $self->getErrInfo(); 218b39c5158Smillert 219b39c5158Smillert my $buffer = ''; 220b39c5158Smillert my $status = $self->smartRead(\$buffer, 1); 221b39c5158Smillert $self->pushBack($buffer) if length $buffer; 222b39c5158Smillert $self->setErrInfo($info); 223b39c5158Smillert 224b39c5158Smillert return $status == 0 ; 225b39c5158Smillert } 226b39c5158Smillert elsif (defined *$self->{InputEvent}) 227b39c5158Smillert { *$self->{EventEof} } 228b39c5158Smillert else 229b39c5158Smillert { *$self->{BufferOffset} >= length(${ *$self->{Buffer} }) } 230b39c5158Smillert} 231b39c5158Smillert 232b39c5158Smillertsub clearError 233b39c5158Smillert{ 234b39c5158Smillert my $self = shift ; 235b39c5158Smillert 236b39c5158Smillert *$self->{ErrorNo} = 0 ; 237b39c5158Smillert ${ *$self->{Error} } = '' ; 238b39c5158Smillert} 239b39c5158Smillert 240b39c5158Smillertsub getErrInfo 241b39c5158Smillert{ 242b39c5158Smillert my $self = shift ; 243b39c5158Smillert 244b39c5158Smillert return [ *$self->{ErrorNo}, ${ *$self->{Error} } ] ; 245b39c5158Smillert} 246b39c5158Smillert 247b39c5158Smillertsub setErrInfo 248b39c5158Smillert{ 249b39c5158Smillert my $self = shift ; 250b39c5158Smillert my $ref = shift; 251b39c5158Smillert 252b39c5158Smillert *$self->{ErrorNo} = $ref->[0] ; 253b39c5158Smillert ${ *$self->{Error} } = $ref->[1] ; 254b39c5158Smillert} 255b39c5158Smillert 256b39c5158Smillertsub saveStatus 257b39c5158Smillert{ 258b39c5158Smillert my $self = shift ; 259b39c5158Smillert my $errno = shift() + 0 ; 260b39c5158Smillert 261b39c5158Smillert *$self->{ErrorNo} = $errno; 262b39c5158Smillert ${ *$self->{Error} } = '' ; 263b39c5158Smillert 264b39c5158Smillert return *$self->{ErrorNo} ; 265b39c5158Smillert} 266b39c5158Smillert 267b39c5158Smillert 268b39c5158Smillertsub saveErrorString 269b39c5158Smillert{ 270b39c5158Smillert my $self = shift ; 271b39c5158Smillert my $retval = shift ; 272b39c5158Smillert 273b39c5158Smillert ${ *$self->{Error} } = shift ; 274898184e3Ssthen *$self->{ErrorNo} = @_ ? shift() + 0 : STATUS_ERROR ; 275b39c5158Smillert 276b39c5158Smillert return $retval; 277b39c5158Smillert} 278b39c5158Smillert 279b39c5158Smillertsub croakError 280b39c5158Smillert{ 281b39c5158Smillert my $self = shift ; 282b39c5158Smillert $self->saveErrorString(0, $_[0]); 283b39c5158Smillert croak $_[0]; 284b39c5158Smillert} 285b39c5158Smillert 286b39c5158Smillert 287b39c5158Smillertsub closeError 288b39c5158Smillert{ 289b39c5158Smillert my $self = shift ; 290b39c5158Smillert my $retval = shift ; 291b39c5158Smillert 292b39c5158Smillert my $errno = *$self->{ErrorNo}; 293b39c5158Smillert my $error = ${ *$self->{Error} }; 294b39c5158Smillert 295b39c5158Smillert $self->close(); 296b39c5158Smillert 297b39c5158Smillert *$self->{ErrorNo} = $errno ; 298b39c5158Smillert ${ *$self->{Error} } = $error ; 299b39c5158Smillert 300b39c5158Smillert return $retval; 301b39c5158Smillert} 302b39c5158Smillert 303b39c5158Smillertsub error 304b39c5158Smillert{ 305b39c5158Smillert my $self = shift ; 306b39c5158Smillert return ${ *$self->{Error} } ; 307b39c5158Smillert} 308b39c5158Smillert 309b39c5158Smillertsub errorNo 310b39c5158Smillert{ 311b39c5158Smillert my $self = shift ; 312b39c5158Smillert return *$self->{ErrorNo}; 313b39c5158Smillert} 314b39c5158Smillert 315b39c5158Smillertsub HeaderError 316b39c5158Smillert{ 317b39c5158Smillert my ($self) = shift; 318b39c5158Smillert return $self->saveErrorString(undef, "Header Error: $_[0]", STATUS_ERROR); 319b39c5158Smillert} 320b39c5158Smillert 321b39c5158Smillertsub TrailerError 322b39c5158Smillert{ 323b39c5158Smillert my ($self) = shift; 324b39c5158Smillert return $self->saveErrorString(G_ERR, "Trailer Error: $_[0]", STATUS_ERROR); 325b39c5158Smillert} 326b39c5158Smillert 327b39c5158Smillertsub TruncatedHeader 328b39c5158Smillert{ 329b39c5158Smillert my ($self) = shift; 330b39c5158Smillert return $self->HeaderError("Truncated in $_[0] Section"); 331b39c5158Smillert} 332b39c5158Smillert 333b39c5158Smillertsub TruncatedTrailer 334b39c5158Smillert{ 335b39c5158Smillert my ($self) = shift; 336b39c5158Smillert return $self->TrailerError("Truncated in $_[0] Section"); 337b39c5158Smillert} 338b39c5158Smillert 339b39c5158Smillertsub postCheckParams 340b39c5158Smillert{ 341b39c5158Smillert return 1; 342b39c5158Smillert} 343b39c5158Smillert 344b39c5158Smillertsub checkParams 345b39c5158Smillert{ 346b39c5158Smillert my $self = shift ; 347b39c5158Smillert my $class = shift ; 348b39c5158Smillert 349b39c5158Smillert my $got = shift || IO::Compress::Base::Parameters::new(); 350b39c5158Smillert 351b39c5158Smillert my $Valid = { 35291f110e0Safresh1 'blocksize' => [IO::Compress::Base::Common::Parse_unsigned, 16 * 1024], 35391f110e0Safresh1 'autoclose' => [IO::Compress::Base::Common::Parse_boolean, 0], 35491f110e0Safresh1 'strict' => [IO::Compress::Base::Common::Parse_boolean, 0], 35591f110e0Safresh1 'append' => [IO::Compress::Base::Common::Parse_boolean, 0], 35691f110e0Safresh1 'prime' => [IO::Compress::Base::Common::Parse_any, undef], 35791f110e0Safresh1 'multistream' => [IO::Compress::Base::Common::Parse_boolean, 0], 35891f110e0Safresh1 'transparent' => [IO::Compress::Base::Common::Parse_any, 1], 35991f110e0Safresh1 'scan' => [IO::Compress::Base::Common::Parse_boolean, 0], 36091f110e0Safresh1 'inputlength' => [IO::Compress::Base::Common::Parse_unsigned, undef], 36191f110e0Safresh1 'binmodeout' => [IO::Compress::Base::Common::Parse_boolean, 0], 36291f110e0Safresh1 #'decode' => [IO::Compress::Base::Common::Parse_any, undef], 363b39c5158Smillert 36491f110e0Safresh1 #'consumeinput' => [IO::Compress::Base::Common::Parse_boolean, 0], 365b39c5158Smillert 366b39c5158Smillert $self->getExtraParams(), 367b39c5158Smillert 368b39c5158Smillert #'Todo - Revert to ordinary file on end Z_STREAM_END'=> 0, 369b39c5158Smillert # ContinueAfterEof 370b39c5158Smillert } ; 371b39c5158Smillert 37291f110e0Safresh1 $Valid->{trailingdata} = [IO::Compress::Base::Common::Parse_writable_scalar, undef] 373b39c5158Smillert if *$self->{OneShot} ; 374b39c5158Smillert 375b39c5158Smillert $got->parse($Valid, @_ ) 37691f110e0Safresh1 or $self->croakError("${class}: " . $got->getError()) ; 377b39c5158Smillert 378b39c5158Smillert $self->postCheckParams($got) 379b39c5158Smillert or $self->croakError("${class}: " . $self->error()) ; 380b39c5158Smillert 381b39c5158Smillert return $got; 382b39c5158Smillert} 383b39c5158Smillert 384b39c5158Smillertsub _create 385b39c5158Smillert{ 386b39c5158Smillert my $obj = shift; 387b39c5158Smillert my $got = shift; 388b39c5158Smillert my $append_mode = shift ; 389b39c5158Smillert 390b39c5158Smillert my $class = ref $obj; 391b39c5158Smillert $obj->croakError("$class: Missing Input parameter") 392b39c5158Smillert if ! @_ && ! $got ; 393b39c5158Smillert 394b39c5158Smillert my $inValue = shift ; 395b39c5158Smillert 396b39c5158Smillert *$obj->{OneShot} = 0 ; 397b39c5158Smillert 398b39c5158Smillert if (! $got) 399b39c5158Smillert { 400b39c5158Smillert $got = $obj->checkParams($class, undef, @_) 401b39c5158Smillert or return undef ; 402b39c5158Smillert } 403b39c5158Smillert 404b39c5158Smillert my $inType = whatIsInput($inValue, 1); 405b39c5158Smillert 406b39c5158Smillert $obj->ckInputParam($class, $inValue, 1) 407b39c5158Smillert or return undef ; 408b39c5158Smillert 409b39c5158Smillert *$obj->{InNew} = 1; 410b39c5158Smillert 411b39c5158Smillert $obj->ckParams($got) 412b39c5158Smillert or $obj->croakError("${class}: " . *$obj->{Error}); 413b39c5158Smillert 414b39c5158Smillert if ($inType eq 'buffer' || $inType eq 'code') { 415b39c5158Smillert *$obj->{Buffer} = $inValue ; 416b39c5158Smillert *$obj->{InputEvent} = $inValue 417b39c5158Smillert if $inType eq 'code' ; 418b39c5158Smillert } 419b39c5158Smillert else { 420b39c5158Smillert if ($inType eq 'handle') { 421b39c5158Smillert *$obj->{FH} = $inValue ; 422b39c5158Smillert *$obj->{Handle} = 1 ; 423b39c5158Smillert 424b39c5158Smillert # Need to rewind for Scan 425b39c5158Smillert *$obj->{FH}->seek(0, SEEK_SET) 42691f110e0Safresh1 if $got->getValue('scan'); 427b39c5158Smillert } 428b39c5158Smillert else { 429b39c5158Smillert no warnings ; 430b39c5158Smillert my $mode = '<'; 43191f110e0Safresh1 $mode = '+<' if $got->getValue('scan'); 432b39c5158Smillert *$obj->{StdIO} = ($inValue eq '-'); 433eac174f2Safresh1 *$obj->{FH} = IO::File->new( "$mode $inValue" ) 434b39c5158Smillert or return $obj->saveErrorString(undef, "cannot open file '$inValue': $!", $!) ; 435b39c5158Smillert } 436b39c5158Smillert 437b39c5158Smillert *$obj->{LineNo} = $. = 0; 438b39c5158Smillert setBinModeInput(*$obj->{FH}) ; 439b39c5158Smillert 440b39c5158Smillert my $buff = "" ; 441b39c5158Smillert *$obj->{Buffer} = \$buff ; 442b39c5158Smillert } 443b39c5158Smillert 44491f110e0Safresh1# if ($got->getValue('decode')) { 44591f110e0Safresh1# my $want_encoding = $got->getValue('decode'); 44691f110e0Safresh1# *$obj->{Encoding} = IO::Compress::Base::Common::getEncoding($obj, $class, $want_encoding); 44791f110e0Safresh1# } 44891f110e0Safresh1# else { 44991f110e0Safresh1# *$obj->{Encoding} = undef; 45091f110e0Safresh1# } 451b39c5158Smillert 45291f110e0Safresh1 *$obj->{InputLength} = $got->parsed('inputlength') 45391f110e0Safresh1 ? $got->getValue('inputlength') 454b39c5158Smillert : undef ; 45591f110e0Safresh1 *$obj->{InputLengthRemaining} = $got->getValue('inputlength'); 456b39c5158Smillert *$obj->{BufferOffset} = 0 ; 45791f110e0Safresh1 *$obj->{AutoClose} = $got->getValue('autoclose'); 45891f110e0Safresh1 *$obj->{Strict} = $got->getValue('strict'); 45991f110e0Safresh1 *$obj->{BlockSize} = $got->getValue('blocksize'); 46091f110e0Safresh1 *$obj->{Append} = $got->getValue('append'); 46191f110e0Safresh1 *$obj->{AppendOutput} = $append_mode || $got->getValue('append'); 46291f110e0Safresh1 *$obj->{ConsumeInput} = $got->getValue('consumeinput'); 46391f110e0Safresh1 *$obj->{Transparent} = $got->getValue('transparent'); 46491f110e0Safresh1 *$obj->{MultiStream} = $got->getValue('multistream'); 465b39c5158Smillert 466b39c5158Smillert # TODO - move these two into RawDeflate 46791f110e0Safresh1 *$obj->{Scan} = $got->getValue('scan'); 46891f110e0Safresh1 *$obj->{ParseExtra} = $got->getValue('parseextra') 46991f110e0Safresh1 || $got->getValue('strict') ; 470b39c5158Smillert *$obj->{Type} = ''; 47191f110e0Safresh1 *$obj->{Prime} = $got->getValue('prime') || '' ; 472b39c5158Smillert *$obj->{Pending} = ''; 473b39c5158Smillert *$obj->{Plain} = 0; 474b39c5158Smillert *$obj->{PlainBytesRead} = 0; 475b39c5158Smillert *$obj->{InflatedBytesRead} = 0; 476eac174f2Safresh1 *$obj->{UnCompSize} = U64->new; 477eac174f2Safresh1 *$obj->{CompSize} = U64->new; 478b39c5158Smillert *$obj->{TotalInflatedBytesRead} = 0; 479b39c5158Smillert *$obj->{NewStream} = 0 ; 480b39c5158Smillert *$obj->{EventEof} = 0 ; 481b39c5158Smillert *$obj->{ClassName} = $class ; 482b39c5158Smillert *$obj->{Params} = $got ; 483b39c5158Smillert 484b39c5158Smillert if (*$obj->{ConsumeInput}) { 485b39c5158Smillert *$obj->{InNew} = 0; 486b39c5158Smillert *$obj->{Closed} = 0; 487b39c5158Smillert return $obj 488b39c5158Smillert } 489b39c5158Smillert 490b39c5158Smillert my $status = $obj->mkUncomp($got); 491b39c5158Smillert 492b39c5158Smillert return undef 493b39c5158Smillert unless defined $status; 494b39c5158Smillert 495898184e3Ssthen *$obj->{InNew} = 0; 496898184e3Ssthen *$obj->{Closed} = 0; 497898184e3Ssthen 498b46d8ef2Safresh1 return $obj 499b46d8ef2Safresh1 if *$obj->{Pause} ; 500b46d8ef2Safresh1 501898184e3Ssthen if ($status) { 502898184e3Ssthen # Need to try uncompressing to catch the case 503898184e3Ssthen # where the compressed file uncompresses to an 504898184e3Ssthen # empty string - so eof is set immediately. 505898184e3Ssthen 506898184e3Ssthen my $out_buffer = ''; 507898184e3Ssthen 508898184e3Ssthen $status = $obj->read(\$out_buffer); 509898184e3Ssthen 510898184e3Ssthen if ($status < 0) { 511898184e3Ssthen *$obj->{ReadStatus} = [ $status, $obj->error(), $obj->errorNo() ]; 512898184e3Ssthen } 513898184e3Ssthen 514898184e3Ssthen $obj->ungetc($out_buffer) 515898184e3Ssthen if length $out_buffer; 516898184e3Ssthen } 517898184e3Ssthen else { 518b39c5158Smillert return undef 519b39c5158Smillert unless *$obj->{Transparent}; 520b39c5158Smillert 521b39c5158Smillert $obj->clearError(); 522b39c5158Smillert *$obj->{Type} = 'plain'; 523b39c5158Smillert *$obj->{Plain} = 1; 524b39c5158Smillert $obj->pushBack(*$obj->{HeaderPending}) ; 525b39c5158Smillert } 526b39c5158Smillert 527b39c5158Smillert push @{ *$obj->{InfoList} }, *$obj->{Info} ; 528b39c5158Smillert 529b39c5158Smillert $obj->saveStatus(STATUS_OK) ; 530b39c5158Smillert *$obj->{InNew} = 0; 531b39c5158Smillert *$obj->{Closed} = 0; 532b39c5158Smillert 533b39c5158Smillert return $obj; 534b39c5158Smillert} 535b39c5158Smillert 536b39c5158Smillertsub ckInputParam 537b39c5158Smillert{ 538b39c5158Smillert my $self = shift ; 539b39c5158Smillert my $from = shift ; 540b39c5158Smillert my $inType = whatIsInput($_[0], $_[1]); 541b39c5158Smillert 542b39c5158Smillert $self->croakError("$from: input parameter not a filename, filehandle, array ref or scalar ref") 543b39c5158Smillert if ! $inType ; 544b39c5158Smillert 545b39c5158Smillert# if ($inType eq 'filename' ) 546b39c5158Smillert# { 547b39c5158Smillert# return $self->saveErrorString(1, "$from: input filename is undef or null string", STATUS_ERROR) 548b39c5158Smillert# if ! defined $_[0] || $_[0] eq '' ; 549b39c5158Smillert# 550b39c5158Smillert# if ($_[0] ne '-' && ! -e $_[0] ) 551b39c5158Smillert# { 552b39c5158Smillert# return $self->saveErrorString(1, 553b39c5158Smillert# "input file '$_[0]' does not exist", STATUS_ERROR); 554b39c5158Smillert# } 555b39c5158Smillert# } 556b39c5158Smillert 557b39c5158Smillert return 1; 558b39c5158Smillert} 559b39c5158Smillert 560b39c5158Smillert 561b39c5158Smillertsub _inf 562b39c5158Smillert{ 563b39c5158Smillert my $obj = shift ; 564b39c5158Smillert 565b39c5158Smillert my $class = (caller)[0] ; 566b39c5158Smillert my $name = (caller(1))[3] ; 567b39c5158Smillert 568b39c5158Smillert $obj->croakError("$name: expected at least 1 parameters\n") 569b39c5158Smillert unless @_ >= 1 ; 570b39c5158Smillert 571b39c5158Smillert my $input = shift ; 572b39c5158Smillert my $haveOut = @_ ; 573b39c5158Smillert my $output = shift ; 574b39c5158Smillert 575b39c5158Smillert 576eac174f2Safresh1 my $x = IO::Compress::Base::Validator->new($class, *$obj->{Error}, $name, $input, $output) 577b39c5158Smillert or return undef ; 578b39c5158Smillert 579b39c5158Smillert push @_, $output if $haveOut && $x->{Hash}; 580b39c5158Smillert 581b39c5158Smillert *$obj->{OneShot} = 1 ; 582b39c5158Smillert 583b39c5158Smillert my $got = $obj->checkParams($name, undef, @_) 584b39c5158Smillert or return undef ; 585b39c5158Smillert 58691f110e0Safresh1 if ($got->parsed('trailingdata')) 587b39c5158Smillert { 58891f110e0Safresh1# my $value = $got->valueRef('TrailingData'); 58991f110e0Safresh1# warn "TD $value "; 59091f110e0Safresh1# #$value = $$value; 59191f110e0Safresh1## warn "TD $value $$value "; 59291f110e0Safresh1# 59391f110e0Safresh1# return retErr($obj, "Parameter 'TrailingData' not writable") 59491f110e0Safresh1# if readonly $$value ; 59591f110e0Safresh1# 59691f110e0Safresh1# if (ref $$value) 59791f110e0Safresh1# { 59891f110e0Safresh1# return retErr($obj,"Parameter 'TrailingData' not a scalar reference") 59991f110e0Safresh1# if ref $$value ne 'SCALAR' ; 60091f110e0Safresh1# 60191f110e0Safresh1# *$obj->{TrailingData} = $$value ; 60291f110e0Safresh1# } 60391f110e0Safresh1# else 60491f110e0Safresh1# { 60591f110e0Safresh1# return retErr($obj,"Parameter 'TrailingData' not a scalar") 60691f110e0Safresh1# if ref $value ne 'SCALAR' ; 60791f110e0Safresh1# 60891f110e0Safresh1# *$obj->{TrailingData} = $value ; 60991f110e0Safresh1# } 61091f110e0Safresh1 61191f110e0Safresh1 *$obj->{TrailingData} = $got->getValue('trailingdata'); 612b39c5158Smillert } 613b39c5158Smillert 61491f110e0Safresh1 *$obj->{MultiStream} = $got->getValue('multistream'); 61591f110e0Safresh1 $got->setValue('multistream', 0); 616b39c5158Smillert 617b39c5158Smillert $x->{Got} = $got ; 618b39c5158Smillert 619b39c5158Smillert# if ($x->{Hash}) 620b39c5158Smillert# { 621b39c5158Smillert# while (my($k, $v) = each %$input) 622b39c5158Smillert# { 623b39c5158Smillert# $v = \$input->{$k} 624b39c5158Smillert# unless defined $v ; 625b39c5158Smillert# 626b39c5158Smillert# $obj->_singleTarget($x, $k, $v, @_) 627b39c5158Smillert# or return undef ; 628b39c5158Smillert# } 629b39c5158Smillert# 630b39c5158Smillert# return keys %$input ; 631b39c5158Smillert# } 632b39c5158Smillert 633b39c5158Smillert if ($x->{GlobMap}) 634b39c5158Smillert { 635b39c5158Smillert $x->{oneInput} = 1 ; 636b39c5158Smillert foreach my $pair (@{ $x->{Pairs} }) 637b39c5158Smillert { 638b39c5158Smillert my ($from, $to) = @$pair ; 639b39c5158Smillert $obj->_singleTarget($x, $from, $to, @_) 640b39c5158Smillert or return undef ; 641b39c5158Smillert } 642b39c5158Smillert 643b39c5158Smillert return scalar @{ $x->{Pairs} } ; 644b39c5158Smillert } 645b39c5158Smillert 646b39c5158Smillert if (! $x->{oneOutput} ) 647b39c5158Smillert { 648b39c5158Smillert my $inFile = ($x->{inType} eq 'filenames' 649b39c5158Smillert || $x->{inType} eq 'filename'); 650b39c5158Smillert 651b39c5158Smillert $x->{inType} = $inFile ? 'filename' : 'buffer'; 652b39c5158Smillert 653b39c5158Smillert foreach my $in ($x->{oneInput} ? $input : @$input) 654b39c5158Smillert { 655b39c5158Smillert my $out ; 656b39c5158Smillert $x->{oneInput} = 1 ; 657b39c5158Smillert 658b39c5158Smillert $obj->_singleTarget($x, $in, $output, @_) 659b39c5158Smillert or return undef ; 660b39c5158Smillert } 661b39c5158Smillert 662b39c5158Smillert return 1 ; 663b39c5158Smillert } 664b39c5158Smillert 665b39c5158Smillert # finally the 1 to 1 and n to 1 666b39c5158Smillert return $obj->_singleTarget($x, $input, $output, @_); 667b39c5158Smillert 668b39c5158Smillert croak "should not be here" ; 669b39c5158Smillert} 670b39c5158Smillert 671b39c5158Smillertsub retErr 672b39c5158Smillert{ 673b39c5158Smillert my $x = shift ; 674b39c5158Smillert my $string = shift ; 675b39c5158Smillert 676b39c5158Smillert ${ $x->{Error} } = $string ; 677b39c5158Smillert 678b39c5158Smillert return undef ; 679b39c5158Smillert} 680b39c5158Smillert 681b39c5158Smillertsub _singleTarget 682b39c5158Smillert{ 683b39c5158Smillert my $self = shift ; 684b39c5158Smillert my $x = shift ; 685b39c5158Smillert my $input = shift; 686b39c5158Smillert my $output = shift; 687b39c5158Smillert 688b39c5158Smillert my $buff = ''; 689b39c5158Smillert $x->{buff} = \$buff ; 690b39c5158Smillert 691b39c5158Smillert my $fh ; 692b39c5158Smillert if ($x->{outType} eq 'filename') { 693b39c5158Smillert my $mode = '>' ; 694b39c5158Smillert $mode = '>>' 69591f110e0Safresh1 if $x->{Got}->getValue('append') ; 696eac174f2Safresh1 $x->{fh} = IO::File->new( "$mode $output" ) 697b39c5158Smillert or return retErr($x, "cannot open file '$output': $!") ; 698b46d8ef2Safresh1 binmode $x->{fh} ; 699b39c5158Smillert 700b39c5158Smillert } 701b39c5158Smillert 702b39c5158Smillert elsif ($x->{outType} eq 'handle') { 703b39c5158Smillert $x->{fh} = $output; 704b46d8ef2Safresh1 binmode $x->{fh} ; 70591f110e0Safresh1 if ($x->{Got}->getValue('append')) { 706b39c5158Smillert seek($x->{fh}, 0, SEEK_END) 707b39c5158Smillert or return retErr($x, "Cannot seek to end of output filehandle: $!") ; 708b39c5158Smillert } 709b39c5158Smillert } 710b39c5158Smillert 711b39c5158Smillert 712b39c5158Smillert elsif ($x->{outType} eq 'buffer' ) 713b39c5158Smillert { 714b39c5158Smillert $$output = '' 71591f110e0Safresh1 unless $x->{Got}->getValue('append'); 716b39c5158Smillert $x->{buff} = $output ; 717b39c5158Smillert } 718b39c5158Smillert 719b39c5158Smillert if ($x->{oneInput}) 720b39c5158Smillert { 721b39c5158Smillert defined $self->_rd2($x, $input, $output) 722b39c5158Smillert or return undef; 723b39c5158Smillert } 724b39c5158Smillert else 725b39c5158Smillert { 726b39c5158Smillert for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input) 727b39c5158Smillert { 728b39c5158Smillert defined $self->_rd2($x, $element, $output) 729b39c5158Smillert or return undef ; 730b39c5158Smillert } 731b39c5158Smillert } 732b39c5158Smillert 733b39c5158Smillert 734b39c5158Smillert if ( ($x->{outType} eq 'filename' && $output ne '-') || 73591f110e0Safresh1 ($x->{outType} eq 'handle' && $x->{Got}->getValue('autoclose'))) { 736b39c5158Smillert $x->{fh}->close() 737b39c5158Smillert or return retErr($x, $!); 738b39c5158Smillert delete $x->{fh}; 739b39c5158Smillert } 740b39c5158Smillert 741b39c5158Smillert return 1 ; 742b39c5158Smillert} 743b39c5158Smillert 744b39c5158Smillertsub _rd2 745b39c5158Smillert{ 746b39c5158Smillert my $self = shift ; 747b39c5158Smillert my $x = shift ; 748b39c5158Smillert my $input = shift; 749b39c5158Smillert my $output = shift; 750b39c5158Smillert 75191f110e0Safresh1 my $z = IO::Compress::Base::Common::createSelfTiedObject($x->{Class}, *$self->{Error}); 752b39c5158Smillert 753b39c5158Smillert $z->_create($x->{Got}, 1, $input, @_) 754b39c5158Smillert or return undef ; 755b39c5158Smillert 756b39c5158Smillert my $status ; 757b39c5158Smillert my $fh = $x->{fh}; 758b39c5158Smillert 759b39c5158Smillert while (1) { 760b39c5158Smillert 761b39c5158Smillert while (($status = $z->read($x->{buff})) > 0) { 762b39c5158Smillert if ($fh) { 763b8851fccSafresh1 local $\; 764b8851fccSafresh1 print $fh ${ $x->{buff} } 765b39c5158Smillert or return $z->saveErrorString(undef, "Error writing to output file: $!", $!); 766b39c5158Smillert ${ $x->{buff} } = '' ; 767b39c5158Smillert } 768b39c5158Smillert } 769b39c5158Smillert 770b39c5158Smillert if (! $x->{oneOutput} ) { 771b39c5158Smillert my $ot = $x->{outType} ; 772b39c5158Smillert 773b39c5158Smillert if ($ot eq 'array') 774b39c5158Smillert { push @$output, $x->{buff} } 775b39c5158Smillert elsif ($ot eq 'hash') 776b39c5158Smillert { $output->{$input} = $x->{buff} } 777b39c5158Smillert 778b39c5158Smillert my $buff = ''; 779b39c5158Smillert $x->{buff} = \$buff; 780b39c5158Smillert } 781b39c5158Smillert 782b39c5158Smillert last if $status < 0 || $z->smartEof(); 783b39c5158Smillert 784b39c5158Smillert last 785b39c5158Smillert unless *$self->{MultiStream}; 786b39c5158Smillert 787b39c5158Smillert $status = $z->nextStream(); 788b39c5158Smillert 789b39c5158Smillert last 790b39c5158Smillert unless $status == 1 ; 791b39c5158Smillert } 792b39c5158Smillert 793b39c5158Smillert return $z->closeError(undef) 794b39c5158Smillert if $status < 0 ; 795b39c5158Smillert 796b39c5158Smillert ${ *$self->{TrailingData} } = $z->trailingData() 797b39c5158Smillert if defined *$self->{TrailingData} ; 798b39c5158Smillert 799b39c5158Smillert $z->close() 800b39c5158Smillert or return undef ; 801b39c5158Smillert 802b39c5158Smillert return 1 ; 803b39c5158Smillert} 804b39c5158Smillert 805b39c5158Smillertsub TIEHANDLE 806b39c5158Smillert{ 807b39c5158Smillert return $_[0] if ref($_[0]); 808b39c5158Smillert die "OOPS\n" ; 809b39c5158Smillert 810b39c5158Smillert} 811b39c5158Smillert 812b39c5158Smillertsub UNTIE 813b39c5158Smillert{ 814b39c5158Smillert my $self = shift ; 815b39c5158Smillert} 816b39c5158Smillert 817b39c5158Smillert 818b39c5158Smillertsub getHeaderInfo 819b39c5158Smillert{ 820b39c5158Smillert my $self = shift ; 821b39c5158Smillert wantarray ? @{ *$self->{InfoList} } : *$self->{Info}; 822b39c5158Smillert} 823b39c5158Smillert 824b39c5158Smillertsub readBlock 825b39c5158Smillert{ 826b39c5158Smillert my $self = shift ; 827b39c5158Smillert my $buff = shift ; 828b39c5158Smillert my $size = shift ; 829b39c5158Smillert 830b39c5158Smillert if (defined *$self->{CompressedInputLength}) { 831b39c5158Smillert if (*$self->{CompressedInputLengthRemaining} == 0) { 832b39c5158Smillert delete *$self->{CompressedInputLength}; 833b39c5158Smillert *$self->{CompressedInputLengthDone} = 1; 834b39c5158Smillert return STATUS_OK ; 835b39c5158Smillert } 83691f110e0Safresh1 $size = List::Util::min($size, *$self->{CompressedInputLengthRemaining} ); 837b39c5158Smillert *$self->{CompressedInputLengthRemaining} -= $size ; 838b39c5158Smillert } 839b39c5158Smillert 840b39c5158Smillert my $status = $self->smartRead($buff, $size) ; 841898184e3Ssthen return $self->saveErrorString(STATUS_ERROR, "Error Reading Data: $!", $!) 842898184e3Ssthen if $status == STATUS_ERROR ; 843b39c5158Smillert 844b39c5158Smillert if ($status == 0 ) { 845b39c5158Smillert *$self->{Closed} = 1 ; 846b39c5158Smillert *$self->{EndStream} = 1 ; 847b39c5158Smillert return $self->saveErrorString(STATUS_ERROR, "unexpected end of file", STATUS_ERROR); 848b39c5158Smillert } 849b39c5158Smillert 850b39c5158Smillert return STATUS_OK; 851b39c5158Smillert} 852b39c5158Smillert 853b39c5158Smillertsub postBlockChk 854b39c5158Smillert{ 855b39c5158Smillert return STATUS_OK; 856b39c5158Smillert} 857b39c5158Smillert 858b39c5158Smillertsub _raw_read 859b39c5158Smillert{ 860b39c5158Smillert # return codes 861b39c5158Smillert # >0 - ok, number of bytes read 862b39c5158Smillert # =0 - ok, eof 863b39c5158Smillert # <0 - not ok 864b39c5158Smillert 865b39c5158Smillert my $self = shift ; 866b39c5158Smillert 867b39c5158Smillert return G_EOF if *$self->{Closed} ; 868b39c5158Smillert return G_EOF if *$self->{EndStream} ; 869b39c5158Smillert 870b39c5158Smillert my $buffer = shift ; 871b39c5158Smillert my $scan_mode = shift ; 872b39c5158Smillert 873b39c5158Smillert if (*$self->{Plain}) { 874b39c5158Smillert my $tmp_buff ; 875b39c5158Smillert my $len = $self->smartRead(\$tmp_buff, *$self->{BlockSize}) ; 876b39c5158Smillert 877b39c5158Smillert return $self->saveErrorString(G_ERR, "Error reading data: $!", $!) 878898184e3Ssthen if $len == STATUS_ERROR ; 879b39c5158Smillert 880b39c5158Smillert if ($len == 0 ) { 881b39c5158Smillert *$self->{EndStream} = 1 ; 882b39c5158Smillert } 883b39c5158Smillert else { 884b39c5158Smillert *$self->{PlainBytesRead} += $len ; 885b39c5158Smillert $$buffer .= $tmp_buff; 886b39c5158Smillert } 887b39c5158Smillert 888b39c5158Smillert return $len ; 889b39c5158Smillert } 890b39c5158Smillert 891b39c5158Smillert if (*$self->{NewStream}) { 892b39c5158Smillert 893b39c5158Smillert $self->gotoNextStream() > 0 894b39c5158Smillert or return G_ERR; 895b39c5158Smillert 896b39c5158Smillert # For the headers that actually uncompressed data, put the 897b39c5158Smillert # uncompressed data into the output buffer. 898b39c5158Smillert $$buffer .= *$self->{Pending} ; 899b39c5158Smillert my $len = length *$self->{Pending} ; 900b39c5158Smillert *$self->{Pending} = ''; 901b39c5158Smillert return $len; 902b39c5158Smillert } 903b39c5158Smillert 904b39c5158Smillert my $temp_buf = ''; 905b39c5158Smillert my $outSize = 0; 906b39c5158Smillert my $status = $self->readBlock(\$temp_buf, *$self->{BlockSize}, $outSize) ; 907898184e3Ssthen 908b39c5158Smillert return G_ERR 909b39c5158Smillert if $status == STATUS_ERROR ; 910b39c5158Smillert 911b39c5158Smillert my $buf_len = 0; 912b39c5158Smillert if ($status == STATUS_OK) { 913b39c5158Smillert my $beforeC_len = length $temp_buf; 914b39c5158Smillert my $before_len = defined $$buffer ? length $$buffer : 0 ; 915b39c5158Smillert $status = *$self->{Uncomp}->uncompr(\$temp_buf, $buffer, 916b39c5158Smillert defined *$self->{CompressedInputLengthDone} || 917b39c5158Smillert $self->smartEof(), $outSize); 918b39c5158Smillert 919b39c5158Smillert # Remember the input buffer if it wasn't consumed completely 920b39c5158Smillert $self->pushBack($temp_buf) if *$self->{Uncomp}{ConsumesInput}; 921b39c5158Smillert 922b39c5158Smillert return $self->saveErrorString(G_ERR, *$self->{Uncomp}{Error}, *$self->{Uncomp}{ErrorNo}) 923b39c5158Smillert if $self->saveStatus($status) == STATUS_ERROR; 924b39c5158Smillert 925b39c5158Smillert $self->postBlockChk($buffer, $before_len) == STATUS_OK 926b39c5158Smillert or return G_ERR; 927b39c5158Smillert 928b39c5158Smillert $buf_len = defined $$buffer ? length($$buffer) - $before_len : 0; 929b39c5158Smillert 930b39c5158Smillert *$self->{CompSize}->add($beforeC_len - length $temp_buf) ; 931b39c5158Smillert 932b39c5158Smillert *$self->{InflatedBytesRead} += $buf_len ; 933b39c5158Smillert *$self->{TotalInflatedBytesRead} += $buf_len ; 934b39c5158Smillert *$self->{UnCompSize}->add($buf_len) ; 935b39c5158Smillert 936898184e3Ssthen $self->filterUncompressed($buffer, $before_len); 937b39c5158Smillert 93891f110e0Safresh1# if (*$self->{Encoding}) { 93991f110e0Safresh1# use Encode ; 94091f110e0Safresh1# *$self->{PendingDecode} .= substr($$buffer, $before_len) ; 94191f110e0Safresh1# my $got = *$self->{Encoding}->decode(*$self->{PendingDecode}, Encode::FB_QUIET) ; 94291f110e0Safresh1# substr($$buffer, $before_len) = $got; 94391f110e0Safresh1# } 944b39c5158Smillert } 945b39c5158Smillert 946b39c5158Smillert if ($status == STATUS_ENDSTREAM) { 947b39c5158Smillert 948b39c5158Smillert *$self->{EndStream} = 1 ; 949b39c5158Smillert 950b39c5158Smillert my $trailer; 951b39c5158Smillert my $trailer_size = *$self->{Info}{TrailerLength} ; 952b39c5158Smillert my $got = 0; 953b39c5158Smillert if (*$self->{Info}{TrailerLength}) 954b39c5158Smillert { 955b39c5158Smillert $got = $self->smartRead(\$trailer, $trailer_size) ; 956b39c5158Smillert } 957b39c5158Smillert 958b39c5158Smillert if ($got == $trailer_size) { 959b39c5158Smillert $self->chkTrailer($trailer) == STATUS_OK 960b39c5158Smillert or return G_ERR; 961b39c5158Smillert } 962b39c5158Smillert else { 963b39c5158Smillert return $self->TrailerError("trailer truncated. Expected " . 964b39c5158Smillert "$trailer_size bytes, got $got") 965b39c5158Smillert if *$self->{Strict}; 966b39c5158Smillert $self->pushBack($trailer) ; 967b39c5158Smillert } 968b39c5158Smillert 9696fb12b70Safresh1 # TODO - if want file pointer, do it here 970b39c5158Smillert 971b39c5158Smillert if (! $self->smartEof()) { 972b39c5158Smillert *$self->{NewStream} = 1 ; 973b39c5158Smillert 974b39c5158Smillert if (*$self->{MultiStream}) { 975b39c5158Smillert *$self->{EndStream} = 0 ; 976b39c5158Smillert return $buf_len ; 977b39c5158Smillert } 978b39c5158Smillert } 979b39c5158Smillert 980b39c5158Smillert } 981b39c5158Smillert 982b39c5158Smillert 983b39c5158Smillert # return the number of uncompressed bytes read 984b39c5158Smillert return $buf_len ; 985b39c5158Smillert} 986b39c5158Smillert 987b39c5158Smillertsub reset 988b39c5158Smillert{ 989b39c5158Smillert my $self = shift ; 990b39c5158Smillert 991b39c5158Smillert return *$self->{Uncomp}->reset(); 992b39c5158Smillert} 993b39c5158Smillert 994b39c5158Smillertsub filterUncompressed 995b39c5158Smillert{ 996b39c5158Smillert} 997b39c5158Smillert 998b39c5158Smillert#sub isEndStream 999b39c5158Smillert#{ 1000b39c5158Smillert# my $self = shift ; 1001b39c5158Smillert# return *$self->{NewStream} || 1002b39c5158Smillert# *$self->{EndStream} ; 1003b39c5158Smillert#} 1004b39c5158Smillert 1005b39c5158Smillertsub nextStream 1006b39c5158Smillert{ 1007b39c5158Smillert my $self = shift ; 1008b39c5158Smillert 1009eac174f2Safresh1 # An uncompressed file cannot have a next stream, so 1010eac174f2Safresh1 # return immediately. 1011eac174f2Safresh1 return 0 1012eac174f2Safresh1 if *$self->{Plain} ; 1013eac174f2Safresh1 1014b39c5158Smillert my $status = $self->gotoNextStream(); 1015b39c5158Smillert $status == 1 1016b39c5158Smillert or return $status ; 1017b39c5158Smillert 101856d68f1eSafresh1 *$self->{Pending} = '' 101956d68f1eSafresh1 if $self !~ /IO::Uncompress::RawInflate/ && ! *$self->{MultiStream}; 102056d68f1eSafresh1 1021b39c5158Smillert *$self->{TotalInflatedBytesRead} = 0 ; 1022b39c5158Smillert *$self->{LineNo} = $. = 0; 1023b39c5158Smillert 1024b39c5158Smillert return 1; 1025b39c5158Smillert} 1026b39c5158Smillert 1027b39c5158Smillertsub gotoNextStream 1028b39c5158Smillert{ 1029b39c5158Smillert my $self = shift ; 1030b39c5158Smillert 1031b39c5158Smillert if (! *$self->{NewStream}) { 1032b39c5158Smillert my $status = 1; 1033b39c5158Smillert my $buffer ; 1034b39c5158Smillert 1035b39c5158Smillert # TODO - make this more efficient if know the offset for the end of 1036b39c5158Smillert # the stream and seekable 1037b39c5158Smillert $status = $self->read($buffer) 1038b39c5158Smillert while $status > 0 ; 1039b39c5158Smillert 1040b39c5158Smillert return $status 1041b39c5158Smillert if $status < 0; 1042b39c5158Smillert } 1043b39c5158Smillert 1044b39c5158Smillert *$self->{NewStream} = 0 ; 1045b39c5158Smillert *$self->{EndStream} = 0 ; 1046898184e3Ssthen *$self->{CompressedInputLengthDone} = undef ; 1047898184e3Ssthen *$self->{CompressedInputLength} = undef ; 1048b39c5158Smillert $self->reset(); 1049b39c5158Smillert *$self->{UnCompSize}->reset(); 1050b39c5158Smillert *$self->{CompSize}->reset(); 1051b39c5158Smillert 1052b39c5158Smillert my $magic = $self->ckMagic(); 1053b39c5158Smillert 1054b39c5158Smillert if ( ! defined $magic) { 1055898184e3Ssthen if (! *$self->{Transparent} || $self->eof()) 1056b39c5158Smillert { 1057b39c5158Smillert *$self->{EndStream} = 1 ; 1058b39c5158Smillert return 0; 1059b39c5158Smillert } 1060b39c5158Smillert 106156d68f1eSafresh1 # Not EOF, so Transparent mode kicks in now for trailing data 106256d68f1eSafresh1 # Reset member name in case anyone calls getHeaderInfo()->{Name} 106356d68f1eSafresh1 *$self->{Info} = { Name => undef, Type => 'plain' }; 106456d68f1eSafresh1 1065b39c5158Smillert $self->clearError(); 1066b39c5158Smillert *$self->{Type} = 'plain'; 1067b39c5158Smillert *$self->{Plain} = 1; 1068b39c5158Smillert $self->pushBack(*$self->{HeaderPending}) ; 1069b39c5158Smillert } 1070b39c5158Smillert else 1071b39c5158Smillert { 1072b39c5158Smillert *$self->{Info} = $self->readHeader($magic); 1073b39c5158Smillert 1074b39c5158Smillert if ( ! defined *$self->{Info} ) { 1075b39c5158Smillert *$self->{EndStream} = 1 ; 1076b39c5158Smillert return -1; 1077b39c5158Smillert } 1078b39c5158Smillert } 1079b39c5158Smillert 1080b39c5158Smillert push @{ *$self->{InfoList} }, *$self->{Info} ; 1081b39c5158Smillert 1082b39c5158Smillert return 1; 1083b39c5158Smillert} 1084b39c5158Smillert 1085b39c5158Smillertsub streamCount 1086b39c5158Smillert{ 1087b39c5158Smillert my $self = shift ; 1088b39c5158Smillert return 1 if ! defined *$self->{InfoList}; 1089b39c5158Smillert return scalar @{ *$self->{InfoList} } ; 1090b39c5158Smillert} 1091b39c5158Smillert 1092b39c5158Smillertsub read 1093b39c5158Smillert{ 1094b39c5158Smillert # return codes 1095b39c5158Smillert # >0 - ok, number of bytes read 1096b39c5158Smillert # =0 - ok, eof 1097b39c5158Smillert # <0 - not ok 1098b39c5158Smillert 1099b39c5158Smillert my $self = shift ; 1100b39c5158Smillert 1101898184e3Ssthen if (defined *$self->{ReadStatus} ) { 1102898184e3Ssthen my $status = *$self->{ReadStatus}[0]; 1103898184e3Ssthen $self->saveErrorString( @{ *$self->{ReadStatus} } ); 1104898184e3Ssthen delete *$self->{ReadStatus} ; 1105898184e3Ssthen return $status ; 1106898184e3Ssthen } 1107898184e3Ssthen 1108b39c5158Smillert return G_EOF if *$self->{Closed} ; 1109b39c5158Smillert 1110b39c5158Smillert my $buffer ; 1111b39c5158Smillert 1112b39c5158Smillert if (ref $_[0] ) { 1113b39c5158Smillert $self->croakError(*$self->{ClassName} . "::read: buffer parameter is read-only") 111491f110e0Safresh1 if Scalar::Util::readonly(${ $_[0] }); 1115b39c5158Smillert 1116b39c5158Smillert $self->croakError(*$self->{ClassName} . "::read: not a scalar reference $_[0]" ) 1117b39c5158Smillert unless ref $_[0] eq 'SCALAR' ; 1118b39c5158Smillert $buffer = $_[0] ; 1119b39c5158Smillert } 1120b39c5158Smillert else { 1121b39c5158Smillert $self->croakError(*$self->{ClassName} . "::read: buffer parameter is read-only") 112291f110e0Safresh1 if Scalar::Util::readonly($_[0]); 1123b39c5158Smillert 1124b39c5158Smillert $buffer = \$_[0] ; 1125b39c5158Smillert } 1126b39c5158Smillert 1127b39c5158Smillert my $length = $_[1] ; 1128b39c5158Smillert my $offset = $_[2] || 0; 1129b39c5158Smillert 1130b39c5158Smillert if (! *$self->{AppendOutput}) { 1131b39c5158Smillert if (! $offset) { 1132b46d8ef2Safresh1 1133b39c5158Smillert $$buffer = '' ; 1134b39c5158Smillert } 1135b39c5158Smillert else { 1136b39c5158Smillert if ($offset > length($$buffer)) { 1137b39c5158Smillert $$buffer .= "\x00" x ($offset - length($$buffer)); 1138b39c5158Smillert } 1139b39c5158Smillert else { 1140b39c5158Smillert substr($$buffer, $offset) = ''; 1141b39c5158Smillert } 1142b39c5158Smillert } 1143b39c5158Smillert } 1144898184e3Ssthen elsif (! defined $$buffer) { 1145898184e3Ssthen $$buffer = '' ; 1146898184e3Ssthen } 1147b39c5158Smillert 1148b39c5158Smillert return G_EOF if !length *$self->{Pending} && *$self->{EndStream} ; 1149b39c5158Smillert 1150b39c5158Smillert # the core read will return 0 if asked for 0 bytes 1151b39c5158Smillert return 0 if defined $length && $length == 0 ; 1152b39c5158Smillert 1153b39c5158Smillert $length = $length || 0; 1154b39c5158Smillert 1155b39c5158Smillert $self->croakError(*$self->{ClassName} . "::read: length parameter is negative") 1156b39c5158Smillert if $length < 0 ; 1157b39c5158Smillert 1158b39c5158Smillert # Short-circuit if this is a simple read, with no length 1159b39c5158Smillert # or offset specified. 1160b39c5158Smillert unless ( $length || $offset) { 1161b39c5158Smillert if (length *$self->{Pending}) { 1162b39c5158Smillert $$buffer .= *$self->{Pending} ; 1163b39c5158Smillert my $len = length *$self->{Pending}; 1164b39c5158Smillert *$self->{Pending} = '' ; 1165b39c5158Smillert return $len ; 1166b39c5158Smillert } 1167b39c5158Smillert else { 1168b39c5158Smillert my $len = 0; 1169b39c5158Smillert $len = $self->_raw_read($buffer) 1170b39c5158Smillert while ! *$self->{EndStream} && $len == 0 ; 1171b39c5158Smillert return $len ; 1172b39c5158Smillert } 1173b39c5158Smillert } 1174b39c5158Smillert 1175b39c5158Smillert # Need to jump through more hoops - either length or offset 1176b39c5158Smillert # or both are specified. 1177b39c5158Smillert my $out_buffer = *$self->{Pending} ; 1178b39c5158Smillert *$self->{Pending} = ''; 1179b39c5158Smillert 1180b39c5158Smillert 1181b39c5158Smillert while (! *$self->{EndStream} && length($out_buffer) < $length) 1182b39c5158Smillert { 1183b39c5158Smillert my $buf_len = $self->_raw_read(\$out_buffer); 1184b39c5158Smillert return $buf_len 1185b39c5158Smillert if $buf_len < 0 ; 1186b39c5158Smillert } 1187b39c5158Smillert 1188b39c5158Smillert $length = length $out_buffer 1189b39c5158Smillert if length($out_buffer) < $length ; 1190b39c5158Smillert 1191b39c5158Smillert return 0 1192b39c5158Smillert if $length == 0 ; 1193b39c5158Smillert 1194b39c5158Smillert $$buffer = '' 1195b39c5158Smillert if ! defined $$buffer; 1196b39c5158Smillert 1197b39c5158Smillert $offset = length $$buffer 1198b39c5158Smillert if *$self->{AppendOutput} ; 1199b39c5158Smillert 1200b39c5158Smillert *$self->{Pending} = $out_buffer; 1201b39c5158Smillert $out_buffer = \*$self->{Pending} ; 1202b39c5158Smillert 1203b39c5158Smillert substr($$buffer, $offset) = substr($$out_buffer, 0, $length) ; 1204b39c5158Smillert substr($$out_buffer, 0, $length) = '' ; 1205b39c5158Smillert 1206b39c5158Smillert return $length ; 1207b39c5158Smillert} 1208b39c5158Smillert 1209b39c5158Smillertsub _getline 1210b39c5158Smillert{ 1211b39c5158Smillert my $self = shift ; 1212898184e3Ssthen my $status = 0 ; 1213b39c5158Smillert 1214b39c5158Smillert # Slurp Mode 1215b39c5158Smillert if ( ! defined $/ ) { 1216b39c5158Smillert my $data ; 1217898184e3Ssthen 1 while ($status = $self->read($data)) > 0 ; 1218898184e3Ssthen return ($status, \$data); 1219b39c5158Smillert } 1220b39c5158Smillert 1221b39c5158Smillert # Record Mode 1222b39c5158Smillert if ( ref $/ eq 'SCALAR' && ${$/} =~ /^\d+$/ && ${$/} > 0) { 1223b39c5158Smillert my $reclen = ${$/} ; 1224b39c5158Smillert my $data ; 1225898184e3Ssthen $status = $self->read($data, $reclen) ; 1226898184e3Ssthen return ($status, \$data); 1227b39c5158Smillert } 1228b39c5158Smillert 1229b39c5158Smillert # Paragraph Mode 1230b39c5158Smillert if ( ! length $/ ) { 1231b39c5158Smillert my $paragraph ; 1232898184e3Ssthen while (($status = $self->read($paragraph)) > 0 ) { 1233b39c5158Smillert if ($paragraph =~ s/^(.*?\n\n+)//s) { 1234b39c5158Smillert *$self->{Pending} = $paragraph ; 1235b39c5158Smillert my $par = $1 ; 1236898184e3Ssthen return (1, \$par); 1237b39c5158Smillert } 1238b39c5158Smillert } 1239898184e3Ssthen return ($status, \$paragraph); 1240b39c5158Smillert } 1241b39c5158Smillert 1242b39c5158Smillert # $/ isn't empty, or a reference, so it's Line Mode. 1243b39c5158Smillert { 1244b39c5158Smillert my $line ; 1245b39c5158Smillert my $p = \*$self->{Pending} ; 1246898184e3Ssthen while (($status = $self->read($line)) > 0 ) { 1247b39c5158Smillert my $offset = index($line, $/); 1248b39c5158Smillert if ($offset >= 0) { 1249b39c5158Smillert my $l = substr($line, 0, $offset + length $/ ); 1250b39c5158Smillert substr($line, 0, $offset + length $/) = ''; 1251b39c5158Smillert $$p = $line; 1252898184e3Ssthen return (1, \$l); 1253b39c5158Smillert } 1254b39c5158Smillert } 1255b39c5158Smillert 1256898184e3Ssthen return ($status, \$line); 1257b39c5158Smillert } 1258b39c5158Smillert} 1259b39c5158Smillert 1260b39c5158Smillertsub getline 1261b39c5158Smillert{ 1262b39c5158Smillert my $self = shift; 1263898184e3Ssthen 1264898184e3Ssthen if (defined *$self->{ReadStatus} ) { 1265898184e3Ssthen $self->saveErrorString( @{ *$self->{ReadStatus} } ); 1266898184e3Ssthen delete *$self->{ReadStatus} ; 1267898184e3Ssthen return undef; 1268898184e3Ssthen } 1269898184e3Ssthen 1270898184e3Ssthen return undef 1271898184e3Ssthen if *$self->{Closed} || (!length *$self->{Pending} && *$self->{EndStream}) ; 1272898184e3Ssthen 1273b39c5158Smillert my $current_append = *$self->{AppendOutput} ; 1274b39c5158Smillert *$self->{AppendOutput} = 1; 1275898184e3Ssthen 1276898184e3Ssthen my ($status, $lineref) = $self->_getline(); 1277b39c5158Smillert *$self->{AppendOutput} = $current_append; 1278898184e3Ssthen 1279898184e3Ssthen return undef 1280898184e3Ssthen if $status < 0 || length $$lineref == 0 ; 1281898184e3Ssthen 1282898184e3Ssthen $. = ++ *$self->{LineNo} ; 1283898184e3Ssthen 1284b39c5158Smillert return $$lineref ; 1285b39c5158Smillert} 1286b39c5158Smillert 1287b39c5158Smillertsub getlines 1288b39c5158Smillert{ 1289b39c5158Smillert my $self = shift; 1290b39c5158Smillert $self->croakError(*$self->{ClassName} . 1291b39c5158Smillert "::getlines: called in scalar context\n") unless wantarray; 1292b39c5158Smillert my($line, @lines); 1293b39c5158Smillert push(@lines, $line) 1294b39c5158Smillert while defined($line = $self->getline); 1295b39c5158Smillert return @lines; 1296b39c5158Smillert} 1297b39c5158Smillert 1298b39c5158Smillertsub READLINE 1299b39c5158Smillert{ 1300b39c5158Smillert goto &getlines if wantarray; 1301b39c5158Smillert goto &getline; 1302b39c5158Smillert} 1303b39c5158Smillert 1304b39c5158Smillertsub getc 1305b39c5158Smillert{ 1306b39c5158Smillert my $self = shift; 1307b39c5158Smillert my $buf; 1308b39c5158Smillert return $buf if $self->read($buf, 1); 1309b39c5158Smillert return undef; 1310b39c5158Smillert} 1311b39c5158Smillert 1312b39c5158Smillertsub ungetc 1313b39c5158Smillert{ 1314b39c5158Smillert my $self = shift; 1315b39c5158Smillert *$self->{Pending} = "" unless defined *$self->{Pending} ; 1316b39c5158Smillert *$self->{Pending} = $_[0] . *$self->{Pending} ; 1317b39c5158Smillert} 1318b39c5158Smillert 1319b39c5158Smillert 1320b39c5158Smillertsub trailingData 1321b39c5158Smillert{ 1322b39c5158Smillert my $self = shift ; 1323b39c5158Smillert 1324b39c5158Smillert if (defined *$self->{FH} || defined *$self->{InputEvent} ) { 1325b39c5158Smillert return *$self->{Prime} ; 1326b39c5158Smillert } 1327b39c5158Smillert else { 1328b39c5158Smillert my $buf = *$self->{Buffer} ; 1329b39c5158Smillert my $offset = *$self->{BufferOffset} ; 1330b39c5158Smillert return substr($$buf, $offset) ; 1331b39c5158Smillert } 1332b39c5158Smillert} 1333b39c5158Smillert 1334b39c5158Smillert 1335b39c5158Smillertsub eof 1336b39c5158Smillert{ 1337b39c5158Smillert my $self = shift ; 1338b39c5158Smillert 1339b39c5158Smillert return (*$self->{Closed} || 1340b39c5158Smillert (!length *$self->{Pending} 1341b39c5158Smillert && ( $self->smartEof() || *$self->{EndStream}))) ; 1342b39c5158Smillert} 1343b39c5158Smillert 1344b39c5158Smillertsub tell 1345b39c5158Smillert{ 1346b39c5158Smillert my $self = shift ; 1347b39c5158Smillert 1348b39c5158Smillert my $in ; 1349b39c5158Smillert if (*$self->{Plain}) { 1350b39c5158Smillert $in = *$self->{PlainBytesRead} ; 1351b39c5158Smillert } 1352b39c5158Smillert else { 1353b39c5158Smillert $in = *$self->{TotalInflatedBytesRead} ; 1354b39c5158Smillert } 1355b39c5158Smillert 1356b39c5158Smillert my $pending = length *$self->{Pending} ; 1357b39c5158Smillert 1358b39c5158Smillert return 0 if $pending > $in ; 1359b39c5158Smillert return $in - $pending ; 1360b39c5158Smillert} 1361b39c5158Smillert 1362b39c5158Smillertsub close 1363b39c5158Smillert{ 1364b39c5158Smillert # todo - what to do if close is called before the end of the gzip file 1365b39c5158Smillert # do we remember any trailing data? 1366b39c5158Smillert my $self = shift ; 1367b39c5158Smillert 1368b39c5158Smillert return 1 if *$self->{Closed} ; 1369b39c5158Smillert 1370b39c5158Smillert untie *$self 1371b39c5158Smillert if $] >= 5.008 ; 1372b39c5158Smillert 1373b39c5158Smillert my $status = 1 ; 1374b39c5158Smillert 1375b39c5158Smillert if (defined *$self->{FH}) { 1376b39c5158Smillert if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) { 1377b39c5158Smillert local $.; 1378b39c5158Smillert $! = 0 ; 1379b39c5158Smillert $status = *$self->{FH}->close(); 1380b39c5158Smillert return $self->saveErrorString(0, $!, $!) 1381b39c5158Smillert if !*$self->{InNew} && $self->saveStatus($!) != 0 ; 1382b39c5158Smillert } 1383b39c5158Smillert delete *$self->{FH} ; 1384b39c5158Smillert $! = 0 ; 1385b39c5158Smillert } 1386b39c5158Smillert *$self->{Closed} = 1 ; 1387b39c5158Smillert 1388b39c5158Smillert return 1; 1389b39c5158Smillert} 1390b39c5158Smillert 1391b39c5158Smillertsub DESTROY 1392b39c5158Smillert{ 1393b39c5158Smillert my $self = shift ; 1394b39c5158Smillert local ($., $@, $!, $^E, $?); 1395b39c5158Smillert 1396b39c5158Smillert $self->close() ; 1397b39c5158Smillert} 1398b39c5158Smillert 1399b39c5158Smillertsub seek 1400b39c5158Smillert{ 1401b39c5158Smillert my $self = shift ; 1402b39c5158Smillert my $position = shift; 1403b39c5158Smillert my $whence = shift ; 1404b39c5158Smillert 1405b39c5158Smillert my $here = $self->tell() ; 1406b39c5158Smillert my $target = 0 ; 1407b39c5158Smillert 1408b39c5158Smillert 1409b39c5158Smillert if ($whence == SEEK_SET) { 1410b39c5158Smillert $target = $position ; 1411b39c5158Smillert } 1412b39c5158Smillert elsif ($whence == SEEK_CUR) { 1413b39c5158Smillert $target = $here + $position ; 1414b39c5158Smillert } 1415b39c5158Smillert elsif ($whence == SEEK_END) { 1416b39c5158Smillert $target = $position ; 1417b39c5158Smillert $self->croakError(*$self->{ClassName} . "::seek: SEEK_END not allowed") ; 1418b39c5158Smillert } 1419b39c5158Smillert else { 1420b39c5158Smillert $self->croakError(*$self->{ClassName} ."::seek: unknown value, $whence, for whence parameter"); 1421b39c5158Smillert } 1422b39c5158Smillert 1423b39c5158Smillert # short circuit if seeking to current offset 1424b39c5158Smillert if ($target == $here) { 1425b39c5158Smillert # On ordinary filehandles, seeking to the current 1426b39c5158Smillert # position also clears the EOF condition, so we 1427b39c5158Smillert # emulate this behavior locally while simultaneously 1428b39c5158Smillert # cascading it to the underlying filehandle 1429b39c5158Smillert if (*$self->{Plain}) { 1430b39c5158Smillert *$self->{EndStream} = 0; 1431b39c5158Smillert seek(*$self->{FH},0,1) if *$self->{FH}; 1432b39c5158Smillert } 1433b39c5158Smillert return 1; 1434b39c5158Smillert } 1435b39c5158Smillert 1436b39c5158Smillert # Outlaw any attempt to seek backwards 1437b39c5158Smillert $self->croakError( *$self->{ClassName} ."::seek: cannot seek backwards") 1438b39c5158Smillert if $target < $here ; 1439b39c5158Smillert 1440b39c5158Smillert # Walk the file to the new offset 1441b39c5158Smillert my $offset = $target - $here ; 1442b39c5158Smillert 1443b39c5158Smillert my $got; 144491f110e0Safresh1 while (($got = $self->read(my $buffer, List::Util::min($offset, *$self->{BlockSize})) ) > 0) 1445b39c5158Smillert { 1446b39c5158Smillert $offset -= $got; 1447b39c5158Smillert last if $offset == 0 ; 1448b39c5158Smillert } 1449b39c5158Smillert 1450b39c5158Smillert $here = $self->tell() ; 1451b39c5158Smillert return $offset == 0 ? 1 : 0 ; 1452b39c5158Smillert} 1453b39c5158Smillert 1454b39c5158Smillertsub fileno 1455b39c5158Smillert{ 1456b39c5158Smillert my $self = shift ; 1457b39c5158Smillert return defined *$self->{FH} 1458b39c5158Smillert ? fileno *$self->{FH} 1459b39c5158Smillert : undef ; 1460b39c5158Smillert} 1461b39c5158Smillert 1462b39c5158Smillertsub binmode 1463b39c5158Smillert{ 1464b39c5158Smillert 1; 1465b39c5158Smillert# my $self = shift ; 1466b39c5158Smillert# return defined *$self->{FH} 1467b39c5158Smillert# ? binmode *$self->{FH} 1468b39c5158Smillert# : 1 ; 1469b39c5158Smillert} 1470b39c5158Smillert 1471b39c5158Smillertsub opened 1472b39c5158Smillert{ 1473b39c5158Smillert my $self = shift ; 1474b39c5158Smillert return ! *$self->{Closed} ; 1475b39c5158Smillert} 1476b39c5158Smillert 1477b39c5158Smillertsub autoflush 1478b39c5158Smillert{ 1479b39c5158Smillert my $self = shift ; 1480b39c5158Smillert return defined *$self->{FH} 1481b39c5158Smillert ? *$self->{FH}->autoflush(@_) 1482b39c5158Smillert : undef ; 1483b39c5158Smillert} 1484b39c5158Smillert 1485b39c5158Smillertsub input_line_number 1486b39c5158Smillert{ 1487b39c5158Smillert my $self = shift ; 1488b39c5158Smillert my $last = *$self->{LineNo}; 1489b39c5158Smillert $. = *$self->{LineNo} = $_[1] if @_ ; 1490b39c5158Smillert return $last; 1491b39c5158Smillert} 1492b39c5158Smillert 1493eac174f2Safresh1sub _notAvailable 1494eac174f2Safresh1{ 1495eac174f2Safresh1 my $name = shift ; 1496eac174f2Safresh1 return sub { croak "$name Not Available: File opened only for intput" ; } ; 1497eac174f2Safresh1} 1498eac174f2Safresh1 1499eac174f2Safresh1{ 1500eac174f2Safresh1 no warnings 'once'; 1501b39c5158Smillert 1502b39c5158Smillert *BINMODE = \&binmode; 1503b39c5158Smillert *SEEK = \&seek; 1504b39c5158Smillert *READ = \&read; 1505b39c5158Smillert *sysread = \&read; 1506b39c5158Smillert *TELL = \&tell; 1507b39c5158Smillert *EOF = \&eof; 1508b39c5158Smillert 1509b39c5158Smillert *FILENO = \&fileno; 1510b39c5158Smillert *CLOSE = \&close; 1511b39c5158Smillert 1512b39c5158Smillert *print = _notAvailable('print'); 1513b39c5158Smillert *PRINT = _notAvailable('print'); 1514b39c5158Smillert *printf = _notAvailable('printf'); 1515b39c5158Smillert *PRINTF = _notAvailable('printf'); 1516b39c5158Smillert *write = _notAvailable('write'); 1517b39c5158Smillert *WRITE = _notAvailable('write'); 1518b39c5158Smillert 1519b39c5158Smillert #*sysread = \&read; 1520b39c5158Smillert #*syswrite = \&_notAvailable; 1521eac174f2Safresh1} 1522b39c5158Smillert 1523b39c5158Smillert 1524b39c5158Smillert 1525b39c5158Smillertpackage IO::Uncompress::Base ; 1526b39c5158Smillert 1527b39c5158Smillert 1528b39c5158Smillert1 ; 1529b39c5158Smillert__END__ 1530b39c5158Smillert 1531b39c5158Smillert=head1 NAME 1532b39c5158Smillert 1533b39c5158SmillertIO::Uncompress::Base - Base Class for IO::Uncompress modules 1534b39c5158Smillert 1535b39c5158Smillert=head1 SYNOPSIS 1536b39c5158Smillert 1537b39c5158Smillert use IO::Uncompress::Base ; 1538b39c5158Smillert 1539b39c5158Smillert=head1 DESCRIPTION 1540b39c5158Smillert 1541b39c5158SmillertThis module is not intended for direct use in application code. Its sole 15426fb12b70Safresh1purpose is to be sub-classed by IO::Uncompress modules. 1543b39c5158Smillert 154456d68f1eSafresh1=head1 SUPPORT 154556d68f1eSafresh1 154656d68f1eSafresh1General feedback/questions/bug reports should be sent to 154756d68f1eSafresh1L<https://github.com/pmqs/IO-Compress/issues> (preferred) or 154856d68f1eSafresh1L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>. 154956d68f1eSafresh1 1550b39c5158Smillert=head1 SEE ALSO 1551b39c5158Smillert 1552b46d8ef2Safresh1L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress> 1553b39c5158Smillert 1554898184e3SsthenL<IO::Compress::FAQ|IO::Compress::FAQ> 1555b39c5158Smillert 1556b39c5158SmillertL<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, 1557b39c5158SmillertL<Archive::Tar|Archive::Tar>, 1558b39c5158SmillertL<IO::Zlib|IO::Zlib> 1559b39c5158Smillert 1560b39c5158Smillert=head1 AUTHOR 1561b39c5158Smillert 15629f11ffb7Safresh1This module was written by Paul Marquess, C<pmqs@cpan.org>. 1563b39c5158Smillert 1564b39c5158Smillert=head1 MODIFICATION HISTORY 1565b39c5158Smillert 1566b39c5158SmillertSee the Changes file. 1567b39c5158Smillert 1568b39c5158Smillert=head1 COPYRIGHT AND LICENSE 1569b39c5158Smillert 1570*3d61058aSafresh1Copyright (c) 2005-2024 Paul Marquess. All rights reserved. 1571b39c5158Smillert 1572b39c5158SmillertThis program is free software; you can redistribute it and/or 1573b39c5158Smillertmodify it under the same terms as Perl itself. 1574