rubyzip/lib/zip/ioextras/abstract_input_stream.rb

128 lines
3.6 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2013-08-27 04:26:14 +08:00
module Zip
module IOExtras # :nodoc:
2013-08-27 04:26:14 +08:00
# 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 # :nodoc:
2013-08-27 04:26:14 +08:00
include Enumerable
include FakeIO
def initialize
super
@lineno = 0
@pos = 0
2021-03-06 08:36:09 +08:00
@output_buffer = +''
2013-08-27 04:26:14 +08:00
end
attr_accessor :lineno
attr_reader :pos
2021-03-06 08:36:09 +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 && number_of_bytes <= @output_buffer.bytesize
2013-08-27 04:26:14 +08:00
@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?
return nil if number_of_bytes&.positive?
2015-03-21 16:27:44 +08:00
return ''
end
2013-08-27 04:26:14 +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?
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
2013-08-27 04:26:14 +08:00
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?
2013-08-27 04:26:14 +08:00
@output_buffer << produce_input
over_limit = number_of_bytes && @output_buffer.bytesize >= number_of_bytes
2013-08-27 04:26:14 +08:00
end
sep_index = [
match_index + a_sep_string.bytesize,
number_of_bytes || @output_buffer.bytesize
].min
@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
def ungetc(byte)
@output_buffer = byte.chr + @output_buffer
end
2013-08-27 04:26:14 +08:00
def flush
ret_val = @output_buffer
2021-03-06 08:36:09 +08:00
@output_buffer = +''
2013-08-27 04:26:14 +08:00
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
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)
loop { yield readline(a_sep_string) }
2013-08-27 04:26:14 +08:00
rescue EOFError
# 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
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
end