Class: Multipart::Post::CompositeReadIO

Inherits:
Object
  • Object
show all
Defined in:
lib/multipart/post/composite_read_io.rb

Overview

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

Examples:

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.



31
32
33
34
# File 'lib/multipart/post/composite_read_io.rb', line 31

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

Instance Method Details

#closeObject

Close all the underyling IOs.



37
38
39
40
41
42
43
44
# File 'lib/multipart/post/composite_read_io.rb', line 37

def close
  @ios.each do |io|
    io.close if io.respond_to?(:close)
  end

  @ios = nil
  @index = 0
end

#closed?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/multipart/post/composite_read_io.rb', line 46

def closed?
  @ios.nil?
end

#read(length = nil, outbuf = nil) ⇒ Object

Read from IOs in order until length bytes have been received.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/multipart/post/composite_read_io.rb', line 51

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

#rewindObject



72
73
74
75
# File 'lib/multipart/post/composite_read_io.rb', line 72

def rewind
  @ios.each { |io| io.rewind }
  @index = 0
end