diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-10 18:28:31 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-10 18:28:31 +0000 |
commit | 0f78940a0f759f8b50fc3f549405ff2eafacf77f (patch) | |
tree | aad8a7f3fb8054aaa963068393ed6f36908bfee5 /libjava | |
parent | cac3caec0f3d5434e271773940effd232f3ed469 (diff) | |
download | gcc-0f78940a0f759f8b50fc3f549405ff2eafacf77f.tar.gz |
* gcj/javaprims.h: Updated.
* java/lang/String.java (String(StringBuilder)): New constructor.
* java/lang/natStringBuilder.cc: New file.
* java/lang/StringBuilder.java: New file.
* Makefile.in: Rebuilt.
* Makefile.am (core_java_source_files): Added StringBuilder.java.
(nat_source_files): Added natStringBuilder.cc.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99535 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 10 | ||||
-rw-r--r-- | libjava/Makefile.am | 2 | ||||
-rw-r--r-- | libjava/Makefile.in | 23 | ||||
-rw-r--r-- | libjava/gcj/javaprims.h | 16 | ||||
-rw-r--r-- | libjava/java/lang/String.java | 14 | ||||
-rw-r--r-- | libjava/java/lang/StringBuilder.java | 937 | ||||
-rw-r--r-- | libjava/java/lang/natStringBuilder.cc | 29 |
7 files changed, 1018 insertions, 13 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index bbcff752642..1ba485b91b2 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,13 @@ +2005-05-10 Tom Tromey <tromey@redhat.com> + + * gcj/javaprims.h: Updated. + * java/lang/String.java (String(StringBuilder)): New constructor. + * java/lang/natStringBuilder.cc: New file. + * java/lang/StringBuilder.java: New file. + * Makefile.in: Rebuilt. + * Makefile.am (core_java_source_files): Added StringBuilder.java. + (nat_source_files): Added natStringBuilder.cc. + 2005-05-10 Paolo Bonzini <bonzini@gnu.org> PR java/21436 diff --git a/libjava/Makefile.am b/libjava/Makefile.am index a369fafefc0..124bfe23a6b 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -2931,6 +2931,7 @@ java/lang/StackTraceElement.java \ java/lang/StrictMath.java \ java/lang/String.java \ java/lang/StringBuffer.java \ +java/lang/StringBuilder.java \ java/lang/StringIndexOutOfBoundsException.java \ java/lang/System.java \ java/lang/Thread.java \ @@ -3926,6 +3927,7 @@ java/lang/natObject.cc \ java/lang/natRuntime.cc \ java/lang/natString.cc \ java/lang/natStringBuffer.cc \ +java/lang/natStringBuilder.cc \ java/lang/natSystem.cc \ java/lang/natThread.cc \ java/lang/natVMClassLoader.cc \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 387fdb45546..966dab73a98 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -264,8 +264,8 @@ am__libgcj0_convenience_la_SOURCES_DIST = prims.cc jni.cc exception.cc \ java/lang/natFloat.cc java/lang/natMath.cc \ java/lang/natObject.cc java/lang/natRuntime.cc \ java/lang/natString.cc java/lang/natStringBuffer.cc \ - java/lang/natSystem.cc java/lang/natThread.cc \ - java/lang/natVMClassLoader.cc \ + java/lang/natStringBuilder.cc java/lang/natSystem.cc \ + java/lang/natThread.cc java/lang/natVMClassLoader.cc \ java/lang/natVMSecurityManager.cc java/lang/natVMThrowable.cc \ java/lang/ref/natReference.cc java/lang/reflect/natArray.cc \ java/lang/reflect/natConstructor.cc \ @@ -337,6 +337,7 @@ am__libgcj0_convenience_la_SOURCES_DIST = prims.cc jni.cc exception.cc \ java/lang/StackOverflowError.java \ java/lang/StackTraceElement.java java/lang/StrictMath.java \ java/lang/String.java java/lang/StringBuffer.java \ + java/lang/StringBuilder.java \ java/lang/StringIndexOutOfBoundsException.java \ java/lang/System.java java/lang/Thread.java \ java/lang/ThreadDeath.java java/lang/ThreadGroup.java \ @@ -2312,8 +2313,8 @@ am__objects_5 = gnu/classpath/natSystemProperties.lo \ java/lang/natFloat.lo java/lang/natMath.lo \ java/lang/natObject.lo java/lang/natRuntime.lo \ java/lang/natString.lo java/lang/natStringBuffer.lo \ - java/lang/natSystem.lo java/lang/natThread.lo \ - java/lang/natVMClassLoader.lo \ + java/lang/natStringBuilder.lo java/lang/natSystem.lo \ + java/lang/natThread.lo java/lang/natVMClassLoader.lo \ java/lang/natVMSecurityManager.lo java/lang/natVMThrowable.lo \ java/lang/ref/natReference.lo java/lang/reflect/natArray.lo \ java/lang/reflect/natConstructor.lo \ @@ -2381,7 +2382,7 @@ am__objects_8 = java/lang/AbstractMethodError.lo \ java/lang/SecurityManager.lo java/lang/Short.lo \ java/lang/StackOverflowError.lo java/lang/StackTraceElement.lo \ java/lang/StrictMath.lo java/lang/String.lo \ - java/lang/StringBuffer.lo \ + java/lang/StringBuffer.lo java/lang/StringBuilder.lo \ java/lang/StringIndexOutOfBoundsException.lo \ java/lang/System.lo java/lang/Thread.lo \ java/lang/ThreadDeath.lo java/lang/ThreadGroup.lo \ @@ -6735,6 +6736,7 @@ java/lang/StackTraceElement.java \ java/lang/StrictMath.java \ java/lang/String.java \ java/lang/StringBuffer.java \ +java/lang/StringBuilder.java \ java/lang/StringIndexOutOfBoundsException.java \ java/lang/System.java \ java/lang/Thread.java \ @@ -7719,6 +7721,7 @@ java/lang/natObject.cc \ java/lang/natRuntime.cc \ java/lang/natString.cc \ java/lang/natStringBuffer.cc \ +java/lang/natStringBuilder.cc \ java/lang/natSystem.cc \ java/lang/natThread.cc \ java/lang/natVMClassLoader.cc \ @@ -8369,6 +8372,8 @@ java/lang/natString.lo: java/lang/$(am__dirstamp) \ java/lang/$(DEPDIR)/$(am__dirstamp) java/lang/natStringBuffer.lo: java/lang/$(am__dirstamp) \ java/lang/$(DEPDIR)/$(am__dirstamp) +java/lang/natStringBuilder.lo: java/lang/$(am__dirstamp) \ + java/lang/$(DEPDIR)/$(am__dirstamp) java/lang/natSystem.lo: java/lang/$(am__dirstamp) \ java/lang/$(DEPDIR)/$(am__dirstamp) java/lang/natThread.lo: java/lang/$(am__dirstamp) \ @@ -8676,6 +8681,8 @@ java/lang/String.lo: java/lang/$(am__dirstamp) \ java/lang/$(DEPDIR)/$(am__dirstamp) java/lang/StringBuffer.lo: java/lang/$(am__dirstamp) \ java/lang/$(DEPDIR)/$(am__dirstamp) +java/lang/StringBuilder.lo: java/lang/$(am__dirstamp) \ + java/lang/$(DEPDIR)/$(am__dirstamp) java/lang/StringIndexOutOfBoundsException.lo: \ java/lang/$(am__dirstamp) java/lang/$(DEPDIR)/$(am__dirstamp) java/lang/System.lo: java/lang/$(am__dirstamp) \ @@ -17174,6 +17181,8 @@ mostlyclean-compile: -rm -f java/lang/String.lo -rm -f java/lang/StringBuffer.$(OBJEXT) -rm -f java/lang/StringBuffer.lo + -rm -f java/lang/StringBuilder.$(OBJEXT) + -rm -f java/lang/StringBuilder.lo -rm -f java/lang/StringIndexOutOfBoundsException.$(OBJEXT) -rm -f java/lang/StringIndexOutOfBoundsException.lo -rm -f java/lang/System.$(OBJEXT) @@ -17266,6 +17275,8 @@ mostlyclean-compile: -rm -f java/lang/natString.lo -rm -f java/lang/natStringBuffer.$(OBJEXT) -rm -f java/lang/natStringBuffer.lo + -rm -f java/lang/natStringBuilder.$(OBJEXT) + -rm -f java/lang/natStringBuilder.lo -rm -f java/lang/natSystem.$(OBJEXT) -rm -f java/lang/natSystem.lo -rm -f java/lang/natThread.$(OBJEXT) @@ -21174,6 +21185,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/StrictMath.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/String.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/StringBuffer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/StringBuilder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/StringIndexOutOfBoundsException.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/System.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/Thread.Plo@am__quote@ @@ -21220,6 +21232,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natRuntime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natString.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natStringBuffer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natStringBuilder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natSystem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natThread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@java/lang/$(DEPDIR)/natVMClassLoader.Plo@am__quote@ diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h index e972f7ba518..99fc7a3b345 100644 --- a/libjava/gcj/javaprims.h +++ b/libjava/gcj/javaprims.h @@ -1,7 +1,7 @@ // javaprims.h - Main external header file for libgcj. -*- c++ -*- -/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation This file is part of libgcj. @@ -78,24 +78,24 @@ extern "Java" class IOException; class InputStream; class InputStreamReader; - class InterfaceComparator; class InterruptedIOException; class InvalidClassException; class InvalidObjectException; class LineNumberInputStream; class LineNumberReader; - class MemberComparator; - class MyIOException; class NotActiveException; class NotSerializableException; class ObjectInput; class ObjectInputStream; class ObjectInputStream$GetField; + class ObjectInputStream$ValidatorAndPriority; class ObjectInputValidation; class ObjectOutput; class ObjectOutputStream; class ObjectOutputStream$PutField; class ObjectStreamClass; + class ObjectStreamClass$InterfaceComparator; + class ObjectStreamClass$MemberComparator; class ObjectStreamConstants; class ObjectStreamException; class ObjectStreamField; @@ -124,7 +124,6 @@ extern "Java" class UTFDataFormatException; class UnsupportedEncodingException; class VMObjectStreamClass; - class ValidatorAndPriority; class WriteAbortedException; class Writer; } @@ -204,6 +203,7 @@ extern "Java" class String; class String$CaseInsensitiveComparator; class StringBuffer; + class StringBuilder; class StringIndexOutOfBoundsException; class System; class Thread; @@ -211,6 +211,7 @@ extern "Java" class ThreadGroup; class ThreadLocal; class Throwable; + class Throwable$StaticData; class UnknownError; class UnsatisfiedLinkError; class UnsupportedClassVersionError; @@ -256,6 +257,8 @@ extern "Java" { class AbstractCollection; class AbstractList; + class AbstractList$RandomAccessSubList; + class AbstractList$SubList; class AbstractMap; class AbstractMap$BasicMapEntry; class AbstractSequentialList; @@ -342,7 +345,6 @@ extern "Java" class PropertyResourceBundle; class Random; class RandomAccess; - class RandomAccessSubList; class ResourceBundle; class ResourceBundle$BundleKey; class Set; @@ -351,7 +353,6 @@ extern "Java" class SortedSet; class Stack; class StringTokenizer; - class SubList; class TimeZone; class Timer; class Timer$Scheduler; @@ -376,6 +377,7 @@ extern "Java" class JarEntry; class JarException; class JarFile; + class JarFile$EntryInputStream; class JarFile$JarEnumeration; class JarInputStream; class JarOutputStream; diff --git a/libjava/java/lang/String.java b/libjava/java/lang/String.java index e8bb1bba1d9..bc69ead7163 100644 --- a/libjava/java/lang/String.java +++ b/libjava/java/lang/String.java @@ -1,5 +1,5 @@ /* String.java -- immutable character sequences; the object of string literals - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -398,6 +398,18 @@ public final class String implements Serializable, Comparable, CharSequence } /** + * Creates a new String using the character sequence represented by + * the StringBuilder. Subsequent changes to buf do not affect the String. + * + * @param buffer StringBuilder to copy + * @throws NullPointerException if buffer is null + */ + public String(StringBuilder buffer) + { + this(buffer.value, 0, buffer.count); + } + + /** * Special constructor which can share an array when safe to do so. * * @param data the characters to copy diff --git a/libjava/java/lang/StringBuilder.java b/libjava/java/lang/StringBuilder.java new file mode 100644 index 00000000000..4f121e7edf9 --- /dev/null +++ b/libjava/java/lang/StringBuilder.java @@ -0,0 +1,937 @@ +/* StringBuilder.java -- Unsynchronized growable strings + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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.lang; + +import java.io.Serializable; + +/** + * <code>StringBuilder</code> represents a changeable <code>String</code>. + * It provides the operations required to modify the + * <code>StringBuilder</code>, including insert, replace, delete, append, + * and reverse. It like <code>StringBuffer</code>, but is not + * synchronized. It is ideal for use when it is known that the + * object will only be used from a single thread. + * + * <p><code>StringBuilder</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>StringBuilder</code> can have in it before it has to grow (growing + * the char array is an expensive operation involving <code>new</code>). + * + * <p>Incidentally, compilers often implement the String operator "+" + * by using a <code>StringBuilder</code> operation:<br> + * <code>a + b</code><br> + * is the same as<br> + * <code>new StringBuilder().append(a).append(b).toString()</code>. + * + * <p>Classpath's StringBuilder is capable of sharing memory with Strings for + * efficiency. This will help when a StringBuilder is converted to a String + * and the StringBuilder is not changed after that (quite common when + * performing string concatenation). + * + * @author Paul Fisher + * @author John Keiser + * @author Tom Tromey + * @author Eric Blake (ebb9@email.byu.edu) + * @see String + * @see StringBuffer + * + * @since 1.5 + */ +// FIX15: Implement Appendable when co-variant methods are available +public final class StringBuilder + implements Serializable, CharSequence +{ + // Implementation note: if you change this class, you usually will + // want to change StringBuffer as well. + + /** + * For compatability with Sun's JDK + */ + private static final long serialVersionUID = 4383685877147921099L; + + /** + * Index of next available character (and thus the size of the current + * string contents). Note that this has permissions set this way so that + * String can get the value. + * + * @serial the number of characters in the buffer + */ + int count; + + /** + * The buffer. Note that this has permissions set this way so that String + * can get the value. + * + * @serial the buffer + */ + char[] value; + + /** + * The default capacity of a buffer. + */ + private static final int DEFAULT_CAPACITY = 16; + + /** + * Create a new StringBuilder with default capacity 16. + */ + public StringBuilder() + { + this(DEFAULT_CAPACITY); + } + + /** + * Create an empty <code>StringBuilder</code> with the specified initial + * capacity. + * + * @param capacity the initial capacity + * @throws NegativeArraySizeException if capacity is negative + */ + public StringBuilder(int capacity) + { + value = new char[capacity]; + } + + /** + * Create a new <code>StringBuilder</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 convert + * @throws NullPointerException if str is null + */ + public StringBuilder(String str) + { + // Unfortunately, because the size is 16 larger, we cannot share. + count = str.count; + value = new char[count + DEFAULT_CAPACITY]; + str.getChars(0, count, value, 0); + } + + /** + * Create a new <code>StringBuilder</code> with the characters in the + * specified <code>CharSequence</code>. Initial capacity will be the + * length of the sequence plus 16; if the sequence reports a length + * less than or equal to 0, then the initial capacity will be 16. + * + * @param seq the initializing <code>CharSequence</code> + * @throws NullPointerException if str is null + */ + public StringBuilder(CharSequence seq) + { + int len = seq.length(); + count = len <= 0 ? 0 : len; + value = new char[count + DEFAULT_CAPACITY]; + for (int i = 0; i < len; ++i) + value[i] = seq.charAt(i); + } + + /** + * Get the length of the <code>String</code> this <code>StringBuilder</code> + * would create. Not to be confused with the <em>capacity</em> of the + * <code>StringBuilder</code>. + * + * @return the length of this <code>StringBuilder</code> + * @see #capacity() + * @see #setLength(int) + */ + public int length() + { + return count; + } + + /** + * Get the total number of characters this <code>StringBuilder</code> can + * support before it must be grown. Not to be confused with <em>length</em>. + * + * @return the capacity of this <code>StringBuilder</code> + * @see #length() + * @see #ensureCapacity(int) + */ + public int capacity() + { + return value.length; + } + + /** + * Increase the capacity of this <code>StringBuilder</code>. This will + * ensure that an expensive growing operation will not occur until + * <code>minimumCapacity</code> is reached. The buffer is grown to the + * larger of <code>minimumCapacity</code> and + * <code>capacity() * 2 + 2</code>, if it is not already large enough. + * + * @param minimumCapacity the new capacity + * @see #capacity() + */ + public void ensureCapacity(int minimumCapacity) + { + if (minimumCapacity > value.length) + { + int max = value.length * 2 + 2; + minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); + char[] nb = new char[minimumCapacity]; + System.arraycopy(value, 0, nb, 0, count); + value = nb; + } + } + + /** + * Set the length of this StringBuilder. If the new length is greater than + * the current length, all the new characters are set to '\0'. If the new + * length is less than the current length, the first <code>newLength</code> + * characters of the old array will be preserved, and the remaining + * characters are truncated. + * + * @param newLength the new length + * @throws IndexOutOfBoundsException if the new length is negative + * (while unspecified, this is a StringIndexOutOfBoundsException) + * @see #length() + */ + public void setLength(int newLength) + { + if (newLength < 0) + throw new StringIndexOutOfBoundsException(newLength); + + int valueLength = value.length; + + /* Always call ensureCapacity in order to preserve copy-on-write + semantics. */ + ensureCapacity(newLength); + + if (newLength < valueLength) + { + /* If the StringBuilder's value just grew, then we know that + value is newly allocated and the region between count and + newLength is filled with '\0'. */ + count = newLength; + } + else + { + /* The StringBuilder's value doesn't need to grow. However, + we should clear out any cruft that may exist. */ + while (count < newLength) + value[count++] = '\0'; + } + } + + /** + * 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 + * @throws IndexOutOfBoundsException if index is negative or >= length() + * (while unspecified, this is a StringIndexOutOfBoundsException) + */ + public char charAt(int index) + { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException(index); + return value[index]; + } + + /** + * Get the specified array of characters. <code>srcOffset - srcEnd</code> + * characters will be copied into the array you pass in. + * + * @param srcOffset the index to start copying from (inclusive) + * @param srcEnd the index to stop copying from (exclusive) + * @param dst the array to copy into + * @param dstOffset the index to start copying into + * @throws NullPointerException if dst is null + * @throws IndexOutOfBoundsException if any source or target indices are + * out of range (while unspecified, source problems cause a + * StringIndexOutOfBoundsException, and dest problems cause an + * ArrayIndexOutOfBoundsException) + * @see System#arraycopy(Object, int, Object, int, int) + */ + public void getChars(int srcOffset, int srcEnd, + char[] dst, int dstOffset) + { + if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset) + throw new StringIndexOutOfBoundsException(); + System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); + } + + /** + * 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 + * @throws IndexOutOfBoundsException if index is negative or >= length() + * (while unspecified, this is a StringIndexOutOfBoundsException) + */ + public 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; + } + + /** + * Append the <code>String</code> value of the argument to this + * <code>StringBuilder</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>StringBuilder</code> + * @see String#valueOf(Object) + * @see #append(String) + */ + public StringBuilder append(Object obj) + { + return append(obj == null ? "null" : obj.toString()); + } + + /** + * Append the <code>String</code> to this <code>StringBuilder</code>. If + * str is null, the String "null" is appended. + * + * @param str the <code>String</code> to append + * @return this <code>StringBuilder</code> + */ + public StringBuilder append(String str) + { + if (str == null) + str = "null"; + int len = str.count; + ensureCapacity(count + len); + str.getChars(0, len, value, count); + count += len; + return this; + } + + /** + * Append the <code>StringBuilder</code> value of the argument to this + * <code>StringBuilder</code>. This behaves the same as + * <code>append((Object) stringBuffer)</code>, except it is more efficient. + * + * @param stringBuffer the <code>StringBuilder</code> to convert and append + * @return this <code>StringBuilder</code> + * @see #append(Object) + */ + public StringBuilder append(StringBuffer stringBuffer) + { + if (stringBuffer == null) + return append("null"); + synchronized (stringBuffer) + { + int len = stringBuffer.count; + ensureCapacity(count + len); + System.arraycopy(stringBuffer.value, 0, value, count, len); + count += len; + } + return this; + } + + /** + * Append the <code>char</code> array to this <code>StringBuilder</code>. + * This is similar (but more efficient) than + * <code>append(new String(data))</code>, except in the case of null. + * + * @param data the <code>char[]</code> to append + * @return this <code>StringBuilder</code> + * @throws NullPointerException if <code>str</code> is <code>null</code> + * @see #append(char[], int, int) + */ + public StringBuilder append(char[] data) + { + return append(data, 0, data.length); + } + + /** + * Append part of the <code>char</code> array to this + * <code>StringBuilder</code>. This is similar (but more efficient) than + * <code>append(new String(data, offset, count))</code>, except in the case + * of null. + * + * @param data the <code>char[]</code> to append + * @param offset the start location in <code>str</code> + * @param count the number of characters to get from <code>str</code> + * @return this <code>StringBuilder</code> + * @throws NullPointerException if <code>str</code> is <code>null</code> + * @throws IndexOutOfBoundsException if offset or count is out of range + * (while unspecified, this is a StringIndexOutOfBoundsException) + */ + public StringBuilder append(char[] data, int offset, int count) + { + if (offset < 0 || count < 0 || offset > data.length - count) + throw new StringIndexOutOfBoundsException(); + ensureCapacity(this.count + count); + System.arraycopy(data, offset, value, this.count, count); + this.count += count; + return this; + } + + /** + * Append the <code>String</code> value of the argument to this + * <code>StringBuilder</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>StringBuilder</code> + * @see String#valueOf(boolean) + */ + public StringBuilder append(boolean bool) + { + return append(bool ? "true" : "false"); + } + + /** + * Append the <code>char</code> to this <code>StringBuilder</code>. + * + * @param ch the <code>char</code> to append + * @return this <code>StringBuilder</code> + */ + public StringBuilder append(char ch) + { + ensureCapacity(count + 1); + value[count++] = ch; + return this; + } + + /** + * Append the characters in the <code>CharSequence</code> to this + * buffer. + * + * @param seq the <code>CharSequence</code> providing the characters + * @return this <code>StringBuilder</code> + */ + public StringBuilder append(CharSequence seq) + { + return append(seq, 0, seq.length()); + } + + /** + * Append some characters from the <code>CharSequence</code> to this + * buffer. If the argument is null, the four characters "null" are + * appended. + * + * @param seq the <code>CharSequence</code> providing the characters + * @param start the starting index + * @param end one past the final index + * @return this <code>StringBuilder</code> + */ + public StringBuilder append(CharSequence seq, int start, + int end) + { + if (seq == null) + return append("null"); + if (end - start > 0) + { + ensureCapacity(count + end - start); + for (; start < end; ++start) + value[count++] = seq.charAt(start); + } + return this; + } + + /** + * Append the <code>String</code> value of the argument to this + * <code>StringBuilder</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>StringBuilder</code> + * @see String#valueOf(int) + */ + // FIXME: this is native in libgcj in StringBuffer. + public StringBuilder append(int inum) + { + return append(String.valueOf(inum)); + } + + /** + * Append the <code>String</code> value of the argument to this + * <code>StringBuilder</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>StringBuilder</code> + * @see String#valueOf(long) + */ + public StringBuilder append(long lnum) + { + return append(Long.toString(lnum, 10)); + } + + /** + * Append the <code>String</code> value of the argument to this + * <code>StringBuilder</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>StringBuilder</code> + * @see String#valueOf(float) + */ + public StringBuilder append(float fnum) + { + return append(Float.toString(fnum)); + } + + /** + * Append the <code>String</code> value of the argument to this + * <code>StringBuilder</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>StringBuilder</code> + * @see String#valueOf(double) + */ + public StringBuilder append(double dnum) + { + return append(Double.toString(dnum)); + } + + /** + * Delete characters from this <code>StringBuilder</code>. + * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is + * harmless for end to be larger than length(). + * + * @param start the first character to delete + * @param end the index after the last character to delete + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if start or end are out of bounds + */ + public StringBuilder 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(count); + if (count - end != 0) + System.arraycopy(value, end, value, start, count - end); + count -= end - start; + return this; + } + + /** + * Delete a character from this <code>StringBuilder</code>. + * + * @param index the index of the character to delete + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if index is out of bounds + */ + public StringBuilder deleteCharAt(int index) + { + return delete(index, index + 1); + } + + /** + * 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 StringBuilder, 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>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if start or end are out of bounds + * @throws NullPointerException if str is null + */ + public StringBuilder replace(int start, int end, String str) + { + if (start < 0 || start > count || start > end) + throw new StringIndexOutOfBoundsException(start); + + int len = str.count; + // Calculate the difference in 'count' after the replace. + int delta = len - (end > count ? count : end) + start; + ensureCapacity(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; + } + + /** + * Creates a substring of this StringBuilder, starting at a specified index + * and ending at the end of this StringBuilder. + * + * @param beginIndex index to start substring (base 0) + * @return new String which is a substring of this StringBuilder + * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds + * @see #substring(int, int) + */ + public String substring(int beginIndex) + { + return substring(beginIndex, count); + } + + /** + * Creates a substring of this StringBuilder, starting at a specified index + * and ending at one character before a specified index. This is implemented + * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy + * the CharSequence interface. + * + * @param beginIndex index to start at (inclusive, base 0) + * @param endIndex index to end at (exclusive) + * @return new String which is a substring of this StringBuilder + * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of + * bounds + * @see #substring(int, int) + */ + public CharSequence subSequence(int beginIndex, int endIndex) + { + return substring(beginIndex, endIndex); + } + + /** + * Creates a substring of this StringBuilder, starting at a specified index + * and ending at one character before a specified index. + * + * @param beginIndex index to start at (inclusive, base 0) + * @param endIndex index to end at (exclusive) + * @return new String which is a substring of this StringBuilder + * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out + * of bounds + */ + public String substring(int beginIndex, int endIndex) + { + int len = endIndex - beginIndex; + if (beginIndex < 0 || endIndex > count || endIndex < beginIndex) + throw new StringIndexOutOfBoundsException(); + if (len == 0) + return ""; + return new String(value, beginIndex, len); + } + + /** + * Insert a subarray of the <code>char[]</code> argument into this + * <code>StringBuilder</code>. + * + * @param offset the place to insert in this buffer + * @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>StringBuilder</code> + * @throws NullPointerException if <code>str</code> is <code>null</code> + * @throws StringIndexOutOfBoundsException if any index is out of bounds + */ + public StringBuilder insert(int offset, + char[] str, int str_offset, int len) + { + if (offset < 0 || offset > count || len < 0 + || str_offset < 0 || str_offset > str.length - len) + throw new StringIndexOutOfBoundsException(); + ensureCapacity(count + len); + System.arraycopy(value, offset, value, offset + len, count - offset); + System.arraycopy(str, str_offset, value, offset, len); + count += len; + return this; + } + + /** + * Insert the <code>String</code> value of the argument into this + * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert + * to <code>String</code>. + * + * @param offset the place to insert in this buffer + * @param obj the <code>Object</code> to convert and insert + * @return this <code>StringBuilder</code> + * @exception StringIndexOutOfBoundsException if offset is out of bounds + * @see String#valueOf(Object) + */ + public StringBuilder insert(int offset, Object obj) + { + return insert(offset, obj == null ? "null" : obj.toString()); + } + + /** + * Insert the <code>String</code> argument into this + * <code>StringBuilder</code>. If str is null, the String "null" is used + * instead. + * + * @param offset the place to insert in this buffer + * @param str the <code>String</code> to insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + */ + public StringBuilder insert(int offset, String str) + { + if (offset < 0 || offset > count) + throw new StringIndexOutOfBoundsException(offset); + if (str == null) + str = "null"; + int len = str.count; + ensureCapacity(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>StringBuilder</code>. + * + * @param offset the place to insert in this buffer + * @param data the <code>char[]</code> to insert + * @return this <code>StringBuilder</code> + * @throws NullPointerException if <code>data</code> is <code>null</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + * @see #insert(int, char[], int, int) + */ + public StringBuilder insert(int offset, char[] data) + { + return insert(offset, data, 0, data.length); + } + + /** + * Insert the <code>String</code> value of the argument into this + * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert + * to <code>String</code>. + * + * @param offset the place to insert in this buffer + * @param bool the <code>boolean</code> to convert and insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + * @see String#valueOf(boolean) + */ + public StringBuilder insert(int offset, boolean bool) + { + return insert(offset, bool ? "true" : "false"); + } + + /** + * Insert the <code>char</code> argument into this <code>StringBuilder</code>. + * + * @param offset the place to insert in this buffer + * @param ch the <code>char</code> to insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + */ + public StringBuilder 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; + } + + /** + * Insert the <code>String</code> value of the argument into this + * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert + * to <code>String</code>. + * + * @param offset the place to insert in this buffer + * @param inum the <code>int</code> to convert and insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + * @see String#valueOf(int) + */ + public StringBuilder insert(int offset, int inum) + { + return insert(offset, String.valueOf(inum)); + } + + /** + * Insert the <code>String</code> value of the argument into this + * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert + * to <code>String</code>. + * + * @param offset the place to insert in this buffer + * @param lnum the <code>long</code> to convert and insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + * @see String#valueOf(long) + */ + public StringBuilder insert(int offset, long lnum) + { + return insert(offset, Long.toString(lnum, 10)); + } + + /** + * Insert the <code>String</code> value of the argument into this + * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert + * to <code>String</code>. + * + * @param offset the place to insert in this buffer + * @param fnum the <code>float</code> to convert and insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + * @see String#valueOf(float) + */ + public StringBuilder insert(int offset, float fnum) + { + return insert(offset, Float.toString(fnum)); + } + + /** + * Insert the <code>String</code> value of the argument into this + * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert + * to <code>String</code>. + * + * @param offset the place to insert in this buffer + * @param dnum the <code>double</code> to convert and insert + * @return this <code>StringBuilder</code> + * @throws StringIndexOutOfBoundsException if offset is out of bounds + * @see String#valueOf(double) + */ + public StringBuilder insert(int offset, double dnum) + { + return insert(offset, Double.toString(dnum)); + } + + /** + * Finds the first instance of a substring in this StringBuilder. + * + * @param str String to find + * @return location (base 0) of the String, or -1 if not found + * @throws NullPointerException if str is null + * @see #indexOf(String, int) + */ + public int indexOf(String str) + { + return indexOf(str, 0); + } + + /** + * Finds the first instance of a String in this StringBuilder, starting at + * a given index. If starting index is less than 0, the search starts at + * the beginning of this String. If the starting index is greater than the + * length of this String, or the substring is not found, -1 is returned. + * + * @param str String to find + * @param fromIndex index to start the search + * @return location (base 0) of the String, or -1 if not found + * @throws NullPointerException if str is null + */ + public int indexOf(String str, int fromIndex) + { + if (fromIndex < 0) + fromIndex = 0; + int limit = count - str.count; + for ( ; fromIndex <= limit; fromIndex++) + if (regionMatches(fromIndex, str)) + return fromIndex; + return -1; + } + + /** + * Finds the last instance of a substring in this StringBuilder. + * + * @param str String to find + * @return location (base 0) of the String, or -1 if not found + * @throws NullPointerException if str is null + * @see #lastIndexOf(String, int) + */ + public int lastIndexOf(String str) + { + return lastIndexOf(str, count - str.count); + } + + /** + * Finds the last instance of a String in this StringBuilder, starting at a + * given index. If starting index is greater than the maximum valid index, + * then the search begins at the end of this String. If the starting index + * is less than zero, or the substring is not found, -1 is returned. + * + * @param str String to find + * @param fromIndex index to start the search + * @return location (base 0) of the String, or -1 if not found + * @throws NullPointerException if str is null + */ + public int lastIndexOf(String str, int fromIndex) + { + fromIndex = Math.min(fromIndex, count - str.count); + for ( ; fromIndex >= 0; fromIndex--) + if (regionMatches(fromIndex, str)) + return fromIndex; + return -1; + } + + /** + * Reverse the characters in this StringBuilder. The same sequence of + * characters exists, but in the reverse index ordering. + * + * @return this <code>StringBuilder</code> + */ + public StringBuilder reverse() + { + // Call ensureCapacity to enforce copy-on-write. + ensureCapacity(count); + for (int i = count >> 1, j = count - i; --i >= 0; ++j) + { + char c = value[i]; + value[i] = value[j]; + value[j] = c; + } + return this; + } + + /** + * Convert this <code>StringBuilder</code> to a <code>String</code>. The + * String is composed of the characters currently in this StringBuilder. Note + * that the result is a copy, and that future modifications to this buffer + * do not affect the String. + * + * @return the characters in this StringBuilder + */ + public String toString() + { + return new String(this); + } + + /** + * Predicate which determines if a substring of this matches another String + * starting at a specified offset for each String and continuing for a + * specified length. This is more efficient than creating a String to call + * indexOf on. + * + * @param toffset index to start comparison at for this String + * @param other non-null String to compare to region of this + * @return true if regions match, false otherwise + * @see #indexOf(String, int) + * @see #lastIndexOf(String, int) + * @see String#regionMatches(boolean, int, String, int, int) + */ + // GCJ LOCAL: Native to access String internals properly. + private native boolean regionMatches(int toffset, String other); +} diff --git a/libjava/java/lang/natStringBuilder.cc b/libjava/java/lang/natStringBuilder.cc new file mode 100644 index 00000000000..e2c8c29f6e3 --- /dev/null +++ b/libjava/java/lang/natStringBuilder.cc @@ -0,0 +1,29 @@ +// Native methods for StringBuilder. + +/* Copyright (C) 2005 Free Software Foundation + + 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. */ + +#include <config.h> +#include <gcj/cni.h> +#include <java/lang/StringBuilder.h> +#include <java/lang/String.h> + +jboolean +java::lang::StringBuilder::regionMatches(jint offset, jstring other) +{ + int len = other->count; + int index = 0; + jchar *sc = elements (value); + jchar *oc = _Jv_GetStringChars (other); + while (--len >= 0) + { + if (sc[offset++] != oc[index++]) + return false; + } + return true; +} |