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}