Source Code Cross Referenced for PipedReader.java in  » 6.0-JDK-Core » io-nio » java » io » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » io nio » java.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.io;
027
028        /**
029         * Piped character-input streams.
030         *
031         * @version 	1.25, 07/05/05
032         * @author	Mark Reinhold
033         * @since	JDK1.1
034         */
035
036        public class PipedReader extends Reader {
037            boolean closedByWriter = false;
038            boolean closedByReader = false;
039            boolean connected = false;
040
041            /* REMIND: identification of the read and write sides needs to be
042               more sophisticated.  Either using thread groups (but what about
043               pipes within a thread?) or using finalization (but it may be a
044               long time until the next GC). */
045            Thread readSide;
046            Thread writeSide;
047
048            /** 
049             * The size of the pipe's circular input buffer. 
050             */
051            private static final int DEFAULT_PIPE_SIZE = 1024;
052
053            /**
054             * The circular buffer into which incoming data is placed.
055             */
056            char buffer[];
057
058            /**
059             * The index of the position in the circular buffer at which the 
060             * next character of data will be stored when received from the connected 
061             * piped writer. <code>in&lt;0</code> implies the buffer is empty, 
062             * <code>in==out</code> implies the buffer is full
063             */
064            int in = -1;
065
066            /**
067             * The index of the position in the circular buffer at which the next 
068             * character of data will be read by this piped reader.
069             */
070            int out = 0;
071
072            /**
073             * Creates a <code>PipedReader</code> so
074             * that it is connected to the piped writer
075             * <code>src</code>. Data written to <code>src</code> 
076             * will then be available as input from this stream.
077             *
078             * @param      src   the stream to connect to.
079             * @exception  IOException  if an I/O error occurs.
080             */
081            public PipedReader(PipedWriter src) throws IOException {
082                this (src, DEFAULT_PIPE_SIZE);
083            }
084
085            /**
086             * Creates a <code>PipedReader</code> so that it is connected
087             * to the piped writer <code>src</code> and uses the specified
088             * pipe size for the pipe's buffer. Data written to <code>src</code> 
089             * will then be  available as input from this stream.
090            
091             * @param      src       the stream to connect to.
092             * @param      pipeSize  the size of the pipe's buffer.
093             * @exception  IOException  if an I/O error occurs.
094             * @exception  IllegalArgumentException if <code>pipeSize <= 0</code>.
095             * @since	   1.6
096             */
097            public PipedReader(PipedWriter src, int pipeSize)
098                    throws IOException {
099                initPipe(pipeSize);
100                connect(src);
101            }
102
103            /**
104             * Creates a <code>PipedReader</code> so
105             * that it is not yet {@linkplain #connect(java.io.PipedWriter)
106             * connected}. It must be {@linkplain java.io.PipedWriter#connect(
107             * java.io.PipedReader) connected} to a <code>PipedWriter</code>
108             * before being used.
109             */
110            public PipedReader() {
111                initPipe(DEFAULT_PIPE_SIZE);
112            }
113
114            /**
115             * Creates a <code>PipedReader</code> so that it is not yet 
116             * {@link #connect(java.io.PipedWriter) connected} and uses
117             * the specified pipe size for the pipe's buffer.
118             * It must be  {@linkplain java.io.PipedWriter#connect(
119             * java.io.PipedReader) connected} to a <code>PipedWriter</code>
120             * before being used.
121             *
122             * @param   pipeSize the size of the pipe's buffer.
123             * @exception  IllegalArgumentException if <code>pipeSize <= 0</code>.
124             * @since	   1.6
125             */
126            public PipedReader(int pipeSize) {
127                initPipe(pipeSize);
128            }
129
130            private void initPipe(int pipeSize) {
131                if (pipeSize <= 0) {
132                    throw new IllegalArgumentException("Pipe size <= 0");
133                }
134                buffer = new char[pipeSize];
135            }
136
137            /**
138             * Causes this piped reader to be connected
139             * to the piped  writer <code>src</code>.
140             * If this object is already connected to some
141             * other piped writer, an <code>IOException</code>
142             * is thrown.
143             * <p>
144             * If <code>src</code> is an
145             * unconnected piped writer and <code>snk</code>
146             * is an unconnected piped reader, they
147             * may be connected by either the call:
148             * <p>
149             * <pre><code>snk.connect(src)</code> </pre> 
150             * <p>
151             * or the call:
152             * <p>
153             * <pre><code>src.connect(snk)</code> </pre> 
154             * <p>
155             * The two
156             * calls have the same effect.
157             *
158             * @param      src   The piped writer to connect to.
159             * @exception  IOException  if an I/O error occurs.
160             */
161            public void connect(PipedWriter src) throws IOException {
162                src.connect(this );
163            }
164
165            /**
166             * Receives a char of data. This method will block if no input is
167             * available.
168             */
169            synchronized void receive(int c) throws IOException {
170                if (!connected) {
171                    throw new IOException("Pipe not connected");
172                } else if (closedByWriter || closedByReader) {
173                    throw new IOException("Pipe closed");
174                } else if (readSide != null && !readSide.isAlive()) {
175                    throw new IOException("Read end dead");
176                }
177
178                writeSide = Thread.currentThread();
179                while (in == out) {
180                    if ((readSide != null) && !readSide.isAlive()) {
181                        throw new IOException("Pipe broken");
182                    }
183                    /* full: kick any waiting readers */
184                    notifyAll();
185                    try {
186                        wait(1000);
187                    } catch (InterruptedException ex) {
188                        throw new java.io.InterruptedIOException();
189                    }
190                }
191                if (in < 0) {
192                    in = 0;
193                    out = 0;
194                }
195                buffer[in++] = (char) c;
196                if (in >= buffer.length) {
197                    in = 0;
198                }
199            }
200
201            /**
202             * Receives data into an array of characters.  This method will
203             * block until some input is available. 
204             */
205            synchronized void receive(char c[], int off, int len)
206                    throws IOException {
207                while (--len >= 0) {
208                    receive(c[off++]);
209                }
210            }
211
212            /**
213             * Notifies all waiting threads that the last character of data has been
214             * received.
215             */
216            synchronized void receivedLast() {
217                closedByWriter = true;
218                notifyAll();
219            }
220
221            /**
222             * Reads the next character of data from this piped stream.
223             * If no character is available because the end of the stream 
224             * has been reached, the value <code>-1</code> is returned. 
225             * This method blocks until input data is available, the end of
226             * the stream is detected, or an exception is thrown. 
227             *
228             * @return     the next character of data, or <code>-1</code> if the end of the
229             *             stream is reached.
230             * @exception  IOException  if the pipe is
231             *		<a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
232             *		{@link #connect(java.io.PipedWriter) unconnected}, closed,
233             *		or an I/O error occurs.
234             */
235            public synchronized int read() throws IOException {
236                if (!connected) {
237                    throw new IOException("Pipe not connected");
238                } else if (closedByReader) {
239                    throw new IOException("Pipe closed");
240                } else if (writeSide != null && !writeSide.isAlive()
241                        && !closedByWriter && (in < 0)) {
242                    throw new IOException("Write end dead");
243                }
244
245                readSide = Thread.currentThread();
246                int trials = 2;
247                while (in < 0) {
248                    if (closedByWriter) {
249                        /* closed by writer, return EOF */
250                        return -1;
251                    }
252                    if ((writeSide != null) && (!writeSide.isAlive())
253                            && (--trials < 0)) {
254                        throw new IOException("Pipe broken");
255                    }
256                    /* might be a writer waiting */
257                    notifyAll();
258                    try {
259                        wait(1000);
260                    } catch (InterruptedException ex) {
261                        throw new java.io.InterruptedIOException();
262                    }
263                }
264                int ret = buffer[out++];
265                if (out >= buffer.length) {
266                    out = 0;
267                }
268                if (in == out) {
269                    /* now empty */
270                    in = -1;
271                }
272                return ret;
273            }
274
275            /**
276             * Reads up to <code>len</code> characters of data from this piped
277             * stream into an array of characters. Less than <code>len</code> characters
278             * will be read if the end of the data stream is reached or if
279             * <code>len</code> exceeds the pipe's buffer size. This method 
280             * blocks until at least one character of input is available. 
281             *
282             * @param      cbuf     the buffer into which the data is read.
283             * @param      off   the start offset of the data.
284             * @param      len   the maximum number of characters read.
285             * @return     the total number of characters read into the buffer, or
286             *             <code>-1</code> if there is no more data because the end of
287             *             the stream has been reached.
288             * @exception  IOException  if the pipe is
289             *			<a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
290             *          	{@link #connect(java.io.PipedWriter) unconnected}, closed,
291             *			or an I/O error occurs.
292             */
293            public synchronized int read(char cbuf[], int off, int len)
294                    throws IOException {
295                if (!connected) {
296                    throw new IOException("Pipe not connected");
297                } else if (closedByReader) {
298                    throw new IOException("Pipe closed");
299                } else if (writeSide != null && !writeSide.isAlive()
300                        && !closedByWriter && (in < 0)) {
301                    throw new IOException("Write end dead");
302                }
303
304                if ((off < 0) || (off > cbuf.length) || (len < 0)
305                        || ((off + len) > cbuf.length) || ((off + len) < 0)) {
306                    throw new IndexOutOfBoundsException();
307                } else if (len == 0) {
308                    return 0;
309                }
310
311                /* possibly wait on the first character */
312                int c = read();
313                if (c < 0) {
314                    return -1;
315                }
316                cbuf[off] = (char) c;
317                int rlen = 1;
318                while ((in >= 0) && (--len > 0)) {
319                    cbuf[off + rlen] = buffer[out++];
320                    rlen++;
321                    if (out >= buffer.length) {
322                        out = 0;
323                    }
324                    if (in == out) {
325                        /* now empty */
326                        in = -1;
327                    }
328                }
329                return rlen;
330            }
331
332            /**
333             * Tell whether this stream is ready to be read.  A piped character
334             * stream is ready if the circular buffer is not empty.
335             *
336             * @exception  IOException  if the pipe is
337             *			<a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
338             *			{@link #connect(java.io.PipedWriter) unconnected}, or closed.
339             */
340            public synchronized boolean ready() throws IOException {
341                if (!connected) {
342                    throw new IOException("Pipe not connected");
343                } else if (closedByReader) {
344                    throw new IOException("Pipe closed");
345                } else if (writeSide != null && !writeSide.isAlive()
346                        && !closedByWriter && (in < 0)) {
347                    throw new IOException("Write end dead");
348                }
349                if (in < 0) {
350                    return false;
351                } else {
352                    return true;
353                }
354            }
355
356            /**
357             * Closes this piped stream and releases any system resources 
358             * associated with the stream. 
359             *
360             * @exception  IOException  if an I/O error occurs.
361             */
362            public void close() throws IOException {
363                in = -1;
364                closedByReader = true;
365            }
366        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.