# File lib/ole/ranges_io.rb, line 129
  def read limit=nil
    data = ''
    return data if eof?
    limit ||= size
    partial_range, i = offset_and_size @pos
    # this may be conceptually nice (create sub-range starting where we are), but
    # for a large range array its pretty wasteful. even the previous way was. but
    # i'm not trying to optimize this atm. it may even go to c later if necessary.
    ([partial_range] + ranges[i+1..-1]).each do |pos, len|
      @io.seek pos
      if limit < len
        # convoluted, to handle read errors. s may be nil
        s = @io.read limit
        @pos += s.length if s
        break data << s
      end
      # convoluted, to handle ranges beyond the size of the file
      s = @io.read len
      @pos += s.length if s
      data << s
      break if s.length != len
      limit -= len
    end
    data
  end