class EDI::S::StreamingParser

Class StreamingParser

For a documentation, see class EDI::E::StreamingParser; this class is its SEDAS equivalent.

Public Class Methods

new() click to toggle source
# File lib/edi4r/sedas.rb, line 597
def initialize
  @path = 'input stream'
end

Public Instance Methods

go( hnd ) click to toggle source

The one-pass reader & dispatcher of segments, SAX-style.

It reads sequentially through the given records and generates calls to the callbacks on_... Parameter hnd may be any object supporting method gets.

# File lib/edi4r/sedas.rb, line 682
    def go( hnd )
      rec, rec_id, line_no, rec_no, pos_no, folgesatz = nil, nil, 0, 0, 0, nil
      @path = hnd.path if hnd.respond_to? :path
      @msg_begun = @msg_50_begun = false
      @msg_29_nr = nil

      self.on_interchange_start

      catch(:done) do
        loop do
          begin
            rec = hnd.gets
            line_no += 1
            break if rec.nil?
            rec.chomp!
            unless rec =~ /^\s*$/
              pos_no = rec[125,6].to_i
              rec_id = rec[0,2]
              raise "Wrong record order at line #{line_no}! Expected: #{pos_no}, found: #{rec_no}" if rec_no != pos_no && rec_id !~ /00|01|99/
              folgesatz = rec[146,2] # not valid for 00,01,03,51,96,98,99
            end
            case rec
            when /^\s*$/
              self.on_other( rec )
            when /^00/
              self.on_00( rec )
            when /^99/
              self.on_99( rec )
            when /^01/
              rec_no = pos_no
              # raise "SA01: pos_nr=#{pos_no}, expected 1" if pos_no != 1
              self.on_01( rec )
            when /^98/
              @msg_50_begun = false
              self.on_98( rec )

            when /^[12][25]/
              self.on_msg_end if @msg_begun
              self.on_msg_start( rec ) if folgesatz=='00'
              self.on_segment( rec, rec_id+folgesatz )

            when /^[12][3467]/
              self.on_segment( rec, rec_id+folgesatz )

            when /^29/  # Group change triggers new message!
              if rec[30,1]=='2' # Reli-Nr.
                nr_of_sa29 = rec[31..37] 
              else
                raise "Unexpected SA29 condition"
              end
              if @msg_29_nr != nr_of_sa29 # Group change!
                self.on_msg_end if @msg_begun
                self.on_msg_start( rec )
                @msg_29_nr = nr_of_sa29
              end
              self.on_segment( rec, rec_id+folgesatz )

            when /^50/  # Only first occurrence of SA50 starts a message!
              if not( @msg_50_begun )
                self.on_msg_end if @msg_begun
                raise "First SA50 - syntax error!" if folgesatz!='00'
                self.on_msg_start( rec )
                @msg_50_begun = true
              end
              self.on_segment( rec, rec_id+folgesatz )

            when /^51/
              self.on_segment( rec, '5100' )

            else
              $stderr.puts "Unsupported record type: '#{rec_id}#{folgesatz}' - ignored"
            end

          rescue
            warn "Error at record #{rec_no}, record id=#{rec_id}"
            raise
          end
          rec_no += 1
        end # loop

      end # catch(:done)

      self.on_interchange_end
#      offset
    end
on_00( s ) click to toggle source

Called when UNB or UIB encountered

# File lib/edi4r/sedas.rb, line 621
def on_00( s )
end
on_01( s ) click to toggle source

Called when UNG encountered

# File lib/edi4r/sedas.rb, line 631
def on_01( s )
end
on_98( s ) click to toggle source

Called when UNE encountered

# File lib/edi4r/sedas.rb, line 636
def on_98( s )
end
on_99( s ) click to toggle source

Called when UNZ or UIZ encountered

# File lib/edi4r/sedas.rb, line 626
def on_99( s )
end
on_error(err, offset, fragment, c=nil) click to toggle source

Called upon syntax errors. Parsing should be aborted now.

# File lib/edi4r/sedas.rb, line 670
def on_error(err, offset, fragment, c=nil)
  raise err, "offset = %d, last chars = %s%s" % 
    [offset, fragment, c.nil? ? '<EOF>' : c.chr]
end
on_interchange_end() click to toggle source

Called at EOF - overwrite for your cleanup purposes. Note: Must not throw :done !

# File lib/edi4r/sedas.rb, line 616
def on_interchange_end
end
on_interchange_start() click to toggle source

Called at start of reading - overwrite for your init purposes. Note: Must not throw :done !

# File lib/edi4r/sedas.rb, line 610
def on_interchange_start
end
on_msg_end() click to toggle source

Called when UNT or UIT encountered

# File lib/edi4r/sedas.rb, line 646
def on_msg_end
end
on_msg_start( s ) click to toggle source

Called when UNH or UIH encountered

# File lib/edi4r/sedas.rb, line 641
def on_msg_start( s )
end
on_other( s ) click to toggle source

This callback is usually kept empty. It is called when the parser finds strings between segments or in front of or trailing an interchange.

Strictly speaking, such strings are not permitted by the SEDAS syntax rules. However, some people e.g. seem to add empty lines at the end of a file. The default settings thus ignore such occurrences.

If you need strict conformance checking, feel free to put some code into this callback method, otherwise just ignore it.

# File lib/edi4r/sedas.rb, line 665
def on_other( s )
end
on_segment( s, tag ) click to toggle source

Called when any other segment encountered

# File lib/edi4r/sedas.rb, line 651
def on_segment( s, tag )
end
path() click to toggle source

Convenience method. Returns the path of the File object passed to method go or just string ‘input stream’

# File lib/edi4r/sedas.rb, line 603
def path
  @path
end