Class: REXML::IOSource

Inherits:
Source show all
Defined in:
lib/rexml/source.rb

Overview

A Source that wraps an IO. See the Source class for method documentation

Instance Attribute Summary

Attributes inherited from Source

#buffer, #encoding, #line

Attributes included from Encoding

#encoding

Instance Method Summary collapse

Methods inherited from Source

#match_to, #match_to_consume

Methods included from Encoding

#check_encoding, #decode, #encode

Constructor Details

#initialize(arg, block_size = 500, encoding = nil) ⇒ IOSource

block_size has been deprecated



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
164
165
166
167
168
169
170
171
172
# File 'lib/rexml/source.rb', line 136

def initialize(arg, block_size=500, encoding=nil)
  @er_source = @source = arg
  @to_utf = false

  # Determining the encoding is a deceptively difficult issue to resolve.
  # First, we check the first two bytes for UTF-16.  Then we
  # assume that the encoding is at least ASCII enough for the '>', and
  # we read until we get one of those.  This gives us the XML declaration,
  # if there is one.  If there isn't one, the file MUST be UTF-8, as per
  # the XML spec.  If there is one, we can determine the encoding from
  # it.
  @buffer = ""
  str = @source.read( 2 ) || ''
  if encoding
    self.encoding = encoding
  elsif str[0,2] == "\xfe\xff"
    @line_break = "\000>"
  elsif str[0,2] == "\xff\xfe"
    @line_break = ">\000"
  elsif str[0,2] == "\xef\xbb"
    str += @source.read(1)
    str = '' if (str[2,1] == "\xBF")
    @line_break = ">"
  else
    @line_break = ">"
  end
  super( @source.eof? ? str : str+@source.readline( @line_break ) )

  if !@to_utf and
      @buffer.respond_to?(:force_encoding) and
      @source.respond_to?(:external_encoding) and
      @source.external_encoding != ::Encoding::UTF_8
    @force_utf8 = true
  else
    @force_utf8 = false
  end
end

Instance Method Details

#consume(pattern) ⇒ Object



205
206
207
# File 'lib/rexml/source.rb', line 205

def consume( pattern )
  match( pattern, true )
end

#current_lineObject

Returns the current line in the source.

Returns:

  • the current line in the source



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/rexml/source.rb', line 234

def current_line
  begin
    pos = @er_source.pos        # The byte position in the source
    lineno = @er_source.lineno  # The XML < position in the source
    @er_source.rewind
    line = 0                    # The \r\n position in the source
    begin
      while @er_source.pos < pos
        @er_source.readline
        line += 1
      end
    rescue
    end
  rescue IOError
    pos = -1
    line = -1
  end
  [pos, lineno, line]
end

#empty?Boolean

Returns:

  • (Boolean)


225
226
227
# File 'lib/rexml/source.rb', line 225

def empty?
  super and ( @source.nil? || @source.eof? )
end

#match(pattern, cons = false) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/rexml/source.rb', line 209

def match( pattern, cons=false )
  rv = pattern.match(@buffer)
  @buffer = $' if cons and rv
  while !rv and @source
    begin
      @buffer << readline
      rv = pattern.match(@buffer)
      @buffer = $' if cons and rv
    rescue
      @source = nil
    end
  end
  rv.taint
  rv
end

#positionObject



229
230
231
# File 'lib/rexml/source.rb', line 229

def position
  @er_source.pos rescue 0
end

#readObject



197
198
199
200
201
202
203
# File 'lib/rexml/source.rb', line 197

def read
  begin
    @buffer << readline
  rescue Exception, NameError
    @source = nil
  end
end

#scan(pattern, cons = false) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/rexml/source.rb', line 174

def scan(pattern, cons=false)
  rv = super
  # You'll notice that this next section is very similar to the same
  # section in match(), but just a liiittle different.  This is
  # because it is a touch faster to do it this way with scan()
  # than the way match() does it; enough faster to warrent duplicating
  # some code
  if rv.size == 0
    until @buffer =~ pattern or @source.nil?
      begin
        @buffer << readline
      rescue Iconv::IllegalSequence
        raise
      rescue
        @source = nil
      end
    end
    rv = super
  end
  rv.taint
  rv
end