1 /* 2 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.io; 27 28 import 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 */ 42 public 43 class 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 */ CharArrayWriter()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 */ CharArrayWriter(int initialSize)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 */ write(int c)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 */ write(char c[], int off, int len)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 */ write(String str, int off, int len)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 */ writeTo(Writer out)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 */ append(CharSequence csq)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 */ append(CharSequence csq, int start, int end)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 */ append(char c)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 */ reset()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 */ toCharArray()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 */ size()254 public int size() { 255 return count; 256 } 257 258 /** 259 * Converts input data to a string. 260 * @return the string. 261 */ toString()262 public String toString() { 263 synchronized (lock) { 264 return new String(buf, 0, count); 265 } 266 } 267 268 /** 269 * Flush the stream. 270 */ flush()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 */ close()278 public void close() { } 279 280 } 281