class REXML::IOSource - rexml: Ruby Standard Library Documentation

# class REXML::IOSource

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

### Public Class Methods

new(arg, block_size=500, encoding=nil) click to toggle source

block_size has been deprecated

Calls superclass method `REXML::Source::new`

    # File rexml-3.4.0/lib/rexml/source.rb, line 205
    def initialize(arg, block_size=500, encoding=nil)
      @er_source = @source = arg
      @to_utf = false
      @pending_buffer = nil

      if encoding
        super("", encoding)
      else
        super(@source.read(3) || "")
      end

      if !@to_utf and
          @orig.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

### Public Instance Methods

current_line() click to toggle source

@return the current line in the source

    # File rexml-3.4.0/lib/rexml/source.rb, line 310
    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
        @er_source.seek(pos)
      rescue IOError, SystemCallError
        pos = -1
        line = -1
      end
      [pos, lineno, line]
    end

empty?() click to toggle source
Calls superclass method `REXML::Source#empty?`

    # File rexml-3.4.0/lib/rexml/source.rb, line 305
    def empty?
      super and ( @source.nil? || @source.eof? )
    end

ensure_buffer() click to toggle source

    # File rexml-3.4.0/lib/rexml/source.rb, line 265
    def ensure_buffer
      read if @scanner.eos? && @source
    end

match( pattern, cons=false ) click to toggle source

    # File rexml-3.4.0/lib/rexml/source.rb, line 269
    def match( pattern, cons=false )
      # To avoid performance issue, we need to increase bytes to read per scan
      min_bytes = 1
      while true
        if cons
          md = @scanner.scan(pattern)
        else
          md = @scanner.check(pattern)
        end
        break if md
        return nil if pattern.is_a?(String)
        return nil if @source.nil?
        return nil unless read(nil, min_bytes)
        min_bytes *= 2
      end

      md.nil? ? nil : @scanner
    end

match?( pattern, cons=false ) click to toggle source

    # File rexml-3.4.0/lib/rexml/source.rb, line 288
    def match?( pattern, cons=false )
      # To avoid performance issue, we need to increase bytes to read per scan
      min_bytes = 1
      while true
        if cons
          n_matched_bytes = @scanner.skip(pattern)
        else
          n_matched_bytes = @scanner.match?(pattern)
        end
        return true if n_matched_bytes
        return false if pattern.is_a?(String)
        return false if @source.nil?
        return false unless read(nil, min_bytes)
        min_bytes *= 2
      end
    end

read(term = nil, min_bytes = 1) click to toggle source

    # File rexml-3.4.0/lib/rexml/source.rb, line 226
    def read(term = nil, min_bytes = 1)
      term = encode(term) if term
      begin
        str = readline(term)
        @scanner << str
        read_bytes = str.bytesize
        begin
          while read_bytes < min_bytes
            str = readline(term)
            @scanner << str
            read_bytes += str.bytesize
          end
        rescue IOError
        end
        true
      rescue Exception, NameError
        @source = nil
        false
      end
    end

read_until(term) click to toggle source

    # File rexml-3.4.0/lib/rexml/source.rb, line 247
    def read_until(term)
      pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/
      term = @encoded_terms[term] ||= encode(term)
      until str = @scanner.scan_until(pattern)
        break if @source.nil?
        break if @source.eof?
        @scanner << readline(term)
      end
      if str
        read if @scanner.eos? and !@source.eof?
        str
      else
        rest = @scanner.rest
        @scanner.pos = @scanner.string.bytesize
        rest
      end
    end

### Private Instance Methods

encoding_updated() click to toggle source
Calls superclass method `REXML::Source#encoding_updated`

    # File rexml-3.4.0/lib/rexml/source.rb, line 357
    def encoding_updated
      case @encoding
      when "UTF-16BE", "UTF-16LE"
        @source.binmode
        @source.set_encoding(@encoding, @encoding)
      end
      @line_break = encode(">")
      @pending_buffer, @scanner.string = @scanner.rest, ""
      @pending_buffer.force_encoding(@encoding)
      super
    end

readline(term = nil) click to toggle source

    # File rexml-3.4.0/lib/rexml/source.rb, line 332
    def readline(term = nil)
      if @pending_buffer
        begin
          str = @source.readline(term || @line_break)
        rescue IOError
        end
        if str.nil?
          str = @pending_buffer
        else
          str = @pending_buffer + str
        end
        @pending_buffer = nil
      else
        str = @source.readline(term || @line_break)
      end
      return nil if str.nil?

      if @to_utf
        decode(str)
      else
        str.force_encoding(::Encoding::UTF_8) if @force_utf8
        str
      end
    end