| /* StringBuffer.java -- Growable strings | |
| Copyright (C) 1998, 1999, 2000, 2001 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., 59 Temple Place, Suite 330, Boston, MA | |
| 02111-1307 USA. | |
| As a special exception, if you link this library with other files to | |
| produce an executable, this library does not by itself cause the | |
| resulting executable to be covered by the GNU General Public License. | |
| This exception does not however invalidate any other reasons why the | |
| executable file might be covered by the GNU General Public License. */ | |
| package java.lang; | |
| import java.io.Serializable; | |
| /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 | |
| * Updated using online JDK 1.2 docs. | |
| * Believed complete and correct to JDK 1.2. | |
| * Merged with Classpath. | |
| */ | |
| /** | |
| * <code>StringBuffer</code> represents a changeable <code>String</code>. | |
| * It provides the operations required to modify the | |
| * <code>StringBuffer</code> including insert, replace, delete, append, | |
| * and reverse. | |
| * <P> | |
| * | |
| * <code>StringBuffer</code>s are variable-length in nature, so even if | |
| * you initialize them to a certain size, they can still grow larger than | |
| * that. <EM>Capacity</EM> indicates the number of characters the | |
| * <code>StringBuffer</code> can have in it before it has to grow (growing | |
| * the char array is an expensive operation involving <code>new</code>). | |
| * <P> | |
| * | |
| * Incidentally, the String operator "+" actually is turned into a | |
| * <code>StringBuffer</code> operation: | |
| * <BR> | |
| * <code>a + b</code> | |
| * <BR> | |
| * is the same as | |
| * <BR> | |
| * <code>new StringBuffer(a).append(b).toString()</code>. | |
| * | |
| * @implnote Classpath's StringBuffer is capable of sharing memory with | |
| * Strings for efficiency. This will help in two instances: | |
| * first, when a StringBuffer is created from a String but is | |
| * never changed, and second, when a StringBuffer is converted | |
| * to a String and the StringBuffer is not changed after that. | |
| * | |
| * @since JDK1.0 | |
| * @author Paul Fisher | |
| * @author John Keiser | |
| * @author Tom Tromey | |
| * @see java.lang.String | |
| */ | |
| public final class StringBuffer implements Serializable, CharSequence | |
| { | |
| /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param bool the <code>boolean</code> to convert and append. | |
| * @return this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(boolean) | |
| */ | |
| public StringBuffer append (boolean bool) | |
| { | |
| return append (String.valueOf(bool)); | |
| } | |
| /** Append the <code>char</code> to this <code>StringBuffer</code>. | |
| * @param c the <code>char</code> to append. | |
| * @return this <code>StringBuffer</code>. | |
| */ | |
| public synchronized StringBuffer append (char ch) | |
| { | |
| ensureCapacity_unsynchronized (count + 1); | |
| value[count++] = ch; | |
| return this; | |
| } | |
| /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param inum the <code>int</code> to convert and append. | |
| * @return this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(int) | |
| */ | |
| public native StringBuffer append (int inum); | |
| /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param lnum the <code>long</code> to convert and append. | |
| * @return this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(long) | |
| */ | |
| public StringBuffer append (long lnum) | |
| { | |
| return append (String.valueOf(lnum)); | |
| } | |
| /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param fnum the <code>float</code> to convert and append. | |
| * @return this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(float) | |
| */ | |
| public StringBuffer append (float fnum) | |
| { | |
| return append (String.valueOf(fnum)); | |
| } | |
| /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param dnum the <code>double</code> to convert and append. | |
| * @return this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(double) | |
| */ | |
| public StringBuffer append (double dnum) | |
| { | |
| return append (String.valueOf(dnum)); | |
| } | |
| /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param obj the <code>Object</code> to convert and append. | |
| * @return this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(java.lang.Object) | |
| */ | |
| public StringBuffer append (Object obj) | |
| { | |
| return append (String.valueOf(obj)); | |
| } | |
| /** Append the <code>String</code> to this <code>StringBuffer</code>. | |
| * @param str the <code>String</code> to append. | |
| * @return this <code>StringBuffer</code>. | |
| */ | |
| public synchronized StringBuffer append (String str) | |
| { | |
| if (str == null) | |
| str = "null"; | |
| int len = str.length(); | |
| ensureCapacity_unsynchronized (count + len); | |
| str.getChars(0, len, value, count); | |
| count += len; | |
| return this; | |
| } | |
| /** Append the <code>char</code> array to this <code>StringBuffer</code>. | |
| * @param data the <code>char[]</code> to append. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception NullPointerException if <code>str</code> is <code>null</code>. | |
| */ | |
| public StringBuffer append (char[] data) | |
| { | |
| return append (data, 0, data.length); | |
| } | |
| /** Append the <code>char</code> array to this <code>StringBuffer</code>. | |
| * @param data the <code>char[]</code> to append. | |
| * @param offset the place to start grabbing characters from | |
| * <code>str</code>. | |
| * @param count the number of characters to get from <code>str</code>. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception NullPointerException if <code>str</code> is <code>null</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> or | |
| * <code>offset+len</code> is out of range. | |
| */ | |
| public synchronized StringBuffer append (char[] data, int offset, int count) | |
| { | |
| ensureCapacity_unsynchronized (this.count + count); | |
| System.arraycopy(data, offset, value, this.count, count); | |
| this.count += count; | |
| return this; | |
| } | |
| /** Get the total number of characters this <code>StringBuffer</code> | |
| * can support before it must be grown. Not to be confused with | |
| * <em>length</em>. | |
| * @return the capacity of this <code>StringBuffer</code> | |
| * @see #length() | |
| * @see #ensureCapacity(int) | |
| */ | |
| public int capacity () | |
| { | |
| return value.length; | |
| } | |
| /** Get the character at the specified index. | |
| * @param index the index of the character to get, starting at 0. | |
| * @return the character at the specified index. | |
| * @exception IndexOutOfBoundsException if the desired character index | |
| * is negative or greater then length() - 1. | |
| */ | |
| public synchronized char charAt (int index) | |
| { | |
| if (index >= count) | |
| throw new StringIndexOutOfBoundsException (index); | |
| return value[index]; | |
| } | |
| /** Delete characters from this <code>StringBuffer</code>. | |
| * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. | |
| * @param start the first character to delete. | |
| * @param end the index after the last character to delete. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception StringIndexOutOfBoundsException if <code>start</code> | |
| * or <code>end-1</code> are out of bounds, or if | |
| * <code>start > end</code>. | |
| */ | |
| public synchronized StringBuffer delete (int start, int end) | |
| { | |
| if (start < 0 || start > count || start > end) | |
| throw new StringIndexOutOfBoundsException (start); | |
| if (end > count) | |
| end = count; | |
| // This will unshare if required. | |
| ensureCapacity_unsynchronized (count); | |
| if (count - end != 0) | |
| System.arraycopy (value, end, value, start, count - end); | |
| count -= (end - start); | |
| return this; | |
| } | |
| /** Delete a character from this <code>StringBuffer</code>. | |
| * @param index the index of the character to delete. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception StringIndexOutOfBoundsException if <code>index</code> | |
| * is out of bounds. | |
| */ | |
| public StringBuffer deleteCharAt(int index) | |
| { | |
| return delete (index, index + 1); | |
| } | |
| /** Increase the capacity of this <code>StringBuffer</code>. | |
| * This will ensure that an expensive growing operation will not occur | |
| * until <code>minimumCapacity</code> is reached. | |
| * If the capacity is actually already greater than <code>minimumCapacity</code> | |
| * @param minimumCapacity the new capacity. | |
| * @see #capacity() | |
| */ | |
| 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 = (minimumCapacity < max ? max : minimumCapacity); | |
| char[] nb = new char[minimumCapacity]; | |
| System.arraycopy(value, 0, nb, 0, count); | |
| value = nb; | |
| shared = false; | |
| } | |
| } | |
| // ensureCapacity is used by several synchronized methods in StringBuffer. | |
| // There's no need to synchronize again. | |
| private void ensureCapacity_unsynchronized (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 = (minimumCapacity < max ? max : minimumCapacity); | |
| char[] nb = new char[minimumCapacity]; | |
| System.arraycopy(value, 0, nb, 0, count); | |
| value = nb; | |
| shared = false; | |
| } | |
| } | |
| /** Get the specified array of characters. | |
| * The characters will be copied into the array you pass in. | |
| * @param srcOffset the index to start copying from in the | |
| * <code>StringBuffer</code>. | |
| * @param srcEnd the number of characters to copy. | |
| * @param dst the array to copy into. | |
| * @param dstOffset the index to start copying into <code>dst</code>. | |
| * @exception NullPointerException if dst is null. | |
| * @exception IndexOutOfBoundsException if any source or target | |
| * indices are out of range. | |
| * @see java.lang.System#arraycopy(java.lang.Object,int,java.lang.Object,int,int) | |
| */ | |
| 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); | |
| } | |
| /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param offset the place to insert. | |
| * @param bool the <code>boolean</code> to convert and insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(boolean) | |
| */ | |
| public StringBuffer insert (int offset, boolean bool) | |
| { | |
| return insert (offset, bool ? "true" : "false"); | |
| } | |
| /** Insert the <code>char</code> argument into this <code>StringBuffer</code>. | |
| * @param offset the place to insert. | |
| * @param ch the <code>char</code> to insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| */ | |
| public synchronized StringBuffer insert (int offset, char ch) | |
| { | |
| if (offset < 0 || offset > count) | |
| throw new StringIndexOutOfBoundsException (offset); | |
| ensureCapacity_unsynchronized (count+1); | |
| System.arraycopy(value, offset, value, offset+1, count-offset); | |
| value[offset] = ch; | |
| count++; | |
| return this; | |
| } | |
| /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param offset the place to insert. | |
| * @param inum the <code>int</code> to convert and insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(int) | |
| */ | |
| public StringBuffer insert (int offset, int inum) | |
| { | |
| return insert (offset, String.valueOf(inum)); | |
| } | |
| /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param offset the place to insert. | |
| * @param lnum the <code>long</code> to convert and insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(long) | |
| */ | |
| public StringBuffer insert (int offset, long lnum) | |
| { | |
| return insert (offset, String.valueOf(lnum)); | |
| } | |
| /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param offset the place to insert. | |
| * @param fnum the <code>float</code> to convert and insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(float) | |
| */ | |
| public StringBuffer insert (int offset, float fnum) | |
| { | |
| return insert (offset, String.valueOf(fnum)); | |
| } | |
| /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param offset the place to insert. | |
| * @param dnum the <code>double</code> to convert and insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(double) | |
| */ | |
| public StringBuffer insert (int offset, double dnum) | |
| { | |
| return insert (offset, String.valueOf(dnum)); | |
| } | |
| /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
| * Uses <code>String.valueOf()</code> to convert to | |
| * <code>String</code>. | |
| * @param offset the place to insert. | |
| * @param obj the <code>Object</code> to convert and insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| * @see java.lang.String#valueOf(java.lang.Object) | |
| */ | |
| public StringBuffer insert (int offset, Object obj) | |
| { | |
| return insert (offset, String.valueOf(obj)); | |
| } | |
| /** Insert the <code>String</code> argument into this <code>StringBuffer</code>. | |
| * @param offset the place to insert. | |
| * @param str the <code>String</code> to insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| */ | |
| 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_unsynchronized (count+len); | |
| System.arraycopy(value, offset, value, offset+len, count-offset); | |
| str.getChars(0, len, value, offset); | |
| count += len; | |
| return this; | |
| } | |
| /** Insert the <code>char[]</code> argument into this | |
| * <code>StringBuffer</code>. | |
| * @param offset the place to insert. | |
| * @param data the <code>char[]</code> to insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception NullPointerException if <code>data</code> is | |
| * <code>null</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range for this <code>StringBuffer</code>. | |
| */ | |
| public StringBuffer insert (int offset, char[] data) | |
| { | |
| // One could check if offset is invalid here instead of making sure that | |
| // data isn't null before dereferencing, but this works just as well. | |
| return insert (offset, data, 0, data == null ? 0 : data.length); | |
| } | |
| /** Insert the <code>char[]</code> argument into this | |
| * <code>StringBuffer</code>. | |
| * @param offset the place to insert. | |
| * @param str the <code>char[]</code> to insert. | |
| * @param str_offset the index in <code>str</code> to start inserting | |
| * from. | |
| * @param len the number of characters to insert. | |
| * @return this <code>StringBuffer</code>. | |
| * @exception NullPointerException if <code>str</code> is <code>null</code>. | |
| * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
| * of range, for this <code>StringBuffer</code>, or if | |
| * <code>str_offset</code> or <code>str_offset+len</code> | |
| * are out of range for <code>str</code>. | |
| */ | |
| public synchronized StringBuffer insert(int offset, char[] str, | |
| int str_offset, int len) | |
| { | |
| if (offset < 0 || offset > count) | |
| throw new StringIndexOutOfBoundsException (offset); | |
| if (len < 0) | |
| throw new StringIndexOutOfBoundsException (len); | |
| if (str_offset < 0 || str_offset + len > str.length) | |
| throw new StringIndexOutOfBoundsException (str_offset); | |
| ensureCapacity_unsynchronized (count + len); | |
| System.arraycopy(value, offset, value, offset + len, count - offset); | |
| System.arraycopy(str, str_offset, value, offset, len); | |
| count += len; | |
| return this; | |
| } | |
| /** Get the length of the <code>String</code> this | |
| * <code>StringBuffer</code> would create. Not to be confused with the | |
| * <em>capacity</em> of the <code>StringBuffer</code>. | |
| * @return the length of this <code>StringBuffer</code>. | |
| * @see #capacity() | |
| * @see #setLength(int) | |
| */ | |
| public int length () | |
| { | |
| return count; | |
| } | |
| /** Replace characters between index <code>start</code> (inclusive) and | |
| * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code> | |
| * is larger than the size of this StringBuffer, all characters after | |
| * <code>start</code> are replaced. | |
| * @param start the beginning index of characters to delete (inclusive). | |
| * @param end the ending index of characters to delete (exclusive). | |
| * @param str the new <code>String</code> to insert. | |
| * @return this <code>StringBuffer</code>. | |
| */ | |
| public synchronized StringBuffer replace (int start, int end, String str) | |
| { | |
| if (start < 0 || start > count || start > end) | |
| throw new StringIndexOutOfBoundsException (start); | |
| int len = str.length(); | |
| // Calculate the difference in 'count' after the replace. | |
| int delta = len - ((end > count ? count : end) - start); | |
| ensureCapacity_unsynchronized (count + delta); | |
| if (delta != 0 && end < count) | |
| System.arraycopy(value, end, value, end + delta, count - end); | |
| str.getChars (0, len, value, start); | |
| count += delta; | |
| return this; | |
| } | |
| /** Reverse the characters in this StringBuffer. | |
| * @return this <code>StringBuffer</code>. | |
| */ | |
| public synchronized StringBuffer reverse () | |
| { | |
| // Call ensureCapacity to enforce copy-on-write. | |
| ensureCapacity_unsynchronized (count); | |
| 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; | |
| } | |
| /** Set the character at the specified index. | |
| * @param index the index of the character to set starting at 0. | |
| * @param ch the value to set that character to. | |
| * @exception IndexOutOfBoundsException if the specified character | |
| * index is not between 0 and length() - 1 (inclusive). | |
| */ | |
| 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_unsynchronized (count); | |
| value[index] = ch; | |
| } | |
| /** Set the length of this StringBuffer. | |
| * <P> | |
| * If the new length is greater than the current length, all the new | |
| * characters are set to '\0'. | |
| * <P> | |
| * If the new length is less than the current length, the first | |
| * <code>newLength</code> characters of the old array will be | |
| * @param newLength the new length | |
| * @exception IndexOutOfBoundsException if the new length is | |
| * negative. | |
| * @see #length() | |
| */ | |
| public synchronized void setLength (int newLength) | |
| { | |
| if (newLength < 0) | |
| throw new StringIndexOutOfBoundsException (newLength); | |
| ensureCapacity_unsynchronized (newLength); | |
| for (int i = count; i < newLength; ++i) | |
| value[i] = '\0'; | |
| count = newLength; | |
| } | |
| /** Create a new StringBuffer with default capacity 16. | |
| * @see JLS 20.13.1 | |
| */ | |
| public StringBuffer () | |
| { | |
| this (DEFAULT_CAPACITY); | |
| } | |
| /** Create an empty <code>StringBuffer</code> with the specified initial capacity. | |
| * @param capacity the initial capacity. | |
| */ | |
| public StringBuffer (int capacity) | |
| { | |
| count = 0; | |
| value = new char[capacity]; | |
| shared = false; | |
| } | |
| /** Create a new <code>StringBuffer</code> with the characters in the specified <code>String</code>. | |
| * Initial capacity will be the size of the String plus 16. | |
| * @param str the <code>String</code> to make a <code>StringBuffer</code> out of. | |
| * @XXX optimize for sharing. | |
| */ | |
| public StringBuffer (String str) | |
| { | |
| // The documentation is not clear, but experimentation with | |
| // other implementations indicates that StringBuffer(null) | |
| // should throw a NullPointerException. | |
| count = str.length(); | |
| // JLS: The initial capacity of the string buffer is 16 plus the | |
| // length of the argument string. | |
| value = new char[count + DEFAULT_CAPACITY]; | |
| str.getChars(0, count, value, 0); | |
| shared = false; | |
| } | |
| /** | |
| * Creates a substring of this StringBuffer, starting at a specified index | |
| * and ending at the end of this StringBuffer. | |
| * | |
| * @param beginIndex index to start substring (base 0) | |
| * | |
| * @return new String which is a substring of this StringBuffer | |
| * | |
| * @exception StringIndexOutOfBoundsException | |
| * if (beginIndex < 0 || beginIndex > this.length()) | |
| */ | |
| public String substring (int beginIndex) | |
| { | |
| return substring (beginIndex, count); | |
| } | |
| /** | |
| * Creates a substring of this StringBuffer, starting at a specified index | |
| * and ending at one character before a specified index. | |
| * | |
| * @param beginIndex index to start substring (base 0) | |
| * @param endIndex index after the last character to be | |
| * copied into the substring | |
| * | |
| * @return new String which is a substring of this StringBuffer | |
| * | |
| * @exception StringIndexOutOfBoundsException | |
| * if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex) | |
| */ | |
| public synchronized String substring (int beginIndex, int endIndex) | |
| { | |
| if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) | |
| throw new StringIndexOutOfBoundsException (); | |
| // FIXME: for libgcj it would be possible, and more efficient, to | |
| // enable sharing here. | |
| return new String (value, beginIndex, endIndex - beginIndex); | |
| } | |
| /** | |
| * Creates a substring of this StringBuffer, starting at a specified index | |
| * and ending at one character before a specified index. | |
| * <p> | |
| * To implement <code>CharSequence</code>. | |
| * Calls <code>substring(beginIndex, endIndex)</code>. | |
| * | |
| * @param beginIndex index to start substring (base 0) | |
| * @param endIndex index after the last character to be | |
| * copied into the substring | |
| * | |
| * @return new String which is a substring of this StringBuffer | |
| * | |
| * @exception StringIndexOutOfBoundsException | |
| * if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex) | |
| */ | |
| public CharSequence subSequence (int beginIndex, int endIndex) | |
| { | |
| return substring(beginIndex, endIndex); | |
| } | |
| /** Convert this <code>StringBuffer</code> to a <code>String</code>. | |
| * @return the characters in this StringBuffer | |
| */ | |
| public String toString () | |
| { | |
| // Note: in libgcj this causes the StringBuffer to be shared. In | |
| // Classpath it does not. | |
| return new String (this); | |
| } | |
| // Index of next available character. Note that this has | |
| // permissions set this way so that String can get the value. | |
| int count; | |
| // The buffer. Note that this has permissions set this way so that | |
| // String can get the value. | |
| char[] value; | |
| // 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. Note that | |
| // this has permissions set this way so that String can get the | |
| // value. | |
| boolean shared; | |
| static final long serialVersionUID = 3388685877147921107L; | |
| private final static int DEFAULT_CAPACITY = 16; // JLS 20.13.1 | |
| } |