class Rack::Lint::InputWrapper

def close(*args)

# * +close+ must never be called on the input stream.
def close(*args)
  assert("rack.input#close must not be called") { false }
end

def each(*args)

# * +each+ must be called without arguments and only yield Strings.
def each(*args)
  assert("rack.input#each called with arguments") { args.size == 0 }
  @input.each { |line|
    assert("rack.input#each didn't yield a String") {
      line.kind_of? String
    }
    yield line
  }
end

def gets(*args)

# or +nil+ on EOF.
# * +gets+ must be called without arguments and return a string,
def gets(*args)
  assert("rack.input#gets called with arguments") { args.size == 0 }
  v = @input.gets
  assert("rack.input#gets didn't return a String") {
    v.nil? or v.kind_of? String
  }
  v
end

def initialize(input)

def initialize(input)
  @input = input
end

def read(*args)

# into +buffer+ instead of a newly created String object.
# If +buffer+ is given, then the read data will be placed
#
# and not nil, or "" if +length+ is not given or is nil.
# When EOF is reached, this method returns nil if +length+ is given
#
# all data until EOF.
# If +length+ is not given or nil, then this method reads
#
# +length+ bytes from the input stream.
# If +length+ is given and not nil, then this method reads at most
#
# and +buffer+ must be a String and may not be nil.
# If given, +length+ must be a non-negative Integer (>= 0) or +nil+,
#
# Its signature is read([length, [buffer]]).
# * +read+ behaves like IO#read.
def read(*args)
  assert("rack.input#read called with too many arguments") {
    args.size <= 2
  }
  if args.size >= 1
    assert("rack.input#read called with non-integer and non-nil length") {
      args.first.kind_of?(Integer) || args.first.nil?
    }
    assert("rack.input#read called with a negative length") {
      args.first.nil? || args.first >= 0
    }
  end
  if args.size >= 2
    assert("rack.input#read called with non-String buffer") {
      args[1].kind_of?(String)
    }
  end
  v = @input.read(*args)
  assert("rack.input#read didn't return nil or a String") {
    v.nil? or v.kind_of? String
  }
  if args[0].nil?
    assert("rack.input#read(nil) returned nil on EOF") {
      !v.nil?
    }
  end
  v
end

def rewind(*args)

# if the underlying input stream is not rewindable.
# developers must buffer the input data into some rewindable object
# that is, it may not be a pipe or a socket. Therefore, handler
# stream back to the beginning. It must not raise Errno::ESPIPE:
# * +rewind+ must be called without arguments. It rewinds the input
def rewind(*args)
  assert("rack.input#rewind called with arguments") { args.size == 0 }
  assert("rack.input#rewind raised Errno::ESPIPE") {
    begin
      @input.rewind
      true
    rescue Errno::ESPIPE
      false
    end
  }
end