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