1. /*
  2. * @(#)DigestOutputStream.java 1.25 01/11/29
  3. *
  4. * Copyright 2002 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.25 01/11/29
  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. */
  58. public MessageDigest getMessageDigest() {
  59. return digest;
  60. }
  61. /**
  62. * Associates the specified message digest with this stream.
  63. *
  64. * @param digest the message digest to be associated with this stream.
  65. */
  66. public void setMessageDigest(MessageDigest digest) {
  67. this.digest = digest;
  68. }
  69. /**
  70. * Updates the message digest (if the digest function is on) using
  71. * the specified byte, and in any case writes the byte
  72. * to the output stream. That is, if the digest function is on
  73. * (see {@link on(boolean) on}), this method calls
  74. * <code>update</code> on the message digest associated with this
  75. * stream, passing it the byte <code>b</code>. This method then
  76. * writes the byte to the output stream, blocking until the byte
  77. * is actually written.
  78. *
  79. * @param b the byte to be used for updating and writing to the
  80. * output stream.
  81. *
  82. * @exception IOException if an I/O error occurs.
  83. *
  84. * @see MessageDigest#update(byte)
  85. */
  86. public void write(int b) throws IOException {
  87. if (on) {
  88. digest.update((byte)b);
  89. }
  90. out.write(b);
  91. }
  92. /**
  93. * Updates the message digest (if the digest function is on) using
  94. * the specified subarray, and in any case writes the subarray to
  95. * the output stream. That is, if the digest function is on (see
  96. * {@link on(boolean) on}), this method calls <code>update</code>
  97. * on the message digest associated with this stream, passing it
  98. * the subarray specifications. This method then writes the subarray
  99. * bytes to the output stream, blocking until the bytes are actually
  100. * written.
  101. *
  102. * @param b the array containing the subarray to be used for updating
  103. * and writing to the output stream.
  104. *
  105. * @param off the offset into <code>b</code> of the first byte to
  106. * be updated and written.
  107. *
  108. * @param len the number of bytes of data to be updated and written
  109. * from <code>b</code>, starting at offset <code>off</code>.
  110. *
  111. * @exception IOException if an I/O error occurs.
  112. *
  113. * @see MessageDigest#update(byte[], int, int)
  114. */
  115. public void write(byte[] b, int off, int len) throws IOException {
  116. if (on) {
  117. digest.update(b, off, len);
  118. }
  119. out.write(b, off, len);
  120. }
  121. /**
  122. * Turns the digest function on or off. The default is on. When
  123. * it is on, a call to one of the <code>write</code> methods results in an
  124. * update on the message digest. But when it is off, the message
  125. * digest is not updated.
  126. *
  127. * @param on true to turn the digest function on, false to turn it
  128. * off.
  129. */
  130. public void on(boolean on) {
  131. this.on = on;
  132. }
  133. /**
  134. * Prints a string representation of this digest output stream and
  135. * its associated message digest object.
  136. */
  137. public String toString() {
  138. return "[Digest Output Stream] " + digest.toString();
  139. }
  140. }