File Coverage

blib/lib/IO/All.pm
Criterion Covered Total %
statement 412 470 87.6
branch 133 182 73.0
condition 34 72 47.2
subroutine 104 120 86.6
pod 56 57 98.2
total 739 901 82.0


line stmt bran cond sub pod time code
1 58     58   1200301 use strict; use warnings;
  58     58   134  
  58         2224  
  58         262  
  58         83  
  58         4102  
2             package IO::All;
3             our $VERSION = '0.85';
4              
5             require Carp;
6             # So one can use Carp::carp "$message" - without the parenthesis.
7             sub Carp::carp;
8              
9 58     58   21586 use IO::All::Base -base;
  58         119  
  58         425  
10              
11 58     58   332 use File::Spec();
  58         78  
  58         1513  
12 58     58   28518 use Symbol();
  58         58572  
  58         1532  
13 58     58   321 use Fcntl;
  58         92  
  58         12127  
14 58     58   324 use Cwd ();
  58         117  
  58         85008  
15              
16             our @EXPORT = qw(io);
17              
18             #===============================================================================
19             # Object creation and setup methods
20             #===============================================================================
21             my $autoload = {
22             qw(
23             touch file
24              
25             dir_handle dir
26             All dir
27             all_files dir
28             All_Files dir
29             all_dirs dir
30             All_Dirs dir
31             all_links dir
32             All_Links dir
33             mkdir dir
34             mkpath dir
35             next dir
36              
37             stdin stdio
38             stdout stdio
39             stderr stdio
40              
41             socket_handle socket
42             accept socket
43             shutdown socket
44              
45             readlink link
46             symlink link
47             )
48             };
49              
50             # XXX - These should die if the given argument exists but is not a
51             # link, dbm, etc.
52 9     9 1 12 sub link {my $self = shift; require IO::All::Link; IO::All::Link::link($self, @_) }
  9         1311  
  9         27  
53 2     2 1 3 sub dbm {my $self = shift; require IO::All::DBM; IO::All::DBM::dbm($self, @_) }
  2         924  
  2         10  
54 0     0 1 0 sub mldbm {my $self = shift; require IO::All::MLDBM; IO::All::MLDBM::mldbm($self, @_) }
  0         0  
  0         0  
55              
56 579     579 0 681 sub autoload {my $self = shift; $autoload }
  579         2845  
