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: * Abstract class for reading character streams. The only methods that a
030: * subclass must implement are read(char[], int, int) and close(). Most
031: * subclasses, however, will override some of the methods defined here in order
032: * to provide higher efficiency, additional functionality, or both.
033: *
034: *
035: * @see BufferedReader
036: * @see LineNumberReader
037: * @see CharArrayReader
038: * @see InputStreamReader
039: * @see FileReader
040: * @see FilterReader
041: * @see PushbackReader
042: * @see PipedReader
043: * @see StringReader
044: * @see Writer
045: *
046: * @version 1.36, 07/05/05
047: * @author Mark Reinhold
048: * @since JDK1.1
049: */
050:
051: public abstract class Reader implements Readable, Closeable {
052:
053: /**
054: * The object used to synchronize operations on this stream. For
055: * efficiency, a character-stream object may use an object other than
056: * itself to protect critical sections. A subclass should therefore use
057: * the object in this field rather than <tt>this</tt> or a synchronized
058: * method.
059: */
060: protected Object lock;
061:
062: /**
063: * Creates a new character-stream reader whose critical sections will
064: * synchronize on the reader itself.
065: */
066: protected Reader() {
067: this.lock = this;
068: }
069:
070: /**
071: * Creates a new character-stream reader whose critical sections will
072: * synchronize on the given object.
073: *
074: * @param lock The Object to synchronize on.
075: */
076: protected Reader(Object lock) {
077: if (lock == null) {
078: throw new NullPointerException();
079: }
080: this.lock = lock;
081: }
082:
083: /**
084: * Attempts to read characters into the specified character buffer.
085: * The buffer is used as a repository of characters as-is: the only
086: * changes made are the results of a put operation. No flipping or
087: * rewinding of the buffer is performed.
088: *
089: * @param target the buffer to read characters into
090: * @return The number of characters added to the buffer, or
091: * -1 if this source of characters is at its end
092: * @throws IOException if an I/O error occurs
093: * @throws NullPointerException if target is null
094: * @throws ReadOnlyBufferException if target is a read only buffer
095: * @since 1.5
096: */
097: public int read(java.nio.CharBuffer target) throws IOException {
098: int len = target.remaining();
099: char[] cbuf = new char[len];
100: int n = read(cbuf, 0, len);
101: if (n > 0)
102: target.put(cbuf, 0, n);
103: return n;
104: }
105:
106: /**
107: * Reads a single character. This method will block until a character is
108: * available, an I/O error occurs, or the end of the stream is reached.
109: *
110: * <p> Subclasses that intend to support efficient single-character input
111: * should override this method.
112: *
113: * @return The character read, as an integer in the range 0 to 65535
114: * (<tt>0x00-0xffff</tt>), or -1 if the end of the stream has
115: * been reached
116: *
117: * @exception IOException If an I/O error occurs
118: */
119: public int read() throws IOException {
120: char cb[] = new char[1];
121: if (read(cb, 0, 1) == -1)
122: return -1;
123: else
124: return cb[0];
125: }
126:
127: /**
128: * Reads characters into an array. This method will block until some input
129: * is available, an I/O error occurs, or the end of the stream is reached.
130: *
131: * @param cbuf Destination buffer
132: *
133: * @return The number of characters read, or -1
134: * if the end of the stream
135: * has been reached
136: *
137: * @exception IOException If an I/O error occurs
138: */
139: public int read(char cbuf[]) throws IOException {
140: return read(cbuf, 0, cbuf.length);
141: }
142:
143: /**
144: * Reads characters into a portion of an array. This method will block
145: * until some input is available, an I/O error occurs, or the end of the
146: * stream is reached.
147: *
148: * @param cbuf Destination buffer
149: * @param off Offset at which to start storing characters
150: * @param len Maximum number of characters to read
151: *
152: * @return The number of characters read, or -1 if the end of the
153: * stream has been reached
154: *
155: * @exception IOException If an I/O error occurs
156: */
157: abstract public int read(char cbuf[], int off, int len)
158: throws IOException;
159:
160: /** Maximum skip-buffer size */
161: private static final int maxSkipBufferSize = 8192;
162:
163: /** Skip buffer, null until allocated */
164: private char skipBuffer[] = null;
165:
166: /**
167: * Skips characters. This method will block until some characters are
168: * available, an I/O error occurs, or the end of the stream is reached.
169: *
170: * @param n The number of characters to skip
171: *
172: * @return The number of characters actually skipped
173: *
174: * @exception IllegalArgumentException If <code>n</code> is negative.
175: * @exception IOException If an I/O error occurs
176: */
177: public long skip(long n) throws IOException {
178: if (n < 0L)
179: throw new IllegalArgumentException("skip value is negative");
180: int nn = (int) Math.min(n, maxSkipBufferSize);
181: synchronized (lock) {
182: if ((skipBuffer == null) || (skipBuffer.length < nn))
183: skipBuffer = new char[nn];
184: long r = n;
185: while (r > 0) {
186: int nc = read(skipBuffer, 0, (int) Math.min(r, nn));
187: if (nc == -1)
188: break;
189: r -= nc;
190: }
191: return n - r;
192: }
193: }
194:
195: /**
196: * Tells whether this stream is ready to be read.
197: *
198: * @return True if the next read() is guaranteed not to block for input,
199: * false otherwise. Note that returning false does not guarantee that the
200: * next read will block.
201: *
202: * @exception IOException If an I/O error occurs
203: */
204: public boolean ready() throws IOException {
205: return false;
206: }
207:
208: /**
209: * Tells whether this stream supports the mark() operation. The default
210: * implementation always returns false. Subclasses should override this
211: * method.
212: *
213: * @return true if and only if this stream supports the mark operation.
214: */
215: public boolean markSupported() {
216: return false;
217: }
218:
219: /**
220: * Marks the present position in the stream. Subsequent calls to reset()
221: * will attempt to reposition the stream to this point. Not all
222: * character-input streams support the mark() operation.
223: *
224: * @param readAheadLimit Limit on the number of characters that may be
225: * read while still preserving the mark. After
226: * reading this many characters, attempting to
227: * reset the stream may fail.
228: *
229: * @exception IOException If the stream does not support mark(),
230: * or if some other I/O error occurs
231: */
232: public void mark(int readAheadLimit) throws IOException {
233: throw new IOException("mark() not supported");
234: }
235:
236: /**
237: * Resets the stream. If the stream has been marked, then attempt to
238: * reposition it at the mark. If the stream has not been marked, then
239: * attempt to reset it in some way appropriate to the particular stream,
240: * for example by repositioning it to its starting point. Not all
241: * character-input streams support the reset() operation, and some support
242: * reset() without supporting mark().
243: *
244: * @exception IOException If the stream has not been marked,
245: * or if the mark has been invalidated,
246: * or if the stream does not support reset(),
247: * or if some other I/O error occurs
248: */
249: public void reset() throws IOException {
250: throw new IOException("reset() not supported");
251: }
252:
253: /**
254: * Closes the stream and releases any system resources associated with
255: * it. Once the stream has been closed, further read(), ready(),
256: * mark(), reset(), or skip() invocations will throw an IOException.
257: * Closing a previously closed stream has no effect.
258: *
259: * @exception IOException If an I/O error occurs
260: */
261: abstract public void close() throws IOException;
262:
263: }
|