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

org.opendaylight.controller.cluster.io.ChunkedInputStream Maven / Gradle / Ivy

There is a newer version: 10.0.4
Show newest version
/*
 * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.controller.cluster.io;

import static java.util.Objects.requireNonNull;

import java.io.InputStream;
import java.util.Iterator;

final class ChunkedInputStream extends InputStream {
    private final Iterator remainingChunks;

    private byte[] currentChunk;
    private int currentLimit;
    private int currentOffset;
    private int available;

    ChunkedInputStream(final int size, final Iterator iterator) {
        remainingChunks = requireNonNull(iterator);
        currentChunk = remainingChunks.next();
        currentLimit = currentChunk.length;
        available = size;
    }

    @Override
    public int available() {
        return available;
    }

    @Override
    public int read() {
        if (currentChunk == null) {
            return -1;
        }

        int ret = currentChunk[currentOffset] & 0xff;
        consumeBytes(1);
        return ret;
    }

    @Override
    @SuppressWarnings("checkstyle:ParameterName")
    public int read(final byte[] b) {
        return read(b, 0, b.length);
    }

    @Override
    @SuppressWarnings("checkstyle:ParameterName")
    public int read(final byte[] b, final int off, final int len) {
        if (len < 0) {
            throw new IndexOutOfBoundsException();
        }
        if (currentChunk == null) {
            return -1;
        }

        final int result = Math.min(available, len);
        int toOffset = off;
        int toCopy = result;

        while (toCopy != 0) {
            final int count = currentBytes(toCopy);
            System.arraycopy(currentChunk, currentOffset, b, toOffset, count);
            consumeBytes(count);
            toOffset += count;
            toCopy -= count;
        }

        return result;
    }

    @Override
    @SuppressWarnings("checkstyle:ParameterName")
    public long skip(final long n) {
        final int result = (int) Math.min(available, n);

        int toSkip = result;
        while (toSkip != 0) {
            final int count = currentBytes(toSkip);
            consumeBytes(count);
            toSkip -= count;
        }

        return result;
    }

    private int currentBytes(final int desired) {
        return Math.min(desired, currentLimit - currentOffset);
    }

    private void consumeBytes(final int count) {
        currentOffset += count;
        available -= count;

        if (currentOffset == currentLimit) {
            if (remainingChunks.hasNext()) {
                currentChunk = remainingChunks.next();
                currentLimit = currentChunk.length;
            } else {
                currentChunk = null;
                currentLimit = 0;
            }
            currentOffset = 0;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy