@@ -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