1 2package IO::Compress::Base ; 3 4require 5.004 ; 5 6use strict ; 7use warnings; 8 9use IO::Compress::Base::Common 2.024 ; 10 11use IO::File ; 12use Scalar::Util qw(blessed readonly); 13 14#use File::Glob; 15#require Exporter ; 16use Carp ; 17use Symbol; 18use bytes; 19 20our (@ISA, $VERSION); 21@ISA = qw(Exporter IO::File); 22 23$VERSION = '2.024'; 24 25#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. 26 27sub saveStatus 28{ 29 my $self = shift ; 30 ${ *$self->{ErrorNo} } = shift() + 0 ; 31 ${ *$self->{Error} } = '' ; 32 33 return ${ *$self->{ErrorNo} } ; 34} 35 36 37sub saveErrorString 38{ 39 my $self = shift ; 40 my $retval = shift ; 41 ${ *$self->{Error} } = shift ; 42 ${ *$self->{ErrorNo} } = shift() + 0 if @_ ; 43 44 return $retval; 45} 46 47sub croakError 48{ 49 my $self = shift ; 50 $self->saveErrorString(0, $_[0]); 51 croak $_[0]; 52} 53 54sub closeError 55{ 56 my $self = shift ; 57 my $retval = shift ; 58 59 my $errno = *$self->{ErrorNo}; 60 my $error = ${ *$self->{Error} }; 61 62 $self->close(); 63 64 *$self->{ErrorNo} = $errno ; 65 ${ *$self->{Error} } = $error ; 66 67 return $retval; 68} 69 70 71 72sub error 73{ 74 my $self = shift ; 75 return ${ *$self->{Error} } ; 76} 77 78sub errorNo 79{ 80 my $self = shift ; 81 return ${ *$self->{ErrorNo} } ; 82} 83 84 85sub writeAt 86{ 87 my $self = shift ; 88 my $offset = shift; 89 my $data = shift; 90 91 if (defined *$self->{FH}) { 92 my $here = tell(*$self->{FH}); 93 return $self->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) 94 if $here < 0 ; 95 seek(*$self->{FH}, $offset, SEEK_SET) 96 or return $self->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ; 97 defined *$self->{FH}->write($data, length $data) 98 or return $self->saveErrorString(undef, $!, $!) ; 99 seek(*$self->{FH}, $here, SEEK_SET) 100 or return $self->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ; 101 } 102 else { 103 substr(${ *$self->{Buffer} }, $offset, length($data)) = $data ; 104 } 105 106 return 1; 107} 108 109sub output 110{ 111 my $self = shift ; 112 my $data = shift ; 113 my $last = shift ; 114 115 return 1 116 if length $data == 0 && ! $last ; 117 118 if ( *$self->{FilterEnvelope} ) { 119 *_ = \$data; 120 &{ *$self->{FilterEnvelope} }(); 121 } 122 123 if (length $data) { 124 if ( defined *$self->{FH} ) { 125 defined *$self->{FH}->write( $data, length $data ) 126 or return $self->saveErrorString(0, $!, $!); 127 } 128 else { 129 ${ *$self->{Buffer} } .= $data ; 130 } 131 } 132 133 return 1; 134} 135 136sub getOneShotParams 137{ 138 return ( 'MultiStream' => [1, 1, Parse_boolean, 1], 139 ); 140} 141 142sub checkParams 143{ 144 my $self = shift ; 145 my $class = shift ; 146 147 my $got = shift || IO::Compress::Base::Parameters::new(); 148 149 $got->parse( 150 { 151 # Generic Parameters 152 'AutoClose' => [1, 1, Parse_boolean, 0], 153 #'Encode' => [1, 1, Parse_any, undef], 154 'Strict' => [0, 1, Parse_boolean, 1], 155 'Append' => [1, 1, Parse_boolean, 0], 156 'BinModeIn' => [1, 1, Parse_boolean, 0], 157 158 'FilterEnvelope' => [1, 1, Parse_any, undef], 159 160 $self->getExtraParams(), 161 *$self->{OneShot} ? $self->getOneShotParams() 162 : (), 163 }, 164 @_) or $self->croakError("${class}: $got->{Error}") ; 165 166 return $got ; 167} 168 169sub _create 170{ 171 my $obj = shift; 172 my $got = shift; 173 174 *$obj->{Closed} = 1 ; 175 176 my $class = ref $obj; 177 $obj->croakError("$class: Missing Output parameter") 178 if ! @_ && ! $got ; 179 180 my $outValue = shift ; 181 my $oneShot = 1 ; 182 183 if (! $got) 184 { 185 $oneShot = 0 ; 186 $got = $obj->checkParams($class, undef, @_) 187 or return undef ; 188 } 189 190 my $lax = ! $got->value('Strict') ; 191 192 my $outType = whatIsOutput($outValue); 193 194 $obj->ckOutputParam($class, $outValue) 195 or return undef ; 196 197 if ($outType eq 'buffer') { 198 *$obj->{Buffer} = $outValue; 199 } 200 else { 201 my $buff = "" ; 202 *$obj->{Buffer} = \$buff ; 203 } 204 205 # Merge implies Append 206 my $merge = $got->value('Merge') ; 207 my $appendOutput = $got->value('Append') || $merge ; 208 *$obj->{Append} = $appendOutput; 209 *$obj->{FilterEnvelope} = $got->value('FilterEnvelope') ; 210 211 if ($merge) 212 { 213 # Switch off Merge mode if output file/buffer is empty/doesn't exist 214 if (($outType eq 'buffer' && length $$outValue == 0 ) || 215 ($outType ne 'buffer' && (! -e $outValue || (-w _ && -z _))) ) 216 { $merge = 0 } 217 } 218 219 # If output is a file, check that it is writable 220 #no warnings; 221 #if ($outType eq 'filename' && -e $outValue && ! -w _) 222 # { return $obj->saveErrorString(undef, "Output file '$outValue' is not writable" ) } 223 224 225 226 if ($got->parsed('Encode')) { 227 my $want_encoding = $got->value('Encode'); 228 *$obj->{Encoding} = getEncoding($obj, $class, $want_encoding); 229 } 230 231 $obj->ckParams($got) 232 or $obj->croakError("${class}: " . $obj->error()); 233 234 235 $obj->saveStatus(STATUS_OK) ; 236 237 my $status ; 238 if (! $merge) 239 { 240 *$obj->{Compress} = $obj->mkComp($got) 241 or return undef; 242 243 *$obj->{UnCompSize} = new U64 ; 244 *$obj->{CompSize} = new U64 ; 245 246 if ( $outType eq 'buffer') { 247 ${ *$obj->{Buffer} } = '' 248 unless $appendOutput ; 249 } 250 else { 251 if ($outType eq 'handle') { 252 *$obj->{FH} = $outValue ; 253 setBinModeOutput(*$obj->{FH}) ; 254 $outValue->flush() ; 255 *$obj->{Handle} = 1 ; 256 if ($appendOutput) 257 { 258 seek(*$obj->{FH}, 0, SEEK_END) 259 or return $obj->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ; 260 261 } 262 } 263 elsif ($outType eq 'filename') { 264 no warnings; 265 my $mode = '>' ; 266 $mode = '>>' 267 if $appendOutput; 268 *$obj->{FH} = new IO::File "$mode $outValue" 269 or return $obj->saveErrorString(undef, "cannot open file '$outValue': $!", $!) ; 270 *$obj->{StdIO} = ($outValue eq '-'); 271 setBinModeOutput(*$obj->{FH}) ; 272 } 273 } 274 275 *$obj->{Header} = $obj->mkHeader($got) ; 276 $obj->output( *$obj->{Header} ) 277 or return undef; 278 } 279 else 280 { 281 *$obj->{Compress} = $obj->createMerge($outValue, $outType) 282 or return undef; 283 } 284 285 *$obj->{Closed} = 0 ; 286 *$obj->{AutoClose} = $got->value('AutoClose') ; 287 *$obj->{Output} = $outValue; 288 *$obj->{ClassName} = $class; 289 *$obj->{Got} = $got; 290 *$obj->{OneShot} = 0 ; 291 292 return $obj ; 293} 294 295sub ckOutputParam 296{ 297 my $self = shift ; 298 my $from = shift ; 299 my $outType = whatIsOutput($_[0]); 300 301 $self->croakError("$from: output parameter not a filename, filehandle or scalar ref") 302 if ! $outType ; 303 304 #$self->croakError("$from: output filename is undef or null string") 305 #if $outType eq 'filename' && (! defined $_[0] || $_[0] eq '') ; 306 307 $self->croakError("$from: output buffer is read-only") 308 if $outType eq 'buffer' && readonly(${ $_[0] }); 309 310 return 1; 311} 312 313 314sub _def 315{ 316 my $obj = shift ; 317 318 my $class= (caller)[0] ; 319 my $name = (caller(1))[3] ; 320 321 $obj->croakError("$name: expected at least 1 parameters\n") 322 unless @_ >= 1 ; 323 324 my $input = shift ; 325 my $haveOut = @_ ; 326 my $output = shift ; 327 328 my $x = new IO::Compress::Base::Validator($class, *$obj->{Error}, $name, $input, $output) 329 or return undef ; 330 331 push @_, $output if $haveOut && $x->{Hash}; 332 333 *$obj->{OneShot} = 1 ; 334 335 my $got = $obj->checkParams($name, undef, @_) 336 or return undef ; 337 338 $x->{Got} = $got ; 339 340# if ($x->{Hash}) 341# { 342# while (my($k, $v) = each %$input) 343# { 344# $v = \$input->{$k} 345# unless defined $v ; 346# 347# $obj->_singleTarget($x, 1, $k, $v, @_) 348# or return undef ; 349# } 350# 351# return keys %$input ; 352# } 353 354 if ($x->{GlobMap}) 355 { 356 $x->{oneInput} = 1 ; 357 foreach my $pair (@{ $x->{Pairs} }) 358 { 359 my ($from, $to) = @$pair ; 360 $obj->_singleTarget($x, 1, $from, $to, @_) 361 or return undef ; 362 } 363 364 return scalar @{ $x->{Pairs} } ; 365 } 366 367 if (! $x->{oneOutput} ) 368 { 369 my $inFile = ($x->{inType} eq 'filenames' 370 || $x->{inType} eq 'filename'); 371 372 $x->{inType} = $inFile ? 'filename' : 'buffer'; 373 374 foreach my $in ($x->{oneInput} ? $input : @$input) 375 { 376 my $out ; 377 $x->{oneInput} = 1 ; 378 379 $obj->_singleTarget($x, $inFile, $in, \$out, @_) 380 or return undef ; 381 382 push @$output, \$out ; 383 #if ($x->{outType} eq 'array') 384 # { push @$output, \$out } 385 #else 386 # { $output->{$in} = \$out } 387 } 388 389 return 1 ; 390 } 391 392 # finally the 1 to 1 and n to 1 393 return $obj->_singleTarget($x, 1, $input, $output, @_); 394 395 croak "should not be here" ; 396} 397 398sub _singleTarget 399{ 400 my $obj = shift ; 401 my $x = shift ; 402 my $inputIsFilename = shift; 403 my $input = shift; 404 405 if ($x->{oneInput}) 406 { 407 $obj->getFileInfo($x->{Got}, $input) 408 if isaFilename($input) and $inputIsFilename ; 409 410 my $z = $obj->_create($x->{Got}, @_) 411 or return undef ; 412 413 414 defined $z->_wr2($input, $inputIsFilename) 415 or return $z->closeError(undef) ; 416 417 return $z->close() ; 418 } 419 else 420 { 421 my $afterFirst = 0 ; 422 my $inputIsFilename = ($x->{inType} ne 'array'); 423 my $keep = $x->{Got}->clone(); 424 425 #for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input) 426 for my $element ( @$input) 427 { 428 my $isFilename = isaFilename($element); 429 430 if ( $afterFirst ++ ) 431 { 432 defined addInterStream($obj, $element, $isFilename) 433 or return $obj->closeError(undef) ; 434 } 435 else 436 { 437 $obj->getFileInfo($x->{Got}, $element) 438 if $isFilename; 439 440 $obj->_create($x->{Got}, @_) 441 or return undef ; 442 } 443 444 defined $obj->_wr2($element, $isFilename) 445 or return $obj->closeError(undef) ; 446 447 *$obj->{Got} = $keep->clone(); 448 } 449 return $obj->close() ; 450 } 451 452} 453 454sub _wr2 455{ 456 my $self = shift ; 457 458 my $source = shift ; 459 my $inputIsFilename = shift; 460 461 my $input = $source ; 462 if (! $inputIsFilename) 463 { 464 $input = \$source 465 if ! ref $source; 466 } 467 468 if ( ref $input && ref $input eq 'SCALAR' ) 469 { 470 return $self->syswrite($input, @_) ; 471 } 472 473 if ( ! ref $input || isaFilehandle($input)) 474 { 475 my $isFilehandle = isaFilehandle($input) ; 476 477 my $fh = $input ; 478 479 if ( ! $isFilehandle ) 480 { 481 $fh = new IO::File "<$input" 482 or return $self->saveErrorString(undef, "cannot open file '$input': $!", $!) ; 483 } 484 binmode $fh if *$self->{Got}->valueOrDefault('BinModeIn') ; 485 486 my $status ; 487 my $buff ; 488 my $count = 0 ; 489 while ($status = read($fh, $buff, 16 * 1024)) { 490 $count += length $buff; 491 defined $self->syswrite($buff, @_) 492 or return undef ; 493 } 494 495 return $self->saveErrorString(undef, $!, $!) 496 if ! defined $status ; 497 498 if ( (!$isFilehandle || *$self->{AutoClose}) && $input ne '-') 499 { 500 $fh->close() 501 or return undef ; 502 } 503 504 return $count ; 505 } 506 507 croak "Should not be here"; 508 return undef; 509} 510 511sub addInterStream 512{ 513 my $self = shift ; 514 my $input = shift ; 515 my $inputIsFilename = shift ; 516 517 if (*$self->{Got}->value('MultiStream')) 518 { 519 $self->getFileInfo(*$self->{Got}, $input) 520 #if isaFilename($input) and $inputIsFilename ; 521 if isaFilename($input) ; 522 523 # TODO -- newStream needs to allow gzip/zip header to be modified 524 return $self->newStream(); 525 } 526 elsif (*$self->{Got}->value('AutoFlush')) 527 { 528 #return $self->flush(Z_FULL_FLUSH); 529 } 530 531 return 1 ; 532} 533 534sub getFileInfo 535{ 536} 537 538sub TIEHANDLE 539{ 540 return $_[0] if ref($_[0]); 541 die "OOPS\n" ; 542} 543 544sub UNTIE 545{ 546 my $self = shift ; 547} 548 549sub DESTROY 550{ 551 my $self = shift ; 552 local ($., $@, $!, $^E, $?); 553 554 $self->close() ; 555 556 # TODO - memory leak with 5.8.0 - this isn't called until 557 # global destruction 558 # 559 %{ *$self } = () ; 560 undef $self ; 561} 562 563 564 565sub filterUncompressed 566{ 567} 568 569sub syswrite 570{ 571 my $self = shift ; 572 573 my $buffer ; 574 if (ref $_[0] ) { 575 $self->croakError( *$self->{ClassName} . "::write: not a scalar reference" ) 576 unless ref $_[0] eq 'SCALAR' ; 577 $buffer = $_[0] ; 578 } 579 else { 580 $buffer = \$_[0] ; 581 } 582 583 $] >= 5.008 and ( utf8::downgrade($$buffer, 1) 584 or croak "Wide character in " . *$self->{ClassName} . "::write:"); 585 586 587 if (@_ > 1) { 588 my $slen = defined $$buffer ? length($$buffer) : 0; 589 my $len = $slen; 590 my $offset = 0; 591 $len = $_[1] if $_[1] < $len; 592 593 if (@_ > 2) { 594 $offset = $_[2] || 0; 595 $self->croakError(*$self->{ClassName} . "::write: offset outside string") 596 if $offset > $slen; 597 if ($offset < 0) { 598 $offset += $slen; 599 $self->croakError( *$self->{ClassName} . "::write: offset outside string") if $offset < 0; 600 } 601 my $rem = $slen - $offset; 602 $len = $rem if $rem < $len; 603 } 604 605 $buffer = \substr($$buffer, $offset, $len) ; 606 } 607 608 return 0 if ! defined $$buffer || length $$buffer == 0 ; 609 610 if (*$self->{Encoding}) { 611 $$buffer = *$self->{Encoding}->encode($$buffer); 612 } 613 614 $self->filterUncompressed($buffer); 615 616 my $buffer_length = defined $$buffer ? length($$buffer) : 0 ; 617 *$self->{UnCompSize}->add($buffer_length) ; 618 619 my $outBuffer=''; 620 my $status = *$self->{Compress}->compr($buffer, $outBuffer) ; 621 622 return $self->saveErrorString(undef, *$self->{Compress}{Error}, 623 *$self->{Compress}{ErrorNo}) 624 if $status == STATUS_ERROR; 625 626 *$self->{CompSize}->add(length $outBuffer) ; 627 628 $self->output($outBuffer) 629 or return undef; 630 631 return $buffer_length; 632} 633 634sub print 635{ 636 my $self = shift; 637 638 #if (ref $self) { 639 # $self = *$self{GLOB} ; 640 #} 641 642 if (defined $\) { 643 if (defined $,) { 644 defined $self->syswrite(join($,, @_) . $\); 645 } else { 646 defined $self->syswrite(join("", @_) . $\); 647 } 648 } else { 649 if (defined $,) { 650 defined $self->syswrite(join($,, @_)); 651 } else { 652 defined $self->syswrite(join("", @_)); 653 } 654 } 655} 656 657sub printf 658{ 659 my $self = shift; 660 my $fmt = shift; 661 defined $self->syswrite(sprintf($fmt, @_)); 662} 663 664 665 666sub flush 667{ 668 my $self = shift ; 669 670 my $outBuffer=''; 671 my $status = *$self->{Compress}->flush($outBuffer, @_) ; 672 return $self->saveErrorString(0, *$self->{Compress}{Error}, 673 *$self->{Compress}{ErrorNo}) 674 if $status == STATUS_ERROR; 675 676 if ( defined *$self->{FH} ) { 677 *$self->{FH}->clearerr(); 678 } 679 680 *$self->{CompSize}->add(length $outBuffer) ; 681 682 $self->output($outBuffer) 683 or return 0; 684 685 if ( defined *$self->{FH} ) { 686 defined *$self->{FH}->flush() 687 or return $self->saveErrorString(0, $!, $!); 688 } 689 690 return 1; 691} 692 693sub newStream 694{ 695 my $self = shift ; 696 697 $self->_writeTrailer() 698 or return 0 ; 699 700 my $got = $self->checkParams('newStream', *$self->{Got}, @_) 701 or return 0 ; 702 703 $self->ckParams($got) 704 or $self->croakError("newStream: $self->{Error}"); 705 706 *$self->{Compress} = $self->mkComp($got) 707 or return 0; 708 709 *$self->{Header} = $self->mkHeader($got) ; 710 $self->output(*$self->{Header} ) 711 or return 0; 712 713 *$self->{UnCompSize}->reset(); 714 *$self->{CompSize}->reset(); 715 716 return 1 ; 717} 718 719sub reset 720{ 721 my $self = shift ; 722 return *$self->{Compress}->reset() ; 723} 724 725sub _writeTrailer 726{ 727 my $self = shift ; 728 729 my $trailer = ''; 730 731 my $status = *$self->{Compress}->close($trailer) ; 732 return $self->saveErrorString(0, *$self->{Compress}{Error}, *$self->{Compress}{ErrorNo}) 733 if $status == STATUS_ERROR; 734 735 *$self->{CompSize}->add(length $trailer) ; 736 737 $trailer .= $self->mkTrailer(); 738 defined $trailer 739 or return 0; 740 741 return $self->output($trailer); 742} 743 744sub _writeFinalTrailer 745{ 746 my $self = shift ; 747 748 return $self->output($self->mkFinalTrailer()); 749} 750 751sub close 752{ 753 my $self = shift ; 754 755 return 1 if *$self->{Closed} || ! *$self->{Compress} ; 756 *$self->{Closed} = 1 ; 757 758 untie *$self 759 if $] >= 5.008 ; 760 761 $self->_writeTrailer() 762 or return 0 ; 763 764 $self->_writeFinalTrailer() 765 or return 0 ; 766 767 $self->output( "", 1 ) 768 or return 0; 769 770 if (defined *$self->{FH}) { 771 772 #if (! *$self->{Handle} || *$self->{AutoClose}) { 773 if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) { 774 $! = 0 ; 775 *$self->{FH}->close() 776 or return $self->saveErrorString(0, $!, $!); 777 } 778 delete *$self->{FH} ; 779 # This delete can set $! in older Perls, so reset the errno 780 $! = 0 ; 781 } 782 783 return 1; 784} 785 786 787#sub total_in 788#sub total_out 789#sub msg 790# 791#sub crc 792#{ 793# my $self = shift ; 794# return *$self->{Compress}->crc32() ; 795#} 796# 797#sub msg 798#{ 799# my $self = shift ; 800# return *$self->{Compress}->msg() ; 801#} 802# 803#sub dict_adler 804#{ 805# my $self = shift ; 806# return *$self->{Compress}->dict_adler() ; 807#} 808# 809#sub get_Level 810#{ 811# my $self = shift ; 812# return *$self->{Compress}->get_Level() ; 813#} 814# 815#sub get_Strategy 816#{ 817# my $self = shift ; 818# return *$self->{Compress}->get_Strategy() ; 819#} 820 821 822sub tell 823{ 824 my $self = shift ; 825 826 return *$self->{UnCompSize}->get32bit() ; 827} 828 829sub eof 830{ 831 my $self = shift ; 832 833 return *$self->{Closed} ; 834} 835 836 837sub seek 838{ 839 my $self = shift ; 840 my $position = shift; 841 my $whence = shift ; 842 843 my $here = $self->tell() ; 844 my $target = 0 ; 845 846 #use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); 847 use IO::Handle ; 848 849 if ($whence == IO::Handle::SEEK_SET) { 850 $target = $position ; 851 } 852 elsif ($whence == IO::Handle::SEEK_CUR || $whence == IO::Handle::SEEK_END) { 853 $target = $here + $position ; 854 } 855 else { 856 $self->croakError(*$self->{ClassName} . "::seek: unknown value, $whence, for whence parameter"); 857 } 858 859 # short circuit if seeking to current offset 860 return 1 if $target == $here ; 861 862 # Outlaw any attempt to seek backwards 863 $self->croakError(*$self->{ClassName} . "::seek: cannot seek backwards") 864 if $target < $here ; 865 866 # Walk the file to the new offset 867 my $offset = $target - $here ; 868 869 my $buffer ; 870 defined $self->syswrite("\x00" x $offset) 871 or return 0; 872 873 return 1 ; 874} 875 876sub binmode 877{ 878 1; 879# my $self = shift ; 880# return defined *$self->{FH} 881# ? binmode *$self->{FH} 882# : 1 ; 883} 884 885sub fileno 886{ 887 my $self = shift ; 888 return defined *$self->{FH} 889 ? *$self->{FH}->fileno() 890 : undef ; 891} 892 893sub opened 894{ 895 my $self = shift ; 896 return ! *$self->{Closed} ; 897} 898 899sub autoflush 900{ 901 my $self = shift ; 902 return defined *$self->{FH} 903 ? *$self->{FH}->autoflush(@_) 904 : undef ; 905} 906 907sub input_line_number 908{ 909 return undef ; 910} 911 912 913sub _notAvailable 914{ 915 my $name = shift ; 916 return sub { croak "$name Not Available: File opened only for output" ; } ; 917} 918 919*read = _notAvailable('read'); 920*READ = _notAvailable('read'); 921*readline = _notAvailable('readline'); 922*READLINE = _notAvailable('readline'); 923*getc = _notAvailable('getc'); 924*GETC = _notAvailable('getc'); 925 926*FILENO = \&fileno; 927*PRINT = \&print; 928*PRINTF = \&printf; 929*WRITE = \&syswrite; 930*write = \&syswrite; 931*SEEK = \&seek; 932*TELL = \&tell; 933*EOF = \&eof; 934*CLOSE = \&close; 935*BINMODE = \&binmode; 936 937#*sysread = \&_notAvailable; 938#*syswrite = \&_write; 939 9401; 941 942__END__ 943 944=head1 NAME 945 946IO::Compress::Base - Base Class for IO::Compress modules 947 948=head1 SYNOPSIS 949 950 use IO::Compress::Base ; 951 952=head1 DESCRIPTION 953 954This module is not intended for direct use in application code. Its sole 955purpose if to to be sub-classed by IO::Compress modules. 956 957=head1 SEE ALSO 958 959L<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::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress> 960 961L<Compress::Zlib::FAQ|Compress::Zlib::FAQ> 962 963L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, 964L<Archive::Tar|Archive::Tar>, 965L<IO::Zlib|IO::Zlib> 966 967=head1 AUTHOR 968 969This module was written by Paul Marquess, F<pmqs@cpan.org>. 970 971=head1 MODIFICATION HISTORY 972 973See the Changes file. 974 975=head1 COPYRIGHT AND LICENSE 976 977Copyright (c) 2005-2010 Paul Marquess. All rights reserved. 978 979This program is free software; you can redistribute it and/or 980modify it under the same terms as Perl itself. 981 982