Debian lenny version packages
[pkg-perl] / deb-src / libio-compress-base-perl / libio-compress-base-perl-2.012 / lib / 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.012 ;
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.012';
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     if ($outType eq 'filename' && -e $outValue && ! -w _)
221       { return $obj->saveErrorString(undef, "Output file '$outValue' is not writable" ) }
222
223
224
225     if ($got->parsed('Encode')) { 
226         my $want_encoding = $got->value('Encode');
227         *$obj->{Encoding} = getEncoding($obj, $class, $want_encoding);
228     }
229
230     $obj->ckParams($got)
231         or $obj->croakError("${class}: " . $obj->error());
232
233
234     $obj->saveStatus(STATUS_OK) ;
235
236     my $status ;
237     if (! $merge)
238     {
239         *$obj->{Compress} = $obj->mkComp($got)
240             or return undef;
241         
242         *$obj->{UnCompSize} = new U64 ;
243         *$obj->{CompSize} = new U64 ;
244
245         if ( $outType eq 'buffer') {
246             ${ *$obj->{Buffer} }  = ''
247                 unless $appendOutput ;
248         }
249         else {
250             if ($outType eq 'handle') {
251                 *$obj->{FH} = $outValue ;
252                 setBinModeOutput(*$obj->{FH}) ;
253                 $outValue->flush() ;
254                 *$obj->{Handle} = 1 ;
255                 if ($appendOutput)
256                 {
257                     seek(*$obj->{FH}, 0, SEEK_END)
258                         or return $obj->saveErrorString(undef, "Cannot seek to end of output filehandle: $!", $!) ;
259
260                 }
261             }
262             elsif ($outType eq 'filename') {    
263                 my $mode = '>' ;
264                 $mode = '>>'
265                     if $appendOutput;
266                 *$obj->{FH} = new IO::File "$mode $outValue" 
267                     or return $obj->saveErrorString(undef, "cannot open file '$outValue': $!", $!) ;
268                 *$obj->{StdIO} = ($outValue eq '-'); 
269                 setBinModeOutput(*$obj->{FH}) ;
270             }
271         }
272
273         *$obj->{Header} = $obj->mkHeader($got) ;
274         $obj->output( *$obj->{Header} )
275             or return undef;
276     }
277     else
278     {
279         *$obj->{Compress} = $obj->createMerge($outValue, $outType)
280             or return undef;
281     }
282
283     *$obj->{Closed} = 0 ;
284     *$obj->{AutoClose} = $got->value('AutoClose') ;
285     *$obj->{Output} = $outValue;
286     *$obj->{ClassName} = $class;
287     *$obj->{Got} = $got;
288     *$obj->{OneShot} = 0 ;
289
290     return $obj ;
291 }
292
293 sub ckOutputParam 
294 {
295     my $self = shift ;
296     my $from = shift ;
297     my $outType = whatIsOutput($_[0]);
298
299     $self->croakError("$from: output parameter not a filename, filehandle or scalar ref")
300         if ! $outType ;
301
302     $self->croakError("$from: output filename is undef or null string")
303         if $outType eq 'filename' && (! defined $_[0] || $_[0] eq '')  ;
304
305     $self->croakError("$from: output buffer is read-only")
306         if $outType eq 'buffer' && readonly(${ $_[0] });
307     
308     return 1;    
309 }
310
311
312 sub _def
313 {
314     my $obj = shift ;
315     
316     my $class= (caller)[0] ;
317     my $name = (caller(1))[3] ;
318
319     $obj->croakError("$name: expected at least 1 parameters\n")
320         unless @_ >= 1 ;
321
322     my $input = shift ;
323     my $haveOut = @_ ;
324     my $output = shift ;
325
326     my $x = new IO::Compress::Base::Validator($class, *$obj->{Error}, $name, $input, $output)
327         or return undef ;
328
329     push @_, $output if $haveOut && $x->{Hash};
330
331     *$obj->{OneShot} = 1 ;
332
333     my $got = $obj->checkParams($name, undef, @_)
334         or return undef ;
335
336     $x->{Got} = $got ;
337
338 #    if ($x->{Hash})
339 #    {
340 #        while (my($k, $v) = each %$input)
341 #        {
342 #            $v = \$input->{$k} 
343 #                unless defined $v ;
344 #
345 #            $obj->_singleTarget($x, 1, $k, $v, @_)
346 #                or return undef ;
347 #        }
348 #
349 #        return keys %$input ;
350 #    }
351
352     if ($x->{GlobMap})
353     {
354         $x->{oneInput} = 1 ;
355         foreach my $pair (@{ $x->{Pairs} })
356         {
357             my ($from, $to) = @$pair ;
358             $obj->_singleTarget($x, 1, $from, $to, @_)
359                 or return undef ;
360         }
361
362         return scalar @{ $x->{Pairs} } ;
363     }
364
365     if (! $x->{oneOutput} )
366     {
367         my $inFile = ($x->{inType} eq 'filenames' 
368                         || $x->{inType} eq 'filename');
369
370         $x->{inType} = $inFile ? 'filename' : 'buffer';
371         
372         foreach my $in ($x->{oneInput} ? $input : @$input)
373         {
374             my $out ;
375             $x->{oneInput} = 1 ;
376
377             $obj->_singleTarget($x, $inFile, $in, \$out, @_)
378                 or return undef ;
379
380             push @$output, \$out ;
381             #if ($x->{outType} eq 'array')
382             #  { push @$output, \$out }
383             #else
384             #  { $output->{$in} = \$out }
385         }
386
387         return 1 ;
388     }
389
390     # finally the 1 to 1 and n to 1
391     return $obj->_singleTarget($x, 1, $input, $output, @_);
392
393     croak "should not be here" ;
394 }
395
396 sub _singleTarget
397 {
398     my $obj             = shift ;
399     my $x               = shift ;
400     my $inputIsFilename = shift;
401     my $input           = shift;
402     
403     if ($x->{oneInput})
404     {
405         $obj->getFileInfo($x->{Got}, $input)
406             if isaFilename($input) and $inputIsFilename ;
407
408         my $z = $obj->_create($x->{Got}, @_)
409             or return undef ;
410
411
412         defined $z->_wr2($input, $inputIsFilename) 
413             or return $z->closeError(undef) ;
414
415         return $z->close() ;
416     }
417     else
418     {
419         my $afterFirst = 0 ;
420         my $inputIsFilename = ($x->{inType} ne 'array');
421         my $keep = $x->{Got}->clone();
422
423         #for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input)
424         for my $element ( @$input)
425         {
426             my $isFilename = isaFilename($element);
427
428             if ( $afterFirst ++ )
429             {
430                 defined addInterStream($obj, $element, $isFilename)
431                     or return $obj->closeError(undef) ;
432             }
433             else
434             {
435                 $obj->getFileInfo($x->{Got}, $element)
436                     if $isFilename;
437
438                 $obj->_create($x->{Got}, @_)
439                     or return undef ;
440             }
441
442             defined $obj->_wr2($element, $isFilename) 
443                 or return $obj->closeError(undef) ;
444
445             *$obj->{Got} = $keep->clone();
446         }
447         return $obj->close() ;
448     }
449
450 }
451
452 sub _wr2
453 {
454     my $self = shift ;
455
456     my $source = shift ;
457     my $inputIsFilename = shift;
458
459     my $input = $source ;
460     if (! $inputIsFilename)
461     {
462         $input = \$source 
463             if ! ref $source;
464     }
465
466     if ( ref $input && ref $input eq 'SCALAR' )
467     {
468         return $self->syswrite($input, @_) ;
469     }
470
471     if ( ! ref $input  || isaFilehandle($input))
472     {
473         my $isFilehandle = isaFilehandle($input) ;
474
475         my $fh = $input ;
476
477         if ( ! $isFilehandle )
478         {
479             $fh = new IO::File "<$input"
480                 or return $self->saveErrorString(undef, "cannot open file '$input': $!", $!) ;
481         }
482         binmode $fh if *$self->{Got}->valueOrDefault('BinModeIn') ;
483
484         my $status ;
485         my $buff ;
486         my $count = 0 ;
487         while (($status = read($fh, $buff, 16 * 1024)) > 0) {
488             $count += length $buff;
489             defined $self->syswrite($buff, @_) 
490                 or return undef ;
491         }
492
493         return $self->saveErrorString(undef, $!, $!) 
494             if $status < 0 ;
495
496         if ( (!$isFilehandle || *$self->{AutoClose}) && $input ne '-')
497         {    
498             $fh->close() 
499                 or return undef ;
500         }
501
502         return $count ;
503     }
504
505     croak "Should not be here";
506     return undef;
507 }
508
509 sub addInterStream
510 {
511     my $self = shift ;
512     my $input = shift ;
513     my $inputIsFilename = shift ;
514
515     if (*$self->{Got}->value('MultiStream'))
516     {
517         $self->getFileInfo(*$self->{Got}, $input)
518             #if isaFilename($input) and $inputIsFilename ;
519             if isaFilename($input) ;
520
521         # TODO -- newStream needs to allow gzip/zip header to be modified
522         return $self->newStream();
523     }
524     elsif (*$self->{Got}->value('AutoFlush'))
525     {
526         #return $self->flush(Z_FULL_FLUSH);
527     }
528
529     return 1 ;
530 }
531
532 sub getFileInfo
533 {
534 }
535
536 sub TIEHANDLE
537 {
538     return $_[0] if ref($_[0]);
539     die "OOPS\n" ;
540 }
541   
542 sub UNTIE
543 {
544     my $self = shift ;
545 }
546
547 sub DESTROY
548 {
549     my $self = shift ;
550     local ($., $@, $!, $^E, $?);
551     
552     $self->close() ;
553
554     # TODO - memory leak with 5.8.0 - this isn't called until 
555     #        global destruction
556     #
557     %{ *$self } = () ;
558     undef $self ;
559 }
560
561
562
563 sub filterUncompressed
564 {
565 }
566
567 sub syswrite
568 {
569     my $self = shift ;
570
571     my $buffer ;
572     if (ref $_[0] ) {
573         $self->croakError( *$self->{ClassName} . "::write: not a scalar reference" )
574             unless ref $_[0] eq 'SCALAR' ;
575         $buffer = $_[0] ;
576     }
577     else {
578         $buffer = \$_[0] ;
579     }
580
581     $] >= 5.008 and ( utf8::downgrade($$buffer, 1) 
582         or croak "Wide character in " .  *$self->{ClassName} . "::write:");
583
584
585     if (@_ > 1) {
586         my $slen = defined $$buffer ? length($$buffer) : 0;
587         my $len = $slen;
588         my $offset = 0;
589         $len = $_[1] if $_[1] < $len;
590
591         if (@_ > 2) {
592             $offset = $_[2] || 0;
593             $self->croakError(*$self->{ClassName} . "::write: offset outside string") 
594                 if $offset > $slen;
595             if ($offset < 0) {
596                 $offset += $slen;
597                 $self->croakError( *$self->{ClassName} . "::write: offset outside string") if $offset < 0;
598             }
599             my $rem = $slen - $offset;
600             $len = $rem if $rem < $len;
601         }
602
603         $buffer = \substr($$buffer, $offset, $len) ;
604     }
605
606     return 0 if ! defined $$buffer || length $$buffer == 0 ;
607
608     if (*$self->{Encoding}) {
609         $$buffer = *$self->{Encoding}->encode($$buffer);
610     }
611
612     $self->filterUncompressed($buffer);
613
614     my $buffer_length = defined $$buffer ? length($$buffer) : 0 ;
615     *$self->{UnCompSize}->add($buffer_length) ;
616
617     my $outBuffer='';
618     my $status = *$self->{Compress}->compr($buffer, $outBuffer) ;
619
620     return $self->saveErrorString(undef, *$self->{Compress}{Error}, 
621                                          *$self->{Compress}{ErrorNo})
622         if $status == STATUS_ERROR;
623
624     *$self->{CompSize}->add(length $outBuffer) ;
625
626     $self->output($outBuffer)
627         or return undef;
628
629     return $buffer_length;
630 }
631
632 sub print
633 {
634     my $self = shift;
635
636     #if (ref $self) {
637     #    $self = *$self{GLOB} ;
638     #}
639
640     if (defined $\) {
641         if (defined $,) {
642             defined $self->syswrite(join($,, @_) . $\);
643         } else {
644             defined $self->syswrite(join("", @_) . $\);
645         }
646     } else {
647         if (defined $,) {
648             defined $self->syswrite(join($,, @_));
649         } else {
650             defined $self->syswrite(join("", @_));
651         }
652     }
653 }
654
655 sub printf
656 {
657     my $self = shift;
658     my $fmt = shift;
659     defined $self->syswrite(sprintf($fmt, @_));
660 }
661
662
663
664 sub flush
665 {
666     my $self = shift ;
667
668     my $outBuffer='';
669     my $status = *$self->{Compress}->flush($outBuffer, @_) ;
670     return $self->saveErrorString(0, *$self->{Compress}{Error}, 
671                                     *$self->{Compress}{ErrorNo})
672         if $status == STATUS_ERROR;
673
674     if ( defined *$self->{FH} ) {
675         *$self->{FH}->clearerr();
676     }
677
678     *$self->{CompSize}->add(length $outBuffer) ;
679
680     $self->output($outBuffer)
681         or return 0;
682
683     if ( defined *$self->{FH} ) {
684         defined *$self->{FH}->flush()
685             or return $self->saveErrorString(0, $!, $!); 
686     }
687
688     return 1;
689 }
690
691 sub newStream
692 {
693     my $self = shift ;
694   
695     $self->_writeTrailer()
696         or return 0 ;
697
698     my $got = $self->checkParams('newStream', *$self->{Got}, @_)
699         or return 0 ;    
700
701     $self->ckParams($got)
702         or $self->croakError("newStream: $self->{Error}");
703
704     *$self->{Compress} = $self->mkComp($got)
705         or return 0;
706
707     *$self->{Header} = $self->mkHeader($got) ;
708     $self->output(*$self->{Header} )
709         or return 0;
710     
711     *$self->{UnCompSize}->reset();
712     *$self->{CompSize}->reset();
713
714     return 1 ;
715 }
716
717 sub reset
718 {
719     my $self = shift ;
720     return *$self->{Compress}->reset() ;
721 }
722
723 sub _writeTrailer
724 {
725     my $self = shift ;
726
727     my $trailer = '';
728
729     my $status = *$self->{Compress}->close($trailer) ;
730     return $self->saveErrorString(0, *$self->{Compress}{Error}, *$self->{Compress}{ErrorNo})
731         if $status == STATUS_ERROR;
732
733     *$self->{CompSize}->add(length $trailer) ;
734
735     $trailer .= $self->mkTrailer();
736     defined $trailer
737       or return 0;
738
739     return $self->output($trailer);
740 }
741
742 sub _writeFinalTrailer
743 {
744     my $self = shift ;
745
746     return $self->output($self->mkFinalTrailer());
747 }
748
749 sub close
750 {
751     my $self = shift ;
752
753     return 1 if *$self->{Closed} || ! *$self->{Compress} ;
754     *$self->{Closed} = 1 ;
755
756     untie *$self 
757         if $] >= 5.008 ;
758
759     $self->_writeTrailer()
760         or return 0 ;
761
762     $self->_writeFinalTrailer()
763         or return 0 ;
764
765     $self->output( "", 1 )
766         or return 0;
767
768     if (defined *$self->{FH}) {
769
770         #if (! *$self->{Handle} || *$self->{AutoClose}) {
771         if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) {
772             $! = 0 ;
773             *$self->{FH}->close()
774                 or return $self->saveErrorString(0, $!, $!); 
775         }
776         delete *$self->{FH} ;
777         # This delete can set $! in older Perls, so reset the errno
778         $! = 0 ;
779     }
780
781     return 1;
782 }
783
784
785 #sub total_in
786 #sub total_out
787 #sub msg
788 #
789 #sub crc
790 #{
791 #    my $self = shift ;
792 #    return *$self->{Compress}->crc32() ;
793 #}
794 #
795 #sub msg
796 #{
797 #    my $self = shift ;
798 #    return *$self->{Compress}->msg() ;
799 #}
800 #
801 #sub dict_adler
802 #{
803 #    my $self = shift ;
804 #    return *$self->{Compress}->dict_adler() ;
805 #}
806 #
807 #sub get_Level
808 #{
809 #    my $self = shift ;
810 #    return *$self->{Compress}->get_Level() ;
811 #}
812 #
813 #sub get_Strategy
814 #{
815 #    my $self = shift ;
816 #    return *$self->{Compress}->get_Strategy() ;
817 #}
818
819
820 sub tell
821 {
822     my $self = shift ;
823
824     return *$self->{UnCompSize}->get32bit() ;
825 }
826
827 sub eof
828 {
829     my $self = shift ;
830
831     return *$self->{Closed} ;
832 }
833
834
835 sub seek
836 {
837     my $self     = shift ;
838     my $position = shift;
839     my $whence   = shift ;
840
841     my $here = $self->tell() ;
842     my $target = 0 ;
843
844     #use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END);
845     use IO::Handle ;
846
847     if ($whence == IO::Handle::SEEK_SET) {
848         $target = $position ;
849     }
850     elsif ($whence == IO::Handle::SEEK_CUR || $whence == IO::Handle::SEEK_END) {
851         $target = $here + $position ;
852     }
853     else {
854         $self->croakError(*$self->{ClassName} . "::seek: unknown value, $whence, for whence parameter");
855     }
856
857     # short circuit if seeking to current offset
858     return 1 if $target == $here ;    
859
860     # Outlaw any attempt to seek backwards
861     $self->croakError(*$self->{ClassName} . "::seek: cannot seek backwards")
862         if $target < $here ;
863
864     # Walk the file to the new offset
865     my $offset = $target - $here ;
866
867     my $buffer ;
868     defined $self->syswrite("\x00" x $offset)
869         or return 0;
870
871     return 1 ;
872 }
873
874 sub binmode
875 {
876     1;
877 #    my $self     = shift ;
878 #    return defined *$self->{FH} 
879 #            ? binmode *$self->{FH} 
880 #            : 1 ;
881 }
882
883 sub fileno
884 {
885     my $self     = shift ;
886     return defined *$self->{FH} 
887             ? *$self->{FH}->fileno() 
888             : undef ;
889 }
890
891 sub opened
892 {
893     my $self     = shift ;
894     return ! *$self->{Closed} ;
895 }
896
897 sub autoflush
898 {
899     my $self     = shift ;
900     return defined *$self->{FH} 
901             ? *$self->{FH}->autoflush(@_) 
902             : undef ;
903 }
904
905 sub input_line_number
906 {
907     return undef ;
908 }
909
910
911 sub _notAvailable
912 {
913     my $name = shift ;
914     return sub { croak "$name Not Available: File opened only for output" ; } ;
915 }
916
917 *read     = _notAvailable('read');
918 *READ     = _notAvailable('read');
919 *readline = _notAvailable('readline');
920 *READLINE = _notAvailable('readline');
921 *getc     = _notAvailable('getc');
922 *GETC     = _notAvailable('getc');
923
924 *FILENO   = \&fileno;
925 *PRINT    = \&print;
926 *PRINTF   = \&printf;
927 *WRITE    = \&syswrite;
928 *write    = \&syswrite;
929 *SEEK     = \&seek; 
930 *TELL     = \&tell;
931 *EOF      = \&eof;
932 *CLOSE    = \&close;
933 *BINMODE  = \&binmode;
934
935 #*sysread  = \&_notAvailable;
936 #*syswrite = \&_write;
937
938 1; 
939
940 __END__
941
942 =head1 NAME
943
944 IO::Compress::Base - Base Class for IO::Compress modules 
945
946 =head1 SYNOPSIS
947
948     use IO::Compress::Base ;
949
950 =head1 DESCRIPTION
951
952 This module is not intended for direct use in application code. Its sole
953 purpose if to to be sub-classed by IO::Compress modules.
954
955 =head1 SEE ALSO
956
957 L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
958
959 L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
960
961 L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
962 L<Archive::Tar|Archive::Tar>,
963 L<IO::Zlib|IO::Zlib>
964
965 =head1 AUTHOR
966
967 This module was written by Paul Marquess, F<pmqs@cpan.org>. 
968
969 =head1 MODIFICATION HISTORY
970
971 See the Changes file.
972
973 =head1 COPYRIGHT AND LICENSE
974
975 Copyright (c) 2005-2008 Paul Marquess. All rights reserved.
976
977 This program is free software; you can redistribute it and/or
978 modify it under the same terms as Perl itself.
979