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}