Class: Fit4Ruby::FitDefinitionField

Inherits:
BinData::Record
  • Object
show all
Defined in:
lib/fit4ruby/FitDefinitionField.rb

Overview

The FitDefinitionField models the part of the FIT file that contains the template definition for a field of a FitMessageRecord. It should match the corresponding definition in GlobalFitMessages. In case we don’t have a known entry in GlobalFitMessages we can still read the file since we know the exact size of the binary records.

Constant Summary collapse

@@TypeDefs =
[
  # FIT Type, BinData type, undefined value, bytes
  [ 'enum', 'uint8', 0xFF, 1 ],
  [ 'sint8', 'int8', 0x7F, 1 ],
  [ 'uint8', 'uint8', 0xFF, 1 ],
  [ 'sint16', 'int16', 0x7FFF, 2 ],
  [ 'uint16', 'uint16', 0xFFFF, 2 ],
  [ 'sint32', 'int32', 0x7FFFFFFF, 4 ],
  [ 'uint32', 'uint32', 0xFFFFFFFF, 4 ],
  [ 'string', 'string', '', 0 ],
  [ 'float32', 'float', 0xFFFFFFFF, 4 ],
  [ 'float63', 'double', 0xFFFFFFFF, 4 ],
  [ 'uint8z', 'uint8', 0, 1 ],
  [ 'uint16z', 'uint16', 0, 2 ],
  [ 'uint32z', 'uint32', 0, 4 ],
  [ 'byte', 'uint8', 0xFF, 1 ]
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.fit_type_to_bin_data(fit_type) ⇒ Object



53
54
55
56
57
# File 'lib/fit4ruby/FitDefinitionField.rb', line 53

def self.fit_type_to_bin_data(fit_type)
  entry = @@TypeDefs.find { |e| e[0] == fit_type }
  raise "Unknown fit type #{fit_type}" unless entry
  entry[1]
end

.undefined_value(fit_type) ⇒ Object



59
60
61
62
63
# File 'lib/fit4ruby/FitDefinitionField.rb', line 59

def self.undefined_value(fit_type)
  entry = @@TypeDefs.find { |e| e[0] == fit_type }
  raise "Unknown fit type #{fit_type}" unless entry
  entry[2]
end

Instance Method Details

#base_type_bytesObject



159
160
161
162
# File 'lib/fit4ruby/FitDefinitionField.rb', line 159

def base_type_bytes
  check_fit_base_type
  @@TypeDefs[base_type_number.snapshot][3]
end

#initObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/fit4ruby/FitDefinitionField.rb', line 65

def init
  @global_message_number = parent.parent.global_message_number.snapshot
  @global_message_definition = GlobalFitMessages[@global_message_number]
  field_number = field_definition_number.snapshot
  if @global_message_definition &&
     (field = @global_message_definition.fields_by_number[field_number])
     @name = field.respond_to?('name') ? field.name :
                                         "choice_#{field_number}"
     @type = field.respond_to?('type') ? field.type : nil

     if @type && (td = @@TypeDefs[base_type_number]) && td[0] != @type
       Log.warn "#{@global_message_number}:#{@name} must be of type " +
       "#{@type}, not #{td[0]}"
     end
  else
    @name = "field#{field_definition_number.snapshot}"
    @type = nil
    Log.warn { "Unknown field number #{field_definition_number} " +
               "in global message #{@global_message_number}" }
  end
end

#is_array?Boolean

Returns:

  • (Boolean)


144
145
146
147
148
149
150
151
152
153
# File 'lib/fit4ruby/FitDefinitionField.rb', line 144

def is_array?
  if total_bytes > base_type_bytes
    if total_bytes % base_type_bytes != 0
      Log.fatal "Total bytes (#{total_bytes}) must be multiple of " +
                "base type bytes (#{base_type_bytes})."
    end
    return true
  end
  false
end

#nameObject



87
88
89
90
# File 'lib/fit4ruby/FitDefinitionField.rb', line 87

def name
  init unless @global_message_number
  @name
end

#set_type(fit_type) ⇒ Object



132
133
134
135
136
137
# File 'lib/fit4ruby/FitDefinitionField.rb', line 132

def set_type(fit_type)
  idx = @@TypeDefs.index { |x| x[0] == fit_type }
  raise "Unknown type #{fit_type}" unless idx
  self.base_type_number = idx
  self.byte_count = @@TypeDefs[idx][3]
end

#to_machine(value) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/fit4ruby/FitDefinitionField.rb', line 92

def to_machine(value)
  init unless @global_message_number
  value = nil if value == undefined_value

  field_number = field_definition_number.snapshot
  if value.kind_of?(Array)
    ary = []
    value.each { |v| ary << to_machine(v) }
    ary
  else
    if @global_message_definition &&
       (field = @global_message_definition.
        fields_by_number[field_number]) &&
       field.respond_to?('to_machine')
      field.to_machine(value)
    else
      value
    end
  end
end

#to_s(value) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/fit4ruby/FitDefinitionField.rb', line 113

def to_s(value)
  init unless @global_message_number
  value = nil if value == undefined_value

  if value.kind_of?(Array)
    s = '[ '
    value.each { |v| s << to_s(v) + ' ' }
    s + ']'
  else
    field_number = field_definition_number.snapshot
    if @global_message_definition &&
       (field = @global_message_definition.fields_by_number[field_number])
      field.to_s(value)
    else
      "[#{value.to_s}]"
    end
  end
end

#total_bytesObject



155
156
157
# File 'lib/fit4ruby/FitDefinitionField.rb', line 155

def total_bytes
  self.byte_count.snapshot
end

#type(fit_type = false) ⇒ Object



139
140
141
142
# File 'lib/fit4ruby/FitDefinitionField.rb', line 139

def type(fit_type = false)
  check_fit_base_type
  @@TypeDefs[base_type_number.snapshot][fit_type ? 0 : 1]
end

#undefined_valueObject



164
165
166
167
# File 'lib/fit4ruby/FitDefinitionField.rb', line 164

def undefined_value
  check_fit_base_type
  @@TypeDefs[base_type_number.snapshot][2]
end