001 /* CharArrayWriter.java -- Write chars to a buffer 002 Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package java.io; 040 041 /** 042 * This class allows data to be written to a char array buffer and 043 * and then retrieved by an application. The internal char array 044 * buffer is dynamically resized to hold all the data written. Please 045 * be aware that writing large amounts to data to this stream will 046 * cause large amounts of memory to be allocated. 047 * <p> 048 * The size of the internal buffer defaults to 32 and it is resized 049 * in increments of 1024 chars. This behavior can be over-ridden by using the 050 * following two properties: 051 * <p> 052 * <ul> 053 * <li><xmp>gnu.java.io.CharArrayWriter.initialBufferSize</xmp></li> 054 * <li><xmp>gnu.java.io.CharArrayWriter.bufferIncrementSize</xmp></li> 055 * </ul> 056 * <p> 057 * There is a constructor that specified the initial buffer size and 058 * that is the preferred way to set that value because it it portable 059 * across all Java class library implementations. 060 * <p> 061 * 062 * @author Aaron M. Renn (arenn@urbanophile.com) 063 * @author Tom Tromey (tromey@cygnus.com) 064 */ 065 public class CharArrayWriter extends Writer 066 { 067 /** 068 * The default initial buffer size 069 */ 070 private static final int DEFAULT_INITIAL_BUFFER_SIZE = 32; 071 072 /** 073 * This method initializes a new <code>CharArrayWriter</code> with 074 * the default buffer size of 32 chars. If a different initial 075 * buffer size is desired, see the constructor 076 * <code>CharArrayWriter(int size)</code>. 077 */ 078 public CharArrayWriter () 079 { 080 this (DEFAULT_INITIAL_BUFFER_SIZE); 081 } 082 083 /** 084 * This method initializes a new <code>CharArrayWriter</code> with 085 * a specified initial buffer size. 086 * 087 * @param size The initial buffer size in chars 088 */ 089 public CharArrayWriter (int size) 090 { 091 super (); 092 buf = new char[size]; 093 } 094 095 /** 096 * Closes the stream. This method is guaranteed not to free the contents 097 * of the internal buffer, which can still be retrieved. 098 */ 099 public void close () 100 { 101 } 102 103 /** 104 * This method flushes all buffered chars to the stream. 105 */ 106 public void flush () 107 { 108 } 109 110 /** 111 * This method discards all of the chars that have been written to the 112 * internal buffer so far by setting the <code>count</code> variable to 113 * 0. The internal buffer remains at its currently allocated size. 114 */ 115 public void reset () 116 { 117 synchronized (lock) 118 { 119 count = 0; 120 } 121 } 122 123 /** 124 * This method returns the number of chars that have been written to 125 * the buffer so far. This is the same as the value of the protected 126 * <code>count</code> variable. If the <code>reset</code> method is 127 * called, then this value is reset as well. Note that this method does 128 * not return the length of the internal buffer, but only the number 129 * of chars that have been written to it. 130 * 131 * @return The number of chars in the internal buffer 132 * 133 * @see #reset() 134 */ 135 public int size () 136 { 137 return count; 138 } 139 140 /** 141 * This method returns a char array containing the chars that have been 142 * written to this stream so far. This array is a copy of the valid 143 * chars in the internal buffer and its length is equal to the number of 144 * valid chars, not necessarily to the the length of the current 145 * internal buffer. Note that since this method allocates a new array, 146 * it should be used with caution when the internal buffer is very large. 147 */ 148 public char[] toCharArray () 149 { 150 synchronized (lock) 151 { 152 char[] nc = new char[count]; 153 System.arraycopy(buf, 0, nc, 0, count); 154 return nc; 155 } 156 } 157 158 /** 159 * Returns the chars in the internal array as a <code>String</code>. The 160 * chars in the buffer are converted to characters using the system default 161 * encoding. There is an overloaded <code>toString()</code> method that 162 * allows an application specified character encoding to be used. 163 * 164 * @return A <code>String</code> containing the data written to this 165 * stream so far 166 */ 167 public String toString () 168 { 169 synchronized (lock) 170 { 171 return new String (buf, 0, count); 172 } 173 } 174 175 /** 176 * This method writes the writes the specified char into the internal 177 * buffer. 178 * 179 * @param oneChar The char to be read passed as an int 180 */ 181 public void write (int oneChar) 182 { 183 synchronized (lock) 184 { 185 resize (1); 186 buf[count++] = (char) oneChar; 187 } 188 } 189 190 /** 191 * This method writes <code>len</code> chars from the passed in array 192 * <code>buf</code> starting at index <code>offset</code> into that buffer 193 * 194 * @param buffer The char array to write data from 195 * @param offset The index into the buffer to start writing data from 196 * @param len The number of chars to write 197 */ 198 public void write (char[] buffer, int offset, int len) 199 { 200 synchronized (lock) 201 { 202 if (len >= 0) 203 resize (len); 204 System.arraycopy(buffer, offset, buf, count, len); 205 count += len; 206 } 207 } 208 209 /** 210 * This method writes <code>len</code> chars from the passed in 211 * <code>String</code> <code>buf</code> starting at index 212 * <code>offset</code> into the internal buffer. 213 * 214 * @param str The <code>String</code> to write data from 215 * @param offset The index into the string to start writing data from 216 * @param len The number of chars to write 217 */ 218 public void write (String str, int offset, int len) 219 { 220 synchronized (lock) 221 { 222 if (len >= 0) 223 resize (len); 224 str.getChars(offset, offset + len, buf, count); 225 count += len; 226 } 227 } 228 229 /** 230 * This method writes all the chars that have been written to this stream 231 * from the internal buffer to the specified <code>Writer</code>. 232 * 233 * @param out The <code>Writer</code> to write to 234 * 235 * @exception IOException If an error occurs 236 */ 237 public void writeTo (Writer out) throws IOException 238 { 239 synchronized (lock) 240 { 241 out.write(buf, 0, count); 242 } 243 } 244 245 /** 246 * Appends the Unicode character, <code>c</code>, to the output stream 247 * underlying this writer. This is equivalent to <code>write(c)</code>. 248 * 249 * @param c the character to append. 250 * @return a reference to this object. 251 * @since 1.5 252 */ 253 public CharArrayWriter append(char c) 254 { 255 write(c); 256 return this; 257 } 258 259 /** 260 * Appends the specified sequence of Unicode characters to the 261 * output stream underlying this writer. This is equivalent to 262 * appending the results of calling <code>toString()</code> on the 263 * character sequence. As a result, the entire sequence may not be 264 * appended, as it depends on the implementation of 265 * <code>toString()</code> provided by the 266 * <code>CharSequence</code>. For example, if the character 267 * sequence is wrapped around an input buffer, the results will 268 * depend on the current position and length of that buffer. 269 * 270 * @param seq the character sequence to append. If seq is null, 271 * then the string "null" (the string representation of null) 272 * is appended. 273 * @return a reference to this object. 274 * @since 1.5 275 */ 276 public CharArrayWriter append(CharSequence cs) 277 { 278 try 279 { 280 write(cs == null ? "null" : cs.toString()); 281 } 282 catch (IOException _) 283 { 284 // Can't happen. 285 } 286 return this; 287 } 288 289 /** 290 * Appends the specified subsequence of Unicode characters to the 291 * output stream underlying this writer, starting and ending at the 292 * specified positions within the sequence. The behaviour of this 293 * method matches the behaviour of writing the result of 294 * <code>append(seq.subSequence(start,end))</code> when the sequence 295 * is not null. 296 * 297 * @param seq the character sequence to append. If seq is null, 298 * then the string "null" (the string representation of null) 299 * is appended. 300 * @param start the index of the first Unicode character to use from 301 * the sequence. 302 * @param end the index of the last Unicode character to use from the 303 * sequence. 304 * @return a reference to this object. 305 * @throws IndexOutOfBoundsException if either of the indices are negative, 306 * the start index occurs after the end index, or the end index is 307 * beyond the end of the sequence. 308 * @since 1.5 309 */ 310 public CharArrayWriter append(CharSequence cs, int start, int end) 311 { 312 try 313 { 314 write(cs == null ? "null" : cs.subSequence(start, end).toString()); 315 } 316 catch (IOException _) 317 { 318 // Can't happen. 319 } 320 return this; 321 } 322 323 /** 324 * This private method makes the buffer bigger when we run out of room 325 * by allocating a larger buffer and copying the valid chars from the 326 * old array into it. This is obviously slow and should be avoided by 327 * application programmers by setting their initial buffer size big 328 * enough to hold everything if possible. 329 */ 330 private void resize (int len) 331 { 332 if (count + len >= buf.length) 333 { 334 int newlen = buf.length * 2; 335 if (count + len > newlen) 336 newlen = count + len; 337 char[] newbuf = new char[newlen]; 338 System.arraycopy(buf, 0, newbuf, 0, count); 339 buf = newbuf; 340 } 341 } 342 343 /** 344 * The internal buffer where the data written is stored 345 */ 346 protected char[] buf; 347 348 /** 349 * The number of chars that have been written to the buffer 350 */ 351 protected int count; 352 }