Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / IO / Compress / Base.pm
1
2 package IO::Compress::Base ;
3
4 require 5.004 ;
5
6 use strict ;
7 use warnings;
8
9 use IO::Compress::Base::Common 2.023 ;
10
11 use IO::File ;
12 use Scalar::Util qw(blessed readonly);
13
14 #use File::Glob;
15 #require Exporter ;
16 use Carp ;
17 use Symbol;
18 use bytes;
19
20 our (@ISA, $VERSION);
21 @ISA    = qw(Exporter IO::File);
22
23 $VERSION = '2.023';
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
27 sub saveStatus
28 {
29     my $self   = shift ;
30     ${ *$self->{ErrorNo} } = shift() + 0 ;
31     ${ *$self->{Error} } = '' ;
32
33     return ${ *$self->{ErrorNo} } ;
34 }
35
36
37 sub 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
47 sub croakError
48 {
49     my $self   = shift ;
50     $self->saveErrorString(0, $_[0]);
51     croak $_[0];
52 }
53
54 sub 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
72 sub error
73 {
74     my $self   = shift ;
75     return ${ *$self->{Error} } ;
76 }
77
78 sub errorNo
79 {
80     my $self   = shift ;
81     return ${ *$self->{ErrorNo} } ;
82 }
83
84
85 sub 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
109 sub 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
136 sub getOneShotParams
137 {
138     return ( 'MultiStream' => [1, 1, Parse_boolean,   1],
139            );
140 }
141
142 sub 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
169 sub _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
295 sub 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
314 sub _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
398 sub _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
454 sub _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
511 sub 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
534 sub getFileInfo
535 {
536 }
537
538 sub TIEHANDLE
539 {
540     return $_[0] if ref($_[0]);
541     die "OOPS\n" ;
542 }
543   
544 sub UNTIE
545 {
546     my $self = shift ;
547 }
548
549 sub 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
565 sub filterUncompressed
566 {
567 }
568
569 sub 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
634 sub 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
657 sub printf
658 {
659     my $self = shift;
660     my $fmt = shift;
661     defined $self->syswrite(sprintf($fmt, @_));
662 }
663
664
665
666 sub 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
693 sub 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
719 sub reset
720 {
721     my $self = shift ;
722     return *$self->{Compress}->reset() ;
723 }
724
725 sub _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
744 sub _writeFinalTrailer
745 {
746     my $self = shift ;
747
748     return $self->output($self->mkFinalTrailer());
749 }
750
751 sub 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
822 sub tell
823 {
824     my $self = shift ;
825
826     return *$self->{UnCompSize}->get32bit() ;
827 }
828
829 sub eof
830 {
831     my $self = shift ;
832
833     return *$self->{Closed} ;
834 }
835
836
837 sub 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
876 sub binmode
877 {
878     1;
879 #    my $self     = shift ;
880 #    return defined *$self->{FH} 
881 #            ? binmode *$self->{FH} 
882 #            : 1 ;
883 }
884
885 sub fileno
886 {
887     my $self     = shift ;
888     return defined *$self->{FH} 
889             ? *$self->{FH}->fileno() 
890             : undef ;
891 }
892
893 sub opened
894 {
895     my $self     = shift ;
896     return ! *$self->{Closed} ;
897 }
898
899 sub autoflush
900 {
901     my $self     = shift ;
902     return defined *$self->{FH} 
903             ? *$self->{FH}->autoflush(@_) 
904             : undef ;
905 }
906
907 sub input_line_number
908 {
909     return undef ;
910 }
911
912
913 sub _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
940 1; 
941
942 __END__
943
944 =head1 NAME
945
946 IO::Compress::Base - Base Class for IO::Compress modules 
947
948 =head1 SYNOPSIS
949
950     use IO::Compress::Base ;
951
952 =head1 DESCRIPTION
953
954 This module is not intended for direct use in application code. Its sole
955 purpose if to to be sub-classed by IO::Compress modules.
956
957 =head1 SEE ALSO
958
959 L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::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
961 L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
962
963 L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
964 L<Archive::Tar|Archive::Tar>,
965 L<IO::Zlib|IO::Zlib>
966
967 =head1 AUTHOR
968
969 This module was written by Paul Marquess, F<pmqs@cpan.org>. 
970
971 =head1 MODIFICATION HISTORY
972
973 See the Changes file.
974
975 =head1 COPYRIGHT AND LICENSE
976
977 Copyright (c) 2005-2009 Paul Marquess. All rights reserved.
978
979 This program is free software; you can redistribute it and/or
980 modify it under the same terms as Perl itself.
981