KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > PushbackReader


1 /*
2  * @(#)PushbackReader.java 1.18 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.io;
9
10
11 /**
12  * A character-stream reader that allows characters to be pushed back into the
13  * stream.
14  *
15  * @version 1.18, 03/12/19
16  * @author Mark Reinhold
17  * @since JDK1.1
18  */

19
20 public class PushbackReader extends FilterReader JavaDoc {
21
22     /** Pushback buffer */
23     private char[] buf;
24
25     /** Current position in buffer */
26     private int pos;
27
28     /**
29      * Create a new pushback reader with a pushback buffer of the given size.
30      *
31      * @param in The reader from which characters will be read
32      * @param size The size of the pushback buffer
33      * @exception IllegalArgumentException if size is <= 0
34      */

35     public PushbackReader(Reader JavaDoc in, int size) {
36     super(in);
37         if (size <= 0) {
38             throw new IllegalArgumentException JavaDoc("size <= 0");
39         }
40     this.buf = new char[size];
41     this.pos = size;
42     }
43
44     /**
45      * Create a new pushback reader with a one-character pushback buffer.
46      *
47      * @param in The reader from which characters will be read
48      */

49     public PushbackReader(Reader JavaDoc in) {
50     this(in, 1);
51     }
52
53     /** Check to make sure that the stream has not been closed. */
54     private void ensureOpen() throws IOException JavaDoc {
55     if (buf == null)
56         throw new IOException JavaDoc("Stream closed");
57     }
58
59     /**
60      * Read a single character.
61      *
62      * @return The character read, or -1 if the end of the stream has been
63      * reached
64      *
65      * @exception IOException If an I/O error occurs
66      */

67     public int read() throws IOException JavaDoc {
68     synchronized (lock) {
69         ensureOpen();
70         if (pos < buf.length)
71         return buf[pos++];
72         else
73         return super.read();
74     }
75     }
76
77     /**
78      * Read characters into a portion of an array.
79      *
80      * @param cbuf Destination buffer
81      * @param off Offset at which to start writing characters
82      * @param len Maximum number of characters to read
83      *
84      * @return The number of characters read, or -1 if the end of the
85      * stream has been reached
86      *
87      * @exception IOException If an I/O error occurs
88      */

89     public int read(char cbuf[], int off, int len) throws IOException JavaDoc {
90     synchronized (lock) {
91         ensureOpen();
92             try {
93                 if (len <= 0) {
94                     if (len < 0) {
95                         throw new IndexOutOfBoundsException JavaDoc();
96                     } else if ((off < 0) || (off > cbuf.length)) {
97                         throw new IndexOutOfBoundsException JavaDoc();
98                     }
99                     return 0;
100                 }
101                 int avail = buf.length - pos;
102                 if (avail > 0) {
103                     if (len < avail)
104                         avail = len;
105                     System.arraycopy(buf, pos, cbuf, off, avail);
106                     pos += avail;
107                     off += avail;
108                     len -= avail;
109                 }
110                 if (len > 0) {
111                     len = super.read(cbuf, off, len);
112                     if (len == -1) {
113                         return (avail == 0) ? -1 : avail;
114                     }
115                     return avail + len;
116                 }
117                 return avail;
118             } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
119                 throw new IndexOutOfBoundsException JavaDoc();
120             }
121         }
122     }
123
124     /**
125      * Push back a single character.
126      *
127      * @param c The character to push back
128      *
129      * @exception IOException If the pushback buffer is full,
130      * or if some other I/O error occurs
131      */

132     public void unread(int c) throws IOException JavaDoc {
133     synchronized (lock) {
134         ensureOpen();
135         if (pos == 0)
136         throw new IOException JavaDoc("Pushback buffer overflow");
137         buf[--pos] = (char) c;
138     }
139     }
140
141     /**
142      * Push back a portion of an array of characters by copying it to the
143      * front of the pushback buffer. After this method returns, the next
144      * character to be read will have the value <code>cbuf[off]</code>, the
145      * character after that will have the value <code>cbuf[off+1]</code>, and
146      * so forth.
147      *
148      * @param cbuf Character array
149      * @param off Offset of first character to push back
150      * @param len Number of characters to push back
151      *
152      * @exception IOException If there is insufficient room in the pushback
153      * buffer, or if some other I/O error occurs
154      */

155     public void unread(char cbuf[], int off, int len) throws IOException JavaDoc {
156     synchronized (lock) {
157         ensureOpen();
158         if (len > pos)
159         throw new IOException JavaDoc("Pushback buffer overflow");
160         pos -= len;
161         System.arraycopy(cbuf, off, buf, pos, len);
162     }
163     }
164
165     /**
166      * Push back an array of characters by copying it to the front of the
167      * pushback buffer. After this method returns, the next character to be
168      * read will have the value <code>cbuf[0]</code>, the character after that
169      * will have the value <code>cbuf[1]</code>, and so forth.
170      *
171      * @param cbuf Character array to push back
172      *
173      * @exception IOException If there is insufficient room in the pushback
174      * buffer, or if some other I/O error occurs
175      */

176     public void unread(char cbuf[]) throws IOException JavaDoc {
177     unread(cbuf, 0, cbuf.length);
178     }
179
180     /**
181      * Tell whether this stream is ready to be read.
182      *
183      * @exception IOException If an I/O error occurs
184      */

185     public boolean ready() throws IOException JavaDoc {
186     synchronized (lock) {
187         ensureOpen();
188         return (pos < buf.length) || super.ready();
189     }
190     }
191
192     /**
193      * Mark the present position in the stream. The <code>mark</code>
194      * for class <code>PushbackReader</code> always throws an exception.
195      *
196      * @exception IOException Always, since mark is not supported
197      */

198     public void mark(int readAheadLimit) throws IOException JavaDoc {
199     throw new IOException JavaDoc("mark/reset not supported");
200     }
201
202     /**
203      * Reset the stream. The <code>reset</code> method of
204      * <code>PushbackReader</code> always throws an exception.
205      *
206      * @exception IOException Always, since reset is not supported
207      */

208     public void reset() throws IOException JavaDoc {
209     throw new IOException JavaDoc("mark/reset not supported");
210     }
211
212     /**
213      * Tell whether this stream supports the mark() operation, which it does
214      * not.
215      */

216     public boolean markSupported() {
217     return false;
218     }
219
220     /**
221      * Close the stream.
222      *
223      * @exception IOException If an I/O error occurs
224      */

225     public void close() throws IOException JavaDoc {
226     super.close();
227     buf = null;
228     }
229
230     /**
231      * Skip characters. This method will block until some characters are
232      * available, an I/O error occurs, or the end of the stream is reached.
233      *
234      * @param n The number of characters to skip
235      *
236      * @return The number of characters actually skipped
237      *
238      * @exception IllegalArgumentException If <code>n</code> is negative.
239      * @exception IOException If an I/O error occurs
240      */

241     public long skip(long n) throws IOException JavaDoc {
242         if (n < 0L)
243             throw new IllegalArgumentException JavaDoc("skip value is negative");
244     synchronized (lock) {
245             ensureOpen();
246             int avail = buf.length - pos;
247             if (avail > 0) {
248                 if (n <= avail) {
249                     pos += n;
250                     return n;
251                 } else {
252                     pos = buf.length;
253                     n -= avail;
254                 }
255             }
256             return avail + super.skip(n);
257         }
258     }
259
260 }
261
Popular Tags