skipUpTo helpfully falls back from skip invocations which return zero to invoke a read into a buffer.

The current implementation has two inefficiencies which cause unexpected performance degradation in tight loops, especially when a small number of bytes are requested:

1. In many cases skipSafely is able to skip all the requested bytes, there's no need to allocate a read buffer
2. The caller only requests a few bytes are skipped. Calling `ByteStreams.skipFully(stream, 32)` always allocates a 8192 byte buffer.

Proposed solution:
Defer buffer allocation until it is needed, using the minimum of the requested size and BUFFER_SIZE. This reduces allocation pressure in all cases of small skip values, as well as streams that report nonzero bytes available (assuming skip returns a positive value).
public boolean readBoolean() {
      try {
        return input.readBoolean();
      } catch (IOException e) {
        throw new IllegalStateException(e);
      }
    }
    @Override
    public byte readByte() {
      try {
        return input.readByte();
      } catch (EOFException e) {
        throw new IllegalStateException(e);
      } catch (IOException impossible) {
        throw new AssertionError(impossible);
      }
    }
    @Override
    public int readUnsignedByte() {
      try {
        return input.readUnsignedByte();
      } catch (IOException e) {
        throw new IllegalStateException(e);
      }
    }
    @Override
    public short readShort() {
      try {
        return input.readShort();
      } catch (IOException e) {