
net.dongliu.xhttp.json.ByteBuffersInputStream Maven / Gradle / Ivy
The newest version!
package net.dongliu.xhttp.json;
import net.dongliu.commons.Preconditions;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.List;
import static java.util.Objects.requireNonNull;
/**
* Wrap list of ByteBuffers to InputStream.
*/
class ByteBuffersInputStream extends InputStream {
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
private final ByteBuffer[] buffers;
private int index;
ByteBuffersInputStream(List buffers) {
super();
this.buffers = buffers.toArray(ByteBuffer[]::new);
}
@Override
public synchronized int read(byte[] b) {
requireNonNull(b);
return read(b, 0, b.length);
}
@Override
public synchronized int read(byte[] b, int off, int len) {
Preconditions.checkArrayAndRange(b, off, len);
while (current().remaining() <= 0) {
if (!next()) {
return -1;
}
}
var buffer = current();
int read = Math.min(len, buffer.remaining());
buffer.get(b, off, read);
return read;
}
@Override
public synchronized byte[] readAllBytes() {
int total = 0;
for (int i = index; i < buffers.length; i++) {
if (total > MAX_BUFFER_SIZE - buffers[i].remaining()) {
throw new OutOfMemoryError("Required array size too large");
}
total += buffers[i].remaining();
}
byte[] array = new byte[total];
int offset = 0;
for (int i = index; i < buffers.length; i++) {
int remaining = buffers[i].remaining();
buffers[i].get(array, offset, remaining);
offset += remaining;
}
return array;
}
@Override
public int readNBytes(byte[] b, int off, int len) throws IOException {
return super.readNBytes(b, off, len);
}
@Override
public long skip(long n) {
while (current().remaining() <= 0) {
if (!next()) {
return 0;
}
}
int remaining = current().remaining();
current().position(current().limit());
return remaining;
}
@Override
public synchronized int available() {
return current().remaining();
}
@Override
public void close() {
}
@Override
public synchronized void mark(int readlimit) {
super.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
super.reset();
}
@Override
public boolean markSupported() {
return super.markSupported();
}
@Override
public long transferTo(OutputStream out) throws IOException {
return super.transferTo(out);
}
@Override
public synchronized int read() {
while (current().remaining() <= 0) {
if (!next()) {
return -1;
}
}
return Byte.toUnsignedInt(current().get());
}
private ByteBuffer current() {
return buffers[index];
}
private boolean next() {
if (index >= buffers.length - 1) {
return false;
}
index++;
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy