2013-08-27 04:26:14 +08:00
|
|
|
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
|
|
|
|
|
2013-08-30 05:22:19 +08:00
|
|
|
def read(number_of_bytes = nil, buf = '')
|
2013-08-27 04:26:14 +08:00
|
|
|
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
|
|
|
|
|
|
|
|
@pos += tbuf.length
|
|
|
|
|
|
|
|
return nil unless tbuf
|
|
|
|
|
|
|
|
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 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
|