IO-BufferedSelect/0000775001276500001440000000000010575456503012754 5ustar afnusersIO-BufferedSelect/lib/0000775001276500001440000000000010575452315013517 5ustar afnusersIO-BufferedSelect/lib/IO/0000775001276500001440000000000010575456500014026 5ustar afnusersIO-BufferedSelect/lib/IO/BufferedSelect.pm0000664001276500001440000001146310575456413017256 0ustar afnuserspackage IO::BufferedSelect; use strict; use warnings; use IO::Select; =head1 NAME IO::BufferedSelect - Line-buffered select interface =head1 SYNOPSIS use IO::BufferedSelect; my $bs = new BufferedSelect($fh1, $fh2); while(1) { my @ready = $bs->read_line(); foreach(@ready) { my ($fh, $line) = @$_; my $fh_name = ($fh == $fh1 ? "fh1" : "fh2"); print "$fh_name: $line"; } } =head1 DESCRIPTION The C with C: (1) C might indicate that data is available, but C will block because there isn't a full C<$/>-terminated line available. The purpose of this module is to implement a buffered version of the C for readability, not writability or exceptions; and (2) it does not support arbitrary line separators (C<$/>): lines must be delimited by newlines. =cut our $VERSION = '1.0'; =head1 CONSTRUCTOR =over =item new ( HANDLES ) Create a C object for a set of filehandles. Note that because this class buffers input from these filehandles internally, you should B use the C object for reading from them (you shouldn't read from them directly or pass them to other BufferedSelect instances). =back =cut sub new($@) { my $class = shift; my @handles = @_; my $self = { handles => \@handles, buffers => [ map { '' } @handles ], eof => [ map { 0 } @handles ], selector => new IO::Select( @handles ) }; return bless $self; } =head1 METHODS =over =item read_line =item read_line ($timeout) =item read_line ($timeout, @handles) Block until a line is available on one of the filehandles. If C<$timeout> is C, it blocks indefinitely; otherwise, it returns after at most C<$timeout> seconds. If C<@handles> is specified, then only these filehandles will be considered; otherwise, it will use all filehandles passed to the constructor. Returns a list of pairs S>, where C<$fh> is a filehandle and C<$line> is the line that was read (including the newline, ala C). If the filehandle reached EOF, then C<$line> will be undef. Note that "reached EOF" is to be interpreted in the buffered sense: if a filehandle is at EOF but there are newline-terminated lines in C's buffer, C will continue to return lines until the buffer is empty. =cut sub read_line($;$@) { my $self = shift; my ($timeout, @handles) = @_; # Convert @handles to a "set" of indices my %use_idx = (); if(@handles) { foreach my $idx( 0..$#{$self->{handles}} ) { $use_idx{$idx} = 1 if grep { $_ == $self->{handles}->[$idx] } @handles; } } else { $use_idx{$_} = 1 foreach( 0..$#{$self->{handles}} ); } for( my $is_first = 1 ; 1 ; $is_first = 0 ) { # If we have any lines in buffers, return those first my @result = (); foreach my $idx( 0..$#{$self->{handles}} ) { next unless $use_idx{$idx}; if($self->{buffers}->[$idx] =~ s/(.*\n)//) { push @result, [ $self->{handles}->[$idx], $1 ]; } elsif($self->{eof}->[$idx]) { # NOTE: we discard any unterminated data at EOF push @result, [ $self->{handles}->[$idx], undef ]; } } # Only give it one shot if $timeout is defined return @result if ( @result or (defined($timeout) and !$is_first) ); # Do a select(), optionally with a timeout my @ready = $self->{selector}->can_read( $timeout ); # Read into $self->{buffers} foreach my $fh( @ready ) { foreach my $idx( 0..$#{$self->{handles}} ) { next unless $fh == $self->{handles}->[$idx]; next unless $use_idx{$idx}; my $bytes = sysread $fh, $self->{buffers}->[$idx], 1024, length $self->{buffers}->[$idx]; $self->{eof}->[$idx] = 1 if($bytes == 0); } } } } 1; __END__ =back =head1 SEE ALSO L =head1 AUTHOR Antal Novak, Eafn@cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright (C) 2007 by Antal Novak This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut IO-BufferedSelect/Makefile.PL0000664001276500001440000000106110575452337014725 0ustar afnusersuse 5.008008; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'IO::BufferedSelect', VERSION_FROM => 'lib/IO/BufferedSelect.pm', # finds $VERSION PREREQ_PM => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/IO/BufferedSelect.pm', # retrieve abstract from module AUTHOR => 'Antal Novak ') : ()), ); IO-BufferedSelect/README0000664001276500001440000000224110575452315013630 0ustar afnusersIO-BufferedSelect version 1.0 ============================= The README is used to introduce the module and provide instructions on how to install the module, any machine dependencies it may have (for example C compilers and installed libraries) and any other information that should be provided before the module is installed. A README file is required for CPAN modules since CPAN extracts the README file from a module distribution so that people browsing the archive can use it get an idea of the modules uses. It is usually a good idea to provide version information here so that people can decide whether fixes for the module are worth downloading. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules and libraries: blah blah blah COPYRIGHT AND LICENCE Put the correct copyright and licence information here. Copyright (C) 2007 by Antal Novak This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. IO-BufferedSelect/t/0000775001276500001440000000000010575456520013216 5ustar afnusersIO-BufferedSelect/t/IO-BufferedSelect.t0000664001276500001440000000074510575452315016576 0ustar afnusers# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl IO-BufferedSelect.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test::More tests => 1; BEGIN { use_ok('IO::BufferedSelect') }; ######################### # Insert your test code below, the Test::More module is use()ed here so read # its man page ( perldoc Test::More ) for help writing this test script. IO-BufferedSelect/Changes0000664001276500001440000000026110575452315014243 0ustar afnusersRevision history for Perl extension IO::BufferedSelect. 1.0 Tue Mar 13 00:37:49 2007 - original version; created by h2xs 1.23 with options -v 1.0 -X -n IO::BufferedSelect IO-BufferedSelect/MANIFEST0000664001276500001440000000012310575452315014076 0ustar afnusersChanges Makefile.PL MANIFEST README t/IO-BufferedSelect.t lib/IO/BufferedSelect.pm