This is the mail archive of the
java-patches@sourceware.cygnus.com
mailing list for the Java project.
Patch: StringBuffer fixes
- To: java-patches at sourceware dot cygnus dot com, classpath at gnu dot org
- Subject: Patch: StringBuffer fixes
- From: Bryce McKinlay <bryce at albatross dot co dot nz>
- Date: Wed, 10 May 2000 22:29:33 +1200
I checked in the following patch to both libgcj and classpath. It fixes
a few problems I noticed with the new, merged implementation, including
the delete() bug reported by <MSlattery@searchsoft.net>.
I also checked a small regression test (attached) in to the libgcj
testsuite.
regards
[ bryce ]
2000-05-10 Bryce McKinlay <bryce@albatross.co.nz>
* java/lang/StringBuffer.java (delete): Call arrayCopy() correctly.
Avoid arrayCopy() call where possible. Update `count' _after_ calling
arrayCopy().
(replace): Reimplemented. Fix javadoc.
(reverse): Call ensureCapacity_unsynchronized().
(StringBuffer (String)): Use DEFAULT_CAPACITY.
Index: StringBuffer.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/StringBuffer.java,v
retrieving revision 1.5
diff -u -r1.5 StringBuffer.java
--- StringBuffer.java 2000/05/09 22:46:58 1.5
+++ StringBuffer.java 2000/05/10 09:39:38
@@ -227,8 +227,9 @@
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);
- System.arraycopy (value, end - 1, value, start, end - start);
return this;
}
@@ -498,17 +499,31 @@
return count;
}
- /** Delete a character from this <code>StringBuffer</code>.
- * @param index the index of the character to delete.
+ /** 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>.
- * @exception StringIndexOutOfBoundsException if <code>index</code>
- * is out of bounds.
*/
public synchronized StringBuffer replace (int start, int end, String str)
{
- // FIXME: this is inefficient.
- delete (start, end);
- return insert (start, 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 - start);
+
+ str.getChars (0, len, value, start);
+ count += delta;
+ return this;
}
/** Reverse the characters in this StringBuffer.
@@ -516,6 +531,8 @@
*/
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];
@@ -594,7 +611,7 @@
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];
+ value = new char[count + DEFAULT_CAPACITY];
str.getChars(0, count, value, 0);
shared = false;
}
// Test StringBuffer.replace(), reverse(), insert(String), append(String),
// and delete().
public class StringBuffer_1
{
public static void main(String args[])
{
StringBuffer sb = new StringBuffer("45");
sb.insert(0, "123");
sb.append("89");
sb.insert(5, "6");
sb.insert(6, '7');
System.out.println (sb);
sb.delete (3, 99);
String foo = sb.toString();
System.out.println (foo);
sb.reverse();
System.out.println (foo);
System.out.println (sb);
sb = new StringBuffer("1234");
System.out.println(sb.reverse());
sb = new StringBuffer("123456789");
sb.append ("0");
System.out.println(sb);
sb.replace (2, 99, "foo");
System.out.println (sb);
sb = new StringBuffer("123456789");
sb.replace (1, 1, "XX");
System.out.println (sb);
sb = new StringBuffer("123456789");
sb.replace (0, 2, "XX");
System.out.println (sb);
sb = new StringBuffer("123456789");
sb.replace (5, 9, "54321");
System.out.println (sb);
sb = new StringBuffer("123456789");
sb.delete (1,4);
System.out.println (sb);
// Test bounds checks
try
{
sb.insert (-2, "x");
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.insert (96, "x");
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.delete (-2, 2);
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.delete (96, 418);
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.delete (4, 2);
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.replace (-2, 2, "54321");
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.replace (4, 2, "54321");
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
try
{
sb.replace (12, 18, "54321");
}
catch (StringIndexOutOfBoundsException x)
{
System.out.println (x.getClass());
}
}
}
123456789
123
123
321
4321
1234567890
12foo
1XX23456789
XX3456789
1234554321
156789
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException