Class: Amp::Support::MultiIO
Overview
MultiIO
A MultiIO is a class which joins multiple IO classes together. It responds to #read, and its constituent IOs must respond to #read. Since, currently, it only needs to be able to read (and perhaps rewind), that’s all it does. It allows one to feed, say, 3 separate input IO objects into a GZipWriter, and have it seamlessly traverse all 3 IOs.
Instance Attribute Summary collapse
-
#current_io_idx ⇒ Object
Points to the current IO object in the @ios array.
-
#current_pos ⇒ Object
Tracks our current index into the “joined” stream.
-
#ios ⇒ Object
These are all the base IO objects we are joining together.
Instance Method Summary collapse
-
#initialize(*ios) ⇒ MultiIO
constructor
Initializes the MultiIO to contain the given IO objects, in the order in which they are specified as arguments.
-
#read(amt = nil) ⇒ String
Reads from the concatenated IO stream, crossing streams if necessary.
-
#rewind ⇒ Object
Rewinds all the IO objects to position 0.
-
#tell ⇒ Integer
Gets the current position in the concatenated IO stream.
Constructor Details
#initialize(*ios) ⇒ MultiIO
Initializes the MultiIO to contain the given IO objects, in the order in which they are specified as arguments.
24 25 26 27 |
# File 'lib/amp/support/multi_io.rb', line 24 def initialize(*ios) @ios = ios rewind end |
Instance Attribute Details
#current_io_idx ⇒ Object
Points to the current IO object in the @ios array.
14 15 16 |
# File 'lib/amp/support/multi_io.rb', line 14 def current_io_idx @current_io_idx end |
#current_pos ⇒ Object
Tracks our current index into the “joined” stream. In other words, if they were all lumped into 1 stream, how many bytes in would we be?
17 18 19 |
# File 'lib/amp/support/multi_io.rb', line 17 def current_pos @current_pos end |
#ios ⇒ Object
These are all the base IO objects we are joining together.
12 13 14 |
# File 'lib/amp/support/multi_io.rb', line 12 def ios @ios end |
Instance Method Details
#read(amt = nil) ⇒ String
Reads from the concatenated IO stream, crossing streams if necessary. (DON’T CROSS THE STREAMS!!!!)
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 |
# File 'lib/amp/support/multi_io.rb', line 50 def read(amt=nil) if amt==nil # if nil, read it all return @ios[@current_io_idx..-1].map {|io| io.read}.join end results = [] # result strings amount_read = 0 # how much have we read? We need this to match the +amt+ param cur_spot = current_io.tell # our current position while amount_read < amt # until we've read enough to meet the request results << current_io.read(amt - amount_read) # read enough to finish amount_read += current_io.tell - cur_spot # but we might not have actually read that much @current_pos += current_io.tell - cur_spot # update ivar # Do we need to go to the next IO stream? if amount_read < amt && @current_io_idx < @ios.size - 1 # go to the next stream @current_io_idx += 1 # reset it just in case current_io.seek(0) # are we at the last stream? elsif @current_io_idx >= @ios.size - 1 break end # if we need to read from another stream, then remember we're at the start of it cur_spot = 0 end # join 'em up results.join end |
#rewind ⇒ Object
Rewinds all the IO objects to position 0.
31 32 33 34 35 |
# File 'lib/amp/support/multi_io.rb', line 31 def rewind @ios.each {|io| io.seek(0) } @current_pos = 0 @current_io_idx = 0 end |
#tell ⇒ Integer
Gets the current position in the concatenated IO stream.
41 |
# File 'lib/amp/support/multi_io.rb', line 41 def tell; @current_pos; end |