Class: XMLScan::Source

Inherits:
PrivateArray show all
Defined in:
lib/xmlscan/scanner.rb

Instance Method Summary collapse

Constructor Details

#initialize(src) ⇒ Source

Source inherits Array only for speed.



102
103
104
105
106
107
# File 'lib/xmlscan/scanner.rb', line 102

def initialize(src)
  super()
  @src = Input.wrap(src)
  @eof = false
  @last = nil
end

Instance Method Details

#abortObject



118
119
120
121
122
123
# File 'lib/xmlscan/scanner.rb', line 118

def abort
  @eof = true
  @last = nil
  clear
  self
end

#close_tagObject

tag_end?, and remove a ‘>’.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/xmlscan/scanner.rb', line 181

def close_tag               # tag_end?, and remove a `>'.
  unless s = last || @last and s[0] != ?< then
    false
  else
    if s == '>' or s.empty? then
      s1 = get
      unless s = last || @last and s[0] == ?< then  # for speed up
        out = [ s1 ]
        out.push get while s = last || @last and s == '>' || s.empty?
        x=out.pop unless s and s[0] != ?<    # De Morgan
        concat out
      end
    end
    true
  end
end

#eachObject



239
240
241
242
243
244
245
# File 'lib/xmlscan/scanner.rb', line 239

def each
  prepare
  while s = get
    yield s
  end
  self
end

#eof?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/xmlscan/scanner.rb', line 114

def eof?
  @eof and empty?
end

#getObject

Managing source in a private array.

* tag oriented (?< and ?> are the key tokens
* ?> that aren't followed by another ?< or ?> are stripped in splitting


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/xmlscan/scanner.rb', line 130

def get
  pop or
    unless @eof then
      last = @last
      begin
        unless chunk = @src.gets then
          @eof = true
          @last = nil
          return last
          #unshift last # to be popped after reverse!
          #last = nil
          #break
        end
        # negative lookahead: < or >< or >>
        # so don't consume those (but split leaving them always at the
        # end of chunks)
        # consume (>) and split on >
        a = chunk.split(/(?=<|>[<>])|>/, -1)
        if last then
          unless /\A[<>]/ =~ a.first then
            a[0] = last << (a.first || '')
          else
            push last
          end
        end
        raise "size #{size}" if size > 1
        concat a
        last = pop
      end while empty?
      @last = last
      reverse!
      pop
    end
end

#get_plainObject



207
208
209
210
211
# File 'lib/xmlscan/scanner.rb', line 207

def get_plain
  s = get
  s = '>' << s unless not s or (c = s[0]) == ?< or c == ?>  # De Morgan
  s
end

#get_tagObject

get until tag_end?



203
204
205
# File 'lib/xmlscan/scanner.rb', line 203

def get_tag      # get until tag_end?
  s = last || @last and s[0] == ?< and get
end

#get_textObject

get until tag_start?



199
200
201
# File 'lib/xmlscan/scanner.rb', line 199

def get_text     # get until tag_start?
  s = last || @last and s[0] != ?< and get
end

#inspectObject

The following methods are for debug.



224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/xmlscan/scanner.rb', line 224

def inspect
  a = []
  reverse_each { |i|
    a.push ">" unless /\A[<>]/ =~ i
    a.push i.inspect
  }
  last = []
  if @last then
    last.push ">" unless /\A[<>]/ =~ @last
    last.push @last.inspect
  end
  a.push '#eof' if @eof
  "((#{a*' '}) l(#{last*' '}) . #{source.inspect})"
end

#linenoObject



213
214
215
# File 'lib/xmlscan/scanner.rb', line 213

def lineno
  @src.lineno
end

#pathObject



217
218
219
# File 'lib/xmlscan/scanner.rb', line 217

def path
  @src.path
end

#prepareObject



166
167
168
169
170
# File 'lib/xmlscan/scanner.rb', line 166

def prepare
  s = get
  s = get and s = '>' << s if s and s.empty?  # preserve first `>'
  s and push s
end

#sourceObject



109
110
111
# File 'lib/xmlscan/scanner.rb', line 109

def source
  Input.unwrap @src
end

#tag_end?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/xmlscan/scanner.rb', line 173

def tag_end?
  s = last || @last and s[0] != ?<
end

#tag_start?Boolean

Returns:

  • (Boolean)


177
178
179
# File 'lib/xmlscan/scanner.rb', line 177

def tag_start?
  s = last || @last and s[0] == ?<
end

#testObject



247
248
249
# File 'lib/xmlscan/scanner.rb', line 247

def test
  last or @last or (s = get and push s and s)
end