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}