File: abstract_input_stream.rb

package info (click to toggle)
ruby-zip 3.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 11,120 kB
  • sloc: ruby: 9,958; makefile: 23
file content (128 lines) | stat: -rw-r--r-- 3,768 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# frozen_string_literal: true

module Zip
  module IOExtras # :nodoc:
    # 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:
      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 && 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

        if tbuf.nil? || tbuf.empty?
          return nil if number_of_bytes&.positive?

          return ''
        end

        @pos += tbuf.length

        if buf
          buf.replace(tbuf)
        else
          buf = tbuf
        end
        buf
      end

      def readlines(a_sep_string = $INPUT_RECORD_SEPARATOR)
        ret_val = []
        each_line(a_sep_string) { |line| ret_val << line }
        ret_val
      end

      def gets(a_sep_string = $INPUT_RECORD_SEPARATOR, 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    = $INPUT_RECORD_SEPARATOR
        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 = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" 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
          return @output_buffer.empty? ? nil : flush if input_finished?

          @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
        @output_buffer.slice!(0...sep_index)
      end

      def ungetc(byte)
        @output_buffer = byte.chr + @output_buffer
      end

      def flush
        ret_val        = @output_buffer
        @output_buffer = +''
        ret_val
      end

      def readline(a_sep_string = $INPUT_RECORD_SEPARATOR)
        ret_val = gets(a_sep_string)
        raise EOFError unless ret_val

        ret_val
      end

      def each_line(a_sep_string = $INPUT_RECORD_SEPARATOR)
        loop { yield readline(a_sep_string) }
      rescue EOFError
        # We just need to catch this; we don't need to handle it.
      end

      alias each each_line

      def eof?
        @output_buffer.empty? && input_finished?
      end

      # Alias for compatibility. Remove for version 4.
      alias eof eof?
    end
  end
end