classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] Patch: FYI: StringBuffer -vs- 1.5


From: Tom Tromey
Subject: [cp-patches] Patch: FYI: StringBuffer -vs- 1.5
Date: 14 Sep 2005 09:14:03 -0600

I'm checking this in (on the trunk).

This adds the new 1.5 methods to StringBuffer.

Tom

Index: ChangeLog
from  Tom Tromey  <address@hidden>
        * java/lang/StringBuffer.java (StringBuffer): New constructor.
        (trimToSize): New method.
        (codePointAt): Likewise.
        (codePointBefore): Likewise.
        (codePointCount): Likewise.
        (appendCodePoint): Likewise.
        (append): New overloads.
        (insert): Likewise.

Index: java/lang/StringBuffer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/StringBuffer.java,v
retrieving revision 1.31
diff -u -r1.31 StringBuffer.java
--- java/lang/StringBuffer.java 2 Jul 2005 20:32:39 -0000 1.31
+++ java/lang/StringBuffer.java 14 Sep 2005 15:14:56 -0000
@@ -148,6 +148,24 @@
   }
 
   /**
+   * Create a new <code>StringBuffer</code> with the characters from the
+   * specified <code>CharSequence</code>. Initial capacity will be the
+   * size of the CharSequence plus 16.
+   *
+   * @param sequence the <code>String</code> to convert
+   * @throws NullPointerException if str is null
+   *
+   * @since 1.5
+   */
+  public StringBuffer(CharSequence sequence)
+  {
+    count = Math.max(0, sequence.length());
+    value = new char[count + DEFAULT_CAPACITY];
+    for (int i = 0; i < count; ++i)
+      value[i] = sequence.charAt(i);
+  }
+
+  /**
    * 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>.
@@ -244,6 +262,58 @@
   }
 
   /**
+   * Get the code point at the specified index.  This is like #charAt(int),
+   * but if the character is the start of a surrogate pair, and the
+   * following character completes the pair, then the corresponding
+   * supplementary code point is returned.
+   * @param index the index of the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @since 1.5
+   */
+  public synchronized int codePointAt(int index)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    char base = value[index];
+    if (base < Character.MIN_HIGH_SURROGATE
+       || base > Character.MAX_HIGH_SURROGATE
+       || index == count
+       || value[index + 1] < Character.MIN_LOW_SURROGATE
+       || value[index + 1] > Character.MAX_LOW_SURROGATE)
+      return base;
+    return (((base - Character.MIN_HIGH_SURROGATE) << 10)
+           + (value[index + 1] - Character.MIN_LOW_SURROGATE));
+  }
+
+  /**
+   * Get the code point before the specified index.  This is like
+   * #codePointAt(int), but checks the characters at <code>index-1</code> and
+   * <code>index-2</code> to see if they form a supplementary code point.
+   * @param index the index just past the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @since 1.5
+   */
+  public synchronized int codePointBefore(int index)
+  {
+    --index;
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    char base = value[index];
+    if (base < Character.MIN_LOW_SURROGATE
+       || base > Character.MAX_LOW_SURROGATE
+       || index == 0
+       || value[index - 1] < Character.MIN_HIGH_SURROGATE
+       || value[index - 1] > Character.MAX_HIGH_SURROGATE)
+      return base;
+    return (((value[index - 1] - Character.MIN_HIGH_SURROGATE) << 10)
+           + (base - Character.MIN_LOW_SURROGATE));
+  }
+
+  /**
    * Get the specified array of characters. <code>srcOffset - srcEnd</code>
    * characters will be copied into the array you pass in.
    *
@@ -341,6 +411,46 @@
   }
 
   /**
+   * Append the <code>CharSequence</code> value of the argument to this
+   * <code>StringBuffer</code>.
+   *
+   * @param sequence the <code>CharSequence</code> to append
+   * @return this <code>StringBuffer</code>
+   * @see #append(Object)
+   * @since 1.5
+   */
+  public synchronized StringBuffer append(CharSequence sequence)
+  {
+    if (sequence == null)
+      sequence = "null";
+    return append(sequence, 0, sequence.length());
+  }
+
+  /**
+   * Append the specified subsequence of the <code>CharSequence</code>
+   * argument to this <code>StringBuffer</code>.
+   *
+   * @param sequence the <code>CharSequence</code> to append
+   * @param start the starting index
+   * @param end one past the ending index
+   * @return this <code>StringBuffer</code>
+   * @see #append(Object)
+   * @since 1.5
+   */
+  public synchronized StringBuffer append(CharSequence sequence,
+                                         int start, int end)
+  {
+    if (sequence == null)
+      sequence = "null";
+    if (start < 0 || end < 0 || start > end || end > sequence.length())
+      throw new IndexOutOfBoundsException();
+    ensureCapacity_unsynchronized(this.count + end - start);
+    for (int i = start; i < end; ++i)
+      value[count++] = sequence.charAt(i);
+    return this;
+  }
+
+  /**
    * Append the <code>char</code> array to this <code>StringBuffer</code>.
    * This is similar (but more efficient) than
    * <code>append(new String(data))</code>, except in the case of null.
@@ -407,6 +517,24 @@
   }
 
   /**
+   * Append the code point to this <code>StringBuffer</code>.
+   * This is like #append(char), but will append two characters
+   * if a supplementary code point is given.
+   *
+   * @param code the code point to append
+   * @return this <code>StringBuffer</code>
+   * @see Character#toChars(int, char[], int)
+   */
+  public synchronized StringBuffer appendCodePoint(int code)
+  {
+    int len = Character.charCount(code);
+    ensureCapacity_unsynchronized(count + len);
+    Character.toChars(code, value, count);
+    count += len;
+    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>.
@@ -660,6 +788,54 @@
   }
 
   /**
+   * Insert the <code>CharSequence</code> argument into this
+   * <code>StringBuffer</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws IndexOutOfBoundsException if offset is out of bounds
+   * @since 1.5
+   */
+  public synchronized StringBuffer insert(int offset, CharSequence sequence)
+  {
+    if (sequence == null)
+      sequence = "null";
+    return insert(offset, sequence, 0, sequence.length());
+  }
+
+  /**
+   * Insert a subsequence of the <code>CharSequence</code> argument into this
+   * <code>StringBuffer</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @param start the starting index of the subsequence
+   * @param end one past the ending index of the subsequence
+   * @return this <code>StringBuffer</code>
+   * @throws IndexOutOfBoundsException if offset, start,
+   * or end are out of bounds
+   * @since 1.5
+   */
+  public synchronized StringBuffer insert(int offset, CharSequence sequence,
+                                         int start, int end)
+  {
+    if (sequence == null)
+      sequence = "null";
+    if (start < 0 || end < 0 || start > end || end > sequence.length())
+      throw new IndexOutOfBoundsException();
+    int len = end - start;
+    ensureCapacity_unsynchronized(count + len);
+    VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
+    for (int i = start; i < end; ++i)
+      value[offset++] = sequence.charAt(i);
+    count += len;
+    return this;
+  }
+
+  /**
    * Insert the <code>char[]</code> argument into this
    * <code>StringBuffer</code>.
    *
@@ -877,6 +1053,103 @@
   {
     // The string will set this.shared = true.
     return new String(this);
+  }
+
+  /**
+   * This may reduce the amount of memory used by the StringBuffer,
+   * by resizing the internal array to remove unused space.  However,
+   * this method is not required to resize, so this behavior cannot
+   * be relied upon.
+   * @since 1.5
+   */
+  public synchronized void trimToSize()
+  {
+    int wouldSave = value.length - count;
+    // Some random heuristics: if we save less than 20 characters, who
+    // cares.
+    if (wouldSave < 20)
+      return;
+    // If we save more than 200 characters, shrink.
+    // If we save more than 1/4 of the buffer, shrink.
+    if (wouldSave > 200 || wouldSave * 4 > value.length)
+      {
+       char[] newValue = new char[count];
+       VMSystem.arraycopy(value, 0, newValue, 0, count);
+       value = newValue;
+      }
+  }
+
+  /**
+   * Return the number of code points between two indices in the
+   * <code>StringBuffer</code>.  An unpaired surrogate counts as a
+   * code point for this purpose.  Characters outside the indicated
+   * range are not examined, even if the range ends in the middle of a
+   * surrogate pair.
+   *
+   * @param start the starting index
+   * @param end one past the ending index
+   * @return the number of code points
+   * @since 1.5
+   */
+  public synchronized int codePointCount(int start, int end)
+  {
+    int count = 0;
+    while (start < end)
+      {
+       char base = value[start];
+       if (base < Character.MIN_HIGH_SURROGATE
+           || base > Character.MAX_HIGH_SURROGATE
+           || start == end
+           || start == count
+           || value[start + 1] < Character.MIN_LOW_SURROGATE
+           || value[start + 1] > Character.MAX_LOW_SURROGATE)
+         {
+           // Nothing.
+         }
+       else
+         {
+           // Surrogate pair.
+           ++start;
+         }
+       ++start;
+       ++count;
+      }
+    return count;
+  }
+
+  /**
+   * Starting at the given index, this counts forward by the indicated
+   * number of code points, and then returns the resulting index.  An
+   * unpaired surrogate counts as a single code point for this
+   * purpose.
+   *
+   * @param start the starting index
+   * @param codePoints the number of code points
+   * @return the resulting index
+   * @since 1.5
+   */
+  public synchronized int offsetByCodePoints(int start, int codePoints)
+  {
+    while (codePoints > 0)
+      {
+       char base = value[start];
+       if (base < Character.MIN_HIGH_SURROGATE
+           || base > Character.MAX_HIGH_SURROGATE
+           || start == count
+           || value[start + 1] < Character.MIN_LOW_SURROGATE
+           || value[start + 1] > Character.MAX_LOW_SURROGATE)
+         {
+           // Nothing.
+         }
+       else
+         {
+           // Surrogate pair.
+           ++start;
+         }
+       ++start;
+       --codePoints;
+      }
+    return start;
   }
 
   /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]