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).
* beginning.
   */
  @Beta
  public static ByteArrayDataInput newDataInput(byte[] bytes) {
    return newDataInput(new ByteArrayInputStream(bytes));
  }
  /**
   * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array,
   * starting at the given position.
   *
   * @throws IndexOutOfBoundsException if {@code start} is negative or greater than the length of
   *     the array
   */
  @Beta
  public static ByteArrayDataInput newDataInput(byte[] bytes, int start) {
    checkPositionIndex(start, bytes.length);
    return newDataInput(new ByteArrayInputStream(bytes, start, bytes.length - start));
  }
  /**
   * Returns a new {@link ByteArrayDataInput} instance to read from the given {@code
   * ByteArrayInputStream}. The given input stream is not reset before being read from by the
   * returned {@code ByteArrayDataInput}.
   *
   * @since 17.0
   */
  @Beta
  public static ByteArrayDataInput newDataInput(ByteArrayInputStream byteArrayInputStream) {
    return new ByteArrayDataInputStream(checkNotNull(byteArrayInputStream));
  }
  private static class ByteArrayDataInputStream implements ByteArrayDataInput {