/* CharArrayWriter.java -- Write chars to a buffer
   Copyright (C) 1998, 1999, 2001, 2002, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.io;

/**
  * This class allows data to be written to a char array buffer and
  * and then retrieved by an application.   The internal char array
  * buffer is dynamically resized to hold all the data written.  Please
  * be aware that writing large amounts to data to this stream will
  * cause large amounts of memory to be allocated.
  * <p>
  * The size of the internal buffer defaults to 32 and it is resized
  * in increments of 1024 chars.  This behavior can be over-ridden by using the
  * following two properties:
  * <p>
  * <ul>
  * <li><xmp>gnu.java.io.CharArrayWriter.initialBufferSize</xmp></li>
  * <li><xmp>gnu.java.io.CharArrayWriter.bufferIncrementSize</xmp></li>
  * </ul>
  * <p>
  * There is a constructor that specified the initial buffer size and
  * that is the preferred way to set that value because it it portable
  * across all Java class library implementations.
  * <p>
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Tom Tromey (tromey@cygnus.com)
  */
public class CharArrayWriter extends Writer
{
  /**
   * The default initial buffer size
   */
  private static final int DEFAULT_INITIAL_BUFFER_SIZE = 32;

  /**
   * This method initializes a new <code>CharArrayWriter</code> with
   * the default buffer size of 32 chars.  If a different initial
   * buffer size is desired, see the constructor
   * <code>CharArrayWriter(int size)</code>.
   */
  public CharArrayWriter ()
  {
    this (DEFAULT_INITIAL_BUFFER_SIZE);
  }

  /**
   * This method initializes a new <code>CharArrayWriter</code> with
   * a specified initial buffer size.
   *
   * @param size The initial buffer size in chars
   */
  public CharArrayWriter (int size)
  {
    super ();
    buf = new char[size];
  }

  /**
   * Closes the stream.  This method is guaranteed not to free the contents
   * of the internal buffer, which can still be retrieved.
   */
  public void close ()
  {
  }

  /**
   * This method flushes all buffered chars to the stream.
   */
  public void flush ()
  {
  }

  /**
   * This method discards all of the chars that have been written to the
   * internal buffer so far by setting the <code>count</code> variable to
   * 0.  The internal buffer remains at its currently allocated size.
   */
  public void reset ()
  {
    synchronized (lock)
      {
	count = 0;
      }
  }

  /**
   * This method returns the number of chars that have been written to
   * the buffer so far.  This is the same as the value of the protected
   * <code>count</code> variable.  If the <code>reset</code> method is
   * called, then this value is reset as well.  Note that this method does
   * not return the length of the internal buffer, but only the number
   * of chars that have been written to it.
   *
   * @return The number of chars in the internal buffer
   *
   * @see #reset()
   */
  public int size ()
  {
    return count;
  }

  /**
   * This method returns a char array containing the chars that have been
   * written to this stream so far.  This array is a copy of the valid
   * chars in the internal buffer and its length is equal to the number of
   * valid chars, not necessarily to the the length of the current 
   * internal buffer.  Note that since this method allocates a new array,
   * it should be used with caution when the internal buffer is very large.
   */
  public char[] toCharArray ()
  {
    synchronized (lock)
      {      
	char[] nc = new char[count];
	System.arraycopy(buf, 0, nc, 0, count);
	return nc;
      }
  }

  /**
   * Returns the chars in the internal array as a <code>String</code>.  The
   * chars in the buffer are converted to characters using the system default
   * encoding.  There is an overloaded <code>toString()</code> method that
   * allows an application specified character encoding to be used.
   *
   * @return A <code>String</code> containing the data written to this
   *         stream so far
   */
  public String toString ()
  {
    synchronized (lock)
      {
	return new String (buf, 0, count);
      }
  }

  /**
   * This method writes the writes the specified char into the internal
   * buffer.
   *
   * @param oneChar The char to be read passed as an int
   */
  public void write (int oneChar)
  {
    synchronized (lock)
      {
	resize (1);
	buf[count++] = (char) oneChar;
      }
  }

