module BinData::IO::Common::UnSeekableStream
def num_bytes_remaining
def num_bytes_remaining raise IOError, "stream is unseekable" end
def offset_raw
def offset_raw @offset end
def read_raw(n)
def read_raw(n) data = @raw_io.read(n) @offset += data.size if data data end
def read_raw_with_readahead(n)
def read_raw_with_readahead(n) data = "" if @read_data.length > 0 and not @in_readahead bytes_to_consume = [n, @read_data.length].min data << @read_data.slice!(0, bytes_to_consume) n -= bytes_to_consume if @read_data.length == 0 class << self alias_method :read_raw, :read_raw_without_readahead end end end raw_data = @raw_io.read(n) data << raw_data if raw_data if @in_readahead @read_data << data end @offset += data.size data end
def seek_raw(n)
def seek_raw(n) raise IOError, "stream is unseekable" if n < 0 # NOTE: how do we seek on a writable stream? # skip over data in 8k blocks while n > 0 bytes_to_read = [n, 8192].min read_raw(bytes_to_read) n -= bytes_to_read end end
def stream_init
def stream_init @offset = 0 end
def with_readahead(&block)
All io calls in +block+ are rolled back after this
def with_readahead(&block) mark = @offset @read_data = "" @in_readahead = true class << self alias_method :read_raw_without_readahead, :read_raw alias_method :read_raw, :read_raw_with_readahead end begin block.call ensure @offset = mark @in_readahead = false end end
def write_raw(data)
def write_raw(data) @offset += data.size @raw_io.write(data) end