Class: CompositeReadIO

Inherits:
Object
  • Object
show all
Defined in:
lib/composite_io.rb

Overview

Concatenate together multiple IO objects into a single, composite IO object for purposes of reading as a single stream.

Usage:

crio = CompositeReadIO.new(StringIO.new('one'), StringIO.new('two'), StringIO.new('three'))
puts crio.read # => "onetwothree"

Instance Method Summary collapse

Constructor Details

#initialize(*ios) ⇒ CompositeReadIO

Create a new composite-read IO from the arguments, all of which should respond to #read in a manner consistent with IO.



18
19
20
# File 'lib/composite_io.rb', line 18

def initialize(*ios)
  @ios = ios.flatten
end

Instance Method Details

#read(amount = nil, buf = nil) ⇒ Object

Read from the IO object, overlapping across underlying streams as necessary.



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
# File 'lib/composite_io.rb', line 23

def read(amount = nil, buf = nil)
  buffer = buf || ''
  done = if amount; nil; else ''; end
  partial_amount = amount

  loop do
    result = done

    while !@ios.empty? && (result = @ios.first.read(partial_amount)) == done
      @ios.shift
    end

    result.force_encoding("BINARY") if result.respond_to?(:force_encoding)
    buffer << result if result
    partial_amount -= result.length if partial_amount && result != done

    break if partial_amount && partial_amount <= 0
    break if result == done
  end

  if buffer.length > 0
    buffer
  else
    done
  end
end