File Coverage

blib/lib/Data/FDSet.pm
Criterion Covered Total %
statement 29 32 90.6
branch 8 10 80.0
condition n/a
subroutine 8 9 88.8
pod 6 6 100.0
total 51 57 89.4


line stmt bran cond sub pod time code
1             package Data::FDSet;
2              
3 1     1   702 use strict;
  1         4  
  1         29  
4 1     1   4 use warnings;
  1         2  
  1         38  
5              
6             our $VERSION;
7             BEGIN {
8 1     1   394 $VERSION = '0.01';
9             }
10              
11             =encoding utf-8
12              
13             =head1 NAME
14              
15             Data::FDSet - Syntactic sugar for L masks
16              
17             =head1 SYNOPSIS
18              
19             Object-oriented syntax:
20              
21             my $fdset = Data::FDSet->new();
22              
23             # These accept either filehandles or file descriptors:
24             $fdset->add( $some_filehandle, fileno($other_fh) );
25             $fdset->remove( $other_fh );
26              
27             my $rout = Data::FDSet->new();
28              
29             my $got = select( $$rout = $$fdset, undef, undef, 10 );
30              
31             if ($got > 1) {
32             my $fds_to_read_ar = $rout->get_fds();
33             }
34              
35             Or, if you’d rather avoid object-oriented syntax:
36              
37             my $rout = q<>;
38             Data::FDSet::add(\$rout, $some_filehandle, fileno($other_fh))
39              
40             my $fds_to_read_ar = Data::FDSet::get_fds(\$rout);
41              
42             =head1 DESCRIPTION
43              
44             This little module makes working with 4-argument L
45             a bit easier by providing object methods to do the typical operations done
46             on the bitmasks in connection with that function. These methods parallel
47             the functions that C provides to handle C.
48              
49             =cut
50              
51             #----------------------------------------------------------------------
52              
53             =head1 INTERFACE NOTE
54              
55             A Data::FDSet object is a blessed scalar reference to a bitmask.
56             Unlike with most Perl objects, you may safely reference the object
57             internals, e.g., by doing
58              
59             $$rout_obj = $rin;
60              
61             … to replace the bitmask contents. (For this reason, this class defines
62             no method to do the above.)
63              
64             =head1 METHODS
65              
66             =head2 $obj = I->new( [ $BITMASK ] );
67              
68             Instantiates this class. $BITMASK may optionally be passed to
69             initialize the object state.
70              
71             =cut
72              
73             sub new {
74 4     4 1 555 my ($class) = @_;
75              
76 4 100       12 my $sr = defined($_[1]) ? \$_[1] : \do { my $v = q<> };
  3         6  
77              
78 4         12 return bless $sr, $class;
79             }
80              
81             =head2 $obj = I->evacuate()
82              
83             Empty out the object. Analogous to L.
84              
85             Returns I.
86              
87             =cut
88              
89             sub evacuate {
90 0     0 1 0 ${ $_[0] } = q<>;
  0         0  
91              
92 0         0 return $_[0];
93             }
94              
95             =head2 $obj = I->add( $FD_OR_FH [, $FD_OR_FH, .. ] )
96              
97             Add one or more file descriptors to the object.
98             Accepts either Perl filehandles or file descriptors.
99             Analogous to L.
100              
101             =cut
102              
103             sub add {
104 1     1 1 4431 for my $arg ( @_[ 1 .. $#_ ] ) {
105 3 100       4 vec( ${ $_[0] }, defined(fileno($arg)) ? fileno($arg) : $arg, 1 ) = 1;
  3         17  
106             }
107              
108 1         3 return $_[0];
109             }
110              
111             =head2 $obj = I->remove( $FD_OR_FH [, $FD_OR_FH, .. ] )
112              
113             The complement of C.
114             Analogous to L.
115              
116             =cut
117              
118             sub remove {
119 1     1 1 4 for my $arg ( @_[ 1 .. $#_ ] ) {
120 2 50       3 vec( ${ $_[0] }, defined(fileno($arg)) ? fileno($arg) : $arg, 1 ) = 0;
  2         15  
121             }
122              
123 1         2 return $_[0];
124             }
125              
126             =head2 $yn = I->has( $FD_OR_FH )
127              
128             Tests for a file descriptor’s presence in the object.
129             Accepts either a Perl filehandles or a file descriptor.
130             Analogous to L.
131              
132             =cut
133              
134             sub has {
135 1 50   1 1 2 return vec( ${ $_[0] }, defined(fileno($_[1])) ? fileno($_[1]) : $_[1], 1 );
  1         14  
136             }
137              
138             =head2 $fds_ar = I->get_fds()
139              
140             Returns a reference to an array of the file descriptors that are
141             in the object.
142              
143             =cut
144              
145             sub get_fds {
146 5     5 1 36 my $max = 8 * length(${ $_[0] }) - 1;
  5         13  
147              
148 5         7 my @fds;
149              
150 5         13 for my $fd ( 0 .. $max ) {
151 56 100       61 if ( vec(${ $_[0] }, $fd, 1) ) {
  56         101  
152 7         13 push @fds, $fd;
153             }
154             }
155              
156 5         28 return \@fds;
157             }
158              
159             1;