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 */
019 package org.apache.commons.compress.archivers;
020
021 import java.io.IOException;
022 import 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 public abstract class ArchiveInputStream extends InputStream {
041
042 private 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</code> 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 public int read() throws IOException {
080 int num = read(SINGLE, 0, 1);
081 return num == -1 ? -1 : SINGLE[0] & BYTE_MASK;
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 */
090 protected void count(int read) {
091 count((long) read);
092 }
093
094 /**
095 * Increments the counter of already read bytes.
096 * Doesn't increment if the EOF has been hit (read == -1)
097 *
098 * @param read the number of bytes read
099 * @since Apache Commons Compress 1.1
100 */
101 protected void count(long read) {
102 if (read != -1) {
103 bytesRead = bytesRead + read;
104 }
105 }
106
107 /**
108 * Decrements the counter of already read bytes.
109 *
110 * @param pushedBack the number of bytes pushed back.
111 * @since Apache Commons Compress 1.1
112 */
113 protected void pushedBackBytes(long pushedBack) {
114 bytesRead -= pushedBack;
115 }
116
117 /**
118 * Returns the current number of bytes read from this stream.
119 * @return the number of read bytes
120 * @deprecated this method may yield wrong results for large
121 * archives, use #getBytesRead instead
122 */
123 public int getCount() {
124 return (int) bytesRead;
125 }
126
127 /**
128 * Returns the current number of bytes read from this stream.
129 * @return the number of read bytes
130 * @since Apache Commons Compress 1.1
131 */
132 public long getBytesRead() {
133 return bytesRead;
134 }
135
136 /**
137 * Whether this stream is able to read the given entry.
138 *
139 * <p>Some archive formats support variants or details that are
140 * not supported (yet).</p>
141 *
142 * <p>This implementation always returns true.
143 *
144 * @since Apache Commons Compress 1.1
145 */
146 public boolean canReadEntryData(ArchiveEntry ae) {
147 return true;
148 }
149
150 }