1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
module FastImageParsing
class FiberStream # :nodoc:
include StreamUtil
attr_reader :pos
# read_fiber should return nil if it no longer has anything to return when resumed
# so the result of the whole Fiber block should be set to be nil in case yield is no
# longer called
def initialize(read_fiber)
@read_fiber = read_fiber
@pos = 0
@strpos = 0
@str = ''
end
# Peeking beyond the end of the input will raise
def peek(n)
while @strpos + n > @str.size
unused_str = @str[@strpos..-1]
new_string = @read_fiber.resume
raise FastImage::CannotParseImage if !new_string
# we are dealing with bytes here, so force the encoding
new_string.force_encoding("ASCII-8BIT") if new_string.respond_to? :force_encoding
@str = unused_str + new_string
@strpos = 0
end
@str[@strpos, n]
end
def read(n)
result = peek(n)
@strpos += n
@pos += n
result
end
def skip(n)
discarded = 0
fetched = @str[@strpos..-1].size
while n > fetched
discarded += @str[@strpos..-1].size
new_string = @read_fiber.resume
raise FastImage::CannotParseImage if !new_string
new_string.force_encoding("ASCII-8BIT") if new_string.respond_to? :force_encoding
fetched += new_string.size
@str = new_string
@strpos = 0
end
@strpos = @strpos + n - discarded
@pos += n
end
end
end
|