    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 */
    040public abstract class ArchiveInputStream extends InputStream {
    041
    042    private static final int BYTE_MASK = 0xFF;
    043    private final byte[] single = new byte[1];
    044
    045    /** holds the number of bytes read in this stream */
    046    private long bytesRead;
    047
    048    /**
    049     * Whether this stream is able to read the given entry.
    050     *
    051     * <p>
    052     * Some archive formats support variants or details that are not supported (yet).
    053     * </p>
    054     *
    055     * @param archiveEntry
    056     *            the entry to test
    057     * @return This implementation always returns true.
    058     *
    059     * @since 1.1
    060     */
    061    public boolean canReadEntryData(final ArchiveEntry archiveEntry) {
    062        return true;
    063    }
    064
    065    /*
    066     * Note that subclasses also implement specific get() methods which
    067     * return the appropriate class without need for a cast.
    068     * See SVN revision r743259
    069     * @return
    070     * @throws IOException
    071     */
    072    // public abstract XXXArchiveEntry getNextXXXEntry() throws IOException;
    073
    074    /**
    075     * Increments the counter of already read bytes.
    076     * Doesn't increment if the EOF has been hit (read == -1)
    077     *
    078     * @param read the number of bytes read
    079     */
    080    protected void count(final int read) {
    081        count((long) read);
    082    }
    083
    084    /**
    085     * Increments the counter of already read bytes.
    086     * Doesn't increment if the EOF has been hit (read == -1)
    087     *
    088     * @param read the number of bytes read
    089     * @since 1.1
    090     */
    091    protected void count(final long read) {
    092        if (read != -1) {
    093            bytesRead = bytesRead + read;
    094        }
    095    }
    096
    097    /**
    098     * Returns the current number of bytes read from this stream.
    099     * @return the number of read bytes
    100     * @since 1.1
    101     */
    102    public long getBytesRead() {
    103        return bytesRead;
    104    }
    105
    106    /**
    107     * Returns the current number of bytes read from this stream.
    108     * @return the number of read bytes
    109     * @deprecated this method may yield wrong results for large
    110     * archives, use #getBytesRead instead
    111     */
    112    @Deprecated
    113    public int getCount() {
    114        return (int) bytesRead;
    115    }
    116
    117    /**
    118     * Returns the next Archive Entry in this Stream.
    119     *
    120     * @return the next entry,
    121     *         or {@code null} if there are no more entries
    122     * @throws IOException if the next entry could not be read
    123     */
    124    public abstract ArchiveEntry getNextEntry() throws IOException;
    125
    126    /**
    127     * Decrements the counter of already read bytes.
    128     *
    129     * @param pushedBack the number of bytes pushed back.
    130     * @since 1.1
    131     */
    132    protected void pushedBackBytes(final long pushedBack) {
    133        bytesRead -= pushedBack;
    134    }
    135
    136    /**
    137     * Reads a byte of data. This method will block until enough input is
    138     * available.
    139     *
    140     * Simply calls the {@link #read(byte[], int, int)} method.
    141     *
    142     * MUST be overridden if the {@link #read(byte[], int, int)} method
    143     * is not overridden; may be overridden otherwise.
    144     *
    145     * @return the byte read, or -1 if end of input is reached
    146     * @throws IOException
    147     *             if an I/O error has occurred
    148     */
    149    @Override
    150    public int read() throws IOException {
    151        final int num = read(single, 0, 1);
    152        return num == -1 ? -1 : single[0] & BYTE_MASK;
    153    }
    154
    155}