1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.commons.compress.archivers; 20 21 import java.io.IOException; 22 import java.io.InputStream; 23 24 /** 25 * Archive input streams <b>MUST</b> override the 26 * {@link #read(byte[], int, int)} - or {@link #read()} - 27 * method so that reading from the stream generates EOF for the end of 28 * data in each entry as well as at the end of the file proper. 29 * <p> 30 * The {@link #getNextEntry()} method is used to reset the input stream 31 * ready for reading the data from the next entry. 32 * <p> 33 * The input stream classes must also implement a method with the signature: 34 * <pre> 35 * public static boolean matches(byte[] signature, int length) 36 * </pre> 37 * which is used by the {@link ArchiveStreamFactory} to autodetect 38 * the archive type from the first few bytes of a stream. 39 */ 40 public abstract class ArchiveInputStream extends InputStream { 41 42 private final byte[] single = new byte[1]; 43 private static final int BYTE_MASK = 0xFF; 44 45 /** holds the number of bytes read in this stream */ 46 private long bytesRead = 0; 47 48 /** 49 * Returns the next Archive Entry in this Stream. 50 * 51 * @return the next entry, 52 * or {@code null} if there are no more entries 53 * @throws IOException if the next entry could not be read 54 */ getNextEntry()55 public abstract ArchiveEntry getNextEntry() throws IOException; 56 57 /* 58 * Note that subclasses also implement specific get() methods which 59 * return the appropriate class without need for a cast. 60 * See SVN revision r743259 61 * @return 62 * @throws IOException 63 */ 64 // public abstract XXXArchiveEntry getNextXXXEntry() throws IOException; 65 66 /** 67 * Reads a byte of data. This method will block until enough input is 68 * available. 69 * 70 * Simply calls the {@link #read(byte[], int, int)} method. 71 * 72 * MUST be overridden if the {@link #read(byte[], int, int)} method 73 * is not overridden; may be overridden otherwise. 74 * 75 * @return the byte read, or -1 if end of input is reached 76 * @throws IOException 77 * if an I/O error has occurred 78 */ 79 @Override read()80 public int read() throws IOException { 81 final int num = read(single, 0, 1); 82 return num == -1 ? -1 : single[0] & BYTE_MASK; 83 } 84 85 /** 86 * Increments the counter of already read bytes. 87 * Doesn't increment if the EOF has been hit (read == -1) 88 * 89 * @param read the number of bytes read 90 */ count(final int read)91 protected void count(final int read) { 92 count((long) read); 93 } 94 95 /** 96 * Increments the counter of already read bytes. 97 * Doesn't increment if the EOF has been hit (read == -1) 98 * 99 * @param read the number of bytes read 100 * @since 1.1 101 */ count(final long read)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 */ pushedBackBytes(final long pushedBack)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 getCount()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 */ getBytesRead()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 */ canReadEntryData(final ArchiveEntry archiveEntry)151 public boolean canReadEntryData(final ArchiveEntry archiveEntry) { 152 return true; 153 } 154 155 } 156