line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package NetAthlon2::RAW; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
1078319
|
use 5.006; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
42
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
37
|
|
5
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
31
|
|
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
62
|
|
8
|
1
|
|
|
1
|
|
4
|
use POSIX qw(mktime strftime localtime); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
9
|
1
|
|
|
1
|
|
1104
|
use Socket qw(:DEFAULT :crlf); |
|
1
|
|
|
|
|
4464
|
|
|
1
|
|
|
|
|
3565
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require Exporter; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Items to export into callers namespace by default. Note: do not export |
16
|
|
|
|
|
|
|
# names by default without a very good reason. Use EXPORT_OK instead. |
17
|
|
|
|
|
|
|
# Do not simply export all your public functions/methods/constants. |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# This allows declaration use NetAthlon2::RAW qw(:all); |
20
|
|
|
|
|
|
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK |
21
|
|
|
|
|
|
|
# will save memory. |
22
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw() ] ); |
23
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} }); |
24
|
|
|
|
|
|
|
our @EXPORT = qw(); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
our $VERSION = '0.31'; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
our $timeDelta = 1; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
local *FP; |
31
|
|
|
|
|
|
|
local *DIR; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub new { |
34
|
1
|
|
|
1
|
1
|
74
|
my ($class, %opts) = @_; |
35
|
1
|
|
|
|
|
2
|
my ($self); |
36
|
|
|
|
|
|
|
|
37
|
1
|
|
|
|
|
1
|
$self = \%opts; |
38
|
1
|
|
|
|
|
2
|
bless ($self, $class); |
39
|
|
|
|
|
|
|
|
40
|
1
|
|
|
|
|
4
|
return $self; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub open { |
44
|
7
|
|
|
7
|
0
|
20
|
my ($self, $file) = @_; |
45
|
|
|
|
|
|
|
|
46
|
7
|
50
|
33
|
|
|
276
|
if ( defined $file && -f $file ) { |
47
|
7
|
|
|
|
|
64
|
$self->{'file'} = $file; |
48
|
|
|
|
|
|
|
|
49
|
7
|
50
|
|
|
|
35
|
warn "Opening file ($file)\n" if ( exists $self->{'debug'} ); |
50
|
7
|
50
|
|
|
|
438
|
open (*FP, "< $file") || croak "Could not open $file"; |
51
|
7
|
|
|
|
|
39
|
return $self; |
52
|
|
|
|
|
|
|
} else { |
53
|
0
|
|
|
|
|
0
|
croak "$file not a file"; |
54
|
0
|
|
|
|
|
0
|
return undef; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub _parse_preamble { |
59
|
7
|
|
|
7
|
|
12
|
my ($self) = @_; |
60
|
|
|
|
|
|
|
|
61
|
7
|
50
|
|
|
|
34
|
carp "First line not 251" |
62
|
|
|
|
|
|
|
if ( $self->{'RAW'}[0] != 251 ); |
63
|
|
|
|
|
|
|
|
64
|
7
|
|
|
|
|
10
|
$self->{'data'}->{'Sample Rate'} = int(${$self->{'RAW'}}[1]); |
|
7
|
|
|
|
|
34
|
|
65
|
|
|
|
|
|
|
|
66
|
7
|
50
|
|
|
|
75
|
carp "Line 3 not 1" |
67
|
|
|
|
|
|
|
if ( $self->{'RAW'}[2] != 1 ); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# Hear Rate info |
70
|
7
|
|
|
|
|
117
|
( $self->{'data'}->{'Heart Rate'}->{'Zone 1'}->{'Max'}, |
71
|
|
|
|
|
|
|
$self->{'data'}->{'Heart Rate'}->{'Zone 3'}->{'Max'} ) = |
72
|
7
|
|
|
|
|
16
|
split (/\s/, ${$self->{'RAW'}}[3]); |
73
|
7
|
|
|
|
|
89
|
( $self->{'data'}->{'Heart Rate'}->{'Zone 1'}->{'Min'}, |
74
|
|
|
|
|
|
|
$self->{'data'}->{'Heart Rate'}->{'Zone 3'}->{'Min'} ) = |
75
|
7
|
|
|
|
|
19
|
split (/\s/, ${$self->{'RAW'}}[4]); |
76
|
7
|
|
|
|
|
61
|
( $self->{'data'}->{'Heart Rate'}->{'Zone 2'}->{'Max'}, |
77
|
|
|
|
|
|
|
$self->{'data'}->{'Heart Rate'}->{'Anaerobic Threshold'} ) = |
78
|
7
|
|
|
|
|
14
|
split (/\s/, ${$self->{'RAW'}}[5]); |
79
|
7
|
|
|
|
|
71
|
( $self->{'data'}->{'Heart Rate'}->{'Zone 2'}->{'Min'}, |
80
|
|
|
|
|
|
|
$self->{'data'}->{'Heart Rate'}->{'Aerobic Threshold'} ) = |
81
|
7
|
|
|
|
|
15
|
split (/\s/, ${$self->{'RAW'}}[6]); |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# Store the start time (converting to UNIX timestamp) |
84
|
7
|
|
|
|
|
39
|
my ($mon, $day, $year, $hour, $h, $min, $m, $sec, $ampm); |
85
|
7
|
50
|
|
|
|
186
|
if ( $self->{'file'} =~ /Bike(\d{4})-(\d{2})-(\d{2}) (\d{1,2})-(\d{2})([ap]m)\.RAW$/ ) { |
86
|
7
|
|
|
|
|
261
|
$year = $1; |
87
|
7
|
|
|
|
|
60
|
$mon = $2; |
88
|
7
|
|
|
|
|
16
|
$day = $3; |
89
|
7
|
|
|
|
|
46
|
$h = $4; |
90
|
7
|
|
|
|
|
51
|
$m = $5; |
91
|
7
|
|
|
|
|
13
|
$ampm = $6; |
92
|
|
|
|
|
|
|
|
93
|
7
|
50
|
33
|
|
|
40
|
warn "\tyear => $year, month => $mon, day => $day\n\thour => $h, minute => $m, $ampm\n" |
94
|
|
|
|
|
|
|
if ( exists $self->{'debug'} && $self->{'debug'} >= 5 ); |
95
|
|
|
|
|
|
|
|
96
|
7
|
50
|
|
|
|
585
|
if ( ${$self->{'RAW'}}[8] =~ m/^(\d{2})\.(\d{2})\.(\d{2})$/ ) { |
|
7
|
|
|
|
|
240
|
|
97
|
7
|
|
|
|
|
16
|
$hour = $1; |
98
|
7
|
|
|
|
|
32
|
$min = $2; |
99
|
7
|
|
|
|
|
13
|
$sec = $3; |
100
|
|
|
|
|
|
|
|
101
|
7
|
50
|
33
|
|
|
109
|
warn "\thour => $hour, minute => $min, second => $sec\n" |
102
|
|
|
|
|
|
|
if ( exists $self->{'debug'} && $self->{'debug'} >= 5 ); |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# FIXME: There is a bug in some of the RAW data files as |
105
|
|
|
|
|
|
|
# the time encoded in the filename is 1 minute after the |
106
|
|
|
|
|
|
|
# time encoded in the file contents, hence the different |
107
|
|
|
|
|
|
|
# comparison for the minute field. |
108
|
7
|
|
|
|
|
265
|
my $mina = $h * 60 + $m; |
109
|
7
|
|
|
|
|
17
|
my $minb = $hour * 60 + $min; |
110
|
7
|
50
|
|
|
|
32
|
carp "Start time mismatch between file name (" |
111
|
|
|
|
|
|
|
. $self->{'file'} |
112
|
|
|
|
|
|
|
. ") and file contents ($hour:$min)" |
113
|
|
|
|
|
|
|
if ( abs($mina-$minb) > $timeDelta ); |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# deal with the noon and midnight hours. |
116
|
7
|
100
|
66
|
|
|
78
|
$hour += 12 if ( $ampm eq 'pm' && $hour < 12 ); |
117
|
7
|
50
|
33
|
|
|
25
|
$hour = 0 if ( $ampm eq 'am' && $hour == 12 ); |
118
|
|
|
|
|
|
|
|
119
|
7
|
50
|
33
|
|
|
26
|
warn "\thour => $hour\n" |
120
|
|
|
|
|
|
|
if ( exists $self->{'debug'} && $self->{'debug'} >= 5 ); |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
} else { |
123
|
0
|
|
|
|
|
0
|
carp "Can't verify performance start time (" . $self->{'RAW'}[8] . ")"; |
124
|
|
|
|
|
|
|
} |
125
|
7
|
|
|
|
|
113
|
$self->{'data'}->{'Start Time'} = mktime($sec, $min, $hour, $day, ($mon-1), ($year-1900), 0, 0, -1); |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Verify our date and time conversion is correct |
128
|
7
|
|
|
|
|
766
|
my ($d) = strftime ("%Y-%m-%d %H:%M", localtime($self->{'data'}->{'Start Time'})); |
129
|
7
|
50
|
|
|
|
631
|
carp "Failed in Start Date parsing ($year-$mon-$day $hour:$min != $d)\n" |
130
|
|
|
|
|
|
|
if ( $d ne "$year-$mon-$day $hour:$min" ); |
131
|
|
|
|
|
|
|
} else { |
132
|
0
|
|
|
|
|
0
|
carp "Can't determine what day this performance data is from"; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub _parse_summary { |
137
|
7
|
|
|
7
|
|
15
|
my ($self) = @_; |
138
|
|
|
|
|
|
|
|
139
|
7
|
50
|
|
|
|
33
|
carp "Start of summary section line not 254" |
140
|
|
|
|
|
|
|
if ( $self->{'RAW'}[-5] != 254 ); |
141
|
|
|
|
|
|
|
|
142
|
7
|
|
|
|
|
61
|
my ($h, $m, $s, $f) = split (/\./, $self->{'RAW'}[-3] ); |
143
|
7
|
|
|
|
|
18
|
chomp($f); |
144
|
7
|
|
|
|
|
40
|
$self->{'data'}->{'Elapsed Time'} = ($h * 3600 + $m * 60 + $s + $f / 100) + 0.0; |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# Reset the last Elapsed Time in the Check Points to match |
147
|
|
|
|
|
|
|
# the total Elapsed Time. |
148
|
7
|
|
|
|
|
22
|
$self->{'data'}->{'Check Points'}->[scalar @{$self->{'data'}->{'Check Points'}} - 1]->{'Elapsed Time'} |
|
7
|
|
|
|
|
21
|
|
149
|
|
|
|
|
|
|
= $self->{'data'}->{'Elapsed Time'}; |
150
|
|
|
|
|
|
|
|
151
|
7
|
50
|
|
|
|
27
|
carp "Second to last line not 256" |
152
|
|
|
|
|
|
|
if ( $self->{'RAW'}[-2] != 256 ); |
153
|
|
|
|
|
|
|
|
154
|
7
|
|
|
|
|
12
|
my ($u); |
155
|
7
|
|
|
|
|
288
|
( $u, $self->{'data'}->{'Distance'}, $self->{'data'}->{'Cadence'} ) = |
156
|
7
|
|
|
|
|
14
|
split (/\s+/, ${$self->{'RAW'}}[-1]); |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub _parse_line { |
160
|
1935
|
|
|
1935
|
|
3219
|
my ($self, $line) = @_; |
161
|
1935
|
|
|
|
|
1926
|
my ($time, $dist); |
162
|
1935
|
|
|
|
|
2160
|
chomp $line; |
163
|
1935
|
|
|
|
|
2007
|
chop $line; |
164
|
1935
|
|
|
|
|
12450
|
my ($hr, $u, $speed, $power, $cadence, $grade, $alt) = split /\s/, $line; |
165
|
|
|
|
|
|
|
|
166
|
1928
|
|
|
|
|
3138
|
$time = $self->{'data'}->{'Sample Rate'} * |
167
|
|
|
|
|
|
|
( exists $self->{'data'}->{'Check Points'} |
168
|
1935
|
100
|
|
|
|
5569
|
? scalar @{$self->{'data'}->{'Check Points'}} |
169
|
|
|
|
|
|
|
: 0); |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# Insert a calculated distance for this Sample Rate, |
172
|
|
|
|
|
|
|
# which will be used in calculating the Average Speed. |
173
|
1935
|
100
|
|
|
|
5476
|
$dist = ( $speed / 10 ) * |
174
|
|
|
|
|
|
|
( exists $self->{'data'}->{'Check Points'} |
175
|
|
|
|
|
|
|
? ($self->{'data'}->{'Sample Rate'} / 3600) |
176
|
|
|
|
|
|
|
: 0); |
177
|
|
|
|
|
|
|
|
178
|
1935
|
|
|
|
|
1883
|
push @{$self->{'data'}->{'Check Points'}}, |
|
1935
|
|
|
|
|
18817
|
|
179
|
|
|
|
|
|
|
{ |
180
|
|
|
|
|
|
|
'Elapsed Time' => $time, |
181
|
|
|
|
|
|
|
'Calculated Distance' => $dist, |
182
|
|
|
|
|
|
|
'Heart Rate' => $hr, |
183
|
|
|
|
|
|
|
'Grade' => $grade / 10, |
184
|
|
|
|
|
|
|
'Speed' => $speed / 10, |
185
|
|
|
|
|
|
|
'Watts' => $power, |
186
|
|
|
|
|
|
|
'Cadence' => $cadence, |
187
|
|
|
|
|
|
|
'Altitude' => $alt, |
188
|
|
|
|
|
|
|
}; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub _add_averages { |
192
|
7
|
|
|
7
|
|
11
|
my ($self) = @_; |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# Calculate some useful averages |
195
|
7
|
|
|
|
|
25
|
my ( $c, $cc, $w, $wc, $hr, $hrc, $dist ) = ( 0, 0, 0, 0, 0, 0, 0 ); |
196
|
|
|
|
|
|
|
map { |
197
|
1935
|
100
|
|
|
|
5516
|
if ( $_->{'Cadence'} > 0 ) { |
|
7
|
|
|
|
|
60
|
|
198
|
1923
|
|
|
|
|
2459
|
$c += $_->{'Cadence'}; $cc++; |
|
1923
|
|
|
|
|
1980
|
|
199
|
1923
|
100
|
100
|
|
|
9820
|
$self->{'data'}->{'Max Cadence'} = $_->{'Cadence'} |
200
|
|
|
|
|
|
|
if ( ! exists $self->{'data'}->{'Max Cadence'} || $self->{'data'}->{'Max Cadence'} < $_->{'Cadence'} ); |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
1935
|
100
|
|
|
|
4507
|
if ( $_->{'Speed'} > 0 ) { |
204
|
1928
|
100
|
100
|
|
|
9182
|
$self->{'data'}->{'Max Speed'} = $_->{'Speed'} |
205
|
|
|
|
|
|
|
if ( ! exists $self->{'data'}->{'Max Speed'} || $self->{'data'}->{'Max Speed'} < $_->{'Speed'} ); |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# There is a bug when you have a warm up time, the first |
208
|
|
|
|
|
|
|
# checkpoint will have an unrealistic large value for Watts |
209
|
|
|
|
|
|
|
# and a zero value for Speed. |
210
|
1928
|
50
|
|
|
|
4522
|
if ( $_->{'Watts'} > 0 ) { |
211
|
1928
|
|
|
|
|
2292
|
$w += $_->{'Watts'}; $wc++; |
|
1928
|
|
|
|
|
2035
|
|
212
|
1928
|
100
|
100
|
|
|
9381
|
$self->{'data'}->{'Max Watts'} = $_->{'Watts'} |
213
|
|
|
|
|
|
|
if ( ! exists $self->{'data'}->{'Max Watts'} || $self->{'data'}->{'Max Watts'} < $_->{'Watts'} ); |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
} |
216
|
1935
|
100
|
|
|
|
5165
|
if ( $_->{'Heart Rate'} > 0 ) { |
217
|
1857
|
|
|
|
|
8272
|
$hr += $_->{'Heart Rate'}; $hrc++; |
|
1857
|
|
|
|
|
1704
|
|
218
|
1857
|
100
|
100
|
|
|
11369
|
$self->{'data'}->{'Max Heart Rate'} = $_->{'Heart Rate'} |
219
|
|
|
|
|
|
|
if ( ! exists $self->{'data'}->{'Max Heart Rate'} || $self->{'data'}->{'Max Heart Rate'} < $_->{'Heart Rate'} ); |
220
|
|
|
|
|
|
|
} |
221
|
1935
|
100
|
|
|
|
14741
|
$dist += $_->{'Calculated Distance'} |
222
|
|
|
|
|
|
|
if ( ( $_->{'Calculated Distance'} + 0.0 ) > 0 ); |
223
|
7
|
|
|
|
|
9
|
} @{$self->{'data'}->{'Check Points'}}; |
224
|
7
|
50
|
|
|
|
65
|
$self->{'data'}->{'Average Cadence'} = $c / $cc if ( $cc > 0 ); |
225
|
7
|
50
|
|
|
|
33
|
$self->{'data'}->{'Average Watts'} = $w / $wc if ( $wc > 0 ); |
226
|
7
|
100
|
|
|
|
28
|
$self->{'data'}->{'Average Heart Rate'} = $hr / $hrc if ( $hrc > 0 ); |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# BUG: The Distance listed in the file is the total distance |
229
|
|
|
|
|
|
|
# ridden, vs the Elapsed Time is not including any warmup time |
230
|
|
|
|
|
|
|
# For example, in the Bike2009-10-25 5-05.RAW test file, the |
231
|
|
|
|
|
|
|
# elapsed time is 2700 seconds (45 minutes), yet the distance traveled |
232
|
|
|
|
|
|
|
# is 16.87, which was covered in 60 minutes. Therefor, need to recaclute |
233
|
|
|
|
|
|
|
# the average speed based on the checkpoint's average speed. |
234
|
|
|
|
|
|
|
#$self->{'data'}->{'Average Speed'} = |
235
|
|
|
|
|
|
|
# $self->{'data'}->{'Distance'} / ($self->{'data'}->{'Elapsed Time'} / 3600); |
236
|
7
|
|
|
|
|
14
|
$self->{'data'}->{'Calculated Distance'} = $dist; |
237
|
7
|
|
|
|
|
46
|
$self->{'data'}->{'Average Speed'} = $dist / ($self->{'data'}->{'Elapsed Time'} / 3600); |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub _verify_parse { |
241
|
7
|
|
|
7
|
|
13
|
my ($self) = @_; |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
# Verify we got good data. The number of sample lines should be close |
244
|
|
|
|
|
|
|
# to Elapsed Time / Sample Rate. The 1.99 instead of 2 was determined |
245
|
|
|
|
|
|
|
# emperically, and probably due to samping error or clock flux. |
246
|
7
|
|
|
|
|
42
|
carp "Check Point Data does not match Sample Rate" |
247
|
7
|
50
|
|
|
|
11
|
if ( scalar @{$self->{'data'}->{'Check Points'}} != |
248
|
|
|
|
|
|
|
int($self->{'data'}->{'Elapsed Time'} / $self->{'data'}->{'Sample Rate'} + 1.99)); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub parse { |
252
|
7
|
|
|
7
|
1
|
419016
|
my ($self, $file) = @_; |
253
|
7
|
|
|
|
|
118
|
my ($cnt); |
254
|
|
|
|
|
|
|
|
255
|
7
|
50
|
|
|
|
99
|
$self->open($file) || return undef; |
256
|
|
|
|
|
|
|
|
257
|
7
|
50
|
|
|
|
39
|
warn "Reading contents of (" . $file . ")\n" if ( exists $self->{'debug'} ); |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# Change the input record seperator so we get the \r\n eaten by |
260
|
|
|
|
|
|
|
# perl itself, instead of having to code it in the regexes when |
261
|
|
|
|
|
|
|
# parsing the file data. |
262
|
|
|
|
|
|
|
{ |
263
|
7
|
50
|
|
|
|
13
|
local ($/) = $CRLF if ( $^O ne 'MSWin32' ); |
|
7
|
|
|
|
|
111
|
|
264
|
7
|
|
|
|
|
1990
|
@{$self->{'RAW'}} = ; |
|
7
|
|
|
|
|
1431
|
|
265
|
7
|
|
|
|
|
200
|
chomp(@{$self->{'RAW'}}); |
|
7
|
|
|
|
|
163
|
|
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
7
|
|
|
|
|
59
|
$self->close(); |
269
|
|
|
|
|
|
|
|
270
|
7
|
|
|
|
|
39
|
croak "Not enough data in file" |
271
|
7
|
50
|
|
|
|
15
|
if ( scalar @{$self->{'RAW'}} < 14 ); |
272
|
|
|
|
|
|
|
|
273
|
7
|
|
|
|
|
4804
|
delete $self->{'data'}; |
274
|
|
|
|
|
|
|
|
275
|
7
|
|
|
|
|
40
|
$self->_parse_preamble(); |
276
|
|
|
|
|
|
|
|
277
|
7
|
|
|
|
|
63
|
$self->_parse_line($self->{'RAW'}[7]); |
278
|
7
|
|
|
|
|
18
|
for ($cnt = 10; $cnt < scalar (@{$self->{'RAW'}}) - 5; $cnt++) { |
|
1928
|
|
|
|
|
4997
|
|
279
|
1921
|
|
|
|
|
4784
|
$self->_parse_line($self->{'RAW'}[$cnt]); |
280
|
|
|
|
|
|
|
} |
281
|
7
|
|
|
|
|
26
|
$self->_parse_line($self->{'RAW'}[-4]); |
282
|
|
|
|
|
|
|
|
283
|
7
|
|
|
|
|
34
|
$self->_parse_summary(); |
284
|
|
|
|
|
|
|
|
285
|
7
|
|
|
|
|
31
|
$self->_add_averages(); |
286
|
|
|
|
|
|
|
|
287
|
7
|
|
|
|
|
41
|
$self->_verify_parse(); |
288
|
|
|
|
|
|
|
|
289
|
7
|
|
|
|
|
43
|
return ($self->{'data'}); |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
sub close { |
293
|
7
|
|
|
7
|
0
|
19
|
my ($self) = @_; |
294
|
|
|
|
|
|
|
|
295
|
7
|
50
|
|
|
|
31
|
warn "Closing file (" . $self->{'file'} . ")\n" if ( exists $self->{'debug'} ); |
296
|
7
|
|
|
|
|
100
|
close (FP); |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
1; |
300
|
|
|
|
|
|
|
__END__ |