File Coverage

blib/lib/Archive/Zip/SimpleZip.pm
Criterion Covered Total %
statement 210 226 92.9
branch 99 128 77.3
condition 27 39 69.2
subroutine 33 40 82.5
pod 5 9 55.5
total 374 442 84.6


line stmt bran cond sub pod time code
1             package Archive::Zip::SimpleZip;
2              
3 5     5   581119 use strict;
  5         50  
  5         151  
4 5     5   32 use warnings;
  5         10  
  5         201  
5              
6             require 5.006;
7              
8 5     5   2101 use IO::Compress::Zip 2.096 qw(:all);
  5         119344  
  5         1240  
9 5     5   46 use IO::Compress::Base::Common 2.096 ();
  5         74  
  5         123  
10 5     5   27 use IO::Compress::Adapter::Deflate 2.096 ;
  5         68  
  5         727  
11              
12 5     5   35 use Fcntl ();
  5         10  
  5         68  
13 5     5   33 use File::Spec ();
  5         10  
  5         93  
14 5     5   27 use IO::File ();
  5         10  
  5         83  
15 5     5   26 use Scalar::Util ();
  5         11  
  5         128  
16 5     5   41 use Carp;
  5         30  
  5         8493  
17             require Exporter ;
18              
19             our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $SimpleZipError);
20              
21             $SimpleZipError= '';
22             $VERSION = "0.039";
23              
24             @ISA = qw(Exporter);
25             @EXPORT_OK = qw( $SimpleZipError ) ;
26              
27             %EXPORT_TAGS = %IO::Compress::Zip::EXPORT_TAGS ;
28              
29             Exporter::export_ok_tags('all');
30              
31             our %PARAMS = (
32             'name' => [IO::Compress::Base::Common::Parse_any, ''],
33             'comment' => [IO::Compress::Base::Common::Parse_any, ''],
34             'zipcomment' => [IO::Compress::Base::Common::Parse_any, ''],
35             'stream' => [IO::Compress::Base::Common::Parse_boolean, 0],
36             'method' => [IO::Compress::Base::Common::Parse_unsigned, ZIP_CM_DEFLATE],
37             'minimal' => [IO::Compress::Base::Common::Parse_boolean, 0],
38             'zip64' => [IO::Compress::Base::Common::Parse_boolean, 0],
39             'filtername' => [IO::Compress::Base::Common::Parse_code, undef],
40             'canonicalname' => [IO::Compress::Base::Common::Parse_boolean, 1],
41             'textflag' => [IO::Compress::Base::Common::Parse_boolean, 0],
42             'storelinks' => [IO::Compress::Base::Common::Parse_boolean, 0],
43             'autoflush' => [IO::Compress::Base::Common::Parse_boolean, 0],
44             #'storedirs' => [IO::Compress::Base::Common::Parse_boolean, 0],
45             'encode' => [IO::Compress::Base::Common::Parse_any, undef],
46             #'extrafieldlocal' => [IO::Compress::Base::Common::Parse_any, undef],
47             #'extrafieldcentral'=> [IO::Compress::Base::Common::Parse_any, undef],
48             'filtercontainer' => [IO::Compress::Base::Common::Parse_code, undef],
49             # 'time' => [IO::Compress::Base::Common::Parse_any, undef],
50             # 'extime' => [IO::Compress::Base::Common::Parse_any, undef],
51              
52             # Zlib
53             'level' => [IO::Compress::Base::Common::Parse_signed, Z_DEFAULT_COMPRESSION],
54             'strategy' => [IO::Compress::Base::Common::Parse_signed, Z_DEFAULT_STRATEGY],
55              
56             # Lzma
57             'preset' => [IO::Compress::Base::Common::Parse_unsigned, 6],
58             'extreme' => [IO::Compress::Base::Common::Parse_boolean, 0],
59              
60             # Bzip2
61             'blocksize100k' => [IO::Compress::Base::Common::Parse_unsigned, 1],
62             'workfactor' => [IO::Compress::Base::Common::Parse_unsigned, 0],
63             'verbosity' => [IO::Compress::Base::Common::Parse_boolean, 0],
64             );
65              
66              
67             sub _ckParams
68             {
69 1197   66 1197   3653 my $got = shift || IO::Compress::Base::Parameters::new();
70 1197         4341 my $top = shift;
71              
72 1197 100       3348 $got->parse(\%PARAMS, @_)
73             or _myDie("Parameter Error: " . $got->getError()) ;
74              
75 1195 100       250684 if ($top)
76             {
77 232         605 for my $opt ( qw(name comment) )
78             {
79 463 100       1843 _myDie("$opt option not valid in constructor")
80             if $got->parsed($opt);
81             }
82              
83 230         1423 $got->setValue('crc32' => 1);
84 230         1998 $got->setValue('adler32' => 0);
85 230         1662 $got->setValue('os_code' => $Compress::Raw::Zlib::gzip_os_code);
86             }
87             else
88             {
89 963         2041 for my $opt ( qw( zipcomment) )
90             {
91 963 100       2182 _myDie("$opt option only valid in constructor")
92             if $got->parsed($opt);
93             }
94             }
95              
96 1192         6475 my $e = $got->getValue("encode");
97 1192 100       4942 if (defined $e)
98             {
99 13 50       38 _myDie("Encode::find_encoding not found") if ! defined &Encode::find_encoding;
100 13 100       40 _myDie("Unknown Encoding '$e'") if ! defined Encode::find_encoding($e) ;
101             }
102              
103 1191         2127 return $got;
104             }
105              
106             sub _illegalFilename
107             {
108 3     3   101 return _setError(undef, undef, "Illegal Filename") ;
109             }
110              
111              
112             #sub simplezip
113             #{
114             # my $from = shift;
115             # my $filename = shift ;
116             # #my %opts
117             #
118             # my $z = new Archive::Zip::SimpleZip $filename, @_;
119             #
120             # if (ref $from eq 'ARRAY')
121             # {
122             # $z->add($_) for @$from;
123             # }
124             # elsif (ref $from)
125             # {
126             # die "bad";
127             # }
128             # else
129             # {
130             # $z->add($filename);
131             # }
132             #
133             # $z->close();
134             #}
135              
136              
137             sub new
138             {
139 237     237 0 1045617 my $class = shift;
140              
141 237         640 $SimpleZipError = '';
142              
143 237 100       850 return _setError(undef, undef, "Missing Filename")
144             unless @_ ;
145              
146 236         416 my $outValue = shift ;
147 236         377 my $fh;
148              
149 236 100       632 if (!defined $outValue)
150             {
151 1         4 return _illegalFilename
152             }
153              
154 235         689 my $isSTDOUT = ($outValue eq '-') ;
155 235         845 my $outType = IO::Compress::Base::Common::whatIsOutput($outValue);
156              
157 235 100 66     8316 if ($outType eq 'filename')
    50          
158             {
159 145 100 66     2933 if (-e $outValue && ( ! -f _ || ! -w _))
      100        
160             {
161 1         5 return _illegalFilename
162             }
163              
164 144 100       1236 $fh = new IO::File ">$outValue"
165             or return _illegalFilename;
166             }
167             elsif( $outType eq 'buffer' || $outType eq 'handle')
168             {
169 90         192 $fh = $outValue;
170             }
171             else
172             {
173 0         0 return _illegalFilename
174             }
175              
176 233         15624 my $got = _ckParams(undef, 1, @_);
177 229 100       1000 $got->setValue('autoclose' => 1) unless $outType eq 'handle' ;
178 229 100       1644 $got->setValue('stream' => 1) if $isSTDOUT ;
179              
180 229         1412 my $obj = {
181             ZipFile => $outValue,
182             FH => $fh,
183             Open => 1,
184             FilesWritten => 0,
185             Opts => $got,
186             Error => undef,
187             Raw => undef,
188             };
189              
190 229         1086 bless $obj, $class;
191             }
192              
193             sub DESTROY
194             {
195 229     229   1878073 my $self = shift;
196 229         749 $self->close();
197             }
198              
199             sub close
200             {
201 447     447 1 38461 my $self = shift;
202              
203             return 0
204 447 100       5148 if ! $self->{Open} ;
205              
206 229         511 $self->{Open} = 0;
207 229 100 66     786 if ($self->{FilesWritten} || defined $self->{Raw})
208             {
209 223 50       659 if(defined $self->{Zip})
210             {
211 223 100       619 if (defined $self->{Raw})
212             {
213 2         4 $self->{Raw} = undef ;
214             }
215              
216 223 50       1036 $self->{Zip}->_flushCompressed() || return 0;
217 223 50       17759 $self->{Zip}->close() || return 0;
218 223         83917 delete $self->{Zip} ;
219             }
220             }
221              
222 229         15807 1;
223             }
224              
225             sub _newStream
226             {
227 960     960   1279 my $self = shift;
228 960         1158 my $filename = shift ;
229 960         1100 my $options = shift;
230              
231 960 100       1812 if (defined $filename)
232             {
233 27         91 IO::Compress::Zip::getFileInfo(undef, $options, $filename) ;
234              
235             # Force STORE for directories, symbolic links & empty files
236 27 100 66     4738 $options->setValue(method => ZIP_CM_STORE)
      100        
237             if -d $filename || -z _ || -l $filename ;
238             }
239              
240             # Archive::Zip::SimpleZip handles canonical
241 960         2287 $options->setValue(canonicalname => 0);
242              
243 960         6155 $! = 0;
244 960 100       2177 if (! defined $self->{Zip}) {
245 223         672 $self->{Zip} = IO::Compress::Base::Common::createSelfTiedObject('IO::Compress::Zip', \$SimpleZipError);
246             $self->{Zip}->_create($options, $self->{FH})
247 223 50       11206 or die "_create $SimpleZipError";
248             $self->{Zip}->_autoflush()
249 223 50       226355 if $options->getValue('autoflush');
250              
251             }
252             else {
253 737 50       2625 $self->{Zip}->_newStream($options)
254             or die "_newStream - $SimpleZipError";
255             }
256              
257 960         674365 ++ $self->{FilesWritten} ;
258              
259 960         1723 return 1;
260             }
261              
262              
263             sub _setError
264             {
265 7     7   17 $SimpleZipError = $_[2] ;
266 7 100       22 $_[0]->{Error} = $_[2]
267             if defined $_[0] ;
268              
269 7         27 return $_[1];
270             }
271              
272              
273             sub error
274             {
275 0     0 0 0 my $self = shift;
276 0         0 return $self->{Error};
277             }
278              
279             sub _myDie
280             {
281 8     8   1583 $SimpleZipError = $_[0];
282 8         1167 Carp::croak $_[0];
283              
284             }
285              
286             sub _stdPreq
287             {
288 967     967   1484 my $self = shift;
289              
290             return 0
291 967 50       2569 if $self->{Error} ;
292              
293             return $self->_setError(0, "Zip file closed")
294 967 50       2031 if ! $self->{Open} ;
295              
296             return $self->_setError(0, "openMember filehandle already open")
297 967 100       2117 if defined $self->{Raw};
298              
299 965         1976 return 1;
300             }
301              
302             sub add
303             {
304 29     29 1 6673 my $self = shift;
305 29         51 my $filename = shift;
306              
307 29 50       64 $self->_stdPreq or return 0 ;
308              
309 29 100       534 return $self->_setError(0, "File '$filename' does not exist")
310             if ! -e $filename ;
311              
312 28 50       391 return $self->_setError(0, "File '$filename' cannot be read")
313             if ! -r $filename ;
314              
315 28         159 my $options = $self->{Opts}->clone();
316              
317 28         2975 my $got = _ckParams($options, 0, @_);
318              
319             # Force Encode off.
320 27         77 $got->setValue('encode', undef);
321              
322 27   100     189 my $isLink = $got->getValue('storelinks') && -l $filename ;
323 27         552 my $isDir = -d $filename;
324              
325 27 50 33     179 return 0
326             if $filename eq '.' || $filename eq '..';
327              
328 27 100       131 if ($options->getValue("canonicalname"))
329             {
330 26 100       155 if (! $got->parsed("name"))
331             {
332 18   100     171 $got->setValue(name => IO::Compress::Zip::canonicalName($filename, $isDir && ! $isLink));
333             }
334             else
335             {
336 8   33     48 $got->setValue(name => IO::Compress::Zip::canonicalName($got->getValue("name"), $isDir && ! $isLink));
337             }
338             }
339              
340 27         1250 my ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) ;
341              
342 27 100       65 if ( $got->parsed('storelinks') )
343             {
344 5         98 ($mode, $uid, $gid, $size, $atime, $mtime, $ctime)
345             = (lstat($filename))[2, 4, 5, 7, 8, 9, 10] ;
346             }
347             else
348             {
349 22         421 ($mode, $uid, $gid, $size, $atime, $mtime, $ctime)
350             = (stat($filename))[2, 4, 5,7, 8, 9, 10] ;
351             }
352              
353 27         149 $got->setValue(time => $mtime);
354              
355 27 50       223 if (! $got->getValue('minimal')) {
356              
357 27         173 $got->setValue(extime => [$atime, $mtime, $ctime]) ;
358              
359 5     5   2755 use Perl::OSType;
  5         2218  
  5         7734  
360 27         206 my $type = Perl::OSType::os_type();
361 27 50       268 if ( $type eq 'Unix' )
362             {
363 27         85 $got->setValue(exunixn => [$uid, $gid]) ;
364             }
365             # TODO add Windows
366             }
367              
368 27         233 $self->_newStream($filename, $got);
369              
370 27 100       613 if($isLink)
    100          
    50          
