1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.security; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FilterInputStream; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code DigestInputStream} is a {@code FilterInputStream} which maintains an 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * associated message digest. 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DigestInputStream extends FilterInputStream { 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The message digest for this stream. 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected MessageDigest digest; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Indicates whether digest functionality is on or off 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean isOn = true; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a new instance of this {@code DigestInputStream}, using the 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given {@code stream} and the {@code digest}. 41e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param stream 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the input stream. 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param digest 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the message digest. 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DigestInputStream(InputStream stream, MessageDigest digest) { 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(stream); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.digest = digest; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the message digest for this stream. 54e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the message digest for this stream. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public MessageDigest getMessageDigest() { 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return digest; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the message digest which this stream will use. 63e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param digest 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the message digest which this stream will use. 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void setMessageDigest(MessageDigest digest) { 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.digest = digest; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reads the next byte and returns it as an {@code int}. Updates the digest 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for the byte if this function is {@link #on(boolean)}. 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This operation is blocking. 76e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the byte which was read or -1 at end of stream. 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if reading the source stream causes an {@code IOException}. 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 81e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes @Override 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read() throws IOException { 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // read the next byte 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int byteRead = in.read(); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // update digest only if 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - digest functionality is on 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - eos has not been reached 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isOn && (byteRead != -1)) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update((byte)byteRead); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // return byte read 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return byteRead; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reads {@code len} bytes into the specified {@code byte[]}, starting from 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the specified offset. Updates the digest if this function is 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #on(boolean)}. 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This operation is blocking. 101e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param b 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the byte array in which to store the bytes 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param off 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the initial position in {@code b} to store the bytes read from 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this stream 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param len 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the maximum number of bytes to store in {@code b} 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the number of bytes actually read or -1 if the end of the 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * filtered stream has been reached while reading 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if reading the source stream causes an {@code IOException} 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 114e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes @Override 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // read next up to len bytes 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int bytesRead = in.read(b, off, len); 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // update digest only if 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - digest functionality is on 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - eos has not been reached 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isOn && (bytesRead != -1)) { 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(b, off, bytesRead); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // return number of bytes read 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesRead; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enables or disables the digest function (default is on). 130e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param on 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code true} if the digest should be computed, {@code false} 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * otherwise. 134e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * @see MessageDigest 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void on(boolean on) { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isOn = on; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a string containing a concise, human-readable description of this 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code DigestInputStream} including the digest. 143e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return a printable representation for this {@code DigestInputStream}. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 146e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes @Override 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return super.toString() + ", " + digest.toString() + //$NON-NLS-1$ 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (isOn ? ", is on" : ", is off"); //$NON-NLS-1$ //$NON-NLS-2$ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 152