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