1. /*
  2. * @(#)CharArrayWriter.java 1.23 04/07/16
  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. * This class implements a character buffer that can be used as an Writer.
  10. * The buffer automatically grows when data is written to the stream. The data
  11. * can be retrieved using toCharArray() and toString().
  12. * <P>
  13. * Note: Invoking close() on this class has no effect, and methods
  14. * of this class can be called after the stream has closed
  15. * without generating an IOException.
  16. *
  17. * @author Herb Jellinek
  18. * @version 1.23, 07/16/04
  19. * @since JDK1.1
  20. */
  21. public
  22. class CharArrayWriter extends Writer {
  23. /**
  24. * The buffer where data is stored.
  25. */
  26. protected char buf[];
  27. /**
  28. * The number of chars in the buffer.
  29. */
  30. protected int count;
  31. /**
  32. * Creates a new CharArrayWriter.
  33. */
  34. public CharArrayWriter() {
  35. this(32);
  36. }
  37. /**
  38. * Creates a new CharArrayWriter with the specified initial size.
  39. *
  40. * @param initialSize an int specifying the initial buffer size.
  41. * @exception IllegalArgumentException if initialSize is negative
  42. */
  43. public CharArrayWriter(int initialSize) {
  44. if (initialSize < 0) {
  45. throw new IllegalArgumentException("Negative initial size: "
  46. + initialSize);
  47. }
  48. buf = new char[initialSize];
  49. }
  50. /**
  51. * Writes a character to the buffer.
  52. */
  53. public void write(int c) {
  54. synchronized (lock) {
  55. int newcount = count + 1;
  56. if (newcount > buf.length) {
  57. char newbuf[] = new char[Math.max(buf.length << 1, newcount)];
  58. System.arraycopy(buf, 0, newbuf, 0, count);
  59. buf = newbuf;
  60. }
  61. buf[count] = (char)c;
  62. count = newcount;
  63. }
  64. }
  65. /**
  66. * Writes characters to the buffer.
  67. * @param c the data to be written
  68. * @param off the start offset in the data
  69. * @param len the number of chars that are written
  70. */
  71. public void write(char c[], int off, int len) {
  72. if ((off < 0) || (off > c.length) || (len < 0) ||
  73. ((off + len) > c.length) || ((off + len) < 0)) {
  74. throw new IndexOutOfBoundsException();
  75. } else if (len == 0) {
  76. return;
  77. }
  78. synchronized (lock) {
  79. int newcount = count + len;
  80. if (newcount > buf.length) {
  81. char newbuf[] = new char[Math.max(buf.length << 1, newcount)];
  82. System.arraycopy(buf, 0, newbuf, 0, count);
  83. buf = newbuf;
  84. }
  85. System.arraycopy(c, off, buf, count, len);
  86. count = newcount;
  87. }
  88. }
  89. /**
  90. * Write a portion of a string to the buffer.
  91. * @param str String to be written from
  92. * @param off Offset from which to start reading characters
  93. * @param len Number of characters to be written
  94. */
  95. public void write(String str, int off, int len) {
  96. synchronized (lock) {
  97. int newcount = count + len;
  98. if (newcount > buf.length) {
  99. char newbuf[] = new char[Math.max(buf.length << 1, newcount)];
  100. System.arraycopy(buf, 0, newbuf, 0, count);
  101. buf = newbuf;
  102. }
  103. str.getChars(off, off + len, buf, count);
  104. count = newcount;
  105. }
  106. }
  107. /**
  108. * Writes the contents of the buffer to another character stream.
  109. *
  110. * @param out the output stream to write to
  111. * @throws IOException If an I/O error occurs.
  112. */
  113. public void writeTo(Writer out) throws IOException {
  114. synchronized (lock) {
  115. out.write(buf, 0, count);
  116. }
  117. }
  118. /**
  119. * Appends the specified character sequence to this writer.
  120. *
  121. * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
  122. * behaves in exactly the same way as the invocation
  123. *
  124. * <pre>
  125. * out.write(csq.toString()) </pre>
  126. *
  127. * <p> Depending on the specification of <tt>toString</tt> for the
  128. * character sequence <tt>csq</tt>, the entire sequence may not be
  129. * appended. For instance, invoking the <tt>toString</tt> method of a
  130. * character buffer will return a subsequence whose content depends upon
  131. * the buffer's position and limit.
  132. *
  133. * @param csq
  134. * The character sequence to append. If <tt>csq</tt> is
  135. * <tt>null</tt>, then the four characters <tt>"null"</tt> are
  136. * appended to this writer.
  137. *
  138. * @return This writer
  139. *
  140. * @since 1.5
  141. */
  142. public CharArrayWriter append(CharSequence csq) {
  143. String s = (csq == null ? "null" : csq.toString());
  144. write(s, 0, s.length());
  145. return this;
  146. }
  147. /**
  148. * Appends a subsequence of the specified character sequence to this writer.
  149. *
  150. * <p> An invocation of this method of the form <tt>out.append(csq, start,
  151. * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
  152. * exactly the same way as the invocation
  153. *
  154. * <pre>
  155. * out.write(csq.subSequence(start, end).toString()) </pre>
  156. *
  157. * @param csq
  158. * The character sequence from which a subsequence will be
  159. * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
  160. * will be appended as if <tt>csq</tt> contained the four
  161. * characters <tt>"null"</tt>.
  162. *
  163. * @param start
  164. * The index of the first character in the subsequence
  165. *
  166. * @param end
  167. * The index of the character following the last character in the
  168. * subsequence
  169. *
  170. * @return This writer
  171. *
  172. * @throws IndexOutOfBoundsException
  173. * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
  174. * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
  175. * <tt>csq.length()</tt>
  176. *
  177. * @since 1.5
  178. */
  179. public CharArrayWriter append(CharSequence csq, int start, int end) {
  180. String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
  181. write(s, 0, s.length());
  182. return this;
  183. }
  184. /**
  185. * Appends the specified character to this writer.
  186. *
  187. * <p> An invocation of this method of the form <tt>out.append(c)</tt>
  188. * behaves in exactly the same way as the invocation
  189. *
  190. * <pre>
  191. * out.write(c) </pre>
  192. *
  193. * @param c
  194. * The 16-bit character to append
  195. *
  196. * @return This writer
  197. *
  198. * @since 1.5
  199. */
  200. public CharArrayWriter append(char c) {
  201. write(c);
  202. return this;
  203. }
  204. /**
  205. * Resets the buffer so that you can use it again without
  206. * throwing away the already allocated buffer.
  207. */
  208. public void reset() {
  209. count = 0;
  210. }
  211. /**
  212. * Returns a copy of the input data.
  213. *
  214. * @return an array of chars copied from the input data.
  215. */
  216. public char toCharArray()[] {
  217. synchronized (lock) {
  218. char newbuf[] = new char[count];
  219. System.arraycopy(buf, 0, newbuf, 0, count);
  220. return newbuf;
  221. }
  222. }
  223. /**
  224. * Returns the current size of the buffer.
  225. *
  226. * @return an int representing the current size of the buffer.
  227. */
  228. public int size() {
  229. return count;
  230. }
  231. /**
  232. * Converts input data to a string.
  233. * @return the string.
  234. */
  235. public String toString() {
  236. synchronized (lock) {
  237. return new String(buf, 0, count);
  238. }
  239. }
  240. /**
  241. * Flush the stream.
  242. */
  243. public void flush() { }
  244. /**
  245. * Close the stream. This method does not release the buffer, since its
  246. * contents might still be required. Note: Invoking this method in this class
  247. * will have no effect.
  248. */
  249. public void close() { }
  250. }