lib/polyphony/extensions/io.rb in polyphony-1.5 vs lib/polyphony/extensions/io.rb in polyphony-1.6

- old
+ new

@@ -57,16 +57,16 @@ f.seek(offset) if offset length ? f.read(length) : f.read end end - # alias_method :orig_readlines, :readlines - # def readlines(name, sep = $/, limit = nil, getline_args = EMPTY_HASH) - # File.open(name, 'r') do |f| - # f.readlines(sep, limit, getline_args) - # end - # end + alias_method :orig_readlines, :readlines + def readlines(name, sep = $/, limit = nil, getline_args = EMPTY_HASH) + File.open(name, 'r') do |f| + f.readlines(sep, **getline_args) + end + end # @!visibility private alias_method :orig_write, :write # @!visibility private @@ -85,10 +85,46 @@ return orig_popen(cmd, mode) unless block_given? Open3.popen2(cmd) { |_i, o, _t| yield o } end + def copy_stream(src, dst, src_length = nil, src_offset = 0) + close_src = false + close_dst = false + if !src.respond_to?(:readpartial) + src = File.open(src, 'r+') + close_src = true + end + if !dst.respond_to?(:readpartial) + dst = File.open(dst, 'w+') + close_dst = true + end + src.seek(src_offset) if src_offset > 0 + + pipe = Polyphony::Pipe.new + + pipe_to_dst = spin { dst.splice_from(pipe, -65536) } + + count = 0 + if src_length + while count < src_length + count += pipe.splice_from(src, src_length) + end + else + count = pipe.splice_from(src, -65536) + end + + pipe.close + pipe_to_dst.await + + count + ensure + pipe_to_dst&.stop + src.close if close_src + dst.close if close_dst + end + # Splices from one IO to another IO. At least one of the IOs must be a pipe. # If maxlen is negative, splices repeatedly using absolute value of maxlen # until EOF is encountered. # # @param src [IO, Polyphony::Pipe] source to splice from @@ -107,10 +143,21 @@ # @return [Integer] total bytes spliced def double_splice(src, dest) Polyphony.backend_double_splice(src, dest) end + if !Polyphony.respond_to?(:backend_double_splice) + def double_splice(src, dest) + pipe = Polyphony::Pipe.new + f = spin { Polyphony.backend_splice(pipe, dest, -65536) } + Polyphony.backend_splice(src, pipe, -65536) + pipe.close + ensure + f.stop + end + end + # Tees data from the source to the desination. # # @param src [IO, Polyphony::Pipe] source to tee from # @param dest [IO, Polyphony::Pipe] destination to tee to # @param maxlen [Integer] maximum bytes to tee @@ -119,15 +166,10 @@ Polyphony.backend_tee(src, dest, maxlen) end if RUBY_PLATFORM !~ /linux/ # @!visibility private - def double_splice(src, dest) - raise NotImplementedError - end - - # @!visibility private def tee(src, dest, maxlen) raise NotImplementedError end end end @@ -201,11 +243,11 @@ return '' if len == 0 return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf @read_buffer ||= +'' result = Polyphony.backend_read(self, @read_buffer, len, true, -1) - return nil unless result + return '' unless result already_read = @read_buffer @read_buffer = +'' already_read end @@ -278,11 +320,11 @@ line = @read_buffer.slice!(0, idx + sep_size) line = line.chomp if chomp yield line end - result = readpartial(8192, @read_buffer, -1) + result = Polyphony.backend_read(self, @read_buffer, 8192, false, -1) return self if !result end rescue EOFError return self end @@ -434,10 +476,10 @@ # # @return [void] def close return if closed? - Polyphony.backend_close(self) + Polyphony.backend_close(self) rescue nil nil end if RUBY_PLATFORM =~ /linux/ # Tees data from the given IO.