| 
									
										
										
										
											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 |