blob: 791720ce017372b722618a20d13bc5ea49904c89 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1996-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.io;
27
28import java.util.Arrays;
29
30/**
31 * This class implements a character buffer that can be used as an Writer.
32 * The buffer automatically grows when data is written to the stream. The data
33 * can be retrieved using toCharArray() and toString().
34 * <P>
35 * Note: Invoking close() on this class has no effect, and methods
36 * of this class can be called after the stream has closed
37 * without generating an IOException.
38 *
39 * @author Herb Jellinek
40 * @since JDK1.1
41 */
42public
43class CharArrayWriter extends Writer {
44 /**
45 * The buffer where data is stored.
46 */
47 protected char buf[];
48
49 /**
50 * The number of chars in the buffer.
51 */
52 protected int count;
53
54 /**
55 * Creates a new CharArrayWriter.
56 */
57 public CharArrayWriter() {
58 this(32);
59 }
60
61 /**
62 * Creates a new CharArrayWriter with the specified initial size.
63 *
64 * @param initialSize an int specifying the initial buffer size.
65 * @exception IllegalArgumentException if initialSize is negative
66 */
67 public CharArrayWriter(int initialSize) {
68 if (initialSize < 0) {
69 throw new IllegalArgumentException("Negative initial size: "
70 + initialSize);
71 }
72 buf = new char[initialSize];
73 }
74
75 /**
76 * Writes a character to the buffer.
77 */
78 public void write(int c) {
79 synchronized (lock) {
80 int newcount = count + 1;
81 if (newcount > buf.length) {
82 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
83 }
84 buf[count] = (char)c;
85 count = newcount;
86 }
87 }
88
89 /**
90 * Writes characters to the buffer.
91 * @param c the data to be written
92 * @param off the start offset in the data
93 * @param len the number of chars that are written
94 */
95 public void write(char c[], int off, int len) {
96 if ((off < 0) || (off > c.length) || (len < 0) ||
97 ((off + len) > c.length) || ((off + len) < 0)) {
98 throw new IndexOutOfBoundsException();
99 } else if (len == 0) {
100 return;
101 }
102 synchronized (lock) {
103 int newcount = count + len;
104 if (newcount > buf.length) {
105 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
106 }
107 System.arraycopy(c, off, buf, count, len);
108 count = newcount;
109 }
110 }
111
112 /**
113 * Write a portion of a string to the buffer.
114 * @param str String to be written from
115 * @param off Offset from which to start reading characters
116 * @param len Number of characters to be written
117 */
118 public void write(String str, int off, int len) {
119 synchronized (lock) {
120 int newcount = count + len;
121 if (newcount > buf.length) {
122 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
123 }
124 str.getChars(off, off + len, buf, count);
125 count = newcount;
126 }
127 }
128
129 /**
130 * Writes the contents of the buffer to another character stream.
131 *
132 * @param out the output stream to write to
133 * @throws IOException If an I/O error occurs.
134 */
135 public void writeTo(Writer out) throws IOException {
136 synchronized (lock) {
137 out.write(buf, 0, count);
138 }
139 }
140
141 /**
142 * Appends the specified character sequence to this writer.
143 *
144 * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
145 * behaves in exactly the same way as the invocation
146 *
147 * <pre>
148 * out.write(csq.toString()) </pre>
149 *
150 * <p> Depending on the specification of <tt>toString</tt> for the
151 * character sequence <tt>csq</tt>, the entire sequence may not be
152 * appended. For instance, invoking the <tt>toString</tt> method of a
153 * character buffer will return a subsequence whose content depends upon
154 * the buffer's position and limit.
155 *
156 * @param csq
157 * The character sequence to append. If <tt>csq</tt> is
158 * <tt>null</tt>, then the four characters <tt>"null"</tt> are
159 * appended to this writer.
160 *
161 * @return This writer
162 *
163 * @since 1.5
164 */
165 public CharArrayWriter append(CharSequence csq) {
166 String s = (csq == null ? "null" : csq.toString());
167 write(s, 0, s.length());
168 return this;
169 }
170
171 /**
172 * Appends a subsequence of the specified character sequence to this writer.
173 *
174 * <p> An invocation of this method of the form <tt>out.append(csq, start,
175 * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
176 * exactly the same way as the invocation
177 *
178 * <pre>
179 * out.write(csq.subSequence(start, end).toString()) </pre>
180 *
181 * @param csq
182 * The character sequence from which a subsequence will be
183 * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
184 * will be appended as if <tt>csq</tt> contained the four
185 * characters <tt>"null"</tt>.
186 *
187 * @param start
188 * The index of the first character in the subsequence
189 *
190 * @param end
191 * The index of the character following the last character in the
192 * subsequence
193 *
194 * @return This writer
195 *
196 * @throws IndexOutOfBoundsException
197 * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
198 * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
199 * <tt>csq.length()</tt>
200 *
201 * @since 1.5
202 */
203 public CharArrayWriter append(CharSequence csq, int start, int end) {
204 String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
205 write(s, 0, s.length());
206 return this;
207 }
208
209 /**
210 * Appends the specified character to this writer.
211 *
212 * <p> An invocation of this method of the form <tt>out.append(c)</tt>
213 * behaves in exactly the same way as the invocation
214 *
215 * <pre>
216 * out.write(c) </pre>
217 *
218 * @param c
219 * The 16-bit character to append
220 *
221 * @return This writer
222 *
223 * @since 1.5
224 */
225 public CharArrayWriter append(char c) {
226 write(c);
227 return this;
228 }
229
230 /**
231 * Resets the buffer so that you can use it again without
232 * throwing away the already allocated buffer.
233 */
234 public void reset() {
235 count = 0;
236 }
237
238 /**
239 * Returns a copy of the input data.
240 *
241 * @return an array of chars copied from the input data.
242 */
243 public char toCharArray()[] {
244 synchronized (lock) {
245 return Arrays.copyOf(buf, count);
246 }
247 }
248
249 /**
250 * Returns the current size of the buffer.
251 *
252 * @return an int representing the current size of the buffer.
253 */
254 public int size() {
255 return count;
256 }
257
258 /**
259 * Converts input data to a string.
260 * @return the string.
261 */
262 public String toString() {
263 synchronized (lock) {
264 return new String(buf, 0, count);
265 }
266 }
267
268 /**
269 * Flush the stream.
270 */
271 public void flush() { }
272
273 /**
274 * Close the stream. This method does not release the buffer, since its
275 * contents might still be required. Note: Invoking this method in this class
276 * will have no effect.
277 */
278 public void close() { }
279
280}