Created
February 17, 2010 14:42
-
-
Save julik/306661 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Used for IO objects that need to report the current offset at each operation that changes the said offset | |
# (useful for building progress bars that report on a file read operation) | |
class ProgressiveIO < DelegateClass(IO) | |
# Should contain a block that accepts the current offset in bytes and the total size | |
attr_accessor :progress_block | |
# Get or set the total size of the contained IO. If the passed IO is a File object | |
# the size will be preset automatically | |
attr_accessor :total_size | |
def initialize(with_file, &progress_block_arg) | |
__setobj__(with_file) | |
@total_size = with_file.stat.size if with_file.respond_to?(:stat) | |
@progress_block = progress_block_arg.to_proc | |
end | |
def each(sep_string = $/, &blk) | |
# Report offset at each call of the iterator | |
result = super(sep_string) do | line | | |
yield(line) | |
notify_read | |
end | |
end | |
alias_method :each_line, :each | |
def each_byte(&blk) | |
# Report offset at each call of the iterator | |
super { |b| yield(b); notify_read } | |
end | |
def getc | |
returning(super) { notify_read } | |
end | |
def gets | |
returning(super) { notify_read } | |
end | |
def read(*a) | |
returning(super) { notify_read } | |
end | |
def readbytes(*a) | |
returning(super) { notify_read } | |
end | |
def readchar | |
returning(super) { notify_read } | |
end | |
def readline(*a) | |
returning(super) { notify_read } | |
end | |
def readlines(*a) | |
returning(super) { notify_read } | |
end | |
def seek(*a) | |
returning(super) { notify_read } | |
end | |
def ungetc(*a) | |
returning(super) { notify_read } | |
end | |
def pos=(p) | |
returning(super) { notify_read } | |
end | |
private | |
def returning(r) | |
yield; r | |
end | |
def notify_read | |
@progress_block.call(pos, @total_size) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment