001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.io;
019:
020: import org.apache.harmony.luni.util.Msg;
021:
022: /**
023: * PipedOutputStream is a class which places information on a communications
024: * pipe. When two threads want to pass data back and forth, one creates a piped
025: * output stream and the other creates a piped input stream.
026: *
027: * @see PipedInputStream
028: */
029: public class PipedOutputStream extends OutputStream {
030:
031: /**
032: * The destination PipedInputStream
033: */
034: private PipedInputStream dest;
035:
036: /**
037: * Constructs a new unconnected PipedOutputStream. The resulting Stream must
038: * be connected to a PipedInputStream before data may be written to it.
039: */
040: public PipedOutputStream() {
041: super ();
042: }
043:
044: /**
045: * Constructs a new PipedOutputStream connected to the PipedInputStream
046: * <code>dest</code>. Any data written to this stream can be read from
047: * the <code>dest</code>.
048: *
049: * @param dest
050: * the PipedInputStream to connect to.
051: *
052: * @throws IOException
053: * if <code>dest</code> is already connected.
054: */
055: public PipedOutputStream(PipedInputStream dest) throws IOException {
056: super ();
057: connect(dest);
058: }
059:
060: /**
061: * Close this PipedOutputStream. Any data buffered in the corresponding
062: * PipedInputStream can be read, then -1 will be returned to the reader. If
063: * this OutputStream is not connected, this method does nothing.
064: *
065: * @throws IOException
066: * If an error occurs attempting to close this
067: * PipedOutputStream.
068: */
069: @Override
070: public void close() throws IOException {
071: // Is the pipe connected?
072: if (dest != null) {
073: dest.done();
074: dest = null;
075: }
076: }
077:
078: /**
079: * Connects this PipedOutputStream to a PipedInputStream. Any data written
080: * to this OutputStream becomes readable in the InputStream.
081: *
082: * @param stream
083: * the destination PipedInputStream.
084: *
085: * @throws IOException
086: * If this Stream or the dest is already connected.
087: */
088: public void connect(PipedInputStream stream) throws IOException {
089: if (null == stream) {
090: throw new NullPointerException();
091: }
092: if (this .dest != null) {
093: throw new IOException(Msg.getString("K0079")); //$NON-NLS-1$
094: }
095: synchronized (stream) {
096: if (stream.isConnected) {
097: throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
098: }
099: stream.buffer = new byte[PipedInputStream.PIPE_SIZE];
100: stream.isConnected = true;
101: this .dest = stream;
102: }
103: }
104:
105: /**
106: * Notifies the readers on the PipedInputStream that bytes can be read. This
107: * method does nothing if this Stream is not connected.
108: *
109: * @throws IOException
110: * If an IO error occurs during the flush.
111: */
112: @Override
113: public void flush() throws IOException {
114: if (dest != null) {
115: synchronized (dest) {
116: dest.notifyAll();
117: }
118: }
119: }
120:
121: /**
122: * Writes <code>count</code> <code>bytes</code> from this byte array
123: * <code>buffer</code> starting at offset <code>index</code> to this
124: * PipedOutputStream. The written data can now be read from the destination
125: * PipedInputStream. Separate threads should be used for the reader of the
126: * PipedInputStream and the PipedOutputStream. There may be undesirable
127: * results if more than one Thread interacts a input or output pipe.
128: *
129: * @param buffer
130: * the buffer to be written
131: * @param offset
132: * offset in buffer to get bytes
133: * @param count
134: * number of bytes in buffer to write
135: *
136: * @throws IOException
137: * If the receiving thread was terminated without closing the
138: * pipe. This case is not currently handled correctly.
139: * @throws InterruptedIOException
140: * If the pipe is full and the current thread is interrupted
141: * waiting for space to write data. This case is not currently
142: * handled correctly.
143: * @throws NullPointerException
144: * If the receiver has not been connected yet.
145: * @throws IllegalArgumentException
146: * If any of the arguments are out of bounds.
147: */
148: @Override
149: public void write(byte buffer[], int offset, int count)
150: throws IOException {
151: if (dest == null) {
152: // K007b=Pipe Not Connected
153: throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
154: }
155: super .write(buffer, offset, count);
156: }
157:
158: /**
159: * Writes the specified byte <code>oneByte</code> to this
160: * PipedOutputStream. Only the low order byte of <code>oneByte</code> is
161: * written. The data can now be read from the destination PipedInputStream.
162: * Separate threads should be used for the reader of the PipedInputStream
163: * and the PipedOutputStream. There may be undesirable results if more than
164: * one Thread interacts a input or output pipe.
165: *
166: * @param oneByte
167: * the byte to be written
168: *
169: * @throws IOException
170: * If the receiving thread was terminated without closing the
171: * pipe. This case is not currently handled correctly.
172: * @throws InterruptedIOException
173: * If the pipe is full and the current thread is interrupted
174: * waiting for space to write data. This case is not currently
175: * handled correctly.
176: * @throws NullPointerException
177: * If the receiver has not been connected yet.
178: */
179: @Override
180: public void write(int oneByte) throws IOException {
181: if (dest == null) {
182: throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
183: }
184: dest.receive(oneByte);
185: }
186: }
|