Class: Fit4Ruby::GlobalFitMessage

Inherits:
Object
  • Object
show all
Defined in:
lib/fit4ruby/GlobalFitMessage.rb

Overview

The GlobalFitMessage stores an abstract description of a particular FitMessage. It holds information like the name, the global ID number and the data fields of the message.

Defined Under Namespace

Classes: AltField, Field

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, number, field_values_by_name = {}) ⇒ GlobalFitMessage

Create a new GlobalFitMessage definition.

Parameters:

  • name (String)

    name of the FIT message

  • number (Fixnum)

    global message number



223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 223

def initialize(name, number, field_values_by_name = {})
  @name = name
  @number = number
  # Field names must be unique. A name always matches a single Field.
  @fields_by_name = {}
  # Field numbers are not unique. A group of alternative fields shares the
  # same number and is stored as an AltField. Otherwise as Field.
  @fields_by_number = {}
  # To generate the proper definition message we need to know the length
  # of String and Array fields. This is only needed when writing FIT
  # files.
  @field_values_by_name = field_values_by_name
end

Instance Attribute Details

#field_values_by_nameObject (readonly)

Returns the value of attribute field_values_by_name.



24
25
26
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 24

def field_values_by_name
  @field_values_by_name
end

#fields_by_nameObject (readonly)

Returns the value of attribute fields_by_name.



24
25
26
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 24

def fields_by_name
  @fields_by_name
end

#fields_by_numberObject (readonly)

Returns the value of attribute fields_by_number.



24
25
26
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 24

def fields_by_number
  @fields_by_number
end

#nameObject (readonly)

Returns the value of attribute name.



24
25
26
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 24

def name
  @name
end

#numberObject (readonly)

Returns the value of attribute number.



24
25
26
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 24

def number
  @number
end

Instance Method Details

#==(m) ⇒ Object

Two GlobalFitMessage objects are considered equal if they have the same number, name and list of named fields. In case they have String or Array values, they must have identical size.



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 240

def ==(m)
  unless @number == m.number && @name == m.name &&
      @fields_by_name.keys.sort == m.fields_by_name.keys.sort
    return false
  end

  unless @field_values_by_name.size == m.field_values_by_name.size
    return false
  end

  unless @field_values_by_name.empty?
    @field_values_by_name.keys.each do |name|
      a = @field_values_by_name[name]
      b = m.field_values_by_name[name]
      if a.class != b.class
        return false
      end
      if a.is_a?(String)
        if a.bytes.length != b.bytes.length
          return false
        end
      elsif a.is_a?(Array)
        if a.length != b.length
          return false
        end
      end
    end
  end

  true
end

#alt_field(number, ref_field, &block) ⇒ Object

Define a new set of Field alternatives for this message definition.



297
298
299
300
301
302
303
304
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 297

def alt_field(number, ref_field, &block)
  unless @fields_by_name.include?(ref_field)
    raise "Unknown ref_field: #{ref_field}"
  end

  field = AltField.new(self, ref_field, &block)
  register_field_by_number(field, number)
end

#construct(field_values_by_name) ⇒ Object



322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 322

def construct(field_values_by_name)
  gfm = GlobalFitMessage.new(@name, @number, field_values_by_name)

  @fields_by_number.each do |number, field|
    if field.is_a?(AltField)
      # For alternative fields, we need to look at the value of the
      # selector field and pick the corresponding Field.
      field = field.select(field_values_by_name)
    end
    gfm.field(number, field.type, field.name, field.opts)
  end

  gfm
end

#each_field(field_values) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 272

def each_field(field_values)
  @fields_by_number.each do |number, field|
    if field.is_a?(AltField)
      # For alternative fields, we need to look at the value of the
      # selector field and pick the corresponding Field.
      field = field.select(field_values)
    end

    yield(number, field)
  end
end

#field(number, type, name, opts = {}) ⇒ Object

Define a new Field for this message definition.



285
286
287
288
289
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 285

def field(number, type, name, opts = {})
  field = Field.new(type, name, opts)
  register_field_by_name(field, name)
  register_field_by_number(field, number)
end

#has_field?(name) ⇒ Boolean

Check if a field with the given name already exists?

Returns:

  • (Boolean)


292
293
294
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 292

def has_field?(name)
  return @fields_by_name.include?(name)
end

#register_field_by_name(field, name) ⇒ Object



306
307
308
309
310
311
312
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 306

def register_field_by_name(field, name)
  if @fields_by_name.include?(name)
    raise "Field '#{name}' has already been defined"
  end

  @fields_by_name[name] = field
end

#register_field_by_number(field, number) ⇒ Object



314
315
316
317
318
319
320
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 314

def register_field_by_number(field, number)
  if @fields_by_name.include?(number)
    raise "Field #{number} has already been defined"
  end

  @fields_by_number[number] = field
end

#write(io, local_message_type) ⇒ Object



337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/fit4ruby/GlobalFitMessage.rb', line 337

def write(io, local_message_type)
  header = FitRecordHeader.new
  header.normal = 0
  header.message_type = 1
  header.local_message_type = local_message_type
  header.write(io)

  definition = FitDefinition.new
  definition.global_message_number = @number
  definition.setup(self, @field_values_by_name)
  definition.write(io)
end