CheckedInputStream.java revision 858dd42310622fd1b77bfa0fbd85ec851b3925c1
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.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code CheckedInputStream} class is used to maintain a checksum at the 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * same time as the data, on which the checksum is computed, is read from a 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream. The purpose of this checksum is to establish data integrity, 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * comparing the computed checksum against a published checksum value. 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class CheckedInputStream extends java.io.FilterInputStream { 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Checksum check; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new {@code CheckedInputStream} on {@code InputStream} 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code is}. The checksum will be calculated using the algorithm 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implemented by {@code csum}. 37f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 38858dd42310622fd1b77bfa0fbd85ec851b3925c1Jesse Wilson * <p><strong>Warning:</strong> passing a null source creates an invalid 39858dd42310622fd1b77bfa0fbd85ec851b3925c1Jesse Wilson * {@code CheckedInputStream}. All operations on such a stream will fail. 40858dd42310622fd1b77bfa0fbd85ec851b3925c1Jesse Wilson * 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param is 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input stream to calculate checksum from. 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param csum 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an entity implementing the checksum algorithm. 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public CheckedInputStream(InputStream is, Checksum csum) { 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(is); 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project check = csum; 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads one byte of data from the underlying input stream and updates the 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * checksum with the byte data. 54f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code -1} at the end of the stream, a single byte value 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an {@code IOException} occurs. 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int x = in.read(); 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (x != -1) { 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project check.update(x); 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return x; 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads up to n bytes of data from the underlying input stream, storing it 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * into {@code buf}, starting at offset {@code off}. The checksum is 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * updated with the bytes read. 73f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buf 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the byte array in which to store the bytes read. 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param off 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the initial position in {@code buf} to store the bytes read 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from this stream. 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param nbytes 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum number of bytes to store in {@code buf}. 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes actually read or {@code -1} if arrived at the 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * end of the filtered stream while reading the data. 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this stream is closed or some I/O error occurs. 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] buf, int off, int nbytes) throws IOException { 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int x = in.read(buf, off, nbytes); 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (x != -1) { 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project check.update(buf, off, x); 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return x; 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the checksum calculated on the stream read so far. 97f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the updated checksum. 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Checksum getChecksum() { 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return check; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Skip up to n bytes of data on the underlying input stream. Any skipped 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bytes are added to the running checksum value. 107f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson * 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param nbytes 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes to skip. 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this stream is closed or another I/O error occurs. 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes skipped. 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long skip(long nbytes) throws IOException { 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nbytes < 1) { 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long skipped = 0; 120f7c6911047d63bc76292f55ce538da32818dd931Jesse Wilson byte[] b = new byte[(int)Math.min(nbytes, 2048L)]; 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int x, v; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (skipped != nbytes) { 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project x = in.read(b, 0, 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (v = (int) (nbytes - skipped)) > b.length ? b.length : v); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (x == -1) { 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return skipped; 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project check.update(b, 0, x); 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project skipped += x; 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return skipped; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 134