class F4R::Decoder

Decode/Read binary FIT file and return data in a {Registry}.

Public Class Methods

decode(file_name) click to toggle source

FIT binary file decoder/reader by providing data in a human readable format [Hash]

@param [String] file_name path for file to be read

# File lib/f4r.rb, line 1672
def self.decode(file_name)
  io = ::File.open(file_name, 'rb')

  begin
    until io.eof?
      offset = io.pos

      registry = Registry.new(Definition::Header.read(io))

      while io.pos < offset + registry.header.file_size
        record_header = Definition::RecordHeader.read(io)

        local_message_number = record_header.local_message_type.snapshot

        if record_header.for_new_definition?
          record_definition = Definition::Record.read(io)

          registry.definitions << {
            local_message_number: local_message_number,
            message_name: record_definition.global_message[:name],
            header: record_header,
            record: record_definition
          }
        else
          record_definition = registry.definitions.reverse.find do |d|
            d[:local_message_number] == local_message_number
          end[:record]

          data = record_definition.read_data(io)

          record = Record.new(record_definition.global_message[:name])

          record_definition.data_fields.each do |field|
            value = data[field.number].snapshot
            record.set_field_value(field, value)
          end

          registry.add record, local_message_number
        end
      end

      io.seek(2, :CUR)
    end
  ensure
    io.close
  end

  Log.info "Finished reading #{file_name} file."

  registry
end