1. /*
  2. * @(#)Reader.java 1.27 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. package java.io;
  8. /**
  9. * Abstract class for reading character streams. The only methods that a
  10. * subclass must implement are read(char[], int, int) and close(). Most
  11. * subclasses, however, will override some of the methods defined here in order
  12. * to provide higher efficiency, additional functionality, or both.
  13. *
  14. *
  15. * @see BufferedReader
  16. * @see LineNumberReader
  17. * @see CharArrayReader
  18. * @see InputStreamReader
  19. * @see FileReader
  20. * @see FilterReader
  21. * @see PushbackReader
  22. * @see PipedReader
  23. * @see StringReader
  24. * @see Writer
  25. *
  26. * @version 1.27, 03/12/19
  27. * @author Mark Reinhold
  28. * @since JDK1.1
  29. */
  30. public abstract class Reader implements Readable, Closeable {
  31. /**
  32. * The object used to synchronize operations on this stream. For
  33. * efficiency, a character-stream object may use an object other than
  34. * itself to protect critical sections. A subclass should therefore use
  35. * the object in this field rather than <tt>this</tt> or a synchronized
  36. * method.
  37. */
  38. protected Object lock;
  39. /**
  40. * Create a new character-stream reader whose critical sections will
  41. * synchronize on the reader itself.
  42. */
  43. protected Reader() {
  44. this.lock = this;
  45. }
  46. /**
  47. * Create a new character-stream reader whose critical sections will
  48. * synchronize on the given object.
  49. *
  50. * @param lock The Object to synchronize on.
  51. */
  52. protected Reader(Object lock) {
  53. if (lock == null) {
  54. throw new NullPointerException();
  55. }
  56. this.lock = lock;
  57. }
  58. /**
  59. * Attempts to read characters into the specified character buffer.
  60. * The buffer is used as a repository of characters as-is: the only
  61. * changes made are the results of a put operation. No flipping or
  62. * rewinding of the buffer is performed.
  63. *
  64. * @param target the buffer to read characters into
  65. * @return The number of characters added to the buffer, or
  66. * -1 if this source of characters is at its end
  67. * @throws IOException if an I/O error occurs
  68. * @throws NullPointerException if target is null
  69. * @throws ReadOnlyBufferException if target is a read only buffer
  70. */
  71. public int read(java.nio.CharBuffer target) throws IOException {
  72. int len = target.remaining();
  73. char[] cbuf = new char[len];
  74. int n = read(cbuf, 0, len);
  75. if (n > 0)
  76. target.put(cbuf, 0, n);
  77. return n;
  78. }
  79. /**
  80. * Read a single character. This method will block until a character is
  81. * available, an I/O error occurs, or the end of the stream is reached.
  82. *
  83. * <p> Subclasses that intend to support efficient single-character input
  84. * should override this method.
  85. *
  86. * @return The character read, as an integer in the range 0 to 65535
  87. * (<tt>0x00-0xffff</tt>), or -1 if the end of the stream has
  88. * been reached
  89. *
  90. * @exception IOException If an I/O error occurs
  91. */
  92. public int read() throws IOException {
  93. char cb[] = new char[1];
  94. if (read(cb, 0, 1) == -1)
  95. return -1;
  96. else
  97. return cb[0];
  98. }
  99. /**
  100. * Read characters into an array. This method will block until some input
  101. * is available, an I/O error occurs, or the end of the stream is reached.
  102. *
  103. * @param cbuf Destination buffer
  104. *
  105. * @return The number of characters read, or -1
  106. * if the end of the stream
  107. * has been reached
  108. *
  109. * @exception IOException If an I/O error occurs
  110. */
  111. public int read(char cbuf[]) throws IOException {
  112. return read(cbuf, 0, cbuf.length);
  113. }
  114. /**
  115. * Read characters into a portion of an array. This method will block
  116. * until some input is available, an I/O error occurs, or the end of the
  117. * stream is reached.
  118. *
  119. * @param cbuf Destination buffer
  120. * @param off Offset at which to start storing characters
  121. * @param len Maximum number of characters to read
  122. *
  123. * @return The number of characters read, or -1 if the end of the
  124. * stream has been reached
  125. *
  126. * @exception IOException If an I/O error occurs
  127. */
  128. abstract public int read(char cbuf[], int off, int len) throws IOException;
  129. /** Maximum skip-buffer size */
  130. private static final int maxSkipBufferSize = 8192;
  131. /** Skip buffer, null until allocated */
  132. private char skipBuffer[] = null;
  133. /**
  134. * Skip characters. This method will block until some characters are
  135. * available, an I/O error occurs, or the end of the stream is reached.
  136. *
  137. * @param n The number of characters to skip
  138. *
  139. * @return The number of characters actually skipped
  140. *
  141. * @exception IllegalArgumentException If <code>n</code> is negative.
  142. * @exception IOException If an I/O error occurs
  143. */
  144. public long skip(long n) throws IOException {
  145. if (n < 0L)
  146. throw new IllegalArgumentException("skip value is negative");
  147. int nn = (int) Math.min(n, maxSkipBufferSize);
  148. synchronized (lock) {
  149. if ((skipBuffer == null) || (skipBuffer.length < nn))
  150. skipBuffer = new char[nn];
  151. long r = n;
  152. while (r > 0) {
  153. int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
  154. if (nc == -1)
  155. break;
  156. r -= nc;
  157. }
  158. return n - r;
  159. }
  160. }
  161. /**
  162. * Tell whether this stream is ready to be read.
  163. *
  164. * @return True if the next read() is guaranteed not to block for input,
  165. * false otherwise. Note that returning false does not guarantee that the
  166. * next read will block.
  167. *
  168. * @exception IOException If an I/O error occurs
  169. */
  170. public boolean ready() throws IOException {
  171. return false;
  172. }
  173. /**
  174. * Tell whether this stream supports the mark() operation. The default
  175. * implementation always returns false. Subclasses should override this
  176. * method.
  177. *
  178. * @return true if and only if this stream supports the mark operation.
  179. */
  180. public boolean markSupported() {
  181. return false;
  182. }
  183. /**
  184. * Mark the present position in the stream. Subsequent calls to reset()
  185. * will attempt to reposition the stream to this point. Not all
  186. * character-input streams support the mark() operation.
  187. *
  188. * @param readAheadLimit Limit on the number of characters that may be
  189. * read while still preserving the mark. After
  190. * reading this many characters, attempting to
  191. * reset the stream may fail.
  192. *
  193. * @exception IOException If the stream does not support mark(),
  194. * or if some other I/O error occurs
  195. */
  196. public void mark(int readAheadLimit) throws IOException {
  197. throw new IOException("mark() not supported");
  198. }
  199. /**
  200. * Reset the stream. If the stream has been marked, then attempt to
  201. * reposition it at the mark. If the stream has not been marked, then
  202. * attempt to reset it in some way appropriate to the particular stream,
  203. * for example by repositioning it to its starting point. Not all
  204. * character-input streams support the reset() operation, and some support
  205. * reset() without supporting mark().
  206. *
  207. * @exception IOException If the stream has not been marked,
  208. * or if the mark has been invalidated,
  209. * or if the stream does not support reset(),
  210. * or if some other I/O error occurs
  211. */
  212. public void reset() throws IOException {
  213. throw new IOException("reset() not supported");
  214. }
  215. /**
  216. * Close the stream. Once a stream has been closed, further read(),
  217. * ready(), mark(), or reset() invocations will throw an IOException.
  218. * Closing a previously-closed stream, however, has no effect.
  219. *
  220. * @exception IOException If an I/O error occurs
  221. */
  222. abstract public void close() throws IOException;
  223. }