// StringBuffer.java - Growable strings.

/* Copyright (C) 1998, 1999  Cygnus Solutions

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.lang;
import java.io.Serializable;

/**
 * @author Tom Tromey <tromey@cygnus.com>
 * @date October 23, 1998.  
 */

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 */

public final class StringBuffer implements Serializable
{
  public StringBuffer append (boolean bool)
    {
      return append (String.valueOf(bool));
    }

  public synchronized StringBuffer append (char ch)
    {
      ensureCapacity (count + 1);
      value[count++] = ch;
      return this;
    }

  public StringBuffer append (int inum)
    {
      return append (String.valueOf(inum));
    }

  public StringBuffer append (long lnum)
    {
      return append (String.valueOf(lnum));
    }

  public StringBuffer append (float fnum)
    {
      return append (String.valueOf(fnum));
    }

  public StringBuffer append (double dnum)
    {
      return append (String.valueOf(dnum));
    }

  public StringBuffer append (Object obj)
    {
      return append (String.valueOf(obj));
    }

  public synchronized StringBuffer append (String str)
    {
      if (str == null)
	str = "null";
      int len = str.length();
      ensureCapacity (count + len);
      str.getChars(0, len, value, count);
      count += len;
      return this;
    }

  public StringBuffer append (char[] data)
    {
      return append (data, 0, data.length);
    }

  public synchronized StringBuffer append (char[] data, int offset, int count)
    {
      ensureCapacity (this.count + count);
      System.arraycopy(data, offset, value, this.count, count);
      this.count += count;
      return this;
    } 

  public int capacity ()
    {
      return value.length;
    }

  public synchronized char charAt (int index)
    {
      if (index >= count)
	throw new StringIndexOutOfBoundsException (index);
      return value[index];
    }

  public synchronized void ensureCapacity (int minimumCapacity)
    {
      if (shared || minimumCapacity > value.length)
	{
	  // We don't want to make a larger vector when `shared' is
	  // set.  If we do, then setLength becomes very inefficient
	  // when repeatedly reusing a StringBuffer in a loop.
	  int max = (minimumCapacity > value.length
		     ? value.length*2+2
		     : value.length);
	  minimumCapacity = Math.max(minimumCapacity, max);
	  char[] nb = new char[minimumCapacity];
	  System.arraycopy(value, 0, nb, 0, count);
	  value = nb;
	  shared = false;
	}
    }

  public synchronized void getChars (int srcOffset, int srcEnd,
				     char[] dst, int dstOffset)
    {
      if (srcOffset < 0 || srcOffset > srcEnd)
	throw new StringIndexOutOfBoundsException (srcOffset);
      int todo = srcEnd - srcOffset;
      if (srcEnd > count || dstOffset + todo > count)
	throw new StringIndexOutOfBoundsException (srcEnd);
      System.arraycopy(value, srcOffset, dst, dstOffset, todo);
    }

  public StringBuffer insert (int offset, boolean bool)
    {
      return insert (offset, bool ? "true" : "false");
    }

  public synchronized StringBuffer insert (int offset, char ch)
    {
      if (offset < 0 || offset > count)
	throw new StringIndexOutOfBoundsException (offset);
      ensureCapacity (count+1);
      System.arraycopy(value, offset, value, offset+1, count-offset);
      value[offset] = ch;
      count++;
      return this;
    }

  public StringBuffer insert (int offset, int inum)
    {
      return insert (offset, String.valueOf(inum));
    }

  public StringBuffer insert (int offset, long lnum)
    {
      return insert (offset, String.valueOf(lnum));
    }

  public StringBuffer insert (int offset, float fnum)
    {
      return insert (offset, String.valueOf(fnum));
    }

  public StringBuffer insert (int offset, double dnum)
    {
      return insert (offset, String.valueOf(dnum));
    }

  public StringBuffer insert (int offset, Object obj)
    {
      return insert (offset, String.valueOf(obj));
    }

  public synchronized StringBuffer insert (int offset, String str)
    {
      if (offset < 0 || offset > count)
	throw new StringIndexOutOfBoundsException (offset);
      // Note that using `null' is from JDK 1.2.
      if (str == null)
	str = "null";
      int len = str.length();
      ensureCapacity(count+len);
      System.arraycopy(value, offset, value, offset+len, count-offset);
      str.getChars(0, len, value, offset);
      count += len;
      return this;
    }

  public synchronized StringBuffer insert (int offset, char[] data)
    {
      if (offset < 0 || offset > count)
	throw new StringIndexOutOfBoundsException (offset);
      int len = data.length;
      ensureCapacity (count+len);
      System.arraycopy(value, offset, value, offset+len, count-offset);
      System.arraycopy(data, 0, value, offset, len);
      count += len;
      return this;
    }

  public int length ()
    {
      return count;
    }

  public synchronized StringBuffer reverse ()
    {
      for (int i = 0; i < count / 2; ++i)
	{
	  char c = value[i];
	  value[i] = value[count - i - 1];
	  value[count - i - 1] = c;
	}
      return this;
    }

  public synchronized void setCharAt (int index, char ch)
    {
      if (index < 0 || index >= count)
	throw new StringIndexOutOfBoundsException (index);
      // Call ensureCapacity to enforce copy-on-write.
      ensureCapacity (count);
      value[index] = ch;
    }

  public synchronized void setLength (int newLength)
    {
      if (newLength < 0)
	throw new StringIndexOutOfBoundsException (newLength);

      ensureCapacity (newLength);
      for (int i = count; i < newLength; ++i)
	value[i] = '\0';
      count = newLength;
    }

  public StringBuffer ()
    {
      this (16);
    }

  public StringBuffer (int capacity)
    {
      count = 0;
      value = new char[capacity];
      shared = false;
    }

  public StringBuffer (String str)
    {
      // Note: nowhere does it say that we should handle a null
      // argument here.  In fact, the JCL implies that we should not.
      // But this leads to an asymmetry: `null + ""' will fail, while
      // `"" + null' will work.
      if (str == null)
	str = "null";
      count = str.length();
      // JLS: The initial capacity of the string buffer is 16 plus the
      // length of the argument string.
      value = new char[count + 16];
      str.getChars(0, count, value, 0);
      shared = false;
    }

  public String toString ()
    {
      shared = true;
      return new String (this);
    }

  // The buffer.  Note that this has permissions set this way so that
  // String can get the value.
  char[] value;

  // Index of next available character.  Note that this has
  // permissions set this way so that String can get the value.
  int count;

  // True if we need to copy the buffer before writing to it again.
  // FIXME: JDK 1.2 doesn't specify this.  The new buffer-growing
  // semantics make this less useful in that case, too.
  private boolean shared;
}
