@@ -29,23 +29,12 @@ def initialize(ios)
2929 #
3030 # @return [String, nil]
3131 def read ( length = nil , outbuf = nil )
32- outbuf = outbuf . to_s . clear
33- # buffer in JRuby is sometimes US-ASCII, force to ASCII-8BIT
34- outbuf . force_encoding ( Encoding ::BINARY )
32+ data = outbuf . clear . force_encoding ( Encoding ::BINARY ) if outbuf
33+ data ||= "" . b
3534
36- while current_io
37- current_io . read ( length , @buffer )
38- outbuf << @buffer . force_encoding ( Encoding ::BINARY )
39-
40- if length
41- length -= @buffer . bytesize
42- break if length . zero?
43- end
44-
45- advance_io
46- end
35+ read_chunks ( length ) { |chunk | data << chunk }
4736
48- outbuf unless length && outbuf . empty?
37+ data unless length && data . empty?
4938 end
5039
5140 # Returns sum of all IO sizes.
@@ -61,6 +50,30 @@ def rewind
6150
6251 private
6352
53+ # Yields chunks with total length up to `length`.
54+ def read_chunks ( length = nil )
55+ while ( chunk = readpartial ( length ) )
56+ yield chunk . force_encoding ( Encoding ::BINARY )
57+
58+ next if length . nil?
59+
60+ length -= chunk . bytesize
61+
62+ break if length . zero?
63+ end
64+ end
65+
66+ # Reads chunk from current IO with length up to `max_length`.
67+ def readpartial ( max_length = nil )
68+ while current_io
69+ chunk = current_io . read ( max_length , @buffer )
70+
71+ return chunk if chunk && !chunk . empty?
72+
73+ advance_io
74+ end
75+ end
76+
6477 # Returns IO object under the cursor.
6578 def current_io
6679 @ios [ @index ]
0 commit comments