1. /*
  2. * @(#)DigestOutputStream.java 1.28 00/02/02
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.security;
  11. import java.io.IOException;
  12. import java.io.EOFException;
  13. import java.io.OutputStream;
  14. import java.io.FilterOutputStream;
  15. import java.io.PrintStream;
  16. import java.io.ByteArrayOutputStream;
  17. /**
  18. * A transparent stream that updates the associated message digest using
  19. * the bits going through the stream.
  20. *
  21. * <p>To complete the message digest computation, call one of the
  22. * <code>digest</code> methods on the associated message
  23. * digest after your calls to one of this digest ouput stream's
  24. * {@link #write(int) write} methods.
  25. *
  26. * <p>It is possible to turn this stream on or off (see
  27. * {@link #on(boolean) on}). When it is on, a call to one of the
  28. * <code>write</code> methods results in
  29. * an update on the message digest. But when it is off, the message
  30. * digest is not updated. The default is for the stream to be on.
  31. *
  32. * @see MessageDigest
  33. * @see DigestInputStream
  34. *
  35. * @version 1.28 00/02/02
  36. * @author Benjamin Renaud
  37. */
  38. public class DigestOutputStream extends FilterOutputStream {
  39. private boolean on = true;
  40. /**
  41. * The message digest associated with this stream.
  42. */
  43. protected MessageDigest digest;
  44. /**
  45. * Creates a digest output stream, using the specified output stream
  46. * and message digest.
  47. *
  48. * @param stream the output stream.
  49. *
  50. * @param digest the message digest to associate with this stream.
  51. */
  52. public DigestOutputStream(OutputStream stream, MessageDigest digest) {
  53. super(stream);
  54. setMessageDigest(digest);
  55. }
  56. /**
  57. * Returns the message digest associated with this stream.
  58. *
  59. * @return the message digest associated with this stream.
  60. * @see #setMessageDigest(java.security.MessageDigest)
  61. */
  62. public MessageDigest getMessageDigest() {
  63. return digest;
  64. }
  65. /**
  66. * Associates the specified message digest with this stream.
  67. *
  68. * @param digest the message digest to be associated with this stream.
  69. * @see #getMessageDigest()
  70. */
  71. public void setMessageDigest(MessageDigest digest) {
  72. this.digest = digest;
  73. }
  74. /**
  75. * Updates the message digest (if the digest function is on) using
  76. * the specified byte, and in any case writes the byte
  77. * to the output stream. That is, if the digest function is on
  78. * (see {@link #on(boolean) on}), this method calls
  79. * <code>update</code> on the message digest associated with this
  80. * stream, passing it the byte <code>b</code>. This method then
  81. * writes the byte to the output stream, blocking until the byte
  82. * is actually written.
  83. *
  84. * @param b the byte to be used for updating and writing to the
  85. * output stream.
  86. *
  87. * @exception IOException if an I/O error occurs.
  88. *
  89. * @see MessageDigest#update(byte)
  90. */
  91. public void write(int b) throws IOException {
  92. if (on) {
  93. digest.update((byte)b);
  94. }
  95. out.write(b);
  96. }
  97. /**
  98. * Updates the message digest (if the digest function is on) using
  99. * the specified subarray, and in any case writes the subarray to
  100. * the output stream. That is, if the digest function is on (see
  101. * {@link #on(boolean) on}), this method calls <code>update</code>
  102. * on the message digest associated with this stream, passing it
  103. * the subarray specifications. This method then writes the subarray
  104. * bytes to the output stream, blocking until the bytes are actually
  105. * written.
  106. *
  107. * @param b the array containing the subarray to be used for updating
  108. * and writing to the output stream.
  109. *
  110. * @param off the offset into <code>b</code> of the first byte to
  111. * be updated and written.
  112. *
  113. * @param len the number of bytes of data to be updated and written
  114. * from <code>b</code>, starting at offset <code>off</code>.
  115. *
  116. * @exception IOException if an I/O error occurs.
  117. *
  118. * @see MessageDigest#update(byte[], int, int)
  119. */
  120. public void write(byte[] b, int off, int len) throws IOException {
  121. if (on) {
  122. digest.update(b, off, len);
  123. }
  124. out.write(b, off, len);
  125. }
  126. /**
  127. * Turns the digest function on or off. The default is on. When
  128. * it is on, a call to one of the <code>write</code> methods results in an
  129. * update on the message digest. But when it is off, the message
  130. * digest is not updated.
  131. *
  132. * @param on true to turn the digest function on, false to turn it
  133. * off.
  134. */
  135. public void on(boolean on) {
  136. this.on = on;
  137. }
  138. /**
  139. * Prints a string representation of this digest output stream and
  140. * its associated message digest object.
  141. */
  142. public String toString() {
  143. return "[Digest Output Stream] " + digest.toString();
  144. }
  145. }