1. /*
  2. * @(#)CharArrayReader.java 1.15 00/02/02
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.io;
  11. /**
  12. * This class implements a character buffer that can be used as a
  13. * character-input stream.
  14. *
  15. * @author Herb Jellinek
  16. * @version 1.15, 02/02/00
  17. * @since JDK1.1
  18. */
  19. public
  20. class CharArrayReader extends Reader {
  21. /** The character buffer. */
  22. protected char buf[];
  23. /** The current buffer position. */
  24. protected int pos;
  25. /** The position of mark in buffer. */
  26. protected int markedPos = 0;
  27. /** The number of valid characters in the buffer. */
  28. protected int count;
  29. /**
  30. * Create an CharArrayReader from the specified array of chars.
  31. * @param buf Input buffer (not copied)
  32. */
  33. public CharArrayReader(char buf[]) {
  34. this.buf = buf;
  35. this.pos = 0;
  36. this.count = buf.length;
  37. }
  38. /**
  39. * Create an CharArrayReader from the specified array of chars.
  40. * @param buf Input buffer (not copied)
  41. * @param offset Offset of the first char to read
  42. * @param length Number of chars to read
  43. */
  44. public CharArrayReader(char buf[], int offset, int length) {
  45. if ((offset < 0) || (offset > buf.length) || (length < 0) ||
  46. ((offset + length) < 0)) {
  47. throw new IllegalArgumentException();
  48. }
  49. this.buf = buf;
  50. this.pos = offset;
  51. this.count = Math.min(offset + length, buf.length);
  52. this.markedPos = offset;
  53. }
  54. /** Check to make sure that the stream has not been closed */
  55. private void ensureOpen() throws IOException {
  56. if (buf == null)
  57. throw new IOException("Stream closed");
  58. }
  59. /**
  60. * Read a single character.
  61. *
  62. * @exception IOException If an I/O error occurs
  63. */
  64. public int read() throws IOException {
  65. synchronized (lock) {
  66. ensureOpen();
  67. if (pos >= count)
  68. return -1;
  69. else
  70. return buf[pos++];
  71. }
  72. }
  73. /**
  74. * Read characters into a portion of an array.
  75. * @param b Destination buffer
  76. * @param off Offset at which to start storing characters
  77. * @param len Maximum number of characters to read
  78. * @return The actual number of characters read, or -1 if
  79. * the end of the stream has been reached
  80. *
  81. * @exception IOException If an I/O error occurs
  82. */
  83. public int read(char b[], int off, int len) throws IOException {
  84. synchronized (lock) {
  85. ensureOpen();
  86. if ((off < 0) || (off > b.length) || (len < 0) ||
  87. ((off + len) > b.length) || ((off + len) < 0)) {
  88. throw new IndexOutOfBoundsException();
  89. } else if (len == 0) {
  90. return 0;
  91. }
  92. if (pos >= count) {
  93. return -1;
  94. }
  95. if (pos + len > count) {
  96. len = count - pos;
  97. }
  98. if (len <= 0) {
  99. return 0;
  100. }
  101. System.arraycopy(buf, pos, b, off, len);
  102. pos += len;
  103. return len;
  104. }
  105. }
  106. /**
  107. * Skip characters.
  108. * @param n The number of characters to skip
  109. * @return The number of characters actually skipped
  110. *
  111. * @exception IOException If an I/O error occurs
  112. */
  113. public long skip(long n) throws IOException {
  114. synchronized (lock) {
  115. ensureOpen();
  116. if (pos + n > count) {
  117. n = count - pos;
  118. }
  119. if (n < 0) {
  120. return 0;
  121. }
  122. pos += n;
  123. return n;
  124. }
  125. }
  126. /**
  127. * Tell whether this stream is ready to be read. Character-array readers
  128. * are always ready to be read.
  129. *
  130. * @exception IOException If an I/O error occurs
  131. */
  132. public boolean ready() throws IOException {
  133. synchronized (lock) {
  134. ensureOpen();
  135. return (count - pos) > 0;
  136. }
  137. }
  138. /**
  139. * Tell whether this stream supports the mark() operation, which it does.
  140. */
  141. public boolean markSupported() {
  142. return true;
  143. }
  144. /**
  145. * Mark the present position in the stream. Subsequent calls to reset()
  146. * will reposition the stream to this point.
  147. *
  148. * @param readAheadLimit Limit on the number of characters that may be
  149. * read while still preserving the mark. Because
  150. * the stream's input comes from a character array,
  151. * there is no actual limit; hence this argument is
  152. * ignored.
  153. *
  154. * @exception IOException If an I/O error occurs
  155. */
  156. public void mark(int readAheadLimit) throws IOException {
  157. synchronized (lock) {
  158. ensureOpen();
  159. markedPos = pos;
  160. }
  161. }
  162. /**
  163. * Reset the stream to the most recent mark, or to the beginning if it has
  164. * never been marked.
  165. *
  166. * @exception IOException If an I/O error occurs
  167. */
  168. public void reset() throws IOException {
  169. synchronized (lock) {
  170. ensureOpen();
  171. pos = markedPos;
  172. }
  173. }
  174. /**
  175. * Close the stream.
  176. */
  177. public void close() {
  178. buf = null;
  179. }
  180. }