57              
58             sub AUTOLOAD {
59 579     579   906 my $self = shift;
60 579         793 my $method = $IO::All::AUTOLOAD;
61 579         3388 $method =~ s/.*:://;
62 579   33     1676 my $pkg = ref($self) || $self;
63 579 50       1625 $self->throw(qq{Can't locate object method "$method" via package "$pkg"})
64             if $pkg ne $self->_package;
65 579         1375 my $class = $self->_autoload_class($method);
66 578         5772 my $foo = "$self";
67 578         3704 bless $self, $class;
68 578         2088 $self->$method(@_);
69             }
70              
71             sub _autoload_class {
72 579     579   676 my $self = shift;
73 579         702 my $method = shift;
74 579   66     1248 my $class_id = $self->autoload->{$method} || $method;
75 579         1400 my $ucfirst_class_name = 'IO::All::' . ucfirst($class_id);
76 579         1064 my $ucfirst_class_fn = "IO/All/" . ucfirst($class_id) . ".pm";
77 579 100       2276 return $ucfirst_class_name if $INC{$ucfirst_class_fn};
78 65 100       426 return "IO::All::\U$class_id" if $INC{"IO/All/\U$class_id\E.pm"};
79 60         27684 require IO::All::Temp;
80 60 100       3531 if (eval "require $ucfirst_class_name; 1") {
    100          
81 58         131 my $class = $ucfirst_class_name;
82             my $return = $class->can('new')
83             ? $class
84 58 50       972 : do { # (OS X hack)
85 0         0 my $value = $INC{$ucfirst_class_fn};
86 0         0 delete $INC{$ucfirst_class_fn};
87 0         0 $INC{"IO/All/\U$class_id\E.pm"} = $value;
88 0         0 "IO::All::\U$class_id";
89             };
90 58         247 return $return;
91             }
92             elsif (eval "require IO::All::\U$class_id; 1") {
93 1         5 return "IO::All::\U$class_id";
94             }
95 1         9 $self->throw("Can't find a class for method '$method'");
96             }
97              
98             sub new {
99 644     644 1 901 my $self = shift;
100 644   66     2881 my $package = ref($self) || $self;
101 644         1681 my $new = bless Symbol::gensym(), $package;
102 644         9239 $new->_package($package);
103 644 100       1355 $new->_copy_from($self) if ref($self);
104 644         890 my $name = shift;
105 644 100       2891 return $name if UNIVERSAL::isa($name, 'IO::All');
106 641 100       1694 return $new->_init unless defined $name;
107 507 50 33     3309 return $new->handle($name)
108             if UNIVERSAL::isa($name, 'GLOB') or ref(\ $name) eq 'GLOB';
109             # WWW - link is first because a link to a dir returns true for
110             # both -l and -d.
111 507 100       8543 return $new->link($name) if -l $name;
112 498 100       5379 return $new->file($name) if -f $name;
113 226 100       2358 return $new->dir($name) if -d $name;
114 55 50       232 return $new->$1($name) if $name =~ /^([a-z]{3,8}):/;
115 55 100       331 return $new->socket($name) if $name =~ /^[\w\-\.]*:\d{1,5}$/;
116 53 100 66     386 return $new->pipe($name)
117             if $name =~ s/^\s*\|\s*// or $name =~ s/\s*\|\s*$//;
118 51 100       141 return $new->string if $name eq '$';
119 50 100       142 return $new->stdio if $name eq '-';
120 48 100       182 return $new->stderr if $name eq '=';
121 47 100       132 return $new->temp if $name eq '?';
122 46         168 $new->name($name);
123 46         249 $new->_init;
124             }
125              
126             sub _copy_from {
127 1     1   2 my $self = shift;
128 1         2 my $other = shift;
129 1         2 for (keys(%{*$other})) {
  1         4  
130             # XXX Need to audit exclusions here
131 5 100       19 next if /^(_handle|io_handle|is_open)$/;
132 3         6 *$self->{$_} = *$other->{$_};
133             }
134             }
135              
136             sub handle {
137 0     0 1 0 my $self = shift;
138 0 0       0 $self->_handle(shift) if @_;
139 0         0 return $self->_init;
140             }
141              
142             #===============================================================================
143             # Overloading support
144             #===============================================================================
145             my $old_warn_handler = $SIG{__WARN__};
146             $SIG{__WARN__} = sub {
147             if ($_[0] !~ /^Useless use of .+ \(.+\) in void context/) {
148             goto &$old_warn_handler if $old_warn_handler;
149             warn(@_);
150             }
151             };
152              
153 58     58   61962 use overload '""' => '_overload_stringify';
  58         47720  
  58         389  
154 58     58   3661 use overload '|' => '_overload_bitwise_or';
  58         95  
  58         189  
155 58     58   2928 use overload '<<' => '_overload_left_bitshift';
  58         91  
  58         183  
156 58     58   2590 use overload '>>' => '_overload_right_bitshift';
  58         82  
  58         192  
157 58     58   2773 use overload '<' => '_overload_less_than';
  58         90  
  58         189  
158 58     58   2804 use overload '>' => '_overload_greater_than';
  58         541  
  58         342  
159 58     58   2917 use overload '${}' => '_overload_string_deref';
  58         1166  
  58         214  
160 58     58   2969 use overload '@{}' => '_overload_array_deref';
  58         80  
  58         164  
161 58     58   2696 use overload '%{}' => '_overload_hash_deref';
  58         87  
  58         179  
162 58     58   2613 use overload '&{}' => '_overload_code_deref';
  58         116  
  58         205  
163              
164 0     0   0 sub _overload_bitwise_or {my $self = shift; $self->_overload_handler(@_, '|') }
  0         0  
165 6     6   14 sub _overload_left_bitshift {my $self = shift; $self->_overload_handler(@_, '<<') }
  6         23  
166 4     4   71 sub _overload_right_bitshift {my $self = shift; $self->_overload_handler(@_, '>>') }
  4         12  
167 11     11   19 sub _overload_less_than {my $self = shift; $self->_overload_handler(@_, '<') }
  11         48  
168 17     17   261 sub _overload_greater_than {my $self = shift; $self->_overload_handler(@_, '>') }
  17         66  
169 11     11   2869 sub _overload_string_deref {my $self = shift; $self->_overload_handler(@_, '${}') }
  11         51  
170 7     7   16532 sub _overload_array_deref {my $self = shift; $self->_overload_handler(@_, '@{}') }
  7         41  
171 7     7   23 sub _overload_hash_deref {my $self = shift; $self->_overload_handler(@_, '%{}') }
  7         25  
172 0     0   0 sub _overload_code_deref {my $self = shift; $self->_overload_handler(@_, '&{}') }
  0         0  
173              
174             sub _overload_handler {
175 63     63   94 my ($self) = @_;
176 63         181 my $method = $self->_get_overload_method(@_);
177 63         316 $self->$method(@_);
178             }
179              
180             my $op_swap = {
181             '>' => '<', '>>' => '<<',
182             '<' => '>', '<<' => '>>',
183             };
184              
185             sub _overload_table {
186 65     65   75 my $self = shift;
187             (
188 65         777 '* > *' => '_overload_any_to_any',
189             '* < *' => '_overload_any_from_any',
190             '* >> *' => '_overload_any_addto_any',
191             '* << *' => '_overload_any_addfrom_any',
192              
193             '* < scalar' => '_overload_scalar_to_any',
194             '* > scalar' => '_overload_any_to_scalar',
195             '* << scalar' => '_overload_scalar_addto_any',
196             '* >> scalar' => '_overload_any_addto_scalar',
197             )
198             };
199              
200             sub _get_overload_method {
201 63     63   125 my ($self, $arg1, $arg2, $swap, $operator) = @_;
202 63 100       154 if ($swap) {
203 22   33     80 $operator = $op_swap->{$operator} || $operator;
204             }
205 63         166 my $arg1_type = $self->_get_argument_type($arg1);
206 63         164 my $table1 = { $arg1->_overload_table };
207              
208 63 100       287 if ($operator =~ /\{\}$/) {
209 25         58 my $key = "$operator $arg1_type";
210 25   33     145 return $table1->{$key} || $self->_overload_undefined($key);
211             }
212              
213 38         99 my $arg2_type = $self->_get_argument_type($arg2);
214 38 100       219 my @table2 = UNIVERSAL::isa($arg2, "IO::All")
215             ? ($arg2->_overload_table)
216             : ();
217 38         242 my $table = { %$table1, @table2 };
218              
219 38         140 my @keys = (
220             "$arg1_type $operator $arg2_type",
221             "* $operator $arg2_type",
222             );
223 38 100       204 push @keys, "$arg1_type $operator *", "* $operator *"
224             unless $arg2_type =~ /^(scalar|array|hash|code|ref)$/;
225              
226 38         63 for (@keys) {
227 76 100       378 return $table->{$_}
228             if defined $table->{$_};
229             }
230              
231 0         0 return $self->_overload_undefined($keys[0]);
232             }
233              
234             sub _get_argument_type {
235 101     101   116 my $self = shift;
236 101         97 my $argument = shift;
237 101         135 my $ref = ref($argument);
238 101 100       191 return 'scalar' unless $ref;
239 69 50       147 return 'code' if $ref eq 'CODE';
240 69 50       119 return 'array' if $ref eq 'ARRAY';
241 69 50       139 return 'hash' if $ref eq 'HASH';
242 69 50       463 return 'ref' unless $argument->isa('IO::All');
243 69 100 66     205 $argument->file
244             if defined $argument->pathname and not $argument->type;
245 69   50     142 return $argument->type || 'unknown';
246             }
247              
248             sub _overload_stringify {
249 1669     1669   4801 my $self = shift;
250 1669         3441 my $name = $self->pathname;
251 1669 100       6277 return defined($name) ? $name : overload::StrVal($self);
252             }
253              
254             sub _overload_undefined {
255 0     0   0 my $self = shift;
256 0         0 require Carp;
257 0         0 my $key = shift;
258 0 0       0 Carp::carp "Undefined behavior for overloaded IO::All operation: '$key'"
259             if $^W;
260 0         0 return '_overload_noop';
261             }
262              
263             sub _overload_noop {
264 0     0   0 my $self = shift;
265 0         0 return;
266             }
267              
268             sub _overload_any_addfrom_any {
269 1     1   5 $_[1]->append($_[2]->all);
270 1         3 $_[1];
271             }
272              
273             sub _overload_any_addto_any {
274 1     1   4 $_[2]->append($_[1]->all);
275 1         3 $_[2];
276             }
277              
278             sub _overload_any_from_any {
279 0 0 0 0   0 $_[1]->close if $_[1]->is_file and $_[1]->is_open;
280 0         0 $_[1]->print($_[2]->all);
281 0         0 $_[1];
282             }
283              
284             sub _overload_any_to_any {
285 0 0 0 0   0 $_[2]->close if $_[2]->is_file and $_[2]->is_open;
286 0         0 $_[2]->print($_[1]->all);
287 0         0 $_[2];
288             }
289              
290             sub _overload_any_to_scalar {
291 10     10   39 $_[2] = $_[1]->all;
292             }
293              
294             sub _overload_any_addto_scalar {
295 6     6   21 $_[2] .= $_[1]->all;
296 6         28 $_[2];
297             }
298              
299             sub _overload_scalar_addto_any {
300 2     2   13 $_[1]->append($_[2]);
301 2         6 $_[1];
302             }
303              
304             sub _overload_scalar_to_any {
305 14     14   41 local $\;
306 14 50 33     63 $_[1]->close if $_[1]->is_file and $_[1]->is_open;
307 14         73 $_[1]->print($_[2]);
308 14         58 $_[1];
309             }
310              
311             #===============================================================================
312             # Private Accessors
313             #===============================================================================
314             field '_package';
315             field _strict => undef;
316             field _layers => [];
317             field _handle => undef;
318             field _constructor => undef;
319             field _partial_spec_class => undef;
320              
321             #===============================================================================
322             # Public Accessors
323             #===============================================================================
324             chain block_size => 1024;
325             chain errors => undef;
326             field io_handle => undef;
327             field is_open => 0;
328             chain mode => undef;
329             chain name => undef;
330             chain perms => undef;
331             chain separator => $/;
332             field type => '';
333              
334             sub _spec_class {
335 114     114   152 my $self = shift;
336              
337 114         135 my $ret = 'File::Spec';
338 114 100       475 if (my $partial = $self->_partial_spec_class(@_)) {
339 62         193 $ret .= '::' . $partial;
340 62         4602 eval "require $ret";
341             }
342              
343 114         3613 return $ret
344             }
345              
346 622     622 1 702 sub pathname {my $self = shift; $self->name(@_) }
  622         1762  
347              
348             #===============================================================================
349             # Chainable option methods (write only)
350             #===============================================================================
351             option 'assert';
352             option 'autoclose' => 1;
353             option 'backwards';
354             option 'chomp';
355             option 'confess';
356             option 'lock';
357             option 'rdonly';
358             option 'rdwr';
359             option 'strict';
360              
361             #===============================================================================
362             # IO::Handle proxy methods
363             #===============================================================================
364             proxy 'autoflush';
365             proxy 'eof';
366             proxy 'fileno';
367             proxy 'stat';
368             proxy 'tell';
369             proxy 'truncate';
370              
371             #===============================================================================
372             # IO::Handle proxy methods that open the handle if needed
373             #===============================================================================
374             proxy_open print => '>';
375             proxy_open printf => '>';
376             proxy_open sysread => O_RDONLY;
377             proxy_open syswrite => O_CREAT | O_WRONLY;
378             proxy_open seek => $^O eq 'MSWin32' ? '<' : '+<';
379             proxy_open 'getc';
380              
381             #===============================================================================
382             # Tie Interface
383             #===============================================================================
384             sub tie {
385 5     5 1 17 my $self = shift;
386 5         49 tie *$self, $self;
387 5         13 return $self;
388             }
389              
390             sub TIEHANDLE {
391 5 50   5   23 return $_[0] if ref $_[0];
392 0         0 my $class = shift;
393 0         0 my $self = bless Symbol::gensym(), $class;
394 0         0 $self->init(@_);
395             }
396              
397             sub READLINE {
398 12 100   12   3548 goto &getlines if wantarray;
399 10         32 goto &getline;
400             }
401              
402             sub DESTROY {
403 412     412   942302 my $self = shift;
404 58     58   90116 no warnings;
  58         117  
  58         6624  
405 412 50       1181 unless ( $] < 5.008 ) {
406 412 100       1777 untie *$self if tied *$self;
407             }
408 412 100       1065 $self->close if $self->is_open;
409             }
410              
411             sub BINMODE {
412 0     0   0 my $self = shift;
413 0         0 CORE::binmode *$self->io_handle;
414             }
415              
416             {
417 58     58   291 no warnings;
  58         88  
  58         112554  
418             *GETC = \&getc;
419             *PRINT = \&print;
420             *PRINTF = \&printf;
421             *READ = \&read;
422             *WRITE = \&write;
423             *SEEK = \&seek;
424             *TELL = \&getpos;
425             *EOF = \&eof;
426             *CLOSE = \&close;
427             *FILENO = \&fileno;
428             }
429              
430             #===============================================================================
431             # File::Spec Interface
432             #===============================================================================
433 2     2 1 5 sub canonpath {my $self = shift;
434 2 50       4 eval { Cwd::abs_path($self->pathname); 0 } ||
  2         13  
  2         20  
435             File::Spec->canonpath($self->pathname)
436             }
437              
438             sub catdir {
439 4     4 1 5 my $self = shift;
440 4         11 my @args = grep defined, $self->name, @_;
441 4         7 $self->_constructor->()->dir(File::Spec->catdir(@args));
442             }
443             sub catfile {
444 9     9 1 428 my $self = shift;
445 9         25 my @args = grep defined, $self->name, @_;
446 9         28 $self->_constructor->()->file(File::Spec->catfile(@args));
447             }
448 1     1 1 1 sub join {my $self = shift; $self->catfile(@_) }
  1         3  
449             sub curdir {
450 2     2 1 5 my $self = shift;
451 2         10 $self->_constructor->()->dir(File::Spec->curdir);
452             }
453             sub devnull {
454 4     4 1 7 my $self = shift;
455 4         10 $self->_constructor->()->file(File::Spec->devnull);
456             }
457             sub rootdir {
458 1     1 1 2 my $self = shift;
459 1         3 $self->_constructor->()->dir(File::Spec->rootdir);
460             }
461             sub tmpdir {
462 1     1 1 2 my $self = shift;
463 1         3 $self->_constructor->()->dir(File::Spec->tmpdir);
464             }
465             sub updir {
466 1     1 1 2 my $self = shift;
467 1         3 $self->_constructor->()->dir(File::Spec->updir);
468             }
469             sub case_tolerant {
470 1     1 1 2 my $self = shift;
471 1         12 File::Spec->case_tolerant;
472             }
473             sub is_absolute {
474 165     165 1 173 my $self = shift;
475 165         384 File::Spec->file_name_is_absolute($self->pathname);
476             }
477             sub path {
478 1     1 1 2 my $self = shift;
479 1         27 map { $self->_constructor->()->dir($_) } File::Spec->path;
  36         63  
480             }
481             sub splitpath {
482 14     14 1 19 my $self = shift;
483 14         42 File::Spec->splitpath($self->pathname);
484             }
485             sub splitdir {
486 2     2 1 2 my $self = shift;
487 2         6 File::Spec->splitdir($self->pathname);
488             }
489             sub catpath {
490 1     1 1 2 my $self = shift;
491 1         15 $self->_constructor->(File::Spec->catpath(@_));
492             }
493             sub abs2rel {
494 1     1 1 1 my $self = shift;
495 1         4 File::Spec->abs2rel($self->pathname, @_);
496             }
497             sub rel2abs {
498 1     1 1 2 my $self = shift;
499 1         2 File::Spec->rel2abs($self->pathname, @_);
500             }
501              
502             #===============================================================================
503             # Public IO Action Methods
504             #===============================================================================
505             sub absolute {
506 21     21 1 42 my $self = shift;
507 21 100       75 $self->pathname(File::Spec->rel2abs($self->pathname))
508             unless $self->is_absolute;
509 21         46 $self->is_absolute(1);
510 21         43 return $self;
511             }
512              
513             sub all {
514 59     59 1 70 my $self = shift;
515 59         261 $self->_assert_open('<');
516 58         207 local $/;
517 58         155 my $all = $self->io_handle->getline;
518 58         4460 $self->_error_check;
519 58 100       208 $self->_autoclose && $self->close;
520 58         324 return $all;
521             }
522              
523             sub append {
524 6     6 1 15 my $self = shift;
525 6         17 $self->_assert_open('>>');
526 6         18 $self->print(@_);
527             }
528              
529             sub appendln {
530 0     0 1 0 my $self = shift;
531 0         0 $self->_assert_open('>>');
532 0         0 $self->println(@_);
533             }
534              
535             sub binary {
536 9     9 1 11 my $self = shift;
537 9 100       19 CORE::binmode($self->io_handle) if $self->is_open;
538 9         12 push @{$self->_layers}, ":raw";
  9         26  
539 9         47 return $self;
540             }
541              
542             sub binmode {
543 5     5 1 6 my $self = shift;
544 5         6 my $layer = shift;
545 5 100       8 $self->_sane_binmode($layer) if $self->is_open;
546 5         5 push @{$self->_layers}, $layer;
  5         8  
547 5         15 return $self;
548             }
549              
550             sub _sane_binmode {
551 22     22   10185 my ($self, $layer) = @_;
552 22 100   2   67 $layer
  2         10  
  2         3  
  2         16  
553             ? CORE::binmode($self->io_handle, $layer)
554             : CORE::binmode($self->io_handle);
555             }
556              
557             sub buffer {
558 139     139 1 449 my $self = shift;
559 139 100       178 if (not @_) {
560 136 50       192 *$self->{buffer} = do {my $x = ''; \ $x}
  0         0  
  0         0  
561             unless exists *$self->{buffer};
562 136         281 return *$self->{buffer};
563             }
564 3 50       8 my $buffer_ref = ref($_[0]) ? $_[0] : \ $_[0];
565 3 100       7 $$buffer_ref = '' unless defined $$buffer_ref;
566 3         5 *$self->{buffer} = $buffer_ref;
567 3         5 return $self;
568             }
569              
570             sub clear {
571 22     22 1 15 my $self = shift;
572 22         22 my $buffer = *$self->{buffer};
573 22         16 $$buffer = '';
574 22         19 return $self;
575             }
576              
577             sub close {
578 157     157 1 247 my $self = shift;
579 157 50       369 return unless $self->is_open;
580 157         329 $self->is_open(0);
581 157         375 my $io_handle = $self->io_handle;
582 157         346 $self->io_handle(undef);
583 157         405 $self->mode(undef);
584 157 50       651 $io_handle->close(@_)
585             if defined $io_handle;
586 157         3225 return $self;
587             }
588              
589             sub empty {
590 1     1 1 2 my $self = shift;
591 1         108 my $message =
592             "Can't call empty on an object that is neither file nor directory";
593 1         13 $self->throw($message);
594             }
595              
596 0     0 1 0 sub exists {my $self = shift; -e $self->pathname }
  0         0  
597              
598             sub getline {
599 46     46 1 2865 my $self = shift;
600 46 100       134 return $self->getline_backwards
601             if $self->_backwards;
602 42         131 $self->_assert_open('<');
603 42         42 my $line;
604             {
605 42 50       43 local $/ = @_ ? shift(@_) : $self->separator;
  42         161  
606 42         113 $line = $self->io_handle->getline;
607 42 100 66     1352 chomp($line) if $self->_chomp and defined $line;
608             }
609 42         102 $self->_error_check;
610 42 100       176 return $line if defined $line;
611 4 100       25 $self->close if $self->_autoclose;
612 4         10 return undef;
613             }
614              
615             sub getlines {
616 6     6 1 341 my $self = shift;
617 6 100       41 return $self->getlines_backwards
618             if $self->_backwards;
619 5         21 $self->_assert_open('<');
620 5         7 my @lines;
621             {
622 5 100       8 local $/ = @_ ? shift(@_) : $self->separator;
  5         34  
623 5         19 @lines = $self->io_handle->getlines;
624 5 100       331 if ($self->_chomp) {
625 1         7 chomp for @lines;
626             }
627             }
628 5         19 $self->_error_check;
629 5 50       65 return @lines if @lines;
630 0 0       0 $self->close if $self->_autoclose;
631 0         0 return ();
632             }
633              
634 326     326 1 436 sub is_dir {my $self = shift; UNIVERSAL::isa($self, 'IO::All::Dir') }
  326         2892  
635 0     0 1 0 sub is_dbm {my $self = shift; UNIVERSAL::isa($self, 'IO::All::DBM') }
  0         0  
636 131     131 1 158 sub is_file {my $self = shift; UNIVERSAL::isa($self, 'IO::All::File') }
  131         597  
637 4     4 1 24 sub is_link {my $self = shift; UNIVERSAL::isa($self, 'IO::All::Link') }
  4         36  
638 0     0 1 0 sub is_mldbm {my $self = shift; UNIVERSAL::isa($self, 'IO::All::MLDBM') }
  0         0  
639 2     2 1 10 sub is_socket {my $self = shift; UNIVERSAL::isa($self, 'IO::All::Socket') }
  2         13  
640 0     0 1 0 sub is_stdio {my $self = shift; UNIVERSAL::isa($self, 'IO::All::STDIO') }
  0         0  
641 0     0 1 0 sub is_string {my $self = shift; UNIVERSAL::isa($self, 'IO::All::String') }
  0         0  
642 0     0 1 0 sub is_temp {my $self = shift; UNIVERSAL::isa($self, 'IO::All::Temp') }
  0         0  
643              
644             sub length {
645 68     68 1 48 my $self = shift;
646 68         38 length(${$self->buffer});
  68         67  
647             }
648              
649             sub open {
650 3     3 1 3 my $self = shift;
651 3 50       14 return $self if $self->is_open;
652 3         8 $self->is_open(1);
653 3         6 my ($mode, $perms) = @_;
654 3 50       12 $self->mode($mode) if defined $mode;
655 3 50       7 $self->mode('<') unless defined $self->mode;
656 3 50       7 $self->perms($perms) if defined $perms;
657 3         5 my @args;
658 3 50       9 unless ($self->is_dir) {
659 3         6 push @args, $self->mode;
660 3 50       10 push @args, $self->perms if defined $self->perms;
661             }
662 3 50 33     8 if (defined $self->pathname and not $self->type) {
    0 0        
663 3         26 $self->file;
664 3         8 return $self->open(@args);
665             }
666             elsif (defined $self->_handle and
667             not $self->io_handle->opened
668             ) {
669             # XXX Not tested
670 0         0 $self->io_handle->fdopen($self->_handle, @args);
671             }
672 0         0 $self->_set_binmode;
673             }
674              
675             sub println {
676 7     7 1 1001161 my $self = shift;
677 7 50       25 $self->print(map {/\n\z/ ? ($_) : ($_, "\n")} @_);
  22         115  
678             }
679              
680             sub read {
681 46     46 1 368 my $self = shift;
682 46         80 $self->_assert_open('<');
683 46         53 my $length = (@_ or $self->type eq 'dir')
684             ? $self->io_handle->read(@_)
685             : $self->io_handle->read(
686 46 50 33     107 ${$self->buffer},
687             $self->block_size,
688             $self->length,
689             );
690 46         378 $self->_error_check;
691 46   66     106 return $length || $self->_autoclose && $self->close && 0;
692             }
693              
694             {
695 58     58   409 no warnings;
  58         105  
  58         42111  
696             *readline = \&getline;
697             }
698              
699             # deprecated
700             sub scalar {
701 18     18 1 359 my $self = shift;
702 18         71 $self->all(@_);
703             }
704              
705             sub slurp {
706 11     11 1 554 my $self = shift;
707 11         66 my $slurp = $self->all;
708 10 100       47 return $slurp unless wantarray;
709 4         21 my $separator = $self->separator;
710 4 100       25 if ($self->_chomp) {
711 1         3 local $/ = $separator;
712 1         39 map {chomp; $_} split /(?<=\Q$separator\E)/, $slurp;
  17         13  
  17         18  
713             }
714             else {
715 3         184 split /(?<=\Q$separator\E)/, $slurp;
716             }
717             }
718              
719             sub utf8 {
720 9     9 1 19 my $self = shift;
721 9 50       26 if ($] < 5.008) {
722 0         0 die "IO::All -utf8 not supported on Perl older than 5.8";
723             }
724 9         27 $self->encoding('UTF-8');
725 9         26 return $self;
726             }
727              
728             sub _has_utf8 {
729 7     7   16 grep { $_ eq ':encoding(UTF-8)' } @{shift->_layers}
  4         20  
  7         35  
730             }
731              
732             sub encoding {
733 17     17 1 21 my $self = shift;
734 17         21 my $encoding = shift;
735 17 50       37 if ($] < 5.008) {
736 0         0 die "IO::All -encoding not supported on Perl older than 5.8";
737             }
738 17 50       31 die "No valid encoding string sent" if !$encoding;
739 17 100 66     32 $self->_set_encoding($encoding) if $self->is_open and $encoding;
740 17         84 push @{$self->_layers}, ":encoding($encoding)";
  17         38  
