blob: 804f7f860aa72595d5f3a567341857b5e248e8af [file] [log] [blame]
/*
* Copyright (C) 2023, SAP SE and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.util.io;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.InvalidMarkException;
import java.util.Objects;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.internal.JGitText;
/**
* An {@link InputStream} backed by a {@link ByteBuffer}.
*
* @since 6.8
*/
public class ByteBufferInputStream extends InputStream {
private ByteBuffer buf;
/**
* Creates a {@link ByteBufferInputStream}
*
* @param buf
* the ByteBuffer backing the stream
*/
public ByteBufferInputStream(@NonNull ByteBuffer buf) {
this.buf = buf;
}
@Override
public int read() throws IOException {
nullCheck();
if (buf.hasRemaining()) {
return buf.get() & 0xFF;
}
return -1;
}
@Override
public int read(byte[] b) throws IOException {
nullCheck();
return read(b, 0, b.length);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
nullCheck();
Objects.checkFromIndexSize(off, len, b.length);
if (len == 0) {
return 0;
}
int length = Math.min(buf.remaining(), len);
if (length == 0) {
return -1;
}
buf.get(b, off, length);
return length;
}
@Override
public byte[] readAllBytes() throws IOException {
return readNBytes(buf.remaining());
}
@Override
public byte[] readNBytes(int len) throws IOException {
int l = Math.min(len, buf.remaining());
byte[] b = new byte[l];
read(b);
return b;
}
@Override
public int readNBytes(byte[] b, int off, int len) throws IOException {
return read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
nullCheck();
if (n <= 0) {
return 0;
}
// ByteBuffer index has type int
int delta = n > Integer.MAX_VALUE ? buf.remaining()
: Math.min((int) n, buf.remaining());
buf.position(buf.position() + delta);
return delta;
}
@Override
public int available() throws IOException {
nullCheck();
return buf.remaining();
}
@Override
public void close() {
buf = null;
}
@Override
public synchronized void mark(int readlimit) {
buf.mark();
}
@Override
public synchronized void reset() throws IOException {
try {
buf.reset();
} catch (InvalidMarkException e) {
throw new IOException(e);
}
}
@Override
public boolean markSupported() {
return true;
}
private void nullCheck() throws IOException {
if (buf == null) {
throw new IOException(JGitText.get().inputStreamClosed);
}
}
}