module BinData::IO::Common

def buffer_limited_n(n)

def buffer_limited_n(n)
  if @buffer_end_points
    if n.nil? || n > 0
      max = @buffer_end_points[1] - offset
      n = max if n.nil? || n > max
    else
      min = @buffer_end_points[0] - offset
      n = min if n < min
    end
  end
  n
end

def initialize(io)

def initialize(io)
  if self.class === io
    raise ArgumentError, "io must not be a #{self.class}"
  end
  # wrap strings in a StringIO
  if io.respond_to?(:to_str)
    io = BinData::IO.create_string_io(io.to_str)
  end
  @raw_io = io
  @buffer_end_points = nil
  extend seekable? ? SeekableStream : UnSeekableStream
  stream_init
end

def seek(n)

def seek(n)
  seek_raw(buffer_limited_n(n))
end

def seekable?

def seekable?
  @raw_io.pos
rescue NoMethodError, Errno::ESPIPE, Errno::EPIPE, Errno::EINVAL
  nil
end

def with_buffer_common(n)

def with_buffer_common(n)
  prev = @buffer_end_points
  if prev
    avail = prev[1] - offset
    n = avail if n > avail
  end
  @buffer_end_points = [offset, offset + n]
  begin
    yield(*@buffer_end_points)
  ensure
    @buffer_end_points = prev
  end
end