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 <[EMAIL PROTECTED]>.

I also checked a small regression test (attached) in to the libgcj
testsuite.

regards

  [ bryce ]

2000-05-10  Bryce McKinlay  <[EMAIL PROTECTED]>

        * 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

Reply via email to