class EDI::S::StreamingParser
Class StreamingParser
¶ ↑
For a documentation, see class EDI::E::StreamingParser
; this class is its SEDAS equivalent.
Public Class Methods
# File lib/edi4r/sedas.rb, line 597 def initialize @path = 'input stream' end
Public Instance Methods
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
Called when UNB or UIB encountered
# File lib/edi4r/sedas.rb, line 621 def on_00( s ) end
Called when UNG encountered
# File lib/edi4r/sedas.rb, line 631 def on_01( s ) end
Called when UNE encountered
# File lib/edi4r/sedas.rb, line 636 def on_98( s ) end
Called when UNZ or UIZ encountered
# File lib/edi4r/sedas.rb, line 626 def on_99( s ) end
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
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
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
Called when UNT or UIT encountered
# File lib/edi4r/sedas.rb, line 646 def on_msg_end end
Called when UNH or UIH encountered
# File lib/edi4r/sedas.rb, line 641 def on_msg_start( s ) end
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
Called when any other segment encountered
# File lib/edi4r/sedas.rb, line 651 def on_segment( s, tag ) end
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