Skip to content
This repository was archived by the owner on May 8, 2025. It is now read-only.

Commit c86f8f2

Browse files
committed
Handle arrays properly
1 parent bb07819 commit c86f8f2

File tree

1 file changed

+51
-41
lines changed

1 file changed

+51
-41
lines changed

src/phpFITFileAnalysis.php

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class phpFITFileAnalysis
3939
{
4040
public $data_mesgs = []; // Used to store the data read from the file in associative arrays.
4141
private $dev_field_descriptions = [];
42-
4342
private $options = null; // Options provided to __construct().
4443
private $file_contents = ''; // FIT file is read-in to memory as a string, split into an array, and reversed. See __construct().
4544
private $file_pointer = 0; // Points to the location in the file that shall be read next.
@@ -585,42 +584,42 @@ class phpFITFileAnalysis
585584
*/
586585
private $endianness = [
587586
0 => [ // Little Endianness
588-
0 => 'Ctmp', // enum
589-
1 => 'ctmp', // sint8
590-
2 => 'Ctmp', // uint8
591-
131 => 'vtmp', // sint16 - manually convert uint16 to sint16 in fixData()
592-
132 => 'vtmp', // uint16
593-
133 => 'Vtmp', // sint32 - manually convert uint32 to sint32 in fixData()
594-
134 => 'Vtmp', // uint32
595-
7 => 'a*tmp', // string
596-
136 => 'ftmp', // float32
597-
137 => 'dtmp', // float64
598-
10 => 'Ctmp', // uint8z
599-
139 => 'vtmp', // uint16z
600-
140 => 'Vtmp', // uint32z
601-
13 => 'Ctmp', // byte
602-
142 => 'Ptmp', // sint64 - manually convert uint64 to sint64 in fixData()
603-
143 => 'Ptmp', // uint64
604-
144 => 'Ptmp' // uint64z
587+
0 => ['format' => 'Ctmp', 'bytes' => 1], // enum
588+
1 => ['format' => 'ctmp', 'bytes' => 1], // sint8
589+
2 => ['format' => 'Ctmp', 'bytes' => 1], // uint8
590+
131 => ['format' => 'vtmp', 'bytes' => 2], // sint16 - manually convert uint16 to sint16 in fixData()
591+
132 => ['format' => 'vtmp', 'bytes' => 2], // uint16
592+
133 => ['format' => 'Vtmp', 'bytes' => 4], // sint32 - manually convert uint32 to sint32 in fixData()
593+
134 => ['format' => 'Vtmp', 'bytes' => 4], // uint32
594+
7 => ['format' => 'a*tmp', 'bytes' => 1], // string
595+
136 => ['format' => 'ftmp', 'bytes' => 4], // float32
596+
137 => ['format' => 'dtmp', 'bytes' => 8], // float64
597+
10 => ['format' => 'Ctmp', 'bytes' => 1], // uint8z
598+
139 => ['format' => 'vtmp', 'bytes' => 2], // uint16z
599+
140 => ['format' => 'Vtmp', 'bytes' => 4], // uint32z
600+
13 => ['format' => 'Ctmp', 'bytes' => 1], // byte
601+
142 => ['format' => 'Ptmp', 'bytes' => 8], // sint64 - manually convert uint64 to sint64 in fixData()
602+
143 => ['format' => 'Ptmp', 'bytes' => 8], // uint64
603+
144 => ['format' => 'Ptmp', 'bytes' => 8] // uint64z
605604
],
606605
1 => [ // Big Endianness
607-
0 => 'Ctmp', // enum
608-
1 => 'ctmp', // sint8
609-
2 => 'Ctmp', // uint8
610-
131 => 'ntmp', // sint16 - manually convert uint16 to sint16 in fixData()
611-
132 => 'ntmp', // uint16
612-
133 => 'Ntmp', // sint32 - manually convert uint32 to sint32 in fixData()
613-
134 => 'Ntmp', // uint32
614-
7 => 'a*tmp', // string
615-
136 => 'ftmp', // float32
616-
137 => 'dtmp', // float64
617-
10 => 'Ctmp', // uint8z
618-
139 => 'ntmp', // uint16z
619-
140 => 'Ntmp', // uint32z
620-
13 => 'Ctmp', // byte
621-
142 => 'Jtmp', // sint64 - manually convert uint64 to sint64 in fixData()
622-
143 => 'Jtmp', // uint64
623-
144 => 'Jtmp' // uint64z
606+
0 => ['format' => 'Ctmp', 'bytes' => 1], // enum
607+
1 => ['format' => 'ctmp', 'bytes' => 1], // sint8
608+
2 => ['format' => 'Ctmp', 'bytes' => 1], // uint8
609+
131 => ['format' => 'ntmp', 'bytes' => 1], // sint16 - manually convert uint16 to sint16 in fixData()
610+
132 => ['format' => 'ntmp', 'bytes' => 1], // uint16
611+
133 => ['format' => 'Ntmp', 'bytes' => 1], // sint32 - manually convert uint32 to sint32 in fixData()
612+
134 => ['format' => 'Ntmp', 'bytes' => 1], // uint32
613+
7 => ['format' => 'a*tmp', 'bytes' => 1], // string
614+
136 => ['format' => 'ftmp', 'bytes' => 1], // float32
615+
137 => ['format' => 'dtmp', 'bytes' => 1], // float64
616+
10 => ['format' => 'Ctmp', 'bytes' => 1], // uint8z
617+
139 => ['format' => 'ntmp', 'bytes' => 1], // uint16z
618+
140 => ['format' => 'Ntmp', 'bytes' => 1], // uint32z
619+
13 => ['format' => 'Ctmp', 'bytes' => 1], // byte
620+
142 => ['format' => 'Jtmp', 'bytes' => 1], // sint64 - manually convert uint64 to sint64 in fixData()
621+
143 => ['format' => 'Jtmp', 'bytes' => 1], // uint64
622+
144 => ['format' => 'Jtmp', 'bytes' => 1] // uint64z
624623
]
625624
];
626625

@@ -1214,7 +1213,7 @@ private function readDataRecords()
12141213

12151214
$global_mesg_num = ($architecture === 0) ? unpack('v1tmp', substr($this->file_contents, $this->file_pointer, 2))['tmp'] : unpack('n1tmp', substr($this->file_contents, $this->file_pointer, 2))['tmp'];
12161215
$this->file_pointer += 2;
1217-
1216+
12181217
$num_fields = ord(substr($this->file_contents, $this->file_pointer, 1));
12191218
$this->file_pointer++;
12201219

@@ -1279,7 +1278,7 @@ private function readDataRecords()
12791278
// Check that we have information on the Field Definition and a valid base type exists.
12801279
if (isset($this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]) && isset($this->types[$field_defn['base_type']])) {
12811280
// Check if it's an invalid value for the type
1282-
$tmp_value = unpack($this->types[$field_defn['base_type']], substr($this->file_contents, $this->file_pointer, $field_defn['size']))['tmp'];
1281+
$tmp_value = unpack($this->types[$field_defn['base_type']]['format'], substr($this->file_contents, $this->file_pointer, $field_defn['size']))['tmp'];
12831282
if ($tmp_value !== $this->invalid_values[$field_defn['base_type']]) {
12841283
// If it's a timestamp, compensate between different in FIT and Unix timestamp epochs
12851284
if ($field_defn['field_definition_number'] === 253 && !$this->garmin_timestamps) {
@@ -1289,13 +1288,23 @@ private function readDataRecords()
12891288
// If it's a Record data message, store all the pieces in the temporary array as the timestamp may not be first...
12901289
if ($this->defn_mesgs[$local_mesg_type]['global_mesg_num'] === 20) {
12911290
$tmp_record_array[$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['field_name']] = $tmp_value / $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['scale'] - $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['offset'];
1292-
} elseif ($this->defn_mesgs[$local_mesg_type]['global_mesg_num'] === 206) {
1291+
} elseif ($this->defn_mesgs[$local_mesg_type]['global_mesg_num'] === 206) { // Developer Data
12931292
$tmp_record_array[$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['field_name']] = $tmp_value;
12941293
} else {
12951294
if ($field_defn['base_type'] === 7) { // Handle strings appropriately
12961295
$this->data_mesgs[$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['mesg_name']][$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['field_name']][] = filter_var($tmp_value, FILTER_SANITIZE_STRING);
12971296
} else {
1298-
$this->data_mesgs[$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['mesg_name']][$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['field_name']][] = $tmp_value / $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['scale'] - $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['offset'];
1297+
// Handle arrays
1298+
if ($field_defn['size'] !== $this->types[$field_defn['base_type']]['bytes']) {
1299+
$tmp_array = [];
1300+
$num_vals = $field_defn['size'] / $this->types[$field_defn['base_type']]['bytes'];
1301+
for ($i=0; $i<$num_vals; ++$i) {
1302+
$tmp_array[] = unpack($this->types[$field_defn['base_type']]['format'], substr($this->file_contents, $this->file_pointer + ($i * $this->types[$field_defn['base_type']]['bytes']), $field_defn['size']))['tmp']/ $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['scale'] - $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['offset'];
1303+
}
1304+
$this->data_mesgs[$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['mesg_name']][$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['field_name']][] = $tmp_array;
1305+
} else {
1306+
$this->data_mesgs[$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['mesg_name']][$this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['field_name']][] = $tmp_value / $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['scale'] - $this->data_mesg_info[$this->defn_mesgs[$local_mesg_type]['global_mesg_num']]['field_defns'][$field_defn['field_definition_number']]['offset'];
1307+
}
12991308
}
13001309
}
13011310
}
@@ -1323,7 +1332,7 @@ private function readDataRecords()
13231332
$this->data_mesgs['developer_data'][$this->dev_field_descriptions[$field_defn['developer_data_index']][$field_defn['field_definition_number']]['field_name']]['units'] = $this->dev_field_descriptions[$field_defn['developer_data_index']][$field_defn['field_definition_number']]['units'];
13241333

13251334
// Data
1326-
$this->data_mesgs['developer_data'][$this->dev_field_descriptions[$field_defn['developer_data_index']][$field_defn['field_definition_number']]['field_name']]['data'][] = unpack($this->types[$this->dev_field_descriptions[$field_defn['developer_data_index']][$field_defn['field_definition_number']]['fit_base_type_id']], substr($this->file_contents, $this->file_pointer, $field_defn['size']))['tmp'];
1335+
$this->data_mesgs['developer_data'][$this->dev_field_descriptions[$field_defn['developer_data_index']][$field_defn['field_definition_number']]['field_name']]['data'][] = unpack($this->types[$this->dev_field_descriptions[$field_defn['developer_data_index']][$field_defn['field_definition_number']]['fit_base_type_id']]['format'], substr($this->file_contents, $this->file_pointer, $field_defn['size']))['tmp'];
13271336

13281337
$this->file_pointer += $field_defn['size'];
13291338
}
@@ -2587,10 +2596,11 @@ public function showDebugInfo()
25872596
echo '<thead>';
25882597
echo '<th>key</th>';
25892598
echo '<th>PHP unpack() format</th>';
2599+
echo '<th>Bytes</th>';
25902600
echo '</thead>';
25912601
echo '<tbody>';
25922602
foreach ($this->types as $key => $val) {
2593-
echo '<tr><td>'.$key.'</td><td>'.$val[0].'</td></tr>';
2603+
echo '<tr><td>'.$key.'</td><td>'.$val['format'].'</td><td>'.$val['bytes'].'</td></tr>';
25942604
}
25952605
echo '</tbody>';
25962606
echo '</table>';

0 commit comments

Comments
 (0)