module F4R::Encoder

FIT binary file Encoder/Writer

Public Class Methods

encode(file_name, records, source) click to toggle source

Encode/Write binary FIT file

@param [String] file_name path for new FIT file @param [Hash,Registry] records

@param [String] source

Optional source FIT file to be used as a reference for
structuring the binary data.

@return [File] binary FIT file

# File lib/f4r.rb, line 1366
def self.encode(file_name, records, source)
  io = ::File.open(file_name, 'wb+')

  if records.is_a? Registry
    registry = records
  else
    registry = RegistryBuilder.new(records, source).registry
  end

  begin
    start_pos = registry.header.header_size

    io.seek(start_pos)

    local_messages = []
    last_local_message_number = nil
    registry.records.each do |record|

      local_message = local_messages.find do |lm|
        lm[:local_message_number] == record[:local_message_number] &&
          lm[:message_name] == record[:message_name]
      end

      unless local_message ||
          record[:local_message_number] == last_local_message_number

        local_messages << {
          local_message_number: record[:local_message_number],
          message_name: record[:message_name]
        }

        definition = registry.definition(record)
        definition[:header].write(io)
        definition[:record].write(io)
      end

      definition = registry.definition(record)
      definition[:header].write_data_header(io, record)
      definition[:record].write_data(io, record)

      last_local_message_number = record[:local_message_number]
    end

    end_pos = io.pos
    BinData::Uint16le.new(CRC16.crc(IO.binread(io, end_pos, start_pos))).write(io)
    registry.header.data_size = end_pos - start_pos
    io.rewind
    registry.header.write(io)
  ensure
    io.close
  end

  file_name
end