108 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| 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
 | |
| 
 | |
|         @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 |