• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /**
2   *  Licensed to the Apache Software Foundation (ASF) under one or more
3   *  contributor license agreements.  See the NOTICE file distributed with
4   *  this work for additional information regarding copyright ownership.
5   *  The ASF licenses this file to You under the Apache License, Version 2.0
6   *  (the "License"); you may not use this file except in compliance with
7   *  the License.  You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package java.io;
19  
20  import java.nio.CharBuffer;
21  import java.nio.ReadOnlyBufferException;
22  
23  /*** The base class for all readers. A reader is a means of reading data from a source in a character-wise manner. Some readers also
24   * support marking a position in the input and returning to this position later.
25   * <p>
26   * This abstract class does not provide a fully working implementation, so it needs to be subclassed, and at least the
27   * {@link #read(char[], int, int)} and {@link #close()} methods needs to be overridden. Overriding some of the non-abstract
28   * methods is also often advised, since it might result in higher efficiency.
29   * <p>
30   * Many specialized readers for purposes like reading from a file already exist in this package.
31   *
32   * @see Writer */
33  public abstract class Reader implements Readable, Closeable {
34  	/*** The object used to synchronize access to the reader. */
35  	protected Object lock;
36  
37  	/*** Constructs a new {@code Reader} with {@code this} as the object used to synchronize critical sections. */
Reader()38  	protected Reader () {
39  		super();
40  		lock = this;
41  	}
42  
43  	/*** Constructs a new {@code Reader} with {@code lock} used to synchronize critical sections.
44  	 *
45  	 * @param lock the {@code Object} used to synchronize critical sections.
46  	 * @throws NullPointerException if {@code lock} is {@code null}. */
Reader(Object lock)47  	protected Reader (Object lock) {
48  		if (lock == null) {
49  			throw new NullPointerException();
50  		}
51  		this.lock = lock;
52  	}
53  
54  	/*** Closes this reader. Implementations of this method should free any resources associated with the reader.
55  	 *
56  	 * @throws IOException if an error occurs while closing this reader. */
close()57  	public abstract void close () throws IOException;
58  
59  	/*** Sets a mark position in this reader. The parameter {@code readLimit} indicates how many characters can be read before the
60  	 * mark is invalidated. Calling {@code reset()} will reposition the reader back to the marked position if {@code readLimit} has
61  	 * not been surpassed.
62  	 * <p>
63  	 * This default implementation simply throws an {@code IOException}; subclasses must provide their own implementation.
64  	 *
65  	 * @param readLimit the number of characters that can be read before the mark is invalidated.
66  	 * @throws IllegalArgumentException if {@code readLimit < 0}.
67  	 * @throws IOException if an error occurs while setting a mark in this reader.
68  	 * @see #markSupported()
69  	 * @see #reset() */
mark(int readLimit)70  	public void mark (int readLimit) throws IOException {
71  		throw new IOException();
72  	}
73  
74  	/*** Indicates whether this reader supports the {@code mark()} and {@code reset()} methods. This default implementation returns
75  	 * {@code false}.
76  	 *
77  	 * @return always {@code false}. */
markSupported()78  	public boolean markSupported () {
79  		return false;
80  	}
81  
82  	/*** Reads a single character from this reader and returns it as an integer with the two higher-order bytes set to 0. Returns -1
83  	 * if the end of the reader has been reached.
84  	 *
85  	 * @return the character read or -1 if the end of the reader has been reached.
86  	 * @throws IOException if this reader is closed or some other I/O error occurs. */
read()87  	public int read () throws IOException {
88  		synchronized (lock) {
89  			char charArray[] = new char[1];
90  			if (read(charArray, 0, 1) != -1) {
91  				return charArray[0];
92  			}
93  			return -1;
94  		}
95  	}
96  
97  	/*** Reads characters from this reader and stores them in the character array {@code buf} starting at offset 0. Returns the
98  	 * number of characters actually read or -1 if the end of the reader has been reached.
99  	 *
100  	 * @param buf character array to store the characters read.
101  	 * @return the number of characters read or -1 if the end of the reader has been reached.
102  	 * @throws IOException if this reader is closed or some other I/O error occurs. */
read(char buf[])103  	public int read (char buf[]) throws IOException {
104  		return read(buf, 0, buf.length);
105  	}
106  
107  	/*** Reads at most {@code count} characters from this reader and stores them at {@code offset} in the character array {@code buf}
108  	 * . Returns the number of characters actually read or -1 if the end of the reader has been reached.
109  	 *
110  	 * @param buf the character array to store the characters read.
111  	 * @param offset the initial position in {@code buffer} to store the characters read from this reader.
112  	 * @param count the maximum number of characters to read.
113  	 * @return the number of characters read or -1 if the end of the reader has been reached.
114  	 * @throws IOException if this reader is closed or some other I/O error occurs. */
read(char buf[], int offset, int count)115  	public abstract int read (char buf[], int offset, int count) throws IOException;
116  
117  	/*** Indicates whether this reader is ready to be read without blocking. Returns {@code true} if this reader will not block when
118  	 * {@code read} is called, {@code false} if unknown or blocking will occur. This default implementation always returns
119  	 * {@code false}.
120  	 *
121  	 * @return always {@code false}.
122  	 * @throws IOException if this reader is closed or some other I/O error occurs.
123  	 * @see #read()
124  	 * @see #read(char[])
125  	 * @see #read(char[], int, int) */
ready()126  	public boolean ready () throws IOException {
127  		return false;
128  	}
129  
130  	/*** Resets this reader's position to the last {@code mark()} location. Invocations of {@code read()} and {@code skip()} will
131  	 * occur from this new location. If this reader has not been marked, the behavior of {@code reset()} is implementation
132  	 * specific. This default implementation throws an {@code IOException}.
133  	 *
134  	 * @throws IOException always thrown in this default implementation.
135  	 * @see #mark(int)
136  	 * @see #markSupported() */
reset()137  	public void reset () throws IOException {
138  		throw new IOException();
139  	}
140  
141  	/*** Skips {@code amount} characters in this reader. Subsequent calls of {@code read} methods will not return these characters
142  	 * unless {@code reset()} is used. This method may perform multiple reads to read {@code count} characters.
143  	 *
144  	 * @param count the maximum number of characters to skip.
145  	 * @return the number of characters actually skipped.
146  	 * @throws IllegalArgumentException if {@code amount < 0}.
147  	 * @throws IOException if this reader is closed or some other I/O error occurs.
148  	 * @see #mark(int)
149  	 * @see #markSupported()
150  	 * @see #reset() */
skip(long count)151  	public long skip (long count) throws IOException {
152  		if (count < 0) {
153  			throw new IllegalArgumentException();
154  		}
155  		synchronized (lock) {
156  			long skipped = 0;
157  			int toRead = count < 512 ? (int)count : 512;
158  			char charsSkipped[] = new char[toRead];
159  			while (skipped < count) {
160  				int read = read(charsSkipped, 0, toRead);
161  				if (read == -1) {
162  					return skipped;
163  				}
164  				skipped += read;
165  				if (read < toRead) {
166  					return skipped;
167  				}
168  				if (count - skipped < toRead) {
169  					toRead = (int)(count - skipped);
170  				}
171  			}
172  			return skipped;
173  		}
174  	}
175  
176  	/*** Reads characters and puts them into the {@code target} character buffer.
177  	 *
178  	 * @param target the destination character buffer.
179  	 * @return the number of characters put into {@code target} or -1 if the end of this reader has been reached before a character
180  	 *         has been read.
181  	 * @throws IOException if any I/O error occurs while reading from this reader.
182  	 * @throws NullPointerException if {@code target} is {@code null}.
183  	 * @throws ReadOnlyBufferException if {@code target} is read-only. */
184  	public int read (CharBuffer target) throws IOException {
185  		if (null == target) {
186  			throw new NullPointerException();
187  		}
188  		int length = target.length();
189  		char[] buf = new char[length];
190  		length = Math.min(length, read(buf));
191  		if (length > 0) {
192  			target.put(buf, 0, length);
193  		}
194  		return length;
195  	}
196  }
197