File Coverage

blib/lib/Device/MindWave/Packet/ThinkGear.pm
Criterion Covered Total %
statement 89 89 100.0
branch 12 12 100.0
condition n/a
subroutine 18 18 100.0
pod 6 6 100.0
total 125 125 100.0


line stmt bran cond sub pod time code
1             package Device::MindWave::Packet::ThinkGear;
2              
3 4     4   20 use strict;
  4         8  
  4         132  
4 4     4   20 use warnings;
  4         6  
  4         95  
5              
6 4     4   2441 use Device::MindWave::Packet::ThinkGear::DataValue::PoorSignal;
  4         12  
  4         114  
7 4     4   2582 use Device::MindWave::Packet::ThinkGear::DataValue::Attention;
  4         9  
  4         129  
8 4     4   2349 use Device::MindWave::Packet::ThinkGear::DataValue::Meditation;
  4         11  
  4         95  
9 4     4   8485 use Device::MindWave::Packet::ThinkGear::DataValue::BlinkStrength;
  4         8  
  4         106  
10 4     4   2471 use Device::MindWave::Packet::ThinkGear::DataValue::RawWave;
  4         11  
  4         97  
11 4     4   2586 use Device::MindWave::Packet::ThinkGear::DataValue::EEG;
  4         11  
  4         123  
12              
13 4     4   29 use List::Util qw(sum);
  4         8  
  4         290  
14              
15 4     4   20 use base qw(Device::MindWave::Packet);
  4         9  
  4         3187  
16              
17             my %SB_CODE_MAP = (
18             0x02 => 'PoorSignal',
19             0x04 => 'Attention',
20             0x05 => 'Meditation',
21             0x16 => 'BlinkStrength',
22             );
23              
24             my %MB_CODE_MAP = (
25             0x80 => 'RawWave',
26             0x83 => 'EEG',
27             );
28              
29             sub new
30             {
31 6     6 1 53 my ($class, $bytes, $index) = @_;
32              
33 6         22 my $dvs = _parse($bytes, $index);
34 6         28 my $self = { data_values => $dvs, index => 0 };
35 6         26 bless $self, $class;
36 6         35 return $self;
37             }
38              
39             sub _parse_data_value
40             {
41 8     8   14 my ($bytes, $index) = @_;
42              
43 8         10 my $excode = 0;
44 8         13 for (; $index < @{$bytes}; $index++) {
  12         36  
45 12 100       30 if ($bytes->[$index] == 0x55) {
46 4         7 $excode++;
47             } else {
48 8         11 last;
49             }
50             }
51              
52 8 100       23 if ($excode != 0) {
53 2         20 warn "Unhandled data value (uses extended codes).";
54             }
55              
56 8         25 my $code = $bytes->[$index];
57 8 100       19 if ($code < 0x80) {
58 6 100       23 if (exists $SB_CODE_MAP{$code}) {
59 5         13 my $pkg = "Device::MindWave::Packet::ThinkGear::DataValue::".
60             $SB_CODE_MAP{$code};
61 5         27 my $datavalue = $pkg->new($bytes, $index);
62 5         22 return ($datavalue, $index + $datavalue->length());
63             } else {
64 1         7 warn "Unhandled single-byte value code: $code";
65 1         8 return (undef, ($index + 2));
66             }
67             } else {
68 2 100       16 if (exists $MB_CODE_MAP{$code}) {
69 1         3 my $pkg = "Device::MindWave::Packet::ThinkGear::DataValue::".
70             $MB_CODE_MAP{$code};
71 1         4 my $datavalue = $pkg->new($bytes, $index);
72 1         4 return ($datavalue, $index + $datavalue->length());
73             } else {
74 1         3 my $length = $bytes->[$index + 1];
75 1         2 $index += (2 + $length);
76 1         7 warn "Unhandled multi-byte value code: $code";
77 1         8 return (undef, $index);
78             }
79             }
80             }
81              
82             sub _parse
83             {
84 6     6   10 my ($bytes, $index) = @_;
85              
86 6         9 my $length = @{$bytes};
  6         14  
87 6         10 my @dvs;
88             my $dv;
89 6         22 while ($index < $length) {
90 8         21 ($dv, $index) = _parse_data_value($bytes, $index);
91 8 100       33 if (defined $dv) {
92 6         16 push @dvs, $dv;
93             }
94             }
95              
96 6         15 return \@dvs;
97             }
98              
99             sub next_data_value
100             {
101 6     6 1 9 my ($self) = @_;
102              
103 6         21 return $self->{'data_values'}->[$self->{'index'}++];
104             }
105              
106             sub as_bytes
107             {
108 2     2 1 3 my ($self) = @_;
109              
110 2         3 return [ map { @{$_->as_bytes()} } @{$self->{'data_values'}} ];
  6         6  
  6         24  
  2         8  
111             }
112              
113             sub length
114             {
115 1     1 1 2 my ($self) = @_;
116              
117 1         4 return (sum 0, map { $_->length() } @{$self->{'data_values'}});
  5         32  
  1         4  
118             }
119              
120             sub as_string
121             {
122 1     1 1 38 my ($self) = @_;
123              
124 1         2 return join '; ', map { $_->as_string() } @{$self->{'data_values'}};
  5         25  
  1         5  
125             }
126              
127             sub as_hashref
128             {
129 1     1 1 3 my ($self) = @_;
130              
131 1         3 return { map { %{$_->as_hashref()} } @{$self->{'data_values'}} };
  5         6  
  5         23  
  1         4  
132             }
133              
134             1;
135              
136             __END__