/*
 * SimpleInputStream
 *
 * Author: Lasse Collin <lasse.collin@tukaani.org>
 *
 * This file has been put into the public domain.
 * You can do whatever you want with this file.
 */

package org.tukaani.xz;

import java.io.InputStream;
import java.io.IOException;
import org.tukaani.xz.simple.SimpleFilter;

class SimpleInputStream extends InputStream {
    private static final int FILTER_BUF_SIZE = 4096;

    private InputStream in;
    private final SimpleFilter simpleFilter;

    private final byte[] filterBuf = new byte[FILTER_BUF_SIZE];
    private int pos = 0;
    private int filtered = 0;
    private int unfiltered = 0;

    private boolean endReached = false;
    private IOException exception = null;

    private final byte[] tempBuf = new byte[1];

    static int getMemoryUsage() {
        return 1 + FILTER_BUF_SIZE / 1024;
    }

    SimpleInputStream(InputStream in, SimpleFilter simpleFilter) {
        // Check for null because otherwise null isn't detect
        // in this constructor.
        if (in == null)
            throw new NullPointerException();

        // The simpleFilter argument comes from this package
        // so it is known to be non-null already.
        assert simpleFilter != null;

        this.in = in;
        this.simpleFilter = simpleFilter;
    }

    public int read() throws IOException {
        return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
    }

    public int read(byte[] buf, int off, int len) throws IOException {
        if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
            throw new IndexOutOfBoundsException();

        if (len == 0)
            return 0;

        if (in == null)
            throw new XZIOException("Stream closed");

        if (exception != null)
            throw exception;

        try {
            int size = 0;

            while (true) {
                // Copy filtered data into the caller-provided buffer.
                int copySize = Math.min(filtered, len);
                System.arraycopy(filterBuf, pos, buf, off, copySize);
                pos += copySize;
                filtered -= copySize;
                off += copySize;
                len -= copySize;
                size += copySize;

                // If end of filterBuf was reached, move the pending data to
                // the beginning of the buffer so that more data can be
                // copied into filterBuf on the next loop iteration.
                if (pos + filtered + unfiltered == FILTER_BUF_SIZE) {
                    System.arraycopy(filterBuf, pos, filterBuf, 0,
                                     filtered + unfiltered);
                    pos = 0;
                }

                if (len == 0 || endReached)
                    return size > 0 ? size : -1;

                assert filtered == 0;

                // Get more data into the temporary buffer.
                int inSize = FILTER_BUF_SIZE - (pos + filtered + unfiltered);
                inSize = in.read(filterBuf, pos + filtered + unfiltered,
                                 inSize);

                if (inSize == -1) {
                    // Mark the remaining unfiltered bytes to be ready
                    // to be copied out.
                    endReached = true;
                    filtered = unfiltered;
                    unfiltered = 0;
                } else {
                    // Filter the data in filterBuf.
                    unfiltered += inSize;
                    filtered = simpleFilter.code(filterBuf, pos, unfiltered);
                    assert filtered <= unfiltered;
                    unfiltered -= filtered;
                }
            }
        } catch (IOException e) {
            exception = e;
            throw e;
        }
    }

    public int available() throws IOException {
        if (in == null)
            throw new XZIOException("Stream closed");

        if (exception != null)
            throw exception;

        return filtered;
    }

    public void close() throws IOException {
        if (in != null) {
            try {
                in.close();
            } finally {
                in = null;
            }
        }
    }
}
