File Coverage

lib/IOMux/Handler/Read.pm
Criterion Covered Total %
statement 67 78 85.9
branch 14 26 53.8
condition 2 8 25.0
subroutine 17 18 94.4
pod 7 8 87.5
total 107 138 77.5


line stmt bran cond sub pod time code
1             # Copyrights 2011-2020 by [Mark Overmeer ].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5             # This code is part of distribution IOMux. Meta-POD processed with OODoc
6             # into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package IOMux::Handler::Read;
10 7     7   930 use vars '$VERSION';
  7         11  
  7         308  
11             $VERSION = '1.01';
12              
13 7     7   32 use base 'IOMux::Handler';
  7         11  
  7         1582  
14              
15 7     7   42 use warnings;
  7         10  
  7         208  
16 7     7   30 use strict;
  7         13  
  7         192  
17              
18 7     7   29 use Log::Report 'iomux';
  7         11  
  7         57  
19 7     7   2209 use Fcntl;
  7         10  
  7         1763  
20 7     7   50 use POSIX 'errno_h';
  7         28  
  7         74  
21 7     7   2697 use File::Basename 'basename';
  7         12  
  7         5473  
22              
23              
24             sub init($)
25 8     8 0 20 { my ($self, $args) = @_;
26 8         74 $self->SUPER::init($args);
27 8   100     53 $self->{IMHR_read_size} = $args->{read_size} || 32768;
28 8         27 $self->{IMHR_inbuf} = '';
29 8         17 $self;
30             }
31              
32             #-------------------
33              
34             sub readSize(;$)
35 0     0 1 0 { my $self = shift;
36 0 0       0 @_ ? $self->{IMHR_read_size} = shift : $self->{IMHR_read_size};
37             }
38              
39             #-----------------------
40              
41             sub readline($)
42 8     8 1 3808 { my ($self, $cb) = @_;
43 8 100       47 if($self->{IMHR_inbuf} =~ s/^([^\r\n]*)(?:\r?\n)//)
44 4         19 { return $cb->($self, "$1\n");
45             }
46 4 50       9 if($self->{IMHR_eof})
47             { # eof already before readline and no trailing nl
48 0         0 my $line = $self->{IMHR_inbuf};
49 0         0 $self->{IMHR_inbuf} = '';
50 0         0 return $cb->($self, $line);
51             }
52              
53             $self->{IMHR_read_more} = sub
54 4     4   6 { my ($in, $eof) = @_;
55 4 100       10 if($eof)
56 2         4 { delete $self->{IMHR_read_more};
57 2         5 my $line = $self->{IMHR_inbuf};
58 2         3 $self->{IMHR_inbuf} = '';
59 2         7 return $cb->($self, $line);
60             }
61 2 50       4 ${$_[0]} =~ s/^([^\r\n]*)\r?\n//
  2         19  
62             or return;
63 2         5 delete $self->{IMHR_read_more};
64 2         11 $cb->($self, "$1\n");
65 4         67 };
66             }
67              
68              
69             sub slurp($)
70 4     4 1 985 { my ($self, $cb) = @_;
71              
72 4 50       20 if($self->{IMHR_eof}) # eof already before readline
73 0 0       0 { my $in = $self->{IMHR_inbuf} or return $cb->($self, \'');
74 0         0 my $bytes = $$in; # does copy the bytes. Cannot help it easily
75 0         0 $$in = '';
76 0         0 return $cb->($self, \$bytes);
77             }
78              
79             $self->{IMHR_read_more} = sub
80 8     8   17 { my ($in, $eof) = @_;
81 8 100       30 $eof or return;
82 4         9 delete $self->{IMHR_read_more};
83 4         9 my $bytes = $$in; # does copy the bytes
84 4         6 $$in = '';
85 4         21 $cb->($self, \$bytes);
86 4         175 };
87             }
88              
89             #-------------------------
90              
91             sub muxInit($)
92 6     6 1 48 { my ($self, $mux) = @_;
93 6         72 $self->SUPER::muxInit($mux);
94 6         227 $self->fdset(1, 1, 0, 0);
95             }
96              
97             sub muxReadFlagged($)
98 12     12 1 22 { my $self = shift;
99              
100             my $bytes_read
101             = sysread $self->fh, $self->{IMHR_inbuf}, $self->{IMHR_read_size}
102 12         40 , length($self->{IMHR_inbuf});
103              
104 12 100 0     69 if($bytes_read) # > 0
    50 0        
    0          
105 6         54 { $self->muxInput(\$self->{IMHR_inbuf});
106             }
107             elsif(defined $bytes_read) # == 0
108 6         24 { $self->fdset(0, 1, 0, 0);
109 6         154 $self->muxEOF(\$self->{IMHR_inbuf});
110             }
111             elsif($!==EINTR || $!==EAGAIN || $!==EWOULDBLOCK)
112             { # a bit unexpected, but ok
113             }
114             else
115 0         0 { warning __x"read from {name} closed unexpectedly: {err}"
116             , name => $self->name, err => $!;
117 0         0 $self->close;
118             }
119             }
120              
121              
122             sub muxInput($)
123 6     6 1 17 { my ($self, $inbuf) = @_;
124             return $self->{IMHR_read_more}->($inbuf, 0)
125 6 50       86 if $self->{IMHR_read_more};
126             }
127              
128              
129             sub muxEOF($)
130 6     6 1 15 { my ($self, $inbuf) = @_;
131 6         23 $self->{IMHR_eof} = 1;
132             $self->{IMHR_read_more}->($inbuf, 1)
133 6 50       29 if $self->{IMHR_read_more};
134             }
135              
136             1;