class CompositeReadIO
Concatenate together multiple IO objects into a single, composite IO object for purposes of reading as a single stream.
crio = CompositeReadIO.new(StringIO.new('one'),
StringIO.new('two'),
StringIO.new('three'))
puts crio.read # => "onetwothree"
Definitions
def initialize(*ios)
Create a new composite-read IO from the arguments, all of which should respond to #read in a manner consistent with IO.
Implementation
def initialize(*ios)
@ios = ios.flatten
@index = 0
end
def close
Close all the underyling IOs.
Implementation
def close
@ios.each do |io|
io.close if io.respond_to?(:close)
end
@ios = nil
@index = 0
end
def read(length = nil, outbuf = nil)
Read from IOs in order until length
bytes have been received.
Implementation
def read(length = nil, outbuf = nil)
if @ios.nil?
raise IOError, "CompositeReadIO is closed!"
end
got_result = false
outbuf = outbuf ? outbuf.replace("") : String.new
while io = current_io
if result = io.read(length)
got_result ||= !result.nil?
result.force_encoding("BINARY") if result.respond_to?(:force_encoding)
outbuf << result
length -= result.length if length
break if length == 0
end
advance_io
end
(!got_result && length) ? nil : outbuf
end