Class: Bismas::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/bismas/parser.rb

Overview

  1. Each record is terminated by 0x0D 0x0A (CHARS[:newline]).

  2. Each record starts with 0x01 (CHARS[:rs]) or, if it’s a deleted record, with 0xFF (CHARS[:deleted]).

  3. Each field is terminated by 0x00 (CHARS[:fs]).

  4. Each field starts with the category “number”, a run of category_length characters except 0x00, 0x01, 0xDB or 0xFF; trailing space is stripped.

  5. 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.”

Direct Known Subclasses

Legacy

Defined Under Namespace

Classes: Legacy, ParseError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Parser

Returns a new instance of Parser.



79
80
81
82
83
# File 'lib/bismas/parser.rb', line 79

def initialize(options = {})
  @regex = Bismas.regex(options)

  @strict, @silent = options.values_at(:strict, :silent)
end

Class Method Details

.parse(io, options = {}, &block) ⇒ Object



74
75
76
77
# File 'lib/bismas/parser.rb', line 74

def self.parse(io, options = {}, &block)
  klass = options[:legacy] ? Legacy : self
  klass.new(options).parse(io, &block)
end

Instance Method Details

#parse(io, &block) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/bismas/parser.rb', line 85

def parse(io, &block)
  @input = StringScanner.new('')

  io.each { |input|
    @input << input

    parse_record(&block) while @input.check_until(@regex[:newline])
    @input.string = @input.string.byteslice(@input.pos..-1)
  }

  error('Unexpected data') unless @input.eos?

  self
end

#parse_fieldObject



115
116
117
118
119
120
121
122
123
# File 'lib/bismas/parser.rb', line 115

def parse_field
  k = match(:category, 0) and k.rstrip!

  v = match(:field, 1) or error(k ?
    "Unclosed field `#{k}'" : 'Unexpected data', :rest)

  k ? block_given? ? yield(k, v) : [k, v] :
    v.empty? ? nil : error('Malformed field', :field)
end

#parse_recordObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/bismas/parser.rb', line 100

def parse_record
  if match(:deleted)
    match(:skip_line)
    return
  elsif !match_record
    error('Malformed record', :line)
    return
  end

  r = Hash.new { |h, k| h[k] = [] }
  parse_field  { |k, v| r[k] << v } until match(:newline)

  block_given? ? yield(r) : r
end