28 /** |
28 /** |
29 * A piped input stream should be connected |
29 * A piped input stream should be connected |
30 * to a piped output stream; the piped input |
30 * to a piped output stream; the piped input |
31 * stream then provides whatever data bytes |
31 * stream then provides whatever data bytes |
32 * are written to the piped output stream. |
32 * are written to the piped output stream. |
33 * Typically, data is read from a <code>PipedInputStream</code> |
33 * Typically, data is read from a {@code PipedInputStream} |
34 * object by one thread and data is written |
34 * object by one thread and data is written |
35 * to the corresponding <code>PipedOutputStream</code> |
35 * to the corresponding {@code PipedOutputStream} |
36 * by some other thread. Attempting to use |
36 * by some other thread. Attempting to use |
37 * both objects from a single thread is not |
37 * both objects from a single thread is not |
38 * recommended, as it may deadlock the thread. |
38 * recommended, as it may deadlock the thread. |
39 * The piped input stream contains a buffer, |
39 * The piped input stream contains a buffer, |
40 * decoupling read operations from write operations, |
40 * decoupling read operations from write operations, |
78 |
78 |
79 /** |
79 /** |
80 * The index of the position in the circular buffer at which the |
80 * The index of the position in the circular buffer at which the |
81 * next byte of data will be stored when received from the connected |
81 * next byte of data will be stored when received from the connected |
82 * piped output stream. <code>in<0</code> implies the buffer is empty, |
82 * piped output stream. <code>in<0</code> implies the buffer is empty, |
83 * <code>in==out</code> implies the buffer is full |
83 * {@code in==out} implies the buffer is full |
84 * @since 1.1 |
84 * @since 1.1 |
85 */ |
85 */ |
86 protected int in = -1; |
86 protected int in = -1; |
87 |
87 |
88 /** |
88 /** |
91 * @since 1.1 |
91 * @since 1.1 |
92 */ |
92 */ |
93 protected int out = 0; |
93 protected int out = 0; |
94 |
94 |
95 /** |
95 /** |
96 * Creates a <code>PipedInputStream</code> so |
96 * Creates a {@code PipedInputStream} so |
97 * that it is connected to the piped output |
97 * that it is connected to the piped output |
98 * stream <code>src</code>. Data bytes written |
98 * stream {@code src}. Data bytes written |
99 * to <code>src</code> will then be available |
99 * to {@code src} will then be available |
100 * as input from this stream. |
100 * as input from this stream. |
101 * |
101 * |
102 * @param src the stream to connect to. |
102 * @param src the stream to connect to. |
103 * @throws IOException if an I/O error occurs. |
103 * @throws IOException if an I/O error occurs. |
104 */ |
104 */ |
105 public PipedInputStream(PipedOutputStream src) throws IOException { |
105 public PipedInputStream(PipedOutputStream src) throws IOException { |
106 this(src, DEFAULT_PIPE_SIZE); |
106 this(src, DEFAULT_PIPE_SIZE); |
107 } |
107 } |
108 |
108 |
109 /** |
109 /** |
110 * Creates a <code>PipedInputStream</code> so that it is |
110 * Creates a {@code PipedInputStream} so that it is |
111 * connected to the piped output stream |
111 * connected to the piped output stream |
112 * <code>src</code> and uses the specified pipe size for |
112 * {@code src} and uses the specified pipe size for |
113 * the pipe's buffer. |
113 * the pipe's buffer. |
114 * Data bytes written to <code>src</code> will then |
114 * Data bytes written to {@code src} will then |
115 * be available as input from this stream. |
115 * be available as input from this stream. |
116 * |
116 * |
117 * @param src the stream to connect to. |
117 * @param src the stream to connect to. |
118 * @param pipeSize the size of the pipe's buffer. |
118 * @param pipeSize the size of the pipe's buffer. |
119 * @throws IOException if an I/O error occurs. |
119 * @throws IOException if an I/O error occurs. |
125 initPipe(pipeSize); |
125 initPipe(pipeSize); |
126 connect(src); |
126 connect(src); |
127 } |
127 } |
128 |
128 |
129 /** |
129 /** |
130 * Creates a <code>PipedInputStream</code> so |
130 * Creates a {@code PipedInputStream} so |
131 * that it is not yet {@linkplain #connect(java.io.PipedOutputStream) |
131 * that it is not yet {@linkplain #connect(java.io.PipedOutputStream) |
132 * connected}. |
132 * connected}. |
133 * It must be {@linkplain java.io.PipedOutputStream#connect( |
133 * It must be {@linkplain java.io.PipedOutputStream#connect( |
134 * java.io.PipedInputStream) connected} to a |
134 * java.io.PipedInputStream) connected} to a |
135 * <code>PipedOutputStream</code> before being used. |
135 * {@code PipedOutputStream} before being used. |
136 */ |
136 */ |
137 public PipedInputStream() { |
137 public PipedInputStream() { |
138 initPipe(DEFAULT_PIPE_SIZE); |
138 initPipe(DEFAULT_PIPE_SIZE); |
139 } |
139 } |
140 |
140 |
141 /** |
141 /** |
142 * Creates a <code>PipedInputStream</code> so that it is not yet |
142 * Creates a {@code PipedInputStream} so that it is not yet |
143 * {@linkplain #connect(java.io.PipedOutputStream) connected} and |
143 * {@linkplain #connect(java.io.PipedOutputStream) connected} and |
144 * uses the specified pipe size for the pipe's buffer. |
144 * uses the specified pipe size for the pipe's buffer. |
145 * It must be {@linkplain java.io.PipedOutputStream#connect( |
145 * It must be {@linkplain java.io.PipedOutputStream#connect( |
146 * java.io.PipedInputStream) |
146 * java.io.PipedInputStream) |
147 * connected} to a <code>PipedOutputStream</code> before being used. |
147 * connected} to a {@code PipedOutputStream} before being used. |
148 * |
148 * |
149 * @param pipeSize the size of the pipe's buffer. |
149 * @param pipeSize the size of the pipe's buffer. |
150 * @throws IllegalArgumentException if {@code pipeSize <= 0}. |
150 * @throws IllegalArgumentException if {@code pipeSize <= 0}. |
151 * @since 1.6 |
151 * @since 1.6 |
152 */ |
152 */ |
161 buffer = new byte[pipeSize]; |
161 buffer = new byte[pipeSize]; |
162 } |
162 } |
163 |
163 |
164 /** |
164 /** |
165 * Causes this piped input stream to be connected |
165 * Causes this piped input stream to be connected |
166 * to the piped output stream <code>src</code>. |
166 * to the piped output stream {@code src}. |
167 * If this object is already connected to some |
167 * If this object is already connected to some |
168 * other piped output stream, an <code>IOException</code> |
168 * other piped output stream, an {@code IOException} |
169 * is thrown. |
169 * is thrown. |
170 * <p> |
170 * <p> |
171 * If <code>src</code> is an |
171 * If {@code src} is an |
172 * unconnected piped output stream and <code>snk</code> |
172 * unconnected piped output stream and {@code snk} |
173 * is an unconnected piped input stream, they |
173 * is an unconnected piped input stream, they |
174 * may be connected by either the call: |
174 * may be connected by either the call: |
175 * |
175 * |
176 * <pre><code>snk.connect(src)</code> </pre> |
176 * <pre>{@code snk.connect(src)} </pre> |
177 * <p> |
177 * <p> |
178 * or the call: |
178 * or the call: |
179 * |
179 * |
180 * <pre><code>src.connect(snk)</code> </pre> |
180 * <pre>{@code src.connect(snk)} </pre> |
181 * <p> |
181 * <p> |
182 * The two calls have the same effect. |
182 * The two calls have the same effect. |
183 * |
183 * |
184 * @param src The piped output stream to connect to. |
184 * @param src The piped output stream to connect to. |
185 * @throws IOException if an I/O error occurs. |
185 * @throws IOException if an I/O error occurs. |
190 |
190 |
191 /** |
191 /** |
192 * Receives a byte of data. This method will block if no input is |
192 * Receives a byte of data. This method will block if no input is |
193 * available. |
193 * available. |
194 * @param b the byte being received |
194 * @param b the byte being received |
195 * @throws IOException If the pipe is <a href="#BROKEN"> <code>broken</code></a>, |
195 * @throws IOException If the pipe is <a href="#BROKEN"> {@code broken}</a>, |
196 * {@link #connect(java.io.PipedOutputStream) unconnected}, |
196 * {@link #connect(java.io.PipedOutputStream) unconnected}, |
197 * closed, or if an I/O error occurs. |
197 * closed, or if an I/O error occurs. |
198 * @since 1.1 |
198 * @since 1.1 |
199 */ |
199 */ |
200 protected synchronized void receive(int b) throws IOException { |
200 protected synchronized void receive(int b) throws IOException { |
286 notifyAll(); |
286 notifyAll(); |
287 } |
287 } |
288 |
288 |
289 /** |
289 /** |
290 * Reads the next byte of data from this piped input stream. The |
290 * Reads the next byte of data from this piped input stream. The |
291 * value byte is returned as an <code>int</code> in the range |
291 * value byte is returned as an {@code int} in the range |
292 * <code>0</code> to <code>255</code>. |
292 * {@code 0} to {@code 255}. |
293 * This method blocks until input data is available, the end of the |
293 * This method blocks until input data is available, the end of the |
294 * stream is detected, or an exception is thrown. |
294 * stream is detected, or an exception is thrown. |
295 * |
295 * |
296 * @return the next byte of data, or <code>-1</code> if the end of the |
296 * @return the next byte of data, or {@code -1} if the end of the |
297 * stream is reached. |
297 * stream is reached. |
298 * @throws IOException if the pipe is |
298 * @throws IOException if the pipe is |
299 * {@link #connect(java.io.PipedOutputStream) unconnected}, |
299 * {@link #connect(java.io.PipedOutputStream) unconnected}, |
300 * <a href="#BROKEN"> <code>broken</code></a>, closed, |
300 * <a href="#BROKEN"> {@code broken}</a>, closed, |
301 * or if an I/O error occurs. |
301 * or if an I/O error occurs. |
302 */ |
302 */ |
303 public synchronized int read() throws IOException { |
303 public synchronized int read() throws IOException { |
304 if (!connected) { |
304 if (!connected) { |
305 throw new IOException("Pipe not connected"); |
305 throw new IOException("Pipe not connected"); |
339 |
339 |
340 return ret; |
340 return ret; |
341 } |
341 } |
342 |
342 |
343 /** |
343 /** |
344 * Reads up to <code>len</code> bytes of data from this piped input |
344 * Reads up to {@code len} bytes of data from this piped input |
345 * stream into an array of bytes. Less than <code>len</code> bytes |
345 * stream into an array of bytes. Less than {@code len} bytes |
346 * will be read if the end of the data stream is reached or if |
346 * will be read if the end of the data stream is reached or if |
347 * <code>len</code> exceeds the pipe's buffer size. |
347 * {@code len} exceeds the pipe's buffer size. |
348 * If <code>len </code> is zero, then no bytes are read and 0 is returned; |
348 * If {@code len } is zero, then no bytes are read and 0 is returned; |
349 * otherwise, the method blocks until at least 1 byte of input is |
349 * otherwise, the method blocks until at least 1 byte of input is |
350 * available, end of the stream has been detected, or an exception is |
350 * available, end of the stream has been detected, or an exception is |
351 * thrown. |
351 * thrown. |
352 * |
352 * |
353 * @param b the buffer into which the data is read. |
353 * @param b the buffer into which the data is read. |
354 * @param off the start offset in the destination array <code>b</code> |
354 * @param off the start offset in the destination array {@code b} |
355 * @param len the maximum number of bytes read. |
355 * @param len the maximum number of bytes read. |
356 * @return the total number of bytes read into the buffer, or |
356 * @return the total number of bytes read into the buffer, or |
357 * <code>-1</code> if there is no more data because the end of |
357 * {@code -1} if there is no more data because the end of |
358 * the stream has been reached. |
358 * the stream has been reached. |
359 * @throws NullPointerException If <code>b</code> is <code>null</code>. |
359 * @throws NullPointerException If {@code b} is {@code null}. |
360 * @throws IndexOutOfBoundsException If <code>off</code> is negative, |
360 * @throws IndexOutOfBoundsException If {@code off} is negative, |
361 * <code>len</code> is negative, or <code>len</code> is greater than |
361 * {@code len} is negative, or {@code len} is greater than |
362 * <code>b.length - off</code> |
362 * {@code b.length - off} |
363 * @throws IOException if the pipe is <a href="#BROKEN"> <code>broken</code></a>, |
363 * @throws IOException if the pipe is <a href="#BROKEN"> {@code broken}</a>, |
364 * {@link #connect(java.io.PipedOutputStream) unconnected}, |
364 * {@link #connect(java.io.PipedOutputStream) unconnected}, |
365 * closed, or if an I/O error occurs. |
365 * closed, or if an I/O error occurs. |
366 */ |
366 */ |
367 public synchronized int read(byte b[], int off, int len) throws IOException { |
367 public synchronized int read(byte b[], int off, int len) throws IOException { |
368 if (b == null) { |
368 if (b == null) { |
416 * |
416 * |
417 * @return the number of bytes that can be read from this input stream |
417 * @return the number of bytes that can be read from this input stream |
418 * without blocking, or {@code 0} if this input stream has been |
418 * without blocking, or {@code 0} if this input stream has been |
419 * closed by invoking its {@link #close()} method, or if the pipe |
419 * closed by invoking its {@link #close()} method, or if the pipe |
420 * is {@link #connect(java.io.PipedOutputStream) unconnected}, or |
420 * is {@link #connect(java.io.PipedOutputStream) unconnected}, or |
421 * <a href="#BROKEN"> <code>broken</code></a>. |
421 * <a href="#BROKEN"> {@code broken}</a>. |
422 * |
422 * |
423 * @throws IOException if an I/O error occurs. |
423 * @throws IOException if an I/O error occurs. |
424 * @since 1.0.2 |
424 * @since 1.0.2 |
425 */ |
425 */ |
426 public synchronized int available() throws IOException { |
426 public synchronized int available() throws IOException { |