741 17         34 return $self;
742             }
743              
744             sub _set_encoding {
745 2     2   3 my ($self, $encoding) = @_;
746 2         5 return CORE::binmode($self->io_handle, ":encoding($encoding)");
747             }
748              
749             sub write {
750 22     22 1 57 my $self = shift;
751 22         36 $self->_assert_open('>');
752 22         25 my $length = @_
753             ? $self->io_handle->write(@_)
754 22 50       42 : $self->io_handle->write(${$self->buffer}, $self->length);
755 22         270 $self->_error_check;
756 22 50       43 $self->clear unless @_;
757 22         27 return $length;
758             }
759              
760             #===============================================================================
761             # Implementation methods. Subclassable.
762             #===============================================================================
763             sub throw {
764 4     4 1 8 my $self = shift;
765 4         29 require Carp;
766             ;
767 4 50       23 return &{$self->errors}(@_)
  0         0  
768             if $self->errors;
769 4 50       28 return Carp::confess(@_)
770             if $self->_confess;
771 4         882 return Carp::croak(@_);
772             }
773              
774             #===============================================================================
775             # Private instance methods
776             #===============================================================================
777             sub _assert_dirpath {
778 4     4   4 my $self = shift;
779 4         8 my $dir_name = shift;
780             return $dir_name if ((! CORE::length($dir_name)) or
781             -d $dir_name or
782             CORE::mkdir($dir_name, $self->perms || 0755) or
783 4 50 100     85 do {
      50        
      100        
      66        
      33        
784 1         6 require File::Path;
785 1   50     3 File::Path::mkpath($dir_name, 0, $self->perms || 0755 );
786             } or
787             $self->throw("Can't make $dir_name"));
788             }
789              
790             sub _assert_open {
791 10     10   13 my $self = shift;
792 10 100       28 return if $self->is_open;
793 7 100       31 $self->file unless $self->type;
794 7         59 return $self->open(@_);
795             }
796              
797             sub _error_check {
798 242     242   286 my $self = shift;
799 242 50       480 return unless $self->io_handle->can('error');
800 242 50       498 return unless $self->io_handle->error;
801 0         0 $self->throw($!);
802             }
803              
804             sub _set_binmode {
805 123     123   167 my $self = shift;
806 123         136 $self->_sane_binmode($_) for @{$self->_layers};
  123         497  
807 123         12559 return $self;
808             }
809              
810             #===============================================================================
811             # Stat Methods
812             #===============================================================================
813             BEGIN {
814 58     58   360 no strict 'refs';
  58         92  
  58         6286  
815 58     58   264 my @stat_fields = qw(
816             device inode modes nlink uid gid device_id size atime mtime
817             ctime blksize blocks
818             );
819 58         223 foreach my $stat_field_idx (0 .. $#stat_fields)
820             {
821 754         666 my $idx = $stat_field_idx;
822 754         690 my $name = $stat_fields[$idx];
823              
824             *$name = sub {
825 13     13   340 my $self = shift;
826 13   33     30 return (stat($self->io_handle || $self->pathname))[$idx];
827 754         6963 };
828             }
829             }
830