All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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