Acme-Sort-Sleep
view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/Stream.pm view on Meta::CPAN
sub new_for_stdin { shift->new( read_handle => \*STDIN, @_ ) }
sub new_for_stdout { shift->new( write_handle => \*STDOUT, @_ ) }
sub new_for_stdio { shift->new( read_handle => \*STDIN, write_handle => \*STDOUT, @_ ) }
=head2 connect
$future = $stream->connect( %args )
A convenient wrapper for calling the C<connect> method on the underlying
L<IO::Async::Loop> object, passing the C<socktype> hint as C<stream> if not
otherwise supplied.
=cut
sub connect
{
my $self = shift;
return $self->SUPER::connect( socktype => "stream", @_ );
}
=head1 DEBUGGING FLAGS
The following flags in C<IO_ASYNC_DEBUG_FLAGS> enable extra logging:
=over 4
=item C<Sr>
Log byte buffers as data is read from a Stream
=item C<Sw>
Log byte buffers as data is written to a Stream
=back
=cut
=head1 EXAMPLES
=head2 A line-based C<on_read> method
The following C<on_read> method accepts incoming C<\n>-terminated lines and
prints them to the program's C<STDOUT> stream.
sub on_read
{
my $self = shift;
my ( $buffref, $eof ) = @_;
while( $$buffref =~ s/^(.*\n)// ) {
print "Received a line: $1";
}
return 0;
}
Because a reference to the buffer itself is passed, it is simple to use a
C<s///> regular expression on the scalar it points at, to both check if data
is ready (i.e. a whole line), and to remove it from the buffer. If no data is
available then C<0> is returned, to indicate it should not be tried again. If
a line was successfully extracted, then C<1> is returned, to indicate it
should try again in case more lines exist in the buffer.
=head2 Reading binary data
This C<on_read> method accepts incoming records in 16-byte chunks, printing
each one.
sub on_read
{
my ( $self, $buffref, $eof ) = @_;
if( length $$buffref >= 16 ) {
my $record = substr( $$buffref, 0, 16, "" );
print "Received a 16-byte record: $record\n";
return 1;
}
if( $eof and length $$buffref ) {
print "EOF: a partial record still exists\n";
}
return 0;
}
The 4-argument form of C<substr()> extracts the 16-byte record from the buffer
and assigns it to the C<$record> variable, if there was enough data in the
buffer to extract it.
A lot of protocols use a fixed-size header, followed by a variable-sized body
of data, whose size is given by one of the fields of the header. The following
C<on_read> method extracts messages in such a protocol.
sub on_read
{
my ( $self, $buffref, $eof ) = @_;
return 0 unless length $$buffref >= 8; # "N n n" consumes 8 bytes
my ( $len, $x, $y ) = unpack "N n n", $$buffref;
return 0 unless length $$buffref >= 8 + $len;
substr( $$buffref, 0, 8, "" );
my $data = substr( $$buffref, 0, $len, "" );
print "A record with values x=$x y=$y\n";
return 1;
}
In this example, the header is C<unpack()>ed first, to extract the body
length, and then the body is extracted. If the buffer does not have enough
data yet for a complete message then C<0> is returned, and the buffer is left
unmodified for next time. Only when there are enough bytes in total does it
use C<substr()> to remove them.
( run in 0.576 second using v1.01-cache-2.11-cpan-e1769b4cff6 )