Sha256: 70aca796608a4d39fcc04d0cc01340662b2c15c749ca1223fb7618521dff10bf

Contents?: true

Size: 1.42 KB

Versions: 5

Compression:

Stored size: 1.42 KB

Contents

require "tempfile"

module Down
  class ChunkedIO
    attr_reader :tempfile

    def initialize(options)
      @size     = options.fetch(:size)
      @chunks   = options.fetch(:chunks)
      @on_close = options.fetch(:on_close, ->{})
      @tempfile = Tempfile.new("down", binmode: true)
    end

    def size
      @size
    end

    def read(length = nil, outbuf = nil)
      download_chunk until enough_downloaded?(length) || download_finished?
      @tempfile.read(length, outbuf)
    end

    def each_chunk
      return enum_for(__method__) if !block_given?
      yield download_chunk until download_finished?
    end

    def eof?
      @tempfile.eof? && download_finished?
    end

    def rewind
      @tempfile.rewind
    end

    def close
      terminate_download
      @tempfile.close!
    end

    private

    def download_chunk
      chunk = @chunks.next
      write(chunk)
      begin
        @chunks.peek
      rescue StopIteration
        terminate_download
      end
      chunk
    end

    def enough_downloaded?(length)
      length && (@tempfile.pos + length <= @tempfile.size)
    end

    def download_finished?
      !@on_close
    end

    def terminate_download
      if @on_close
        @on_close.call
        @on_close = nil
      end
    end

    def write(chunk)
      current_pos = @tempfile.pos
      @tempfile.pos = @tempfile.size
      @tempfile.write(chunk)
      @tempfile.pos = current_pos
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
down-2.4.1 lib/down/chunked_io.rb
down-2.4.0 lib/down/chunked_io.rb
down-2.3.8 lib/down/chunked_io.rb
down-2.3.7 lib/down/chunked_io.rb
down-2.3.6 lib/down/chunked_io.rb