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 |