/*
 * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.io;

import java.util.Arrays;
import java.util.Objects;

/**
 * A {@code ByteArrayInputStream} contains
 * an internal buffer that contains bytes that
 * may be read from the stream. An internal
 * counter keeps track of the next byte to
 * be supplied by the {@code read} method.
 * <p>
 * Closing a {@code ByteArrayInputStream} has no effect. The methods in
 * this class can be called after the stream has been closed without
 * generating an {@code IOException}.
 *
 * @author  Arthur van Hoff
 * @see     java.io.StringBufferInputStream
 * @since   1.0
 */
public class ByteArrayInputStream extends InputStream {
    private static final int MAX_TRANSFER_SIZE = 128*1024;

    /**
     * An array of bytes that was provided
     * by the creator of the stream. Elements {@code buf[0]}
     * through {@code buf[count-1]} are the
     * only bytes that can ever be read from the
     * stream;  element {@code buf[pos]} is
     * the next byte to be read.
     */
    protected byte[] buf;

    /**
     * The index of the next byte to read from the input stream buffer.
     * This value should always be nonnegative
     * and not larger than the value of {@code count}.
     * The next byte to be read from the input stream buffer
     * will be {@code buf[pos]}.
     */
    protected int pos;

    /**
     * The currently marked position in the stream.
     * ByteArrayInputStream objects are marked at position zero by
     * default when constructed.  They may be marked at another
     * position within the buffer by the {@code mark()} method.
     * The current buffer position is set to this point by the
     * {@code reset()} method.
     * <p>
     * If no mark has been set, then the value of mark is the offset
     * passed to the constructor (or 0 if the offset was not supplied).
     *
     * @since   1.1
     */
    protected int mark = 0;

    /**
     * The index one greater than the last valid byte in the input
     * stream buffer.
     * This value should always be nonnegative
     * and not larger than the length of {@code buf}.
     * It  is one greater than the position of
     * the last byte within {@code buf} that
     * can ever be read  from the input stream buffer.
     */
    protected int count;

    /**
     * Creates a {@code ByteArrayInputStream}
     * so that it  uses {@code buf} as its
     * buffer array.
     * The buffer array is not copied.
     * The initial value of {@code pos}
     * is {@code 0} and the initial value
     * of  {@code count} is the length of
     * {@code buf}.
     *
     * @param   buf   the input buffer.
     */
    public ByteArrayInputStream(byte[] buf) {
        this.buf = buf;
        this.pos = 0;
        this.count = buf.length;
    }

    /**
     * Creates {@code ByteArrayInputStream}
     * that uses {@code buf} as its
     * buffer array. The initial value of {@code pos}
     * is {@code offset} and the initial value
     * of {@code count} is the minimum of {@code offset+length}
     * and {@code buf.length}.
     * The buffer array is not copied. The buffer's mark is
     * set to the specified offset.
     *
     * @param   buf      the input buffer.
     * @param   offset   the offset in the buffer of the first byte to read.
     * @param   length   the maximum number of bytes to read from the buffer.
     */
    public ByteArrayInputStream(byte[] buf, int offset, int length) {
        this.buf = buf;
        this.pos = offset;
        this.count = Math.min(offset + length, buf.length);
        this.mark = offset;
    }

    /**
     * Reads the next byte of data from this input stream. The value
     * byte is returned as an {@code int} in the range
     * {@code 0} to {@code 255}. If no byte is available
     * because the end of the stream has been reached, the value
     * {@code -1} is returned.
     * <p>
     * This {@code read} method
     * cannot block.
     *
     * @return  {@inheritDoc}
     */
    @Override
    public synchronized int read() {
        return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }

    /**
     * Reads up to {@code len} bytes of data into an array of bytes from this
     * input stream.  If {@code pos} equals {@code count}, then {@code -1} is
     * returned to indicate end of file.  Otherwise, the  number {@code k} of
     * bytes read is equal to the smaller of {@code len} and {@code count-pos}.
     * If {@code k} is positive, then bytes {@code buf[pos]} through
     * {@code buf[pos+k-1]} are copied into {@code b[off]} through
     * {@code b[off+k-1]} in the manner performed by {@code System.arraycopy}.
     * The value {@code k} is added into {@code pos} and {@code k} is returned.
     * <p>
     * Unlike the {@link InputStream#read(byte[],int,int) overridden method}
     * of {@code InputStream}, this method returns {@code -1} instead of zero
     * if the end of the stream has been reached and {@code len == 0}.
     * <p>
     * This {@code read} method cannot block.
     *
     * @param   b     {@inheritDoc}
     * @param   off   {@inheritDoc}
     * @param   len   {@inheritDoc}
     * @return  {@inheritDoc}
     * @throws  NullPointerException {@inheritDoc}
     * @throws  IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized int read(byte[] b, int off, int len) {
        Objects.checkFromIndexSize(off, len, b.length);

        if (pos >= count) {
            return -1;
        }

        int avail = count - pos;
        if (len > avail) {
            len = avail;
        }
        if (len <= 0) {
            return 0;
        }
        System.arraycopy(buf, pos, b, off, len);
        pos += len;
        return len;
    }

    @Override
    public synchronized byte[] readAllBytes() {
        byte[] result = Arrays.copyOfRange(buf, pos, count);
        pos = count;
        return result;
    }

    @Override
    public int readNBytes(byte[] b, int off, int len) {
        int n = read(b, off, len);
        return n == -1 ? 0 : n;
    }

    @Override
    public synchronized long transferTo(OutputStream out) throws IOException {
        int len = count - pos;
        if (len > 0) {
            // 'tmpbuf' is null if and only if 'out' is trusted
            byte[] tmpbuf;
            Class<?> outClass = out.getClass();
            if (outClass == ByteArrayOutputStream.class ||
                outClass == FileOutputStream.class ||
                outClass == PipedOutputStream.class)
                tmpbuf = null;
            else
                tmpbuf = new byte[Integer.min(len, MAX_TRANSFER_SIZE)];

            int nwritten = 0;
            while (nwritten < len) {
                int nbyte = Integer.min(len - nwritten, MAX_TRANSFER_SIZE);
                // if 'out' is not trusted, transfer via a temporary buffer
                if (tmpbuf != null) {
                    System.arraycopy(buf, pos, tmpbuf, 0, nbyte);
                    out.write(tmpbuf, 0, nbyte);
                } else
                    out.write(buf, pos, nbyte);
                pos += nbyte;
                nwritten += nbyte;
            }
            assert pos == count;
        }
        return len;
    }

    /**
     * Skips {@code n} bytes of input from this input stream. Fewer
     * bytes might be skipped if the end of the input stream is reached.
     * The actual number {@code k}
     * of bytes to be skipped is equal to the smaller
     * of {@code n} and  {@code count-pos}.
     * The value {@code k} is added into {@code pos}
     * and {@code k} is returned.
     *
     * @param   n   {@inheritDoc}
     * @return  the actual number of bytes skipped.
     */
    @Override
    public synchronized long skip(long n) {
        long k = count - pos;
        if (n < k) {
            k = n < 0 ? 0 : n;
        }

        pos += (int) k;
        return k;
    }

    /**
     * Returns the number of remaining bytes that can be read (or skipped over)
     * from this input stream.
     * <p>
     * The value returned is {@code count - pos},
     * which is the number of bytes remaining to be read from the input buffer.
     *
     * @return  the number of remaining bytes that can be read (or skipped
     *          over) from this input stream without blocking.
     */
    @Override
    public synchronized int available() {
        return count - pos;
    }

    /**
     * Tests if this {@code InputStream} supports mark/reset.
     * @implSpec
     * The {@code markSupported} method of {@code ByteArrayInputStream}
     * always returns {@code true}.
     * @return true
     * @since   1.1
     */
    @Override
    public boolean markSupported() {
        return true;
    }

    /**
     * Set the current marked position in the stream.
     * ByteArrayInputStream objects are marked at position zero by
     * default when constructed.  They may be marked at another
     * position within the buffer by this method.
     * <p>
     * If no mark has been set, then the value of the mark is the
     * offset passed to the constructor (or 0 if the offset was not
     * supplied).
     *
     * <p> Note: The {@code readAheadLimit} for this class
     *  has no meaning.
     *
     * @since   1.1
     */
    @Override
    public void mark(int readAheadLimit) {
        mark = pos;
    }

    /**
     * Resets the buffer to the marked position.  The marked position
     * is 0 unless another position was marked or an offset was specified
     * in the constructor.
     */
    @Override
    public synchronized void reset() {
        pos = mark;
    }

    /**
     * Closing a {@code ByteArrayInputStream} has no effect. The methods in
     * this class can be called after the stream has been closed without
     * generating an {@code IOException}.
     */
    @Override
    public void close() throws IOException {
    }
}