  /**
   * This method writes <code>len</code> chars from the passed in array 
   * <code>buf</code> starting at index <code>offset</code> into that buffer
   *
   * @param buffer The char array to write data from
   * @param offset The index into the buffer to start writing data from
   * @param len The number of chars to write
   */
  public void write (char[] buffer, int offset, int len)
  {
    synchronized (lock)
      {
	if (len >= 0)
	  resize (len);
	System.arraycopy(buffer, offset, buf, count, len);
	count += len;
      }
  }

  /**
   * This method writes <code>len</code> chars from the passed in
   * <code>String</code> <code>buf</code> starting at index
   * <code>offset</code> into the internal buffer.
   *
   * @param str The <code>String</code> to write data from
   * @param offset The index into the string to start writing data from
   * @param len The number of chars to write
   */
  public void write (String str, int offset, int len)
  {
    synchronized (lock)
      {
	if (len >= 0)
	  resize (len);
	str.getChars(offset, offset + len, buf, count);
	count += len;
      }
  }

  /**
   * This method writes all the chars that have been written to this stream
   * from the internal buffer to the specified <code>Writer</code>.
   *
   * @param out The <code>Writer</code> to write to
   *
   * @exception IOException If an error occurs
   */
  public void writeTo (Writer out) throws IOException
  {
    synchronized (lock)
      {
	out.write(buf, 0, count);
      }
  }

  /** 
   * Appends the Unicode character, <code>c</code>, to the output stream
   * underlying this writer.  This is equivalent to <code>write(c)</code>.
   *
   * @param c the character to append.
   * @return a reference to this object.
   * @since 1.5 
   */
  public CharArrayWriter append(char c)
  {
    write(c);
    return this;
  }

  /** 
   * Appends the specified sequence of Unicode characters to the
   * output stream underlying this writer.  This is equivalent to
   * appending the results of calling <code>toString()</code> on the
   * character sequence.  As a result, the entire sequence may not be
   * appended, as it depends on the implementation of
   * <code>toString()</code> provided by the
   * <code>CharSequence</code>.  For example, if the character
   * sequence is wrapped around an input buffer, the results will
   * depend on the current position and length of that buffer.
   *
   * @param cs the character sequence to append.  If cs is null,
   *        then the string "null" (the string representation of null)
   *        is appended.
   * @return a reference to this object.
   * @since 1.5 
   */
  public CharArrayWriter append(CharSequence cs)
  {
    try
      {
	write(cs == null ? "null" : cs.toString());
      }
    catch (IOException _)
      {
	// Can't happen.
      }
    return this;
  }

  /** 
   * Appends the specified subsequence of Unicode characters to the
   * output stream underlying this writer, starting and ending at the
   * specified positions within the sequence.  The behaviour of this
   * method matches the behaviour of writing the result of
   * <code>append(cs.subSequence(start,end))</code> when the sequence
   * is not null.
   *
   * @param cs the character sequence to append.  If cs is null,
   *        then the string "null" (the string representation of null)
   *        is appended.
   * @param start the index of the first Unicode character to use from
   *        the sequence.
   * @param end the index of the last Unicode character to use from the
   *        sequence.
   * @return a reference to this object.
   * @throws IndexOutOfBoundsException if either of the indices are negative,
   *         the start index occurs after the end index, or the end index is
   *         beyond the end of the sequence.
   * @since 1.5
   */
  public CharArrayWriter append(CharSequence cs, int start, int end)
  {
    try
      {
	write(cs == null ? "null" : cs.subSequence(start, end).toString());
      }
    catch (IOException _)
      {
	// Can't happen.
      }
    return this;
  }

  /**
   * This private method makes the buffer bigger when we run out of room
   * by allocating a larger buffer and copying the valid chars from the
   * old array into it.  This is obviously slow and should be avoided by
   * application programmers by setting their initial buffer size big
   * enough to hold everything if possible.
   */
  private void resize (int len)
  {
    if (count + len >= buf.length)
      {
	int newlen = buf.length * 2;
	if (count + len > newlen)
	  newlen = count + len;
	char[] newbuf = new char[newlen];
	System.arraycopy(buf, 0, newbuf, 0, count);
	buf = newbuf;
      }
  }

  /**
   * The internal buffer where the data written is stored
   */
  protected char[] buf;

  /**
   * The number of chars that have been written to the buffer
   */
  protected int count;
}
