    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 * http://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.commons.compress.archivers;
    020
    021import java.io.IOException;
    022import java.io.InputStream;
    023
    024/**
    025 * Archive input streams <b>MUST</b> override the
    026 * {@link #read(byte[], int, int)} - or {@link #read()} -
    027 * method so that reading from the stream generates EOF for the end of
    028 * data in each entry as well as at the end of the file proper.
    029 * <p>
    030 * The {@link #getNextEntry()} method is used to reset the input stream
    031 * ready for reading the data from the next entry.
    032 * <p>
    033 * The input stream classes must also implement a method with the signature:
    034 * <pre>
    035 * public static boolean matches(byte[] signature, int length)
    036 * </pre>
    037 * which is used by the {@link ArchiveStreamFactory} to autodetect
    038 * the archive type from the first few bytes of a stream.
    039 *
    040 * @param <E> The type of {@link ArchiveEntry} produced.
    041 */
    042public abstract class ArchiveInputStream<E extends ArchiveEntry> extends InputStream {
    043
    044    private static final int BYTE_MASK = 0xFF;
    045    private final byte[] single = new byte[1];
    046
    047    /** Holds the number of bytes read in this stream */
    048    private long bytesRead;
    049
    050    /**
    051     * Whether this stream is able to read the given entry.
    052     *
    053     * <p>
    054     * Some archive formats support variants or details that are not supported (yet).
    055     * </p>
    056     *
    057     * @param archiveEntry
    058     *            the entry to test
    059     * @return This implementation always returns true.
    060     *
    061     * @since 1.1
    062     */
    063    public boolean canReadEntryData(final ArchiveEntry archiveEntry) {
    064        return true;
    065    }
    066
    067    /**
    068     * Increments the counter of already read bytes.
    069     * Doesn't increment if the EOF has been hit (read == -1)
    070     *
    071     * @param read the number of bytes read
    072     */
    073    protected void count(final int read) {
    074        count((long) read);
    075    }
    076
    077    /**
    078     * Increments the counter of already read bytes.
    079     * Doesn't increment if the EOF has been hit (read == -1)
    080     *
    081     * @param read the number of bytes read
    082     * @since 1.1
    083     */
    084    protected void count(final long read) {
    085        if (read != -1) {
    086            bytesRead = bytesRead + read;
    087        }
    088    }
    089
    090    /**
    091     * Returns the current number of bytes read from this stream.
    092     * @return the number of read bytes
    093     * @since 1.1
    094     */
    095    public long getBytesRead() {
    096        return bytesRead;
    097    }
    098
    099    /**
    100     * Returns the current number of bytes read from this stream.
    101     * @return the number of read bytes
    102     * @deprecated this method may yield wrong results for large
    103     * archives, use #getBytesRead instead
    104     */
    105    @Deprecated
    106    public int getCount() {
    107        return (int) bytesRead;
    108    }
    109
    110    /**
    111     * Returns the next Archive Entry in this Stream.
    112     *
    113     * @return the next entry,
    114     *         or {@code null} if there are no more entries
    115     * @throws IOException if the next entry could not be read
    116     */
    117    public abstract E getNextEntry() throws IOException;
    118
    119    /**
    120     * Decrements the counter of already read bytes.
    121     *
    122     * @param pushedBack the number of bytes pushed back.
    123     * @since 1.1
    124     */
    125    protected void pushedBackBytes(final long pushedBack) {
    126        bytesRead -= pushedBack;
    127    }
    128
    129    /**
    130     * Reads a byte of data. This method will block until enough input is
    131     * available.
    132     *
    133     * Simply calls the {@link #read(byte[], int, int)} method.
    134     *
    135     * MUST be overridden if the {@link #read(byte[], int, int)} method
    136     * is not overridden; may be overridden otherwise.
    137     *
    138     * @return the byte read, or -1 if end of input is reached
    139     * @throws IOException
    140     *             if an I/O error has occurred
    141     */
    142    @Override
    143    public int read() throws IOException {
    144        final int num = read(single, 0, 1);
    145        return num == -1 ? -1 : single[0] & BYTE_MASK;
    146    }
    147
    148}