Method: NMEAPlus::SourceDecoder#each_complete_message

Defined in:
lib/nmea_plus.rb

#each_complete_message {|NMEAPlus::Message| ... } ⇒ void

This method returns an undefined value.

Attempts to group multipart NMEA messages into chains, and executes the block once for every complete chain. To limit memory use (and be realistic about our ability to match up messages), only 1 message of chain of each NMEA message type can be in progress at any one time.

Examples:

input1 = "!AIVDM,2,1,0,A,58wt8Ui`g??r21`7S=:22058<v05Htp000000015>8OA;0sk,0*7B"
input2 = "!AIVDM,2,2,0,A,eQ8823mDm3kP00000000000,2*5D"
io_source = StringIO.new("#{input1}\n#{input2}")  # source decoder works on any IO object
source_decoder = NMEAPlus::SourceDecoder.new(io_source)
source_decoder.each_complete_message do |message|
  if message.ais && message.ais.message_type == 5
    ais = message.ais  # ais payload shortcut
    puts "Ship with MMSI #{ais.source_mmsi} (#{ais.name.strip}) is going to #{ais.destination.strip}"
    # prints "Ship with MMSI 603916439 (ARCO AVON) is going to HOUSTON"
  end
end

Yields:


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/nmea_plus.rb', line 79

def each_complete_message
  partials = {}  # hash of message type to message-chain-in-progress
  each_message do |msg|
    # don't clutter things up if the message arrives already complete
    if msg.all_messages_received?
      yield msg
      next
    end

    # put message into partials slot (merge if necessary) based on its data type
    slot = msg.data_type
    if partials[slot].nil?                                           # no message in there
      partials[slot] = msg
    elsif 1 != (msg.message_number - partials[slot].message_number)  # broken sequence
      # error! just overwrite what was there
      partials[slot] = msg
    else                                                             # chain on to what's there
      partials[slot].add_message_part(msg)
    end

    # take action if we've completed the chain
    maybe_full = partials[slot]
    if maybe_full.all_messages_received?
      partials[slot] = nil
      yield maybe_full
    end
  end
end