1. /*
  2. * @(#)PipedWriter.java 1.11 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.io;
  8. /**
  9. * Piped character-output streams.
  10. *
  11. * @version 1.11, 01/11/29
  12. * @author Mark Reinhold
  13. * @since JDK1.1
  14. */
  15. public class PipedWriter extends Writer {
  16. /* REMIND: identification of the read and write sides needs to be
  17. more sophisticated. Either using thread groups (but what about
  18. pipes within a thread?) or using finalization (but it may be a
  19. long time until the next GC). */
  20. private PipedReader sink;
  21. /**
  22. * Creates a piped writer connected to the specified piped
  23. * reader. Data characters written to this stream will then be
  24. * available as input from <code>snk</code>.
  25. *
  26. * @param snk The piped reader to connect to.
  27. * @exception IOException if an I/O error occurs.
  28. */
  29. public PipedWriter(PipedReader snk) throws IOException {
  30. connect(snk);
  31. }
  32. /**
  33. * Creates a piped writer that is not yet connected to a
  34. * piped reader. It must be connected to a piped reader,
  35. * either by the receiver or the sender, before being used.
  36. *
  37. * @see java.io.PipedReader#connect(java.io.PipedWriter)
  38. * @see java.io.PipedWriter#connect(java.io.PipedReader)
  39. */
  40. public PipedWriter() {
  41. }
  42. /**
  43. * Connects this piped writer to a receiver. If this object
  44. * is already connected to some other piped reader, an
  45. * <code>IOException</code> is thrown.
  46. * <p>
  47. * If <code>snk</code> is an unconnected piped reader and
  48. * <code>src</code> is an unconnected piped writer, they may
  49. * be connected by either the call:
  50. * <blockquote><pre>
  51. * src.connect(snk)</pre></blockquote>
  52. * or the call:
  53. * <blockquote><pre>
  54. * snk.connect(src)</pre></blockquote>
  55. * The two calls have the same effect.
  56. *
  57. * @param snk the piped reader to connect to.
  58. * @exception IOException if an I/O error occurs.
  59. */
  60. public synchronized void connect(PipedReader snk) throws IOException {
  61. if (snk == null) {
  62. throw new NullPointerException();
  63. } else if (sink != null || snk.connected) {
  64. throw new IOException("Already connected");
  65. }
  66. sink = snk;
  67. snk.in = -1;
  68. snk.out = 0;
  69. snk.connected = true;
  70. }
  71. /**
  72. * Writes the specified <code>char</code> to the piped output stream.
  73. * If a thread was reading data characters from the connected piped input
  74. * stream, but the thread is no longer alive, then an
  75. * <code>IOException</code> is thrown.
  76. * <p>
  77. * Implements the <code>write</code> method of <code>Writer</code>.
  78. *
  79. * @param c the <code>char</code> to be written.
  80. * @exception IOException if an I/O error occurs.
  81. */
  82. public void write(int c) throws IOException {
  83. if (sink == null) {
  84. throw new IOException("Pipe not connected");
  85. }
  86. sink.receive(c);
  87. }
  88. /**
  89. * Writes <code>len</code> characters from the specified character array
  90. * starting at offset <code>off</code> to this piped output stream.
  91. * If a thread was reading data characters from the connected piped input
  92. * stream, but the thread is no longer alive, then an
  93. * <code>IOException</code> is thrown.
  94. *
  95. * @param cbuf the data.
  96. * @param off the start offset in the data.
  97. * @param len the number of characters to write.
  98. * @exception IOException if an I/O error occurs.
  99. */
  100. public void write(char cbuf[], int off, int len) throws IOException {
  101. if (sink == null) {
  102. throw new IOException("Pipe not connected");
  103. } else if ((off < 0) || (off > cbuf.length) || (len < 0) ||
  104. ((off + len) > cbuf.length) || ((off + len) < 0)) {
  105. throw new IndexOutOfBoundsException();
  106. }
  107. sink.receive(cbuf, off, len);
  108. }
  109. /**
  110. * Flushes this output stream and forces any buffered output characters
  111. * to be written out.
  112. * This will notify any readers that characters are waiting in the pipe.
  113. *
  114. * @exception IOException if an I/O error occurs.
  115. */
  116. public synchronized void flush() throws IOException {
  117. if (sink != null) {
  118. synchronized (sink) {
  119. sink.notifyAll();
  120. }
  121. }
  122. }
  123. /**
  124. * Closes this piped output stream and releases any system resources
  125. * associated with this stream. This stream may no longer be used for
  126. * writing characters.
  127. *
  128. * @exception IOException if an I/O error occurs.
  129. */
  130. public void close() throws IOException {
  131. if (sink != null) {
  132. sink.receivedLast();
  133. }
  134. }
  135. }