class Stash::Sword::SequenceIO
A read-only `IO`-like that concatenates a sequence of strings or IOs.
Attributes
index[R]
input[R]
inputs[R]
Public Class Methods
new(inputs)
click to toggle source
Creates a new {SequenceIO} concatenating the specified input sources. Strings are wrapped internally as `StringIO`.
@param inputs [Enumerable<String, IO>] an array of strings and/or IOs to
concatenate
# File lib/stash/sword/sequence_io.rb, line 13 def initialize(inputs) inputs = [inputs] unless inputs.respond_to?(:[]) && inputs.respond_to?(:map) @inputs = to_ios(inputs) binmode if any_binmode(@inputs) @index = 0 @input = @inputs[index] unless inputs.empty? end
Public Instance Methods
binmode()
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 36 def binmode return self if binmode? inputs.each do |input| input.binmode if input.respond_to?(:binmode) end @binmode = true self end
binmode?()
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 45 def binmode? @binmode end
close()
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 49 def close next_input! until input.nil? end
closed?()
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 53 def closed? input.nil? && index >= inputs.length end
read(length = nil, outbuf = nil)
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 28 def read(length = nil, outbuf = nil) # use <= instead of == to get around https://github.com/bbatsov/rubocop/issues/3131 return nil if size <= 0 outbuf = outbuf ? outbuf.clear : '' length ? read_segment(length, outbuf) : read_fully(outbuf) outbuf end
size()
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 21 def size @size ||= inputs.inject(0) do |sum, input| raise "input #{input} does not respond to :size" unless input.respond_to?(:size) sum + input.size end end
Private Instance Methods
any_binmode(ios)
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 97 def any_binmode(ios) ios.each do |io| return true if io.respond_to?(:binmode?) && io.binmode? end false end
next_input!()
click to toggle source
TODO: Array.pop! or something
# File lib/stash/sword/sequence_io.rb, line 85 def next_input! input.close if input && input.respond_to?(:close) @index += 1 @input = index < inputs.length ? inputs[index] : nil end
read_fully(buffer)
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 63 def read_fully(buffer) until input.nil? buffer << input.read(nil) next_input! end end
read_segment(length, buffer)
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 70 def read_segment(length, buffer) return unless input && length > 0 remaining = length if (result = input.read(length)) buffer << result remaining = length - result.length end return unless remaining > 0 next_input! read_segment(remaining, buffer) end
to_ios(inputs)
click to toggle source
# File lib/stash/sword/sequence_io.rb, line 91 def to_ios(inputs) inputs.map do |input| input.respond_to?(:read) ? input : StringIO.new(input.to_s) end end