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