1b39c5158Smillert 2b39c5158Smillertpackage IO::Compress::Base ; 3b39c5158Smillert 4898184e3Ssthenrequire 5.006 ; 5b39c5158Smillert 6b39c5158Smillertuse strict ; 7b39c5158Smillertuse warnings; 8b39c5158Smillert 9*3d61058aSafresh1use IO::Compress::Base::Common 2.212 ; 10b39c5158Smillert 1191f110e0Safresh1use IO::File (); ; 1291f110e0Safresh1use Scalar::Util (); 13b39c5158Smillert 14b39c5158Smillert#use File::Glob; 15b39c5158Smillert#require Exporter ; 16898184e3Ssthenuse Carp() ; 17898184e3Ssthenuse Symbol(); 1891f110e0Safresh1#use bytes; 19b39c5158Smillert 20b39c5158Smillertour (@ISA, $VERSION); 219f11ffb7Safresh1@ISA = qw(IO::File Exporter); 22b39c5158Smillert 23*3d61058aSafresh1$VERSION = '2.212'; 24b39c5158Smillert 25b39c5158Smillert#Can't locate object method "SWASHNEW" via package "utf8" (perhaps you forgot to load "utf8"?) at .../ext/Compress-Zlib/Gzip/blib/lib/Compress/Zlib/Common.pm line 16. 26b39c5158Smillert 27b39c5158Smillertsub saveStatus 28b39c5158Smillert{ 29b39c5158Smillert my $self = shift ; 30b39c5158Smillert ${ *$self->{ErrorNo} } = shift() + 0 ; 31b39c5158Smillert ${ *$self->{Error} } = '' ; 32b39c5158Smillert 33b39c5158Smillert return ${ *$self->{ErrorNo} } ; 34b39c5158Smillert} 35b39c5158Smillert 36b39c5158Smillert 37b39c5158Smillertsub saveErrorString 38b39c5158Smillert{ 39b39c5158Smillert my $self = shift ; 40b39c5158Smillert my $retval = shift ; 41b39c5158Smillert ${ *$self->{Error} } = shift ; 42b39c5158Smillert ${ *$self->{ErrorNo} } = shift() + 0 if @_ ; 43b39c5158Smillert 44b39c5158Smillert return $retval; 45b39c5158Smillert} 46b39c5158Smillert 47b39c5158Smillertsub croakError 48b39c5158Smillert{ 49b39c5158Smillert my $self = shift ; 50b39c5158Smillert $self->saveErrorString(0, $_[0]); 51898184e3Ssthen Carp::croak $_[0]; 52b39c5158Smillert} 53b39c5158Smillert 54b39c5158Smillertsub closeError 55b39c5158Smillert{ 56b39c5158Smillert my $self = shift ; 57b39c5158Smillert my $retval = shift ; 58b39c5158Smillert 59b39c5158Smillert my $errno = *$self->{ErrorNo}; 60b39c5158Smillert my $error = ${ *$self->{Error} }; 61b39c5158Smillert 62b39c5158Smillert $self->close(); 63b39c5158Smillert 64b39c5158Smillert *$self->{ErrorNo} = $errno ; 65b39c5158Smillert ${ *$self->{Error} } = $error ; 66b39c5158Smillert 67b39c5158Smillert return $retval; 68b39c5158Smillert} 69b39c5158Smillert 70b39c5158Smillert 71b39c5158Smillert 72b39c5158Smillertsub error 73b39c5158Smillert{ 74b39c5158Smillert my $self = shift ; 75b39c5158Smillert return ${ *$self->{Error} } ; 76b39c5158Smillert} 77b39c5158Smillert 78b39c5158Smillertsub errorNo 79b39c5158Smillert{ 80b39c5158Smillert my $self = shift ; 81b39c5158Smillert return ${ *$self->{ErrorNo} } ; 82b39c5158Smillert} 83b39c5158Smillert 84b39c5158Smillert 85b39c5158Smillertsub writeAt 86b39c5158Smillert{ 87b39c5158Smillert my $self = shift ; 88b39c5158Smillert my $offset = shift; 89b39c5158Smillert my $data = shift; 90b39c5158Smillert 91b39c5158Smillert if (defined *$self->{FH}) { 92b39c5158Smillert my $here = tell(*$self->{FH}); 93b39c5158Smillert return $self->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) 94b39c5158Smillert if $here < 0 ; 9591f110e0Safresh1 seek(*$self->{FH}, $offset, IO::Handle::SEEK_SET) 96b39c5158Smillert or return $self->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ; 97b39c5158Smillert defined *$self->{FH}->write($data, length $data) 98b39c5158Smillert or return $self->saveErrorString(undef, $!, $!) ; 9991f110e0Safresh1 seek(*$self->{FH}, $here, IO::Handle::SEEK_SET) 100b39c5158Smillert or return $self->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ; 101b39c5158Smillert } 102b39c5158Smillert else { 103b39c5158Smillert substr(${ *$self->{Buffer} }, $offset, length($data)) = $data ; 104b39c5158Smillert } 105b39c5158Smillert 106b39c5158Smillert return 1; 107b39c5158Smillert} 108b39c5158Smillert 109898184e3Ssthensub outputPayload 110898184e3Ssthen{ 111898184e3Ssthen 112898184e3Ssthen my $self = shift ; 113898184e3Ssthen return $self->output(@_); 114898184e3Ssthen} 115898184e3Ssthen 116898184e3Ssthen 117b39c5158Smillertsub output 118b39c5158Smillert{ 119b39c5158Smillert my $self = shift ; 120b39c5158Smillert my $data = shift ; 121b39c5158Smillert my $last = shift ; 122b39c5158Smillert 123b39c5158Smillert return 1 124b39c5158Smillert if length $data == 0 && ! $last ; 125b39c5158Smillert 126898184e3Ssthen if ( *$self->{FilterContainer} ) { 127b39c5158Smillert *_ = \$data; 128898184e3Ssthen &{ *$self->{FilterContainer} }(); 129b39c5158Smillert } 130b39c5158Smillert 131b39c5158Smillert if (length $data) { 132b39c5158Smillert if ( defined *$self->{FH} ) { 133b39c5158Smillert defined *$self->{FH}->write( $data, length $data ) 134b39c5158Smillert or return $self->saveErrorString(0, $!, $!); 135b39c5158Smillert } 136b39c5158Smillert else { 137b39c5158Smillert ${ *$self->{Buffer} } .= $data ; 138b39c5158Smillert } 139b39c5158Smillert } 140b39c5158Smillert 141b39c5158Smillert return 1; 142b39c5158Smillert} 143b39c5158Smillert 144b39c5158Smillertsub getOneShotParams 145b39c5158Smillert{ 14691f110e0Safresh1 return ( 'multistream' => [IO::Compress::Base::Common::Parse_boolean, 1], 147b39c5158Smillert ); 148b39c5158Smillert} 149b39c5158Smillert 15091f110e0Safresh1our %PARAMS = ( 15191f110e0Safresh1 # Generic Parameters 15291f110e0Safresh1 'autoclose' => [IO::Compress::Base::Common::Parse_boolean, 0], 15391f110e0Safresh1 'encode' => [IO::Compress::Base::Common::Parse_any, undef], 15491f110e0Safresh1 'strict' => [IO::Compress::Base::Common::Parse_boolean, 1], 15591f110e0Safresh1 'append' => [IO::Compress::Base::Common::Parse_boolean, 0], 15691f110e0Safresh1 'binmodein' => [IO::Compress::Base::Common::Parse_boolean, 0], 15791f110e0Safresh1 15891f110e0Safresh1 'filtercontainer' => [IO::Compress::Base::Common::Parse_code, undef], 15991f110e0Safresh1 ); 16091f110e0Safresh1 161b39c5158Smillertsub checkParams 162b39c5158Smillert{ 163b39c5158Smillert my $self = shift ; 164b39c5158Smillert my $class = shift ; 165b39c5158Smillert 166b39c5158Smillert my $got = shift || IO::Compress::Base::Parameters::new(); 167b39c5158Smillert 168b39c5158Smillert $got->parse( 169b39c5158Smillert { 17091f110e0Safresh1 %PARAMS, 171b39c5158Smillert 172b39c5158Smillert 173b39c5158Smillert $self->getExtraParams(), 174b39c5158Smillert *$self->{OneShot} ? $self->getOneShotParams() 175b39c5158Smillert : (), 176b39c5158Smillert }, 17791f110e0Safresh1 @_) or $self->croakError("${class}: " . $got->getError()) ; 178b39c5158Smillert 179b39c5158Smillert return $got ; 180b39c5158Smillert} 181b39c5158Smillert 182b39c5158Smillertsub _create 183b39c5158Smillert{ 184b39c5158Smillert my $obj = shift; 185b39c5158Smillert my $got = shift; 186b39c5158Smillert 187b39c5158Smillert *$obj->{Closed} = 1 ; 188b39c5158Smillert 189b39c5158Smillert my $class = ref $obj; 190b39c5158Smillert $obj->croakError("$class: Missing Output parameter") 191b39c5158Smillert if ! @_ && ! $got ; 192b39c5158Smillert 193b39c5158Smillert my $outValue = shift ; 194b39c5158Smillert my $oneShot = 1 ; 195b39c5158Smillert 196b39c5158Smillert if (! $got) 197b39c5158Smillert { 198b39c5158Smillert $oneShot = 0 ; 199b39c5158Smillert $got = $obj->checkParams($class, undef, @_) 200b39c5158Smillert or return undef ; 201b39c5158Smillert } 202b39c5158Smillert 20391f110e0Safresh1 my $lax = ! $got->getValue('strict') ; 204b39c5158Smillert 20591f110e0Safresh1 my $outType = IO::Compress::Base::Common::whatIsOutput($outValue); 206b39c5158Smillert 207b39c5158Smillert $obj->ckOutputParam($class, $outValue) 208b39c5158Smillert or return undef ; 209b39c5158Smillert 210b39c5158Smillert if ($outType eq 'buffer') { 211b39c5158Smillert *$obj->{Buffer} = $outValue; 212b39c5158Smillert } 213b39c5158Smillert else { 214b39c5158Smillert my $buff = "" ; 215b39c5158Smillert *$obj->{Buffer} = \$buff ; 216b39c5158Smillert } 217b39c5158Smillert 218b39c5158Smillert # Merge implies Append 21991f110e0Safresh1 my $merge = $got->getValue('merge') ; 22091f110e0Safresh1 my $appendOutput = $got->getValue('append') || $merge ; 221b39c5158Smillert *$obj->{Append} = $appendOutput; 22291f110e0Safresh1 *$obj->{FilterContainer} = $got->getValue('filtercontainer') ; 223b39c5158Smillert 224b39c5158Smillert if ($merge) 225b39c5158Smillert { 226b39c5158Smillert # Switch off Merge mode if output file/buffer is empty/doesn't exist 227b39c5158Smillert if (($outType eq 'buffer' && length $$outValue == 0 ) || 228b39c5158Smillert ($outType ne 'buffer' && (! -e $outValue || (-w _ && -z _))) ) 229b39c5158Smillert { $merge = 0 } 230b39c5158Smillert } 231b39c5158Smillert 232b39c5158Smillert # If output is a file, check that it is writable 233b39c5158Smillert #no warnings; 234b39c5158Smillert #if ($outType eq 'filename' && -e $outValue && ! -w _) 235b39c5158Smillert # { return $obj->saveErrorString(undef, "Output file '$outValue' is not writable" ) } 236b39c5158Smillert 237b39c5158Smillert $obj->ckParams($got) 238b39c5158Smillert or $obj->croakError("${class}: " . $obj->error()); 239b39c5158Smillert 24091f110e0Safresh1 if ($got->getValue('encode')) { 24191f110e0Safresh1 my $want_encoding = $got->getValue('encode'); 24291f110e0Safresh1 *$obj->{Encoding} = IO::Compress::Base::Common::getEncoding($obj, $class, $want_encoding); 24391f110e0Safresh1 my $x = *$obj->{Encoding}; 24491f110e0Safresh1 } 24591f110e0Safresh1 else { 24691f110e0Safresh1 *$obj->{Encoding} = undef; 24791f110e0Safresh1 } 248b39c5158Smillert 249b39c5158Smillert $obj->saveStatus(STATUS_OK) ; 250b39c5158Smillert 251b39c5158Smillert my $status ; 252b39c5158Smillert if (! $merge) 253b39c5158Smillert { 254b39c5158Smillert *$obj->{Compress} = $obj->mkComp($got) 255b39c5158Smillert or return undef; 256b39c5158Smillert 257eac174f2Safresh1 *$obj->{UnCompSize} = U64->new; 258eac174f2Safresh1 *$obj->{CompSize} = U64->new; 259b39c5158Smillert 260b39c5158Smillert if ( $outType eq 'buffer') { 261b39c5158Smillert ${ *$obj->{Buffer} } = '' 262b39c5158Smillert unless $appendOutput ; 263b39c5158Smillert } 264b39c5158Smillert else { 265b39c5158Smillert if ($outType eq 'handle') { 266b39c5158Smillert *$obj->{FH} = $outValue ; 267b39c5158Smillert setBinModeOutput(*$obj->{FH}) ; 26891f110e0Safresh1 #$outValue->flush() ; 269b39c5158Smillert *$obj->{Handle} = 1 ; 270b39c5158Smillert if ($appendOutput) 271b39c5158Smillert { 27291f110e0Safresh1 seek(*$obj->{FH}, 0, IO::Handle::SEEK_END) 273b39c5158Smillert or return $obj->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ; 274b39c5158Smillert 275b39c5158Smillert } 276b39c5158Smillert } 277b39c5158Smillert elsif ($outType eq 'filename') { 278b39c5158Smillert no warnings; 279b39c5158Smillert my $mode = '>' ; 280b39c5158Smillert $mode = '>>' 281b39c5158Smillert if $appendOutput; 282eac174f2Safresh1 *$obj->{FH} = IO::File->new( "$mode $outValue" ) 283b39c5158Smillert or return $obj->saveErrorString(undef, "cannot open file '$outValue': $!", $!) ; 284b39c5158Smillert *$obj->{StdIO} = ($outValue eq '-'); 285b39c5158Smillert setBinModeOutput(*$obj->{FH}) ; 286b39c5158Smillert } 287b39c5158Smillert } 288b39c5158Smillert 289b39c5158Smillert *$obj->{Header} = $obj->mkHeader($got) ; 290b39c5158Smillert $obj->output( *$obj->{Header} ) 291b39c5158Smillert or return undef; 292898184e3Ssthen $obj->beforePayload(); 293b39c5158Smillert } 294b39c5158Smillert else 295b39c5158Smillert { 296b39c5158Smillert *$obj->{Compress} = $obj->createMerge($outValue, $outType) 297b39c5158Smillert or return undef; 298b39c5158Smillert } 299b39c5158Smillert 300b39c5158Smillert *$obj->{Closed} = 0 ; 30191f110e0Safresh1 *$obj->{AutoClose} = $got->getValue('autoclose') ; 302b39c5158Smillert *$obj->{Output} = $outValue; 303b39c5158Smillert *$obj->{ClassName} = $class; 304b39c5158Smillert *$obj->{Got} = $got; 305b39c5158Smillert *$obj->{OneShot} = 0 ; 306b39c5158Smillert 307b39c5158Smillert return $obj ; 308b39c5158Smillert} 309b39c5158Smillert 310b39c5158Smillertsub ckOutputParam 311b39c5158Smillert{ 312b39c5158Smillert my $self = shift ; 313b39c5158Smillert my $from = shift ; 31491f110e0Safresh1 my $outType = IO::Compress::Base::Common::whatIsOutput($_[0]); 315b39c5158Smillert 316b39c5158Smillert $self->croakError("$from: output parameter not a filename, filehandle or scalar ref") 317b39c5158Smillert if ! $outType ; 318b39c5158Smillert 319b39c5158Smillert #$self->croakError("$from: output filename is undef or null string") 320b39c5158Smillert #if $outType eq 'filename' && (! defined $_[0] || $_[0] eq '') ; 321b39c5158Smillert 322b39c5158Smillert $self->croakError("$from: output buffer is read-only") 32391f110e0Safresh1 if $outType eq 'buffer' && Scalar::Util::readonly(${ $_[0] }); 324b39c5158Smillert 325b39c5158Smillert return 1; 326b39c5158Smillert} 327b39c5158Smillert 328b39c5158Smillert 329b39c5158Smillertsub _def 330b39c5158Smillert{ 331b39c5158Smillert my $obj = shift ; 332b39c5158Smillert 333b39c5158Smillert my $class= (caller)[0] ; 334b39c5158Smillert my $name = (caller(1))[3] ; 335b39c5158Smillert 336b39c5158Smillert $obj->croakError("$name: expected at least 1 parameters\n") 337b39c5158Smillert unless @_ >= 1 ; 338b39c5158Smillert 339b39c5158Smillert my $input = shift ; 340b39c5158Smillert my $haveOut = @_ ; 341b39c5158Smillert my $output = shift ; 342b39c5158Smillert 343eac174f2Safresh1 my $x = IO::Compress::Base::Validator->new($class, *$obj->{Error}, $name, $input, $output) 344b39c5158Smillert or return undef ; 345b39c5158Smillert 346b39c5158Smillert push @_, $output if $haveOut && $x->{Hash}; 347b39c5158Smillert 348b39c5158Smillert *$obj->{OneShot} = 1 ; 349b39c5158Smillert 350b39c5158Smillert my $got = $obj->checkParams($name, undef, @_) 351b39c5158Smillert or return undef ; 352b39c5158Smillert 353b39c5158Smillert $x->{Got} = $got ; 354b39c5158Smillert 355b39c5158Smillert# if ($x->{Hash}) 356b39c5158Smillert# { 357b39c5158Smillert# while (my($k, $v) = each %$input) 358b39c5158Smillert# { 359b39c5158Smillert# $v = \$input->{$k} 360b39c5158Smillert# unless defined $v ; 361b39c5158Smillert# 362b39c5158Smillert# $obj->_singleTarget($x, 1, $k, $v, @_) 363b39c5158Smillert# or return undef ; 364b39c5158Smillert# } 365b39c5158Smillert# 366b39c5158Smillert# return keys %$input ; 367b39c5158Smillert# } 368b39c5158Smillert 369b39c5158Smillert if ($x->{GlobMap}) 370b39c5158Smillert { 371b39c5158Smillert $x->{oneInput} = 1 ; 372b39c5158Smillert foreach my $pair (@{ $x->{Pairs} }) 373b39c5158Smillert { 374b39c5158Smillert my ($from, $to) = @$pair ; 375b39c5158Smillert $obj->_singleTarget($x, 1, $from, $to, @_) 376b39c5158Smillert or return undef ; 377b39c5158Smillert } 378b39c5158Smillert 379b39c5158Smillert return scalar @{ $x->{Pairs} } ; 380b39c5158Smillert } 381b39c5158Smillert 382b39c5158Smillert if (! $x->{oneOutput} ) 383b39c5158Smillert { 384b39c5158Smillert my $inFile = ($x->{inType} eq 'filenames' 385b39c5158Smillert || $x->{inType} eq 'filename'); 386b39c5158Smillert 387b39c5158Smillert $x->{inType} = $inFile ? 'filename' : 'buffer'; 388b39c5158Smillert 389b39c5158Smillert foreach my $in ($x->{oneInput} ? $input : @$input) 390b39c5158Smillert { 391b39c5158Smillert my $out ; 392b39c5158Smillert $x->{oneInput} = 1 ; 393b39c5158Smillert 394b39c5158Smillert $obj->_singleTarget($x, $inFile, $in, \$out, @_) 395b39c5158Smillert or return undef ; 396b39c5158Smillert 397b39c5158Smillert push @$output, \$out ; 398b39c5158Smillert #if ($x->{outType} eq 'array') 399b39c5158Smillert # { push @$output, \$out } 400b39c5158Smillert #else 401b39c5158Smillert # { $output->{$in} = \$out } 402b39c5158Smillert } 403b39c5158Smillert 404b39c5158Smillert return 1 ; 405b39c5158Smillert } 406b39c5158Smillert 407b39c5158Smillert # finally the 1 to 1 and n to 1 408b39c5158Smillert return $obj->_singleTarget($x, 1, $input, $output, @_); 409b39c5158Smillert 410898184e3Ssthen Carp::croak "should not be here" ; 411b39c5158Smillert} 412b39c5158Smillert 413b39c5158Smillertsub _singleTarget 414b39c5158Smillert{ 415b39c5158Smillert my $obj = shift ; 416b39c5158Smillert my $x = shift ; 417b39c5158Smillert my $inputIsFilename = shift; 418b39c5158Smillert my $input = shift; 419b39c5158Smillert 420b39c5158Smillert if ($x->{oneInput}) 421b39c5158Smillert { 422b39c5158Smillert $obj->getFileInfo($x->{Got}, $input) 423898184e3Ssthen if isaScalar($input) || (isaFilename($input) and $inputIsFilename) ; 424b39c5158Smillert 425b39c5158Smillert my $z = $obj->_create($x->{Got}, @_) 426b39c5158Smillert or return undef ; 427b39c5158Smillert 428b39c5158Smillert 429b39c5158Smillert defined $z->_wr2($input, $inputIsFilename) 430b39c5158Smillert or return $z->closeError(undef) ; 431b39c5158Smillert 432b39c5158Smillert return $z->close() ; 433b39c5158Smillert } 434b39c5158Smillert else 435b39c5158Smillert { 436b39c5158Smillert my $afterFirst = 0 ; 437b39c5158Smillert my $inputIsFilename = ($x->{inType} ne 'array'); 438b39c5158Smillert my $keep = $x->{Got}->clone(); 439b39c5158Smillert 440b39c5158Smillert #for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input) 441b39c5158Smillert for my $element ( @$input) 442b39c5158Smillert { 443b39c5158Smillert my $isFilename = isaFilename($element); 444b39c5158Smillert 445b39c5158Smillert if ( $afterFirst ++ ) 446b39c5158Smillert { 447b39c5158Smillert defined addInterStream($obj, $element, $isFilename) 448b39c5158Smillert or return $obj->closeError(undef) ; 449b39c5158Smillert } 450b39c5158Smillert else 451b39c5158Smillert { 452b39c5158Smillert $obj->getFileInfo($x->{Got}, $element) 453898184e3Ssthen if isaScalar($element) || $isFilename; 454b39c5158Smillert 455b39c5158Smillert $obj->_create($x->{Got}, @_) 456b39c5158Smillert or return undef ; 457b39c5158Smillert } 458b39c5158Smillert 459b39c5158Smillert defined $obj->_wr2($element, $isFilename) 460b39c5158Smillert or return $obj->closeError(undef) ; 461b39c5158Smillert 462b39c5158Smillert *$obj->{Got} = $keep->clone(); 463b39c5158Smillert } 464b39c5158Smillert return $obj->close() ; 465b39c5158Smillert } 466b39c5158Smillert 467b39c5158Smillert} 468b39c5158Smillert 469b39c5158Smillertsub _wr2 470b39c5158Smillert{ 471b39c5158Smillert my $self = shift ; 472b39c5158Smillert 473b39c5158Smillert my $source = shift ; 474b39c5158Smillert my $inputIsFilename = shift; 475b39c5158Smillert 476b39c5158Smillert my $input = $source ; 477b39c5158Smillert if (! $inputIsFilename) 478b39c5158Smillert { 479b39c5158Smillert $input = \$source 480b39c5158Smillert if ! ref $source; 481b39c5158Smillert } 482b39c5158Smillert 483b39c5158Smillert if ( ref $input && ref $input eq 'SCALAR' ) 484b39c5158Smillert { 485b39c5158Smillert return $self->syswrite($input, @_) ; 486b39c5158Smillert } 487b39c5158Smillert 488b39c5158Smillert if ( ! ref $input || isaFilehandle($input)) 489b39c5158Smillert { 490b39c5158Smillert my $isFilehandle = isaFilehandle($input) ; 491b39c5158Smillert 492b39c5158Smillert my $fh = $input ; 493b39c5158Smillert 494b39c5158Smillert if ( ! $isFilehandle ) 495b39c5158Smillert { 496eac174f2Safresh1 $fh = IO::File->new( "<$input" ) 497b39c5158Smillert or return $self->saveErrorString(undef, "cannot open file '$input': $!", $!) ; 498b39c5158Smillert } 499b46d8ef2Safresh1 binmode $fh ; 500b39c5158Smillert 501b39c5158Smillert my $status ; 502b39c5158Smillert my $buff ; 503b39c5158Smillert my $count = 0 ; 504b39c5158Smillert while ($status = read($fh, $buff, 16 * 1024)) { 505b39c5158Smillert $count += length $buff; 506b39c5158Smillert defined $self->syswrite($buff, @_) 507b39c5158Smillert or return undef ; 508b39c5158Smillert } 509b39c5158Smillert 510b39c5158Smillert return $self->saveErrorString(undef, $!, $!) 511b39c5158Smillert if ! defined $status ; 512b39c5158Smillert 513b39c5158Smillert if ( (!$isFilehandle || *$self->{AutoClose}) && $input ne '-') 514b39c5158Smillert { 515b39c5158Smillert $fh->close() 516b39c5158Smillert or return undef ; 517b39c5158Smillert } 518b39c5158Smillert 519b39c5158Smillert return $count ; 520b39c5158Smillert } 521b39c5158Smillert 522898184e3Ssthen Carp::croak "Should not be here"; 523b39c5158Smillert return undef; 524b39c5158Smillert} 525b39c5158Smillert 526b39c5158Smillertsub addInterStream 527b39c5158Smillert{ 528b39c5158Smillert my $self = shift ; 529b39c5158Smillert my $input = shift ; 530b39c5158Smillert my $inputIsFilename = shift ; 531b39c5158Smillert 53291f110e0Safresh1 if (*$self->{Got}->getValue('multistream')) 533b39c5158Smillert { 534b39c5158Smillert $self->getFileInfo(*$self->{Got}, $input) 535b39c5158Smillert #if isaFilename($input) and $inputIsFilename ; 536898184e3Ssthen if isaScalar($input) || isaFilename($input) ; 537b39c5158Smillert 538b39c5158Smillert # TODO -- newStream needs to allow gzip/zip header to be modified 539b39c5158Smillert return $self->newStream(); 540b39c5158Smillert } 54191f110e0Safresh1 elsif (*$self->{Got}->getValue('autoflush')) 542b39c5158Smillert { 543b39c5158Smillert #return $self->flush(Z_FULL_FLUSH); 544b39c5158Smillert } 545b39c5158Smillert 546b39c5158Smillert return 1 ; 547b39c5158Smillert} 548b39c5158Smillert 549b39c5158Smillertsub getFileInfo 550b39c5158Smillert{ 551b39c5158Smillert} 552b39c5158Smillert 553b39c5158Smillertsub TIEHANDLE 554b39c5158Smillert{ 555b39c5158Smillert return $_[0] if ref($_[0]); 556b39c5158Smillert die "OOPS\n" ; 557b39c5158Smillert} 558b39c5158Smillert 559b39c5158Smillertsub UNTIE 560b39c5158Smillert{ 561b39c5158Smillert my $self = shift ; 562b39c5158Smillert} 563b39c5158Smillert 564b39c5158Smillertsub DESTROY 565b39c5158Smillert{ 566b39c5158Smillert my $self = shift ; 567b39c5158Smillert local ($., $@, $!, $^E, $?); 568b39c5158Smillert 569b39c5158Smillert $self->close() ; 570b39c5158Smillert 571b39c5158Smillert # TODO - memory leak with 5.8.0 - this isn't called until 572b39c5158Smillert # global destruction 573b39c5158Smillert # 574b39c5158Smillert %{ *$self } = () ; 575b39c5158Smillert undef $self ; 576b39c5158Smillert} 577b39c5158Smillert 578b39c5158Smillert 579b39c5158Smillert 580b39c5158Smillertsub filterUncompressed 581b39c5158Smillert{ 582b39c5158Smillert} 583b39c5158Smillert 584b39c5158Smillertsub syswrite 585b39c5158Smillert{ 586b39c5158Smillert my $self = shift ; 587b39c5158Smillert 588b39c5158Smillert my $buffer ; 589b39c5158Smillert if (ref $_[0] ) { 590b39c5158Smillert $self->croakError( *$self->{ClassName} . "::write: not a scalar reference" ) 591b39c5158Smillert unless ref $_[0] eq 'SCALAR' ; 592b39c5158Smillert $buffer = $_[0] ; 593b39c5158Smillert } 594b39c5158Smillert else { 595b39c5158Smillert $buffer = \$_[0] ; 596b39c5158Smillert } 597b39c5158Smillert 598b39c5158Smillert if (@_ > 1) { 599b39c5158Smillert my $slen = defined $$buffer ? length($$buffer) : 0; 600b39c5158Smillert my $len = $slen; 601b39c5158Smillert my $offset = 0; 602b39c5158Smillert $len = $_[1] if $_[1] < $len; 603b39c5158Smillert 604b39c5158Smillert if (@_ > 2) { 605b39c5158Smillert $offset = $_[2] || 0; 606b39c5158Smillert $self->croakError(*$self->{ClassName} . "::write: offset outside string") 607b39c5158Smillert if $offset > $slen; 608b39c5158Smillert if ($offset < 0) { 609b39c5158Smillert $offset += $slen; 610b39c5158Smillert $self->croakError( *$self->{ClassName} . "::write: offset outside string") if $offset < 0; 611b39c5158Smillert } 612b39c5158Smillert my $rem = $slen - $offset; 613b39c5158Smillert $len = $rem if $rem < $len; 614b39c5158Smillert } 615b39c5158Smillert 616b39c5158Smillert $buffer = \substr($$buffer, $offset, $len) ; 617b39c5158Smillert } 618b39c5158Smillert 61991f110e0Safresh1 return 0 if (! defined $$buffer || length $$buffer == 0) && ! *$self->{FlushPending}; 62091f110e0Safresh1 62191f110e0Safresh1# *$self->{Pending} .= $$buffer ; 62291f110e0Safresh1# 62391f110e0Safresh1# return length $$buffer 62491f110e0Safresh1# if (length *$self->{Pending} < 1024 * 16 && ! *$self->{FlushPending}) ; 62591f110e0Safresh1# 62691f110e0Safresh1# $$buffer = *$self->{Pending} ; 62791f110e0Safresh1# *$self->{Pending} = ''; 628b39c5158Smillert 629b39c5158Smillert if (*$self->{Encoding}) { 630b39c5158Smillert $$buffer = *$self->{Encoding}->encode($$buffer); 631b39c5158Smillert } 63291f110e0Safresh1 else { 63391f110e0Safresh1 $] >= 5.008 and ( utf8::downgrade($$buffer, 1) 63491f110e0Safresh1 or Carp::croak "Wide character in " . *$self->{ClassName} . "::write:"); 63591f110e0Safresh1 } 636b39c5158Smillert 637b39c5158Smillert $self->filterUncompressed($buffer); 638b39c5158Smillert 639b39c5158Smillert my $buffer_length = defined $$buffer ? length($$buffer) : 0 ; 640b39c5158Smillert *$self->{UnCompSize}->add($buffer_length) ; 641b39c5158Smillert 642b39c5158Smillert my $outBuffer=''; 643b39c5158Smillert my $status = *$self->{Compress}->compr($buffer, $outBuffer) ; 644b39c5158Smillert 645b39c5158Smillert return $self->saveErrorString(undef, *$self->{Compress}{Error}, 646b39c5158Smillert *$self->{Compress}{ErrorNo}) 647b39c5158Smillert if $status == STATUS_ERROR; 648b39c5158Smillert 649b39c5158Smillert *$self->{CompSize}->add(length $outBuffer) ; 650b39c5158Smillert 651898184e3Ssthen $self->outputPayload($outBuffer) 652b39c5158Smillert or return undef; 653b39c5158Smillert 654b39c5158Smillert return $buffer_length; 655b39c5158Smillert} 656b39c5158Smillert 657b39c5158Smillertsub print 658b39c5158Smillert{ 659b39c5158Smillert my $self = shift; 660b39c5158Smillert 661b39c5158Smillert #if (ref $self) { 662b39c5158Smillert # $self = *$self{GLOB} ; 663b39c5158Smillert #} 664b39c5158Smillert 665b39c5158Smillert if (defined $\) { 666b39c5158Smillert if (defined $,) { 667b39c5158Smillert defined $self->syswrite(join($,, @_) . $\); 668b39c5158Smillert } else { 669b39c5158Smillert defined $self->syswrite(join("", @_) . $\); 670b39c5158Smillert } 671b39c5158Smillert } else { 672b39c5158Smillert if (defined $,) { 673b39c5158Smillert defined $self->syswrite(join($,, @_)); 674b39c5158Smillert } else { 675b39c5158Smillert defined $self->syswrite(join("", @_)); 676b39c5158Smillert } 677b39c5158Smillert } 678b39c5158Smillert} 679b39c5158Smillert 680b39c5158Smillertsub printf 681b39c5158Smillert{ 682b39c5158Smillert my $self = shift; 683b39c5158Smillert my $fmt = shift; 684b39c5158Smillert defined $self->syswrite(sprintf($fmt, @_)); 685b39c5158Smillert} 686b39c5158Smillert 68791f110e0Safresh1sub _flushCompressed 688b39c5158Smillert{ 689b39c5158Smillert my $self = shift ; 690b39c5158Smillert 691b39c5158Smillert my $outBuffer=''; 692b39c5158Smillert my $status = *$self->{Compress}->flush($outBuffer, @_) ; 693b39c5158Smillert return $self->saveErrorString(0, *$self->{Compress}{Error}, 694b39c5158Smillert *$self->{Compress}{ErrorNo}) 695b39c5158Smillert if $status == STATUS_ERROR; 696b39c5158Smillert 697b39c5158Smillert if ( defined *$self->{FH} ) { 698b39c5158Smillert *$self->{FH}->clearerr(); 699b39c5158Smillert } 700b39c5158Smillert 701b39c5158Smillert *$self->{CompSize}->add(length $outBuffer) ; 702b39c5158Smillert 703898184e3Ssthen $self->outputPayload($outBuffer) 704b39c5158Smillert or return 0; 70591f110e0Safresh1 return 1; 70691f110e0Safresh1} 70791f110e0Safresh1 70891f110e0Safresh1sub flush 70991f110e0Safresh1{ 71091f110e0Safresh1 my $self = shift ; 71191f110e0Safresh1 71291f110e0Safresh1 $self->_flushCompressed(@_) 71391f110e0Safresh1 or return 0; 714b39c5158Smillert 715b39c5158Smillert if ( defined *$self->{FH} ) { 716b39c5158Smillert defined *$self->{FH}->flush() 717b39c5158Smillert or return $self->saveErrorString(0, $!, $!); 718b39c5158Smillert } 719b39c5158Smillert 720b39c5158Smillert return 1; 721b39c5158Smillert} 722b39c5158Smillert 723898184e3Ssthensub beforePayload 724898184e3Ssthen{ 725898184e3Ssthen} 726898184e3Ssthen 727898184e3Ssthensub _newStream 728b39c5158Smillert{ 729b39c5158Smillert my $self = shift ; 730898184e3Ssthen my $got = shift; 731b39c5158Smillert 73291f110e0Safresh1 my $class = ref $self; 73391f110e0Safresh1 734b39c5158Smillert $self->_writeTrailer() 735b39c5158Smillert or return 0 ; 736b39c5158Smillert 737b39c5158Smillert $self->ckParams($got) 738b39c5158Smillert or $self->croakError("newStream: $self->{Error}"); 739b39c5158Smillert 74091f110e0Safresh1 if ($got->getValue('encode')) { 74191f110e0Safresh1 my $want_encoding = $got->getValue('encode'); 74291f110e0Safresh1 *$self->{Encoding} = IO::Compress::Base::Common::getEncoding($self, $class, $want_encoding); 74391f110e0Safresh1 } 74491f110e0Safresh1 else { 74591f110e0Safresh1 *$self->{Encoding} = undef; 74691f110e0Safresh1 } 74791f110e0Safresh1 748b39c5158Smillert *$self->{Compress} = $self->mkComp($got) 749b39c5158Smillert or return 0; 750b39c5158Smillert 751b39c5158Smillert *$self->{Header} = $self->mkHeader($got) ; 752b39c5158Smillert $self->output(*$self->{Header} ) 753b39c5158Smillert or return 0; 754b39c5158Smillert 755b39c5158Smillert *$self->{UnCompSize}->reset(); 756b39c5158Smillert *$self->{CompSize}->reset(); 757b39c5158Smillert 758898184e3Ssthen $self->beforePayload(); 759898184e3Ssthen 760b39c5158Smillert return 1 ; 761b39c5158Smillert} 762b39c5158Smillert 763898184e3Ssthensub newStream 764898184e3Ssthen{ 765898184e3Ssthen my $self = shift ; 766898184e3Ssthen 767898184e3Ssthen my $got = $self->checkParams('newStream', *$self->{Got}, @_) 768898184e3Ssthen or return 0 ; 769898184e3Ssthen 770898184e3Ssthen $self->_newStream($got); 771898184e3Ssthen 772898184e3Ssthen# *$self->{Compress} = $self->mkComp($got) 773898184e3Ssthen# or return 0; 774898184e3Ssthen# 775898184e3Ssthen# *$self->{Header} = $self->mkHeader($got) ; 776898184e3Ssthen# $self->output(*$self->{Header} ) 777898184e3Ssthen# or return 0; 778898184e3Ssthen# 779898184e3Ssthen# *$self->{UnCompSize}->reset(); 780898184e3Ssthen# *$self->{CompSize}->reset(); 781898184e3Ssthen# 782898184e3Ssthen# $self->beforePayload(); 783898184e3Ssthen# 784898184e3Ssthen# return 1 ; 785898184e3Ssthen} 786898184e3Ssthen 787b39c5158Smillertsub reset 788b39c5158Smillert{ 789b39c5158Smillert my $self = shift ; 790b39c5158Smillert return *$self->{Compress}->reset() ; 791b39c5158Smillert} 792b39c5158Smillert 793b39c5158Smillertsub _writeTrailer 794b39c5158Smillert{ 795b39c5158Smillert my $self = shift ; 796b39c5158Smillert 797b39c5158Smillert my $trailer = ''; 798b39c5158Smillert 799b39c5158Smillert my $status = *$self->{Compress}->close($trailer) ; 800b46d8ef2Safresh1 801b39c5158Smillert return $self->saveErrorString(0, *$self->{Compress}{Error}, *$self->{Compress}{ErrorNo}) 802b39c5158Smillert if $status == STATUS_ERROR; 803b39c5158Smillert 804b39c5158Smillert *$self->{CompSize}->add(length $trailer) ; 805b39c5158Smillert 806b39c5158Smillert $trailer .= $self->mkTrailer(); 807b39c5158Smillert defined $trailer 808b39c5158Smillert or return 0; 809b39c5158Smillert return $self->output($trailer); 810b39c5158Smillert} 811b39c5158Smillert 812b39c5158Smillertsub _writeFinalTrailer 813b39c5158Smillert{ 814b39c5158Smillert my $self = shift ; 815b39c5158Smillert 816b39c5158Smillert return $self->output($self->mkFinalTrailer()); 817b39c5158Smillert} 818b39c5158Smillert 819b39c5158Smillertsub close 820b39c5158Smillert{ 821b39c5158Smillert my $self = shift ; 822b39c5158Smillert return 1 if *$self->{Closed} || ! *$self->{Compress} ; 823b39c5158Smillert *$self->{Closed} = 1 ; 824b39c5158Smillert 825b39c5158Smillert untie *$self 826b39c5158Smillert if $] >= 5.008 ; 827b39c5158Smillert 82891f110e0Safresh1 *$self->{FlushPending} = 1 ; 829b39c5158Smillert $self->_writeTrailer() 830b39c5158Smillert or return 0 ; 831b39c5158Smillert 832b39c5158Smillert $self->_writeFinalTrailer() 833b39c5158Smillert or return 0 ; 834b39c5158Smillert 835b39c5158Smillert $self->output( "", 1 ) 836b39c5158Smillert or return 0; 837b39c5158Smillert 838b39c5158Smillert if (defined *$self->{FH}) { 839b39c5158Smillert 840b39c5158Smillert if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) { 841b39c5158Smillert $! = 0 ; 842b39c5158Smillert *$self->{FH}->close() 843b39c5158Smillert or return $self->saveErrorString(0, $!, $!); 844b39c5158Smillert } 845b39c5158Smillert delete *$self->{FH} ; 846b39c5158Smillert # This delete can set $! in older Perls, so reset the errno 847b39c5158Smillert $! = 0 ; 848b39c5158Smillert } 849b39c5158Smillert 850b39c5158Smillert return 1; 851b39c5158Smillert} 852b39c5158Smillert 853b39c5158Smillert 854b39c5158Smillert#sub total_in 855b39c5158Smillert#sub total_out 856b39c5158Smillert#sub msg 857b39c5158Smillert# 858b39c5158Smillert#sub crc 859b39c5158Smillert#{ 860b39c5158Smillert# my $self = shift ; 861b39c5158Smillert# return *$self->{Compress}->crc32() ; 862b39c5158Smillert#} 863b39c5158Smillert# 864b39c5158Smillert#sub msg 865b39c5158Smillert#{ 866b39c5158Smillert# my $self = shift ; 867b39c5158Smillert# return *$self->{Compress}->msg() ; 868b39c5158Smillert#} 869b39c5158Smillert# 870b39c5158Smillert#sub dict_adler 871b39c5158Smillert#{ 872b39c5158Smillert# my $self = shift ; 873b39c5158Smillert# return *$self->{Compress}->dict_adler() ; 874b39c5158Smillert#} 875b39c5158Smillert# 876b39c5158Smillert#sub get_Level 877b39c5158Smillert#{ 878b39c5158Smillert# my $self = shift ; 879b39c5158Smillert# return *$self->{Compress}->get_Level() ; 880b39c5158Smillert#} 881b39c5158Smillert# 882b39c5158Smillert#sub get_Strategy 883b39c5158Smillert#{ 884b39c5158Smillert# my $self = shift ; 885b39c5158Smillert# return *$self->{Compress}->get_Strategy() ; 886b39c5158Smillert#} 887b39c5158Smillert 888b39c5158Smillert 889b39c5158Smillertsub tell 890b39c5158Smillert{ 891b39c5158Smillert my $self = shift ; 892b39c5158Smillert 893b39c5158Smillert return *$self->{UnCompSize}->get32bit() ; 894b39c5158Smillert} 895b39c5158Smillert 896b39c5158Smillertsub eof 897b39c5158Smillert{ 898b39c5158Smillert my $self = shift ; 899b39c5158Smillert 900b39c5158Smillert return *$self->{Closed} ; 901b39c5158Smillert} 902b39c5158Smillert 903b39c5158Smillert 904b39c5158Smillertsub seek 905b39c5158Smillert{ 906b39c5158Smillert my $self = shift ; 907b39c5158Smillert my $position = shift; 908b39c5158Smillert my $whence = shift ; 909b39c5158Smillert 910b39c5158Smillert my $here = $self->tell() ; 911b39c5158Smillert my $target = 0 ; 912b39c5158Smillert 913b39c5158Smillert #use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); 914b39c5158Smillert use IO::Handle ; 915b39c5158Smillert 916b39c5158Smillert if ($whence == IO::Handle::SEEK_SET) { 917b39c5158Smillert $target = $position ; 918b39c5158Smillert } 919b39c5158Smillert elsif ($whence == IO::Handle::SEEK_CUR || $whence == IO::Handle::SEEK_END) { 920b39c5158Smillert $target = $here + $position ; 921b39c5158Smillert } 922b39c5158Smillert else { 923b39c5158Smillert $self->croakError(*$self->{ClassName} . "::seek: unknown value, $whence, for whence parameter"); 924b39c5158Smillert } 925b39c5158Smillert 926b39c5158Smillert # short circuit if seeking to current offset 927b39c5158Smillert return 1 if $target == $here ; 928b39c5158Smillert 929b39c5158Smillert # Outlaw any attempt to seek backwards 930b39c5158Smillert $self->croakError(*$self->{ClassName} . "::seek: cannot seek backwards") 931b39c5158Smillert if $target < $here ; 932b39c5158Smillert 933b39c5158Smillert # Walk the file to the new offset 934b39c5158Smillert my $offset = $target - $here ; 935b39c5158Smillert 936b39c5158Smillert my $buffer ; 937b39c5158Smillert defined $self->syswrite("\x00" x $offset) 938b39c5158Smillert or return 0; 939b39c5158Smillert 940b39c5158Smillert return 1 ; 941b39c5158Smillert} 942b39c5158Smillert 943b39c5158Smillertsub binmode 944b39c5158Smillert{ 945b39c5158Smillert 1; 946b39c5158Smillert# my $self = shift ; 947b39c5158Smillert# return defined *$self->{FH} 948b39c5158Smillert# ? binmode *$self->{FH} 949b39c5158Smillert# : 1 ; 950b39c5158Smillert} 951b39c5158Smillert 952b39c5158Smillertsub fileno 953b39c5158Smillert{ 954b39c5158Smillert my $self = shift ; 955b39c5158Smillert return defined *$self->{FH} 956b39c5158Smillert ? *$self->{FH}->fileno() 957b39c5158Smillert : undef ; 958b39c5158Smillert} 959b39c5158Smillert 960b39c5158Smillertsub opened 961b39c5158Smillert{ 962b39c5158Smillert my $self = shift ; 963b39c5158Smillert return ! *$self->{Closed} ; 964b39c5158Smillert} 965b39c5158Smillert 966b39c5158Smillertsub autoflush 967b39c5158Smillert{ 968b39c5158Smillert my $self = shift ; 969b39c5158Smillert return defined *$self->{FH} 970b39c5158Smillert ? *$self->{FH}->autoflush(@_) 971b39c5158Smillert : undef ; 972b39c5158Smillert} 973b39c5158Smillert 974b39c5158Smillertsub input_line_number 975b39c5158Smillert{ 976b39c5158Smillert return undef ; 977b39c5158Smillert} 978b39c5158Smillert 979b39c5158Smillert 980b39c5158Smillertsub _notAvailable 981b39c5158Smillert{ 982b39c5158Smillert my $name = shift ; 983898184e3Ssthen return sub { Carp::croak "$name Not Available: File opened only for output" ; } ; 984b39c5158Smillert} 985b39c5158Smillert 986eac174f2Safresh1{ 987eac174f2Safresh1 no warnings 'once'; 988eac174f2Safresh1 989b39c5158Smillert *read = _notAvailable('read'); 990b39c5158Smillert *READ = _notAvailable('read'); 991b39c5158Smillert *readline = _notAvailable('readline'); 992b39c5158Smillert *READLINE = _notAvailable('readline'); 993b39c5158Smillert *getc = _notAvailable('getc'); 994b39c5158Smillert *GETC = _notAvailable('getc'); 995b39c5158Smillert 996b39c5158Smillert *FILENO = \&fileno; 997b39c5158Smillert *PRINT = \&print; 998b39c5158Smillert *PRINTF = \&printf; 999b39c5158Smillert *WRITE = \&syswrite; 1000b39c5158Smillert *write = \&syswrite; 1001b39c5158Smillert *SEEK = \&seek; 1002b39c5158Smillert *TELL = \&tell; 1003b39c5158Smillert *EOF = \&eof; 1004b39c5158Smillert *CLOSE = \&close; 1005b39c5158Smillert *BINMODE = \&binmode; 1006eac174f2Safresh1} 1007b39c5158Smillert 1008b39c5158Smillert#*sysread = \&_notAvailable; 1009b39c5158Smillert#*syswrite = \&_write; 1010b39c5158Smillert 1011b39c5158Smillert1; 1012b39c5158Smillert 1013b39c5158Smillert__END__ 1014b39c5158Smillert 1015b39c5158Smillert=head1 NAME 1016b39c5158Smillert 1017b39c5158SmillertIO::Compress::Base - Base Class for IO::Compress modules 1018b39c5158Smillert 1019b39c5158Smillert=head1 SYNOPSIS 1020b39c5158Smillert 1021b39c5158Smillert use IO::Compress::Base ; 1022b39c5158Smillert 1023b39c5158Smillert=head1 DESCRIPTION 1024b39c5158Smillert 1025b39c5158SmillertThis module is not intended for direct use in application code. Its sole 10266fb12b70Safresh1purpose is to be sub-classed by IO::Compress modules. 1027b39c5158Smillert 102856d68f1eSafresh1=head1 SUPPORT 102956d68f1eSafresh1 103056d68f1eSafresh1General feedback/questions/bug reports should be sent to 103156d68f1eSafresh1L<https://github.com/pmqs/IO-Compress/issues> (preferred) or 103256d68f1eSafresh1L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>. 103356d68f1eSafresh1 1034b39c5158Smillert=head1 SEE ALSO 1035b39c5158Smillert 1036b46d8ef2Safresh1L<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> 1037b39c5158Smillert 1038898184e3SsthenL<IO::Compress::FAQ|IO::Compress::FAQ> 1039b39c5158Smillert 1040b39c5158SmillertL<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, 1041b39c5158SmillertL<Archive::Tar|Archive::Tar>, 1042b39c5158SmillertL<IO::Zlib|IO::Zlib> 1043b39c5158Smillert 1044b39c5158Smillert=head1 AUTHOR 1045b39c5158Smillert 10469f11ffb7Safresh1This module was written by Paul Marquess, C<pmqs@cpan.org>. 1047b39c5158Smillert 1048b39c5158Smillert=head1 MODIFICATION HISTORY 1049b39c5158Smillert 1050b39c5158SmillertSee the Changes file. 1051b39c5158Smillert 1052b39c5158Smillert=head1 COPYRIGHT AND LICENSE 1053b39c5158Smillert 1054*3d61058aSafresh1Copyright (c) 2005-2024 Paul Marquess. All rights reserved. 1055b39c5158Smillert 1056b39c5158SmillertThis program is free software; you can redistribute it and/or 1057b39c5158Smillertmodify it under the same terms as Perl itself. 1058