1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
module Zip
module IOExtras
# Implements many of the convenience methods of IO
# such as gets, getc, readline and readlines
# depends on: input_finished?, produce_input and read
module AbstractInputStream
include Enumerable
include FakeIO
def initialize
super
@lineno = 0
@pos = 0
@output_buffer = ''
end
attr_accessor :lineno
attr_reader :pos
def read(number_of_bytes = nil, buf = '')
tbuf = if @output_buffer.bytesize > 0
if number_of_bytes <= @output_buffer.bytesize
@output_buffer.slice!(0, number_of_bytes)
else
number_of_bytes -= @output_buffer.bytesize if number_of_bytes
rbuf = sysread(number_of_bytes, buf)
out = @output_buffer
out << rbuf if rbuf
@output_buffer = ''
out
end
else
sysread(number_of_bytes, buf)
end
if tbuf.nil? || tbuf.length == 0
return nil if number_of_bytes
return ""
end
@pos += tbuf.length
if buf
buf.replace(tbuf)
else
buf = tbuf
end
buf
end
def readlines(a_sep_string = $/)
ret_val = []
each_line(a_sep_string) { |line| ret_val << line }
ret_val
end
def gets(a_sep_string = $/, number_of_bytes = nil)
@lineno = @lineno.next
if number_of_bytes.respond_to?(:to_int)
number_of_bytes = number_of_bytes.to_int
a_sep_string = a_sep_string.to_str if a_sep_string
elsif a_sep_string.respond_to?(:to_int)
number_of_bytes = a_sep_string.to_int
a_sep_string = $/
else
number_of_bytes = nil
a_sep_string = a_sep_string.to_str if a_sep_string
end
return read(number_of_bytes) if a_sep_string.nil?
a_sep_string = "#{$/}#{$/}" if a_sep_string.empty?
buffer_index = 0
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit
buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max
if input_finished?
return @output_buffer.empty? ? nil : flush
end
@output_buffer << produce_input
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
end
sep_index = [match_index + a_sep_string.bytesize, number_of_bytes || @output_buffer.bytesize].min
@pos += sep_index
return @output_buffer.slice!(0...sep_index)
end
def ungetc(byte)
@output_buffer = byte.chr + @output_buffer
end
def flush
ret_val = @output_buffer
@output_buffer = ''
ret_val
end
def readline(a_sep_string = $/)
ret_val = gets(a_sep_string)
raise EOFError unless ret_val
ret_val
end
def each_line(a_sep_string = $/)
while true
yield readline(a_sep_string)
end
rescue EOFError
end
alias_method :each, :each_line
end
end
end
|