File Coverage

blib/lib/Email/Simple/FromHandle.pm
Criterion Covered Total %
statement 71 76 93.4
branch 13 20 65.0
condition 14 22 63.6
subroutine 17 18 94.4
pod 8 8 100.0
total 123 144 85.4


line stmt bran cond sub pod time code
1 4     4   3650 use strict;
  4         10  
  4         160  
2 4     4   25 use warnings;
  4         7  
  4         268  
3             package Email::Simple::FromHandle;
4             {
5             $Email::Simple::FromHandle::VERSION = '0.054';
6             }
7 4     4   3393 use Email::Simple 2.004;
  4         23370  
  4         270  
8 4     4   3619 use parent 'Email::Simple';
  4         1310  
  4         41  
9             # ABSTRACT: an Email::Simple but from a handle
10              
11              
12 4     4   235 use Carp ();
  4         10  
  4         65  
13 4     4   3493 use IO::String;
  4         12636  
  4         144  
14 4     4   101 use Fcntl qw(SEEK_SET);
  4         8  
  4         3593  
15              
16             my $crlf = qr/\x0a\x0d|\x0d\x0a|\x0a|\x0d/; # We are liberal in what we accept.
17              
18              
19 45     45 1 349 sub handle { $_[0]->{handle} }
20              
21              
22 31     31 1 585 sub body_pos { $_[0]->{body_pos} }
23              
24              
25             sub _is_seekable {
26 16     16   22 my ($self) = @_;
27             # on solaris, tell($pipe) == -1, and seeking on a pipe appears to discard the
28             # data waiting
29 16 50       34 return unless $self->body_pos >= 0;
30             # on linux, seeking on a pipe is safe and returns ''
31 16 100       26 return unless seek($self->handle, 0, 1);
32             # fall through: it must be seekable
33 14         67 return 1;
34             }
35              
36             sub reset_handle {
37 16     16 1 5290 my ($self) = @_;
38              
39             # Don't die the first time we try to read from a pipe/socket/etc.
40             # TODO: When reading from something non-seekable, should we
41             # give the option to store data into a temp file, or something similar?
42 16 100 100     32 return unless $self->_is_seekable || $self->{_seek}++;
43              
44 15         29 delete $self->{_get_head_lines};
45              
46 15 100       30 seek $self->handle, $self->body_pos, SEEK_SET
47             or Carp::croak "can't seek: $!";
48             }
49              
50              
51             sub getline {
52 0     0 1 0 my ($self) = @_;
53 0 0       0 unless ($self->{_get_head_lines}) {
54 0         0 $self->{_get_head_lines} = [
55             split(/(?<=\n)/, $self->header_obj->as_string),
56             $self->crlf,
57             ];
58             }
59 0         0 my $handle = $self->handle;
60 0   0     0 return shift @{$self->{_get_head_lines}} || <$handle>;
61             }
62              
63              
64             sub _stream_to_print {
65 2     2   146 my $fh = shift;
66 2 50       4 print {$fh} @_ or Carp::croak "can't print buffer: $!";
  2         27  
67             }
68              
69             sub stream_to {
70 3     3 1 35 my ($self, $fh, $arg) = @_;
71 3   100     28 $arg ||= {};
72 3 50       25 $arg->{reset_handle} = 1 unless exists $arg->{reset_handle};
73             # 65536 is a randomly-chosen magical number that's large enough to be a win
74             # over line-by-line reading but small enough not to impinge very much upon
75             # ram usage -- hdp, 2006-11-27
76 3   50     23 $arg->{chunk_size} ||= 65536;
77 3   100     35 $arg->{write} ||= \&_stream_to_print;
78 3         12 $arg->{write}->($fh, $self->header_obj->as_string . $self->crlf);
79 3 50       213 $self->reset_handle if $arg->{reset_handle};
80 3         74 my $buf;
81 3         8 while (read($self->handle, $buf, $arg->{chunk_size}) > 0) {
82 3         13 $arg->{write}->($fh, $buf);
83             }
84             }
85              
86             #### Methods that override Email::Simple below
87              
88             sub new {
89 6     6 1 4180 my ($class, $handle, $arg) = @_;
90              
91 6   50     116 $arg ||= {};
92 6   33     125 $arg->{header_class} ||= $class->default_header_class;
93              
94 6 50       101 return Email::Simple->new($handle, $arg) unless ref $handle;
95              
96 6         27 my ($head, $mycrlf) = $class->_split_head_from_body($handle);
97              
98 6         65 my $self = bless {
99             handle => $handle,
100             body_pos => tell($handle),
101             mycrlf => $mycrlf,
102             }, $class;
103              
104 6         42 $self->header_obj_set(
105             $arg->{header_class}->new($head, { crlf => $self->crlf })
106             );
107              
108 6         2306 return $self;
109             }
110              
111             sub _split_head_from_body {
112 6     6   9 my ($class, $handle) = @_;
113              
114 6         10 my $text = q{};
115              
116             # XXX it is stupid to use <> if we're really going to have multiple forms
117             # of crlf, but it is expedient to keep doing so for now. -- hdp, 2006-11-28
118             # theoretically, this should be ok, because it will only fail if lines are
119             # terminated with \x0d, which wouldn't be ok for network transport anyway.
120 6         9 my $mycrlf;
121 6         2084 while (<$handle>) {
122 123 100 100     708 last if $mycrlf and /\A$mycrlf\z/;
123 117         168 $text .= $_;
124 117         1213 ($mycrlf) = /($crlf)\z/;
125             }
126              
127 6   50     47 return ($text, $mycrlf || "\n");
128             }
129              
130             sub body_set {
131 2     2 1 456 my $self = shift;
132 2         2 my $body = shift;
133              
134 2         10 my $handle = IO::String->new(\$body);
135 2         68 $self->{handle} = $handle;
136 2         7 $self->{body_pos} = 0;
137             }
138              
139             sub body {
140 7     7 1 6085 my $self = shift;
141 7         9 scalar do {
142 7         33 local $/; ## no critic Local, Punctuation
143 7         19 $self->reset_handle;
144 6         32 my $handle = $self->handle;
145 6         126 <$handle>;
146             };
147             }
148              
149              
150             1;
151              
152             __END__