001: /*
002: * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.security;
027:
028: import java.io.IOException;
029: import java.io.EOFException;
030: import java.io.OutputStream;
031: import java.io.FilterOutputStream;
032: import java.io.PrintStream;
033: import java.io.ByteArrayOutputStream;
034:
035: /**
036: * A transparent stream that updates the associated message digest using
037: * the bits going through the stream.
038: *
039: * <p>To complete the message digest computation, call one of the
040: * <code>digest</code> methods on the associated message
041: * digest after your calls to one of this digest ouput stream's
042: * {@link #write(int) write} methods.
043: *
044: * <p>It is possible to turn this stream on or off (see
045: * {@link #on(boolean) on}). When it is on, a call to one of the
046: * <code>write</code> methods results in
047: * an update on the message digest. But when it is off, the message
048: * digest is not updated. The default is for the stream to be on.
049: *
050: * @see MessageDigest
051: * @see DigestInputStream
052: *
053: * @version 1.38 07/05/05
054: * @author Benjamin Renaud
055: */
056: public class DigestOutputStream extends FilterOutputStream {
057:
058: private boolean on = true;
059:
060: /**
061: * The message digest associated with this stream.
062: */
063: protected MessageDigest digest;
064:
065: /**
066: * Creates a digest output stream, using the specified output stream
067: * and message digest.
068: *
069: * @param stream the output stream.
070: *
071: * @param digest the message digest to associate with this stream.
072: */
073: public DigestOutputStream(OutputStream stream, MessageDigest digest) {
074: super (stream);
075: setMessageDigest(digest);
076: }
077:
078: /**
079: * Returns the message digest associated with this stream.
080: *
081: * @return the message digest associated with this stream.
082: * @see #setMessageDigest(java.security.MessageDigest)
083: */
084: public MessageDigest getMessageDigest() {
085: return digest;
086: }
087:
088: /**
089: * Associates the specified message digest with this stream.
090: *
091: * @param digest the message digest to be associated with this stream.
092: * @see #getMessageDigest()
093: */
094: public void setMessageDigest(MessageDigest digest) {
095: this .digest = digest;
096: }
097:
098: /**
099: * Updates the message digest (if the digest function is on) using
100: * the specified byte, and in any case writes the byte
101: * to the output stream. That is, if the digest function is on
102: * (see {@link #on(boolean) on}), this method calls
103: * <code>update</code> on the message digest associated with this
104: * stream, passing it the byte <code>b</code>. This method then
105: * writes the byte to the output stream, blocking until the byte
106: * is actually written.
107: *
108: * @param b the byte to be used for updating and writing to the
109: * output stream.
110: *
111: * @exception IOException if an I/O error occurs.
112: *
113: * @see MessageDigest#update(byte)
114: */
115: public void write(int b) throws IOException {
116: if (on) {
117: digest.update((byte) b);
118: }
119: out.write(b);
120: }
121:
122: /**
123: * Updates the message digest (if the digest function is on) using
124: * the specified subarray, and in any case writes the subarray to
125: * the output stream. That is, if the digest function is on (see
126: * {@link #on(boolean) on}), this method calls <code>update</code>
127: * on the message digest associated with this stream, passing it
128: * the subarray specifications. This method then writes the subarray
129: * bytes to the output stream, blocking until the bytes are actually
130: * written.
131: *
132: * @param b the array containing the subarray to be used for updating
133: * and writing to the output stream.
134: *
135: * @param off the offset into <code>b</code> of the first byte to
136: * be updated and written.
137: *
138: * @param len the number of bytes of data to be updated and written
139: * from <code>b</code>, starting at offset <code>off</code>.
140: *
141: * @exception IOException if an I/O error occurs.
142: *
143: * @see MessageDigest#update(byte[], int, int)
144: */
145: public void write(byte[] b, int off, int len) throws IOException {
146: if (on) {
147: digest.update(b, off, len);
148: }
149: out.write(b, off, len);
150: }
151:
152: /**
153: * Turns the digest function on or off. The default is on. When
154: * it is on, a call to one of the <code>write</code> methods results in an
155: * update on the message digest. But when it is off, the message
156: * digest is not updated.
157: *
158: * @param on true to turn the digest function on, false to turn it
159: * off.
160: */
161: public void on(boolean on) {
162: this .on = on;
163: }
164:
165: /**
166: * Prints a string representation of this digest output stream and
167: * its associated message digest object.
168: */
169: public String toString() {
170: return "[Digest Output Stream] " + digest.toString();
171: }
172: }
|