371             {
372 3         41 my $target = readlink($filename);
373 3         18 $self->{Zip}->write($target);
374             }
375             elsif (-d $filename)
376             {
377             # Do nothing, a directory has no payload
378             }
379             elsif (-f $filename)
380             {
381 19 50       172 my $fh = new IO::File "<$filename"
382             or die "Cannot open file $filename: $!";
383              
384 19         1479 binmode $fh;
385              
386 19         46 my $data;
387             my $last ;
388 19         81 while ($fh->read($data, 1024 * 16))
389             {
390 19         502 $self->{Zip}->write($data);
391             }
392             }
393             else
394             {
395 0         0 return 0;
396             }
397              
398 27         2756 return 1;
399             }
400              
401              
402             sub addString
403             {
404 861     861 1 195574 my $self = shift;
405 861         1241 my $string = shift;
406              
407 861 100       1795 $self->_stdPreq or return 0 ;
408              
409 860         2963 my $options = $self->{Opts}->clone();
410              
411 860         87915 my $got = _ckParams($options, 0, @_);
412              
413 859 100       1680 _myDie("Missing 'Name' parameter in addString")
414             if ! $got->parsed("name");
415              
416 858 100       3420 $got->setValue(name => IO::Compress::Zip::canonicalName($got->getValue("name")))
417             if $options->getValue("canonicalname") ;
418              
419 858         4712 $self->_newStream(undef, $got);
420 858         2659 $self->{Zip}->write($string);
421              
422 858         58750 return 1;
423             }
424              
425             sub addFileHandle
426             {
427 2     2 1 736 my $self = shift;
428 2         6 my $fh = shift;
429              
430 2 50       8 $self->_stdPreq or return 0 ;
431              
432 2         10 my $options = $self->{Opts}->clone() ;
433              
434 2         192 my $got = _ckParams($options, 0, @_);
435              
436 2 100       6 _myDie("Missing 'Name' parameter in addFileHandle")
437             if ! $got->parsed("name");
438              
439 1 50       8 $got->setValue(name => IO::Compress::Zip::canonicalName($got->getValue("name")))
440             if $options->getValue("canonicalname") ;
441              
442 1         49 $self->_newStream(undef, $got);
443              
444 1         2 my $data;
445              
446 1         9 while ($fh->read($data, 1024 * 16))
447             {
448 1         43 $self->{Zip}->write($data);
449             }
450              
451 1         93 return 1;
452             }
453              
454             # sub createDirectory
455             # {
456             # my $self = shift ;
457             # my $directory = shift;
458              
459             # # TODO - file attributes
460              
461             # $self->_stdPreq or return 0 ;
462              
463             # my $got = _ckParams($options, 0, @_);
464             # $got->setValue(name => IO::Compress::Zip::canonicalName($filename, 1));
465              
466             # $self->_newStream(undef, $got);
467              
468             # return 1;
469             # }
470              
471             sub openMember
472             {
473 75     75 1 7458 my $self = shift;
474              
475 75 100       181 $self->_stdPreq or return undef ;
476              
477 74         276 my $options = $self->{Opts}->clone();
478              
479 74         7399 my $got = _ckParams($options, 0, @_);
480              
481 74 50       157 _myDie("Missing 'Name' parameter in openMember")
482             if ! $got->parsed("name");
483              
484 74 100       404 $got->setValue(name => IO::Compress::Zip::canonicalName($got->getValue("name")))
485             if $options->getValue("canonicalname") ;
486              
487 74         3453 $self->_newStream(undef, $got);
488              
489             # if (1)
490             # {
491 74         219 my $z = IO::Compress::Base::Common::createSelfTiedObject("Archive::Zip::SimpleZip::Handle", \$SimpleZipError) ;
492              
493 74         874 $self->{Raw} = 1;
494              
495 74         165 *$z->{Open} = 1 ;
496 74         137 *$z->{SZ} = $self;
497 74         283 Scalar::Util::weaken *$z->{SZ}; # for 5.8
498              
499 74         614 return $z;
500             # }
501             # else
502             # {
503             # my $handle = Symbol::gensym();
504             # tie *$handle, "Archive::Zip::SimpleZip::Handle", $self, $self->{Zip};
505             #
506             # $self->{Raw} = 1;
507             #
508             # return $handle;
509             # }
510             }
511              
512             sub STORABLE_freeze
513             {
514 0     0 0 0 my $type = ref shift;
515 0         0 croak "Cannot freeze $type object\n";
516             }
517              
518             sub STORABLE_thaw
519             {
520 0     0 0 0 my $type = ref shift;
521 0         0 croak "Cannot thaw $type object\n";
522             }
523              
524              
525              
526             {
527             package Archive::Zip::SimpleZip::Handle ;
528              
529             sub TIEHANDLE
530             {
531 74 50   74   2256 return $_[0] if ref($_[0]);
532 0         0 die "OOPS\n" ;
533             }
534              
535             sub UNTIE
536             {
537 0     0   0 my $self = shift ;
538             }
539              
540             sub DESTROY
541             {
542 74     74   114337 my $self = shift ;
543 74         578 local ($., $@, $!, $^E, $?);
544 74         213 $self->close() ;
545              
546             # TODO - memory leak with 5.8.0 - this isn't called until
547             # global destruction
548             #
549 74         119 %{ *$self } = () ;
  74         379  
550 74         596 undef $self ;
551             }
552              
553              
554             sub close
555             {
556 143     143   12739 my $self = shift ;
557 143 100       456 return 1 if ! *$self->{Open};
558              
559 74         121 *$self->{Open} = 0 ;
560              
561             # untie *$self
562             # if $] >= 5.008 ;
563              
564 74 50       167 if (defined *$self->{SZ})
565             {
566 74         148 *$self->{SZ}{Raw} = undef ;
567 74         150 *$self->{SZ} = undef ;
568             }
569              
570 74         338 1;
571             }
572              
573             sub print
574             {
575 70     70   12732 my $self = shift;
576 70 100       187 $self->_stdPreq() or return 0 ;
577              
578 68         371 *$self->{SZ}{Zip}->print(@_);
579             }
580              
581             sub printf
582             {
583 6     6   1134 my $self = shift;
584 6 50       16 $self->_stdPreq() or return 0 ;
585              
586 6         39 *$self->{SZ}{Zip}->printf(@_);
587             }
588              
589             sub syswrite
590             {
591 6     6   1616 my $self = shift;
592 6 50       18 $self->_stdPreq() or return 0 ;
593              
594 6         26 *$self->{SZ}{Zip}->syswrite(@_);
595             }
596              
597             sub tell
598             {
599 9     9   1222 my $self = shift;
600 9 50       24 $self->_stdPreq() or return 0 ;
601              
602 9         43 *$self->{SZ}{Zip}->tell(@_);
603             }
604              
605             sub eof
606             {
607 0     0   0 my $self = shift;
608 0 0       0 $self->_stdPreq() or return 0 ;
609              
610 0         0 *$self->{SZ}{Zip}->eof;
611             }
612              
613             sub _stdPreq
614             {
615 91     91   140 my $self = shift;
616              
617             return _setError("Zip file closed")
618 91 100 66     533 if ! defined defined *$self->{SZ} || ! *$self->{SZ}{Open} ;
619              
620              
621             return _setError("openMember filehandle closed")
622 89 50 33     330 if ! *$self->{Open} || ! defined *$self->{SZ}{Raw};
623              
624             return 0
625 89 50       200 if *$self->{SZ}{Error} ;
626              
627 89         198 return 1;
628             }
629              
630             sub _setError
631             {
632 2     2   5 $Archive::Zip::SimpleZip::SimpleZipError = $_[0] ;
633 2         13 return 0;
634             }
635              
636             sub clearerr
637             {
638 0     0     my $self = shift;
639              
640 0           return 0;
641             }
642              
643 0     0     sub binmode { 1 }
644             # sub clearerr { $Archive::Zip::SimpleZip::SimpleZipError = '' }
645              
646             *FILENO = \&fileno;
647             *PRINT = \&print;
648             *PRINTF = \&printf;
649             *WRITE = \&syswrite;
650             *write = \&syswrite;
651             *TELL = \&tell;
652             *EOF = \&eof;
653             *CLOSE = \&close;
654             *BINMODE = \&binmode;
655             }
656              
657             #{
658             # package Archive::Zip::SimpleZip::HandleNEW ;
659             #
660             ## TODO - fix this
661             ## require Tie::Handle;
662             ##
663             ## @ISA = qw(Tie::Handle);
664             ##@ISA = qw(IO::Handle) ;
665             #
666             # sub TIEHANDLE
667             # {
668             # my $class = shift;
669             # my $parent = shift;
670             # my $zip = shift;
671             # my $errorRef = shift;
672             #
673             # my %obj = (
674             # Zip => $zip ,
675             # SZ => $parent,
676             # Open => 1,
677             # ) ;
678             #
679             # Scalar::Util::weaken $obj{SZ}; # for 5.8
680             # return bless \%obj, $class;
681             # }
682             #
683             # sub UNTIE
684             # {
685             # my $self = shift ;
686             # }
687             #
688             # sub DESTROY
689             # {
690             # my $self = shift ;
691             # local ($., $@, $!, $^E, $?);
692             # $self->close() ;
693             #
694             # # TODO - memory leak with 5.8.0 - this isn't called until
695             # # global destruction
696             # #
697             # %{ $self } = () ;
698             # undef $self ;
699             # }
700             #
701             # sub close
702             # {
703             # my $self = shift ;
704             # return 1 if ! $self->{Open};
705             #
706             # $self->{Open} = 0 ;
707             #
708             ## untie *$self
709             ## if $] >= 5.008 ;
710             #
711             # if (defined $self->{SZ})
712             # {
713             # $self->{SZ}{Raw} = undef ;
714             # $self->{SZ} = undef ;
715             # }
716             #
717             # 1;
718             # }
719             #
720             # sub print
721             # {
722             # my $self = shift;
723             # $self->_stdPreq() or return 0 ;
724             #
725             # $self->{Zip}->print(@_);
726             # }
727             #
728             # sub printf
729             # {
730             # my $self = shift;
731             # $self->_stdPreq() or return 0 ;
732             #
733             # $self->{Zip}->printf(@_);
734             # }
735             #
736             # sub syswrite
737             # {
738             # my $self = shift;
739             # $self->_stdPreq() or return 0 ;
740             #
741             # $self->{Zip}->syswrite(@_);
742             # }
743             #
744             # sub tell
745             # {
746             # my $self = shift;
747             # $self->_stdPreq() or return 0 ;
748             #
749             # $self->{Zip}->tell(@_);
750             # }
751             #
752             # sub eof
753             # {
754             # my $self = shift;
755             # $self->_stdPreq() or return 0 ;
756             #
757             # $self->{Zip}->eof;
758             # }
759             #
760             # sub _stdPreq
761             # {
762             # my $self = shift;
763             #
764             # return _setError("Zip file closed")
765             # if ! defined defined $self->{SZ} || ! $self->{SZ}{Open} ;
766             #
767             #
768             # return _setError("openMember filehandle closed")
769             # if ! $self->{Open} || ! defined $self->{SZ}{Raw};
770             #
771             # return 0
772             # if $self->{SZ}{Error} ;
773             #
774             # return 1;
775             # }
776             #
777             # sub _setError
778             # {
779             # $Archive::Zip::SimpleZip::SimpleZipError = $_[0] ;
780             # return 0;
781             # }
782             #
783             # sub binmode { 1 }
784             ## sub clearerr { $Archive::Zip::SimpleZip::SimpleZipError = '' }
785             #
786             # *FILENO = \&fileno;
787             # *PRINT = \&print;
788             # *PRINTF = \&printf;
789             # *WRITE = \&syswrite;
790             # *write = \&syswrite;
791             # *TELL = \&tell;
792             ## sub IO::Handle::tell { bless $_[0], "Archive::Zip::SimpleZip::Handle" ; Archive::Zip::SimpleZip::Handle::tell @_ };
793             # *EOF = \&eof;
794             # *CLOSE = \&close;
795             # *BINMODE = \&binmode;
796             #}
797              
798             1;
799              
800             __END__