class Bismas::Parser
-
Each record is terminated by
0x0D
0x0A
(CHARS[:newline]
). -
Each record starts with
0x01
(CHARS[:rs]
) or, if it’s a deleted record, with0xFF
(CHARS[:deleted]
). -
Each field is terminated by
0x00
(CHARS[:fs]
). -
Each field starts with the category “number”, a run of
category_length
characters except0x00
,0x01
,0xDB
or0xFF
; trailing space is stripped. -
The remaining characters of a field form the category content; trailing padding
0xDB
(CHARS[:padding]
) is stripped.
To quote the BISMAS handbook: “Konkret wird bei BISMAS jeder Datensatz durch ASCII(1) eingeleitet. Es folgt die erste Kategorienummer mit dem Kategorieinhalt. Abgeschlossen wird jede Kategorie mit ASCII(0), danach folgt die nächste Kategorienummer und -inhalt usw. Der gesamte Datensatz wird mit ASCII (13)(10) abgeschlossen.”
Public Class Methods
# File lib/bismas/parser.rb 79 def initialize(options = {}) 80 @regex = Bismas.regex(options) 81 82 @strict, @silent = options.values_at(:strict, :silent) 83 end
# File lib/bismas/parser.rb 74 def self.parse(io, options = {}, &block) 75 klass = options[:legacy] ? Legacy : self 76 klass.new(options).parse(io, &block) 77 end
Public Instance Methods
# File lib/bismas/parser.rb 85 def parse(io, &block) 86 @input = StringScanner.new('') 87 88 io.each { |input| 89 @input << input 90 91 parse_record(&block) while @input.check_until(@regex[:newline]) 92 @input.string = @input.string.byteslice(@input.pos..-1) 93 } 94 95 error('Unexpected data') unless @input.eos? 96 97 self 98 end
# File lib/bismas/parser.rb 115 def parse_field 116 k = match(:category, 0) and k.rstrip! 117 118 v = match(:field, 1) or error(k ? 119 "Unclosed field `#{k}'" : 'Unexpected data', :rest) 120 121 k ? block_given? ? yield(k, v) : [k, v] : 122 v.empty? ? nil : error('Malformed field', :field) 123 end
# File lib/bismas/parser.rb 100 def parse_record 101 if match(:deleted) 102 match(:skip_line) 103 return 104 elsif !match_record 105 error('Malformed record', :line) 106 return 107 end 108 109 r = Hash.new { |h, k| h[k] = [] } 110 parse_field { |k, v| r[k] << v } until match(:newline) 111 112 block_given? ? yield(r) : r 113 end
Private Instance Methods
# File lib/bismas/parser.rb 136 def error(message, skip = nil) 137 err = parse_error(message) 138 raise err unless skip && !@strict 139 140 warn err.to_s unless @silent 141 match(:"skip_#{skip}") 142 nil 143 end
# File lib/bismas/parser.rb 127 def match(key, index = nil) 128 res = @input.skip(@regex.fetch(key)) 129 res && index ? @input[index] : res 130 end
# File lib/bismas/parser.rb 132 def match_record 133 match(:rs) 134 end
# File lib/bismas/parser.rb 145 def parse_error(message) 146 ParseError.new(@input, message) 147 end