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

Constant Summary

Constants included from Encoding

Encoding::UNILE, Encoding::UTF_16, Encoding::UTF_8

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

apply, #check_encoding, #decode_ascii, #decode_cp1252, #decode_iconv, #decode_unile, #decode_utf16, #decode_utf8, #encode_ascii, #encode_cp1252, #encode_iconv, #encode_unile, #encode_utf16, #encode_utf8, encoding_method, #from_iso_8859_15, register, #to_iso_8859_15

Constructor Details

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

block_size has been deprecated



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
# File 'lib/rexml/source.rb', line 134

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 0xfe == str[0] && 0xff == str[1]
    @line_break = "\000>"
  elsif 0xff == str[0] && 0xfe == str[1]
    @line_break = ">\000"
  elsif 0xef == str[0] && 0xbb == str[1]
    str += @source.read(1)
    str = '' if (0xbf == str[2])
    @line_break = ">"
  else
    @line_break = ">"
  end
  super str+@source.readline( @line_break )
end

Instance Method Details

#consume(pattern) ⇒ Object



200
201
202
# File 'lib/rexml/source.rb', line 200

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

#current_lineObject

Returns the current line in the source.

Returns:

  • the current line in the source



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

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)


222
223
224
# File 'lib/rexml/source.rb', line 222

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

#match(pattern, cons = false) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/rexml/source.rb', line 204

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

#positionObject



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

def position
  @er_source.stat.pipe? ? 0 : @er_source.pos
end

#readObject



190
191
192
193
194
195
196
197
198
# File 'lib/rexml/source.rb', line 190

def read
  begin
    str = @source.readline(@line_break)
    str = decode(str) if @to_utf and str 
    @buffer << str
  rescue Exception, NameError
    @source = nil
  end
end

#scan(pattern, cons = false) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/rexml/source.rb', line 163

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
        # READLINE OPT
        #str = @source.read(@block_size)
        str = @source.readline(@line_break)
        str = decode(str) if @to_utf and str
        @buffer << str
      rescue Iconv::IllegalSequence
        raise
      rescue
        @source = nil
      end
    end
    rv = super
  end
  rv.taint
  rv
end