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
|
|
|
|
|
2017-06-29 10:57:12 +08:00
|
|
|
if tbuf.nil? || tbuf.empty?
|
2013-09-25 06:29:19 +08:00
|
|
|
return nil if number_of_bytes
|
2020-02-09 21:13:21 +08:00
|
|
|
|
2015-03-21 16:27:44 +08:00
|
|
|
return ''
|
2013-09-25 06:29:19 +08:00
|
|
|
end
|
2013-08-27 04:26:14 +08:00
|
|
|
|
2013-09-25 06:29:19 +08:00
|
|
|
@pos += tbuf.length
|
2013-08-27 04:26:14 +08:00
|
|
|
|
|
|
|
if buf
|
|
|
|
buf.replace(tbuf)
|
|
|
|
else
|
|
|
|
buf = tbuf
|
|
|
|
end
|
|
|
|
buf
|
|
|
|
end
|
|
|
|
|
2019-09-27 04:46:00 +08:00
|
|
|
def readlines(a_sep_string = $INPUT_RECORD_SEPARATOR)
|
2013-08-27 04:26:14 +08:00
|
|
|
ret_val = []
|
|
|
|
each_line(a_sep_string) { |line| ret_val << line }
|
|
|
|
ret_val
|
|
|
|
end
|
|
|
|
|
2019-09-27 04:46:00 +08:00
|
|
|
def gets(a_sep_string = $INPUT_RECORD_SEPARATOR, number_of_bytes = nil)
|
2013-08-27 04:26:14 +08:00
|
|
|
@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
|
2019-09-27 04:46:00 +08:00
|
|
|
a_sep_string = $INPUT_RECORD_SEPARATOR
|
2013-08-27 04:26:14 +08:00
|
|
|
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?
|
2020-02-09 21:13:21 +08:00
|
|
|
|
2019-09-27 04:46:00 +08:00
|
|
|
a_sep_string = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" if a_sep_string.empty?
|
2013-08-27 04:26:14 +08:00
|
|
|
|
|
|
|
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
|
2015-03-25 00:09:22 +08:00
|
|
|
return @output_buffer.empty? ? nil : flush if input_finished?
|
2020-02-09 21:13:21 +08:00
|
|
|
|
2013-08-27 04:26:14 +08:00
|
|
|
@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
|
2015-06-08 15:26:13 +08:00
|
|
|
@pos += sep_index
|
2015-03-23 00:27:29 +08:00
|
|
|
@output_buffer.slice!(0...sep_index)
|
2013-08-27 04:26:14 +08:00
|
|
|
end
|
|
|
|
|
2014-03-12 09:19:24 +08:00
|
|
|
def ungetc(byte)
|
2014-03-12 23:52:12 +08:00
|
|
|
@output_buffer = byte.chr + @output_buffer
|
2014-03-12 09:19:24 +08:00
|
|
|
end
|
|
|
|
|
2013-08-27 04:26:14 +08:00
|
|
|
def flush
|
|
|
|
ret_val = @output_buffer
|
|
|
|
@output_buffer = ''
|
|
|
|
ret_val
|
|
|
|
end
|
|
|
|
|
2019-09-27 04:46:00 +08:00
|
|
|
def readline(a_sep_string = $INPUT_RECORD_SEPARATOR)
|
2013-08-27 04:26:14 +08:00
|
|
|
ret_val = gets(a_sep_string)
|
|
|
|
raise EOFError unless ret_val
|
2020-02-09 21:13:21 +08:00
|
|
|
|
2013-08-27 04:26:14 +08:00
|
|
|
ret_val
|
|
|
|
end
|
|
|
|
|
2019-09-27 04:46:00 +08:00
|
|
|
def each_line(a_sep_string = $INPUT_RECORD_SEPARATOR)
|
2020-02-09 19:01:57 +08:00
|
|
|
loop { yield readline(a_sep_string) }
|
2013-08-27 04:26:14 +08:00
|
|
|
rescue EOFError
|
2020-02-09 19:27:11 +08:00
|
|
|
# We just need to catch this; we don't need to handle it.
|
2013-08-27 04:26:14 +08:00
|
|
|
end
|
|
|
|
|
2020-02-09 23:28:30 +08:00
|
|
|
alias each each_line
|
2019-12-23 23:30:39 +08:00
|
|
|
|
|
|
|
def eof
|
|
|
|
@output_buffer.empty? && input_finished?
|
|
|
|
end
|
|
|
|
|
2020-02-09 23:28:30 +08:00
|
|
|
alias eof? eof
|
2013-08-27 04:26:14 +08:00
|
|
|
end
|
|
|
|
end
|
2014-03-12 09:19:24 +08:00
|
|
|
end
|