001: /*
002: * @(#)DigestInputStream.java 1.40 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.security;
029:
030: import java.io.IOException;
031: import java.io.EOFException;
032: import java.io.InputStream;
033: import java.io.FilterInputStream;
034: import java.io.PrintStream;
035: import java.io.ByteArrayInputStream;
036:
037: /**
038: * A transparent stream that updates the associated message digest using
039: * the bits going through the stream.
040: *
041: * <p>To complete the message digest computation, call one of the
042: * <code>digest</code> methods on the associated message
043: * digest after your calls to one of this digest input stream's
044: * {@link #read() read} methods.
045: *
046: * <p>It is possible to turn this stream on or off (see
047: * {@link #on(boolean) on}). When it is on, a call to one of the
048: * <code>read</code> methods
049: * results in an update on the message digest. But when it is off,
050: * the message digest is not updated. The default is for the stream
051: * to be on.
052: *
053: * <p>Note that digest objects can compute only one digest (see
054: * {@link MessageDigest}),
055: * so that in order to compute intermediate digests, a caller should
056: * retain a handle onto the digest object, and clone it for each
057: * digest to be computed, leaving the orginal digest untouched.
058: *
059: * @see MessageDigest
060: *
061: * @see DigestOutputStream
062: *
063: * @version 1.34 00/02/02
064: * @author Benjamin Renaud
065: */
066:
067: public class DigestInputStream extends FilterInputStream {
068:
069: /* NOTE: This should be made a generic UpdaterInputStream */
070:
071: /* Are we on or off? */
072: private boolean on = true;
073:
074: /**
075: * The message digest associated with this stream.
076: */
077: protected MessageDigest digest;
078:
079: /**
080: * Creates a digest input stream, using the specified input stream
081: * and message digest.
082: *
083: * @param stream the input stream.
084: *
085: * @param digest the message digest to associate with this stream.
086: */
087: public DigestInputStream(InputStream stream, MessageDigest digest) {
088: super (stream);
089: setMessageDigest(digest);
090: }
091:
092: /**
093: * Returns the message digest associated with this stream.
094: *
095: * @return the message digest associated with this stream.
096: * @see #setMessageDigest(java.security.MessageDigest)
097: */
098: public MessageDigest getMessageDigest() {
099: return digest;
100: }
101:
102: /**
103: * Associates the specified message digest with this stream.
104: *
105: * @param digest the message digest to be associated with this stream.
106: * @see #getMessageDigest()
107: */
108: public void setMessageDigest(MessageDigest digest) {
109: this .digest = digest;
110: }
111:
112: /**
113: * Reads a byte, and updates the message digest (if the digest
114: * function is on). That is, this method reads a byte from the
115: * input stream, blocking until the byte is actually read. If the
116: * digest function is on (see {@link #on(boolean) on}), this method
117: * will then call <code>update</code> on the message digest associated
118: * with this stream, passing it the byte read.
119: *
120: * @return the byte read.
121: *
122: * @exception IOException if an I/O error occurs.
123: *
124: * @see MessageDigest#update(byte)
125: */
126: public int read() throws IOException {
127: int ch = in.read();
128: if (on && ch != -1) {
129: digest.update((byte) ch);
130: }
131: return ch;
132: }
133:
134: /**
135: * Reads into a byte array, and updates the message digest (if the
136: * digest function is on). That is, this method reads up to
137: * <code>len</code> bytes from the input stream into the array
138: * <code>b</code>, starting at offset <code>off</code>. This method
139: * blocks until the data is actually
140: * read. If the digest function is on (see
141: * {@link #on(boolean) on}), this method will then call <code>update</code>
142: * on the message digest associated with this stream, passing it
143: * the data.
144: *
145: * @param b the array into which the data is read.
146: *
147: * @param off the starting offset into <code>b</code> of where the
148: * data should be placed.
149: *
150: * @param len the maximum number of bytes to be read from the input
151: * stream into b, starting at offset <code>off</code>.
152: *
153: * @return the actual number of bytes read. This is less than
154: * <code>len</code> if the end of the stream is reached prior to
155: * reading <code>len</code> bytes. -1 is returned if no bytes were
156: * read because the end of the stream had already been reached when
157: * the call was made.
158: *
159: * @exception IOException if an I/O error occurs.
160: *
161: * @see MessageDigest#update(byte[], int, int)
162: */
163: public int read(byte[] b, int off, int len) throws IOException {
164: int result = in.read(b, off, len);
165: if (on && result != -1) {
166: digest.update(b, off, result);
167: }
168: return result;
169: }
170:
171: /**
172: * Turns the digest function on or off. The default is on. When
173: * it is on, a call to one of the <code>read</code> methods results in an
174: * update on the message digest. But when it is off, the message
175: * digest is not updated.
176: *
177: * @param on true to turn the digest function on, false to turn
178: * it off.
179: */
180: public void on(boolean on) {
181: this .on = on;
182: }
183:
184: /**
185: * Prints a string representation of this digest input stream and
186: * its associated message digest object.
187: */
188: public String toString() {
189: return "[Digest Input Stream] " + digest.toString();
190: }
191: }
|