| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package IO::Framed; |
|
2
|
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
71009
|
use strict; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
83
|
|
|
4
|
3
|
|
|
3
|
|
20
|
use warnings; |
|
|
3
|
|
|
|
|
11
|
|
|
|
3
|
|
|
|
|
274
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.12-TRIAL2'; |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=encoding utf-8 |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 NAME |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
IO::Framed - Convenience wrapper for frame-based I/O |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
Reading: |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
#See below about seed bytes. |
|
19
|
|
|
|
|
|
|
my $iof = IO::Framed->new( $fh, 'seed bytes' ); |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
#This returns undef if the $in_fh doesn’t have at least |
|
22
|
|
|
|
|
|
|
#the given length (5 in this case) of bytes to read. |
|
23
|
|
|
|
|
|
|
$frame = $iof->read(5); |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
#Don’t call this after an incomplete read(). |
|
26
|
|
|
|
|
|
|
$line_or_undef = $iof->read_until("\x0a"); |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Writing, unqueued (i.e., for blocking writes): |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
#The second parameter (if given) is executed immediately after the final |
|
31
|
|
|
|
|
|
|
#byte of the payload is written. For blocking I/O this happens |
|
32
|
|
|
|
|
|
|
#before the following method returns. |
|
33
|
|
|
|
|
|
|
$iof->write('hoohoo', sub { print 'sent!' } ); |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Writing, queued (for non-blocking writes): |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
$iof->enable_write_queue(); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
#This just adds to a memory queue: |
|
40
|
|
|
|
|
|
|
$iof->write('hoohoo', sub { print 'sent!' } ); |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
#This will be 1, since we have 1 message/frame queued to send. |
|
43
|
|
|
|
|
|
|
$iof->get_write_queue_count(); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
#Returns 1 if it empties out the queue; 0 otherwise. |
|
46
|
|
|
|
|
|
|
#Partial frame writes are accommodated; the callback given as 2nd |
|
47
|
|
|
|
|
|
|
#argument to write() only fires when the queue item is sent completely. |
|
48
|
|
|
|
|
|
|
my $empty = $iof->flush_write_queue(); |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
You can also use C and C, which |
|
51
|
|
|
|
|
|
|
contain just the read and write features. (C is actually a |
|
52
|
|
|
|
|
|
|
subclass of them both.) |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
While writing L I noticed that I was reimplementing some of the |
|
57
|
|
|
|
|
|
|
same patterns I’d used in L to parse frames from a stream: |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=over |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item * Only read() entire frames, with a read queue for any partials. |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=item * Continuance when a partial frame is delivered. |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item * Write queue with callbacks for non-blocking I/O |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item * Signal resilience: resume read/write after Perl receives a trapped |
|
68
|
|
|
|
|
|
|
signal rather than throwing/giving EINTR. (cf. L) |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=back |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
These are now made available in this distribution. |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 ABOUT READS |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
The premise here is that you expect a given number of bytes at a given time |
|
77
|
|
|
|
|
|
|
and that a partial read should be continued once it is sensible to do so. |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
As a result, C will throw an exception if the number of bytes given |
|
80
|
|
|
|
|
|
|
for a continuance is not the same number as were originally requested. |
|
81
|
|
|
|
|
|
|
C will throw a similar exception if called between an incomplete |
|
82
|
|
|
|
|
|
|
C and its completion. |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Example: |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
#This reads only 2 bytes, so read() will return undef. |
|
87
|
|
|
|
|
|
|
$iof->read(10); |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
#… wait for readiness if non-blocking … |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
#XXX This die()s because we’re in the middle of trying to read |
|
92
|
|
|
|
|
|
|
#10 bytes, not 4. |
|
93
|
|
|
|
|
|
|
$iof->read(4); |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
#If this completes the read (i.e., takes in 8 bytes), then it’ll |
|
96
|
|
|
|
|
|
|
#return the full 10 bytes; otherwise, it’ll return undef again. |
|
97
|
|
|
|
|
|
|
$iof->read(10); |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
EINTR prompts a redo of the read operation. EAGAIN and EWOULDBLOCK (the same |
|
100
|
|
|
|
|
|
|
error generally, but not always) prompt an undef return. |
|
101
|
|
|
|
|
|
|
Any other failures prompt an instance of L to be |
|
102
|
|
|
|
|
|
|
thrown. |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head2 End-Match Reads |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Reader modules now implement a C method, which reads arbitrarily |
|
107
|
|
|
|
|
|
|
many bytes until |
|
108
|
|
|
|
|
|
|
a given sequence of bytes appears then returns those bytes (plus the looked-for |
|
109
|
|
|
|
|
|
|
sequence in the return). An obvious application for this feature |
|
110
|
|
|
|
|
|
|
is line-by-line reads, e.g., to implement HTTP or other line-based protocols. |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head2 Empty Reads |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
This class’s C and C methods will, by default, throw |
|
115
|
|
|
|
|
|
|
an instance of |
|
116
|
|
|
|
|
|
|
L on an empty read. This is normal and logical |
|
117
|
|
|
|
|
|
|
behavior in contexts (like L) where the data stream itself |
|
118
|
|
|
|
|
|
|
indicates when no more data will come across. In such cases an empty read |
|
119
|
|
|
|
|
|
|
is genuinely an error condition: it either means you’re reading past when |
|
120
|
|
|
|
|
|
|
you should, or the other side prematurely went away. |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
In some other cases, though, that empty read is the normal and expected way |
|
123
|
|
|
|
|
|
|
to know that a filehandle/socket has no more data to read. |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
If you prefer, then, you can call the C method to switch |
|
126
|
|
|
|
|
|
|
to a different behavior, e.g.: |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
$framed->allow_empty_read(); |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
my $frame = $framed->read(10); |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
if (length $frame) { |
|
133
|
|
|
|
|
|
|
#yay, we got a frame! |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
elsif (defined $frame) { |
|
136
|
|
|
|
|
|
|
#no more data will come in, so let’s close up shop |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
else { |
|
139
|
|
|
|
|
|
|
#undef means we just haven’t gotten as much data as we want yet; |
|
140
|
|
|
|
|
|
|
#in this case, that means fewer than 10 bytes are available. |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
#---------------------------------------------------------------------- |
|
144
|
|
|
|
|
|
|
# The same example as above with line-oriented input … |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
my $line = $framed->read_until("\x0a"); |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
if (length $line) { |
|
149
|
|
|
|
|
|
|
#yay, we got a line! |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
elsif (defined $line) { |
|
152
|
|
|
|
|
|
|
#no more data will come in, so let’s close up shop |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
else { |
|
155
|
|
|
|
|
|
|
#undef means we just haven’t gotten a full line yet. |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Instead of throwing the aforementioned exception, C now returns |
|
159
|
|
|
|
|
|
|
empty-string on an empty read. That means that you now have to distinguish |
|
160
|
|
|
|
|
|
|
between multiple “falsey” states: undef for when the requested number |
|
161
|
|
|
|
|
|
|
of bytes hasn’t yet arrived, and empty string for when no more bytes |
|
162
|
|
|
|
|
|
|
will ever arrive. But it is also true now that the only exceptions thrown |
|
163
|
|
|
|
|
|
|
are bona fide B, which will suit some applications better than the |
|
164
|
|
|
|
|
|
|
default behavior. |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
NB: If you want to be super-light, you can bring in IO::Framed::Read instead |
|
167
|
|
|
|
|
|
|
of the full IO::Framed. (IO::Framed is already pretty lightweight, though.) |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head1 ABOUT WRITES |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
Writes for blocking I/O are straightforward: the system will always send |
|
172
|
|
|
|
|
|
|
the entire buffer. The OS’s C won’t return until everything |
|
173
|
|
|
|
|
|
|
meant to be written is written. Life is pleasant; life is simple. :) |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Non-blocking I/O is trickier. Not only can the OS’s C write |
|
176
|
|
|
|
|
|
|
a subset of the data it’s given, but we also can’t know that the output |
|
177
|
|
|
|
|
|
|
filehandle is ready right when we want it. This means that we have to queue up |
|
178
|
|
|
|
|
|
|
our writes |
|
179
|
|
|
|
|
|
|
then write them once we know (e.g., through C |
|
180
|
|
|
|
|
|
|
is ready. Each C call, then, enqueues one new buffer to write. |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Since it’s often useful to know when a payload has been sent, |
|
183
|
|
|
|
|
|
|
C accepts an optional callback that will be executed immediately |
|
184
|
|
|
|
|
|
|
after the last byte of the payload is written to the output filehandle. |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Empty out the write queue by calling C and looking for |
|
187
|
|
|
|
|
|
|
a truthy response. (A falsey response means there is still data left in the |
|
188
|
|
|
|
|
|
|
queue.) C gives you the number of queue items left |
|
189
|
|
|
|
|
|
|
to write. (A partially-written item is treated the same as a fully-unwritten |
|
190
|
|
|
|
|
|
|
one.) |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Note that, while it’s acceptable to activate and deactive the write queue, |
|
193
|
|
|
|
|
|
|
the write queue must be empty in order to deactivate it. (You’ll get a |
|
194
|
|
|
|
|
|
|
nasty, untyped exception otherwise!) |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
C returns undef on EAGAIN and EWOULDBLOCK. It retries on EINTR, |
|
197
|
|
|
|
|
|
|
so you should never actually see this error from this module. |
|
198
|
|
|
|
|
|
|
Other errors prompt a thrown exception. |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
NB: C and C return the object, |
|
201
|
|
|
|
|
|
|
so you can instantiate thus: |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
my $nb_writer = IO::Framed::Write->new($fh)->enable_write_queue(); |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
NB: If you want to be super-light, you can bring in IO::Framed::Write instead |
|
206
|
|
|
|
|
|
|
of the full IO::Framed. (IO::Framed is already pretty lightweight, though.) |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=head1 CUSTOM READ & WRITE LOGIC |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
As of version 0.04, you can override READ and WRITE methods with your |
|
211
|
|
|
|
|
|
|
preferred logic. For example, in Linux you might prefer C rather than |
|
212
|
|
|
|
|
|
|
C to avoid SIGPIPE, thus: |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
package My::Framed; |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
use parent qw( IO::Framed::Write ); |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
#Only these two arguments are given. |
|
219
|
|
|
|
|
|
|
sub WRITE { |
|
220
|
|
|
|
|
|
|
return send( $_[0], $_[1], Socket::MSG_NOSIGNAL ); |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
(NB: In *BSD OSes you can set SO_SIGNOPIPE on the filehandle instead.) |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
You can likewise set C to achieve the same effect for reads. |
|
226
|
|
|
|
|
|
|
(C receives all four arguments that C can consume.) |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
B Unlike most inherited methods, C and C do |
|
229
|
|
|
|
|
|
|
NOT receive the object instance. They must follow the same semantics as |
|
230
|
|
|
|
|
|
|
Perl’s C and C: i.e., they must return the number |
|
231
|
|
|
|
|
|
|
of bytes read/written, or return undef and set C<$!> appropriately on error. |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=head1 ERROR RESPONSES |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
An empty read or any I/O error besides the ones mentioned previously |
|
236
|
|
|
|
|
|
|
are indicated via an instance of one of the following exceptions. |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
All exceptions subclass L, which itself |
|
239
|
|
|
|
|
|
|
subclasses C. |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=over |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=item L |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=item L |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
These both have an C property (cf. L’s accessor |
|
248
|
|
|
|
|
|
|
method). |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=item L |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
No properties. If this is thrown, your peer has probably closed the connection. |
|
253
|
|
|
|
|
|
|
Unless you have called C to set an alternate behavior, |
|
254
|
|
|
|
|
|
|
you might want to trap this exception if you call C. |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=back |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
B This distribution doesn’t write to C<$!>. EAGAIN and EWOULDBLOCK on |
|
259
|
|
|
|
|
|
|
C are ignored; all other errors are converted |
|
260
|
|
|
|
|
|
|
to thrown exceptions. |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=cut |
|
263
|
|
|
|
|
|
|
|
|
264
|
3
|
|
|
|
|
26
|
use parent qw( |
|
265
|
|
|
|
|
|
|
IO::Framed::Read |
|
266
|
|
|
|
|
|
|
IO::Framed::Write |
|
267
|
3
|
|
|
3
|
|
456
|
); |
|
|
3
|
|
|
|
|
320
|
|
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub new { |
|
270
|
3
|
|
|
3
|
0
|
1902
|
my ( $class, $in_fh, $out_fh, $initial_buffer ) = @_; |
|
271
|
|
|
|
|
|
|
|
|
272
|
3
|
|
|
|
|
27
|
my $self = $class->SUPER::new( $in_fh, $initial_buffer ); |
|
273
|
|
|
|
|
|
|
|
|
274
|
3
|
|
66
|
|
|
45
|
$self->{'_out_fh'} = $out_fh || $in_fh, |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
return (bless $self, $class)->disable_write_queue(); |
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
1; |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=head1 LEGACY CLASSES |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
This distribution also includes the following B legacy classes: |
|
284
|
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=over |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=item * IO::Framed::Write::Blocking |
|
288
|
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=item * IO::Framed::Write::NonBlocking |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=item * IO::Framed::ReadWrite |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=item * IO::Framed::ReadWrite::Blocking |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item * IO::Framed::ReadWrite::NonBlocking |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=back |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
I’ll keep these in for the time being but eventually B remove them. |
|
300
|
|
|
|
|
|
|
Please adjust any calling code that you might have. |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=head1 REPOSITORY |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
L |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=head1 AUTHOR |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Felipe Gasper (FELIPE) |
|
309
|
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Copyright 2017 by L |
|
313
|
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=head1 LICENSE |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
This distribution is released under the same license as Perl. |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=cut |