File Coverage

blib/lib/CGI/Parse/PSGI/Streaming/Handle.pm
Criterion Covered Total %
statement 39 40 97.5
branch 1 2 50.0
condition n/a
subroutine 10 10 100.0
pod n/a
total 50 52 96.1


line stmt bran cond sub pod time code
1             package CGI::Parse::PSGI::Streaming::Handle;
2 3     3   23 use strict;
  3         6  
  3         90  
3 3     3   16 use warnings;
  3         5  
  3         118  
4             our $VERSION = '1.0.1'; # VERSION
5 3     3   1067 use POSIX 'SEEK_SET';
  3         13012  
  3         16  
6 3     3   2938 use parent 'Tie::Handle';
  3         7  
  3         22  
7              
8             # ABSTRACT: internal class for the tied handle
9              
10              
11             sub TIEHANDLE {
12 5     5   32 my ($class,$callback) = @_;
13              
14             # our state: the callback, a filehandle, and the buffer it writes
15             # to
16 5         21 my $self = { cb => $callback, buffer => '' };
17 2     2   18 open $self->{fh},'>',\($self->{buffer});
  2         5  
  2         17  
  5         123  
18             # make it auto-flush, otherwise we run the risk of losing bits of
19             # data in WRITE
20 5         1838 my $oldfh = select($self->{fh}); $| = 1; select($oldfh); ## no critic(ProhibitOneArgSelect,RequireLocalizedPunctuationVars)
  5         19  
  5         15  
21              
22 5         31 return bless $self, $class;
23             }
24              
25             sub BINMODE {
26 2     2   20 my ($self, $layer) = @_;
27             # this is why we have a filehandle, instead of just passing data
28             # through: emulating all the binmode combinations is a nightmare;
29             # much better to get Perl to handle the mess
30 2 50       11 if (@_==2) {
31 2     1   46 binmode $self->{fh},$layer;
  1         7  
  1         3  
  1         4  
32             }
33             else {
34 0         0 binmode $self->{fh};
35             }
36             }
37              
38             sub WRITE {
39 8     8   1002206 my ($self,$buf,$len,$offset) = @_;
40             # clear the buffer, make the fh print to the beginning of it
41 8         42 seek( $self->{fh}, 0, SEEK_SET );
42 8         21 $self->{buffer}='';
43             # print! this goes through all the PerlIO layers, so encodings&c
44             # just work
45 8         16 print {$self->{fh}} substr($buf, $offset, $len);
  8         4306  
46              
47             # invoke the callback with the data
48 8         44 $self->{cb}->($self->{buffer});
49 8         4081 return $len;
50             }
51              
52             sub CLOSE {
53 1     1   3 my ($self) = @_;
54 1         6 close $self->{fh};
55             # invoke the callback without data to signal the closing
56 1         5 $self->{cb}->();
57 1         1236 return 1;
58             }
59              
60             1;
61              
62             __END__