File Coverage

blib/lib/USB/HID/Report.pm
Criterion Covered Total %
statement 12 72 16.6
branch 0 18 0.0
condition 0 18 0.0
subroutine 4 10 40.0
pod 6 6 100.0
total 22 124 17.7


line stmt bran cond sub pod time code
1             package USB::HID::Report;
2              
3 1     1   7 use feature 'switch';
  1         2  
  1         99  
4 1     1   6 use strict;
  1         2  
  1         30  
5 1     1   6 use warnings;
  1         1  
  1         24  
6              
7 1     1   745 use USB::HID::Report::Field;
  1         2  
  1         1368  
8              
9             our $VERSION = '1';
10              
11             =head1 NAME
12              
13             USB::HID::Report - USB HID Report
14              
15             =head1 SYNOPSIS
16              
17             An object representation of a USB HID Report.
18              
19             use USB::HID::Report;
20              
21             my $report = USB::HID::Report->new( reportID => 1, direction => 'input' );
22             $report->fields( [ USB::HID::Report::Element->new() ] );
23             ...
24              
25             =head1 DESCRIPTION
26              
27             L represents a USB HID Report. When added to an instance of
28             L it can be used to generate the data
29             structures needed to compile the firmware for a USB device.
30              
31             =head1 CONSTRUCTOR
32              
33             =over
34              
35             =item $interface = USB::HID::Report->new(reportID=>$reportID, ...);
36              
37             Constructs and returns a new L object using the passed
38             options. Each option key is the name of an accessor method.
39              
40             When constructing report objects, the report type and ID can be specified with a
41             single key/value pair. For example, you can use C<< new('input' => 3) >> instead
42             of C<< new('type' => 'input', 'reportID' => 3) >>.
43              
44             =back
45              
46             =cut
47              
48             sub new
49             {
50 0     0 1   my ($this, %options) = @_;
51 0   0       my $class = ref($this) || $this;
52              
53             # Set defaults
54 0           my $self = {
55             'collection' => 'report',
56             'reportID' => 1,
57             'type' => 'input',
58             'fields' => [],
59             };
60 0           bless $self, $class;
61              
62 0           while( my ($key, $value) = each %options )
63             {
64             # Handle the 'type => reportID' shortcut
65 0 0 0       if( ($key eq 'input') or ($key eq 'output') or ($key eq 'feature') )
      0        
66             {
67 0           $self->type($key);
68 0           $self->reportID($value);
69             }
70             else
71             {
72 0           $self->$key($value);
73             }
74             }
75              
76 0           return $self;
77             }
78              
79             =head1 ARRAYIFICATION
80              
81             =over
82              
83             =item $report->bytes (or @{$report} )
84              
85             Returns an array of bytes containing all of the items in the report.
86              
87             =back
88              
89             =cut
90              
91             sub bytes
92             {
93 0     0 1   my ($s, $state) = @_;
94              
95 0           my @bytes;
96 0           my $push_report_id = not exists $state->{'global'}{'report_id'};
97              
98 0 0         if( $push_report_id )
99             {
100 0           $state->{'global'}{'report_id'} = $s->reportID;
101 0           push @bytes, USB::HID::Descriptor::Report::Collection('report');
102 0           push @bytes, USB::HID::Descriptor::Report::item('report_id', $s->reportID);
103             }
104              
105             # Emit all of the fields
106 0           $state->{'main'} = $s->type;
107 0           for my $field (@{$s->fields})
  0            
108             {
109 0           push @bytes, $field->bytes($state);
110 0           delete $state->{'local'}; # Local state resets after a Main item
111             }
112              
113 0 0         if( $push_report_id )
114             {
115 0           push @bytes, USB::HID::Descriptor::Report::Collection('end');
116             };
117              
118             # Cleanup the state
119 0           delete $state->{'main'};
120              
121 0           return @bytes;
122             }
123              
124             =head1 ATTRIBUTES
125              
126             =over
127              
128             =item $report->collection
129              
130             Get/Set the collection type used to enclose the report's items. Set to 'none' to
131             use a bare report.
132              
133             =item $report->reportID
134              
135             Get/Set the report's ID. Defaults to 1.
136              
137             =item $report->type
138              
139             Get/Set the report's type ('input', 'output' or 'feature'). Defaults to 'input'.
140              
141             =item $report->fields
142              
143             Get/Set the report's fields.
144              
145             =back
146              
147             =cut
148              
149             sub collection
150             {
151 0     0 1   my $s = shift;
152 0 0         $s->{'collection_type'} = shift if @_;
153 0           $s->{'collection_type'};
154             }
155              
156             sub reportID
157             {
158 0     0 1   my $s = shift;
159 0 0         $s->{'reportID'} = int(shift) & 0xFF if @_;
160 0           $s->{'reportID'};
161             }
162              
163             sub type
164             {
165 0     0 1   my $s = shift;
166 0 0         if( @_ )
167             {
168 0           my $type = shift;
169 0 0 0       $s->{'type'} = $type if(($type eq 'input') ||
      0        
170             ($type eq 'output') ||
171             ($type eq 'feature') );
172             }
173 0           $s->{'type'};
174             }
175              
176             sub fields
177             {
178 0     0 1   my $s = shift;
179 0 0 0       if( @_ and ref($_[0]) eq 'ARRAY' )
180             {
181 0           my @fields;
182 0           while( @{$_[0]} )
  0            
183             {
184 0           my $k = shift @{$_[0]}; # Field name
  0            
185 0           my $v = shift @{$_[0]}; # Field initializer
  0            
186 0 0         next unless USB::HID::Report::Field->can($k);
187 0           given( ref($v) )
188             {
189 0           when('HASH') { push @fields, USB::HID::Report::Field->$k(%{$v}); }
  0            
  0            
190 0           when('ARRAY') { push @fields, USB::HID::Report::Field->$k(@{$v}); }
  0            
  0            
191 0           when('') { push @fields, USB::HID::Report::Field->$k($v); }
  0            
192 0           default { push @fields, $v; }
  0            
193             }
194             }
195 0           $s->{'fields'} = \@fields;
196             }
197 0           $s->{'fields'};
198             }
199              
200             1;
201              
202             =head1 AUTHOR
203              
204             Brandon Fosdick, C<< >>
205              
206             =head1 BUGS
207              
208             Please report any bugs or feature requests to C, or through
209             the web interface at L. I will be notified, and then you'll
210             automatically be notified of progress on your bug as I make changes.
211              
212             =head1 SUPPORT
213              
214             You can find documentation for this module with the perldoc command.
215              
216             perldoc USB::HID::Report
217              
218              
219             You can also look for information at:
220              
221             =over 4
222              
223             =item * RT: CPAN's request tracker (report bugs here)
224              
225             L
226              
227             =item * AnnoCPAN: Annotated CPAN documentation
228              
229             L
230              
231             =item * CPAN Ratings
232              
233             L
234              
235             =item * Search CPAN
236              
237             L
238              
239             =back
240              
241              
242             =head1 ACKNOWLEDGEMENTS
243              
244              
245             =head1 LICENSE AND COPYRIGHT
246              
247             Copyright 2011 Brandon Fosdick.
248              
249             This program is released under the terms of the BSD License.
250              
251             =cut