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