InflaterInputStream.java revision 60eb73fc9f0636c3d0bda5baba641a5f88f8476f
1f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.zip; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.EOFException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FilterInputStream; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.archive.internal.nls.Messages; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class provides an implementation of {@code FilterInputStream} that 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * uncompresses data that was compressed using the <i>DEFLATE</i> algorithm 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (see <a href="http://www.gzip.org/algorithm.txt">specification</a>). 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Basically it wraps the {@code Inflater} class and takes care of the 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffering. 3357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Inflater 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see DeflaterOutputStream 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class InflaterInputStream extends FilterInputStream { 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The inflater used for this stream. 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Inflater inf; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The input buffer used for decompression. 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected byte[] buf; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The length of the buffer. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected int len; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean closed; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 560146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson /** 570146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * True if this stream's last byte has been returned to the user. This 580146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * could be because the underlying stream has been exhausted, or if errors 590146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * were encountered while inflating that stream. 600146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson */ 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean eof; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final int BUF_SIZE = 512; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson int nativeEndBufSize = 0; // android-only 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is the most basic constructor. You only need to pass the {@code 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * InputStream} from which the compressed data is to be read from. Default 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * settings for the {@code Inflater} and internal buffer are be used. In 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * particular the Inflater expects a ZLIB header from the input stream. 7257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param is 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code InputStream} to read data from. 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InflaterInputStream(InputStream is) { 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(is, new Inflater(), BUF_SIZE); 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This constructor lets you pass a specifically initialized Inflater, 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for example one that expects no ZLIB header. 8357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param is 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code InputStream} to read data from. 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inf 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specific {@code Inflater} for uncompressing data. 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InflaterInputStream(InputStream is, Inflater inf) { 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(is, inf, BUF_SIZE); 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This constructor lets you specify both the {@code Inflater} as well as 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the internal buffer size to be used. 9657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param is 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code InputStream} to read data from. 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inf 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specific {@code Inflater} for uncompressing data. 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param bsize 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the size to be used for the internal buffer. 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InflaterInputStream(InputStream is, Inflater inf, int bsize) { 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(is); 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (is == null || inf == null) { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bsize <= 0) { 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.inf = inf; 113f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson // BEGIN android-only 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (is instanceof ZipFile.RAFStream) { 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nativeEndBufSize = bsize; 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = new byte[bsize]; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson // END android-only 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a single byte of decompressed data. 12457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the byte read. 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs reading the byte. 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] b = new byte[1]; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (read(b, 0, 1) == -1) { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return b[0] & 0xff; 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads up to {@code nbytes} of decompressed data and stores it in 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer} starting at {@code off}. 14157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the buffer to write data to. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param off 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * offset in buffer to start writing. 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param nbytes 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of bytes to read. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return Number of uncompressed bytes read 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an IOException occurs. 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] buffer, int off, int nbytes) throws IOException { 15460eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes checkClosed(); 15560eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes if (buffer == null) { 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (off < 0 || nbytes < 0 || off + nbytes > buffer.length) { 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IndexOutOfBoundsException(); 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nbytes == 0) { 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1670146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson if (eof) { 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // avoid int overflow, check null buffer 1720146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson if (off > buffer.length || nbytes < 0 || off < 0 1730146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson || buffer.length - off < nbytes) { 1740146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson throw new ArrayIndexOutOfBoundsException(); 1750146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } 1760146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson 1770146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson do { 1780146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson if (inf.needsInput()) { 1790146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson fill(); 1800146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } 1810146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson // Invariant: if reading returns -1 or throws, eof must be true. 1820146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson // It may also be true if the next read() should return -1. 1830146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson try { 1840146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson int result = inf.inflate(buffer, off, nbytes); 1850146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson eof = inf.finished(); 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result > 0) { 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1880146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } else if (eof) { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (inf.needsDictionary()) { 1910146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson eof = true; 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (len == -1) { 1940146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson eof = true; 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new EOFException(); 19657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson // If result == 0, fill() and try again 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1980146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } catch (DataFormatException e) { 1990146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson eof = true; 2000146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson if (len == -1) { 2010146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson throw new EOFException(); 2020146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } 2030146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson throw (IOException) (new IOException().initCause(e)); 2040146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } 2050146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson } while (true); 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Fills the input buffer with data to be decompressed. 21057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an {@code IOException} occurs. 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void fill() throws IOException { 21560eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes checkClosed(); 216f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson // BEGIN android-only 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nativeEndBufSize > 0) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ZipFile.RAFStream is = (ZipFile.RAFStream)in; 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (is.mSharedRaf) { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long len = is.mLength - is.mOffset; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (len > nativeEndBufSize) len = nativeEndBufSize; 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int cnt = inf.setFileInput(is.mSharedRaf.getFD(), is.mOffset, (int)nativeEndBufSize); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project is.skip(cnt); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((len = in.read(buf)) > 0) { 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inf.setInput(buf, 0, len); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 230f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson // END android-only 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Skips up to n bytes of uncompressed data. 23557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param nbytes 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes to skip. 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of uncompressed bytes skipped. 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs skipping. 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long skip(long nbytes) throws IOException { 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nbytes >= 0) { 24557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson if (buf == null) { 246f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson buf = new byte[(int)Math.min(nbytes, BUF_SIZE)]; 24757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson } 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long count = 0, rem = 0; 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (count < nbytes) { 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int x = read(buf, 0, 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (rem = nbytes - count) > buf.length ? buf.length 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : (int) rem); 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (x == -1) { 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return count; 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count += x; 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return count; 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2640146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * Returns 0 when when this stream has exhausted its input; and 1 otherwise. 2650146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * A result of 1 does not guarantee that further bytes can be returned, 2660146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * with or without blocking. 2670146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * 2680146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * <p>Although consistent with the RI, this behavior is inconsistent with 2690146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * {@link InputStream#available()}, and violates the <a 2700146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov 2710146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * Substitution Principle</a>. This method should not be used. 27257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 2730146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * @return 0 if no further bytes are available. Otherwise returns 1, 2740146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * which suggests (but does not guarantee) that additional bytes are 2750146d778677790cf6aee98fbb8a5e7d24eb023a4Jesse Wilson * available. 276582d926fbf5f5fd4800def67f86ecfedee44681eElliott Hughes * @throws IOException if this stream is closed or an error occurs 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int available() throws IOException { 28060eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes checkClosed(); 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (eof) { 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 1; 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the input stream. 28957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an error occurs closing the input stream. 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!closed) { 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inf.end(); 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project closed = true; 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project eof = true; 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.close(); 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 30257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 30457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * Marks the current position in the stream. This implementation overrides 30557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * the super type implementation to do nothing at all. 30657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param readlimit 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of no use. 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void mark(int readlimit) { 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // do nothing 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reset the position of the stream to the last marked position. This 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation overrides the supertype implementation and always throws 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an {@link IOException IOException} when called. 31957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the method is called 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 32457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson public void reset() throws IOException { 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IOException(); 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 32757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether the receiver implements {@code mark} semantics. This type 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * does not support {@code mark()}, so always responds {@code false}. 33157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson * 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return false, always 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean markSupported() { 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 33960eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes private void checkClosed() throws IOException { 34060eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes if (closed) { 34160eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes throw new IOException("Stream is closed"); 34260eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes } 34360eb73fc9f0636c3d0bda5baba641a5f88f8476fElliott Hughes } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 345