emul/mini/src/main/java/java/lang/AbstractStringBuilder.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 23 Jan 2013 20:39:23 +0100
branchemul
changeset 554 05224402145d
parent 403 emul/src/main/java/java/lang/AbstractStringBuilder.java@2dcc8f2e1a1b
child 560 53fafe384803
permissions -rw-r--r--
First attempt to separate 'mini' profile from the rest of JDK APIs
     1 /*
     2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.lang;
    27 
    28 /**
    29  * A mutable sequence of characters.
    30  * <p>
    31  * Implements a modifiable string. At any point in time it contains some
    32  * particular sequence of characters, but the length and content of the
    33  * sequence can be changed through certain method calls.
    34  *
    35  * @author      Michael McCloskey
    36  * @author      Martin Buchholz
    37  * @author      Ulf Zibis
    38  * @since       1.5
    39  */
    40 abstract class AbstractStringBuilder implements Appendable, CharSequence {
    41     /**
    42      * The value is used for character storage.
    43      */
    44     char[] value;
    45 
    46     /**
    47      * The count is the number of characters used.
    48      */
    49     int count;
    50 
    51     /**
    52      * This no-arg constructor is necessary for serialization of subclasses.
    53      */
    54     AbstractStringBuilder() {
    55     }
    56 
    57     /**
    58      * Creates an AbstractStringBuilder of the specified capacity.
    59      */
    60     AbstractStringBuilder(int capacity) {
    61         value = new char[capacity];
    62     }
    63 
    64     /**
    65      * Returns the length (character count).
    66      *
    67      * @return  the length of the sequence of characters currently
    68      *          represented by this object
    69      */
    70     public int length() {
    71         return count;
    72     }
    73 
    74     /**
    75      * Returns the current capacity. The capacity is the amount of storage
    76      * available for newly inserted characters, beyond which an allocation
    77      * will occur.
    78      *
    79      * @return  the current capacity
    80      */
    81     public int capacity() {
    82         return value.length;
    83     }
    84 
    85     /**
    86      * Ensures that the capacity is at least equal to the specified minimum.
    87      * If the current capacity is less than the argument, then a new internal
    88      * array is allocated with greater capacity. The new capacity is the
    89      * larger of:
    90      * <ul>
    91      * <li>The <code>minimumCapacity</code> argument.
    92      * <li>Twice the old capacity, plus <code>2</code>.
    93      * </ul>
    94      * If the <code>minimumCapacity</code> argument is nonpositive, this
    95      * method takes no action and simply returns.
    96      *
    97      * @param   minimumCapacity   the minimum desired capacity.
    98      */
    99     public void ensureCapacity(int minimumCapacity) {
   100         if (minimumCapacity > 0)
   101             ensureCapacityInternal(minimumCapacity);
   102     }
   103 
   104     /**
   105      * This method has the same contract as ensureCapacity, but is
   106      * never synchronized.
   107      */
   108     private void ensureCapacityInternal(int minimumCapacity) {
   109         // overflow-conscious code
   110         if (minimumCapacity - value.length > 0)
   111             expandCapacity(minimumCapacity);
   112     }
   113 
   114     /**
   115      * This implements the expansion semantics of ensureCapacity with no
   116      * size check or synchronization.
   117      */
   118     void expandCapacity(int minimumCapacity) {
   119         int newCapacity = value.length * 2 + 2;
   120         if (newCapacity - minimumCapacity < 0)
   121             newCapacity = minimumCapacity;
   122         if (newCapacity < 0) {
   123             if (minimumCapacity < 0) // overflow
   124                 throw new OutOfMemoryError();
   125             newCapacity = Integer.MAX_VALUE;
   126         }
   127         value = copyOf(value, newCapacity);
   128     }
   129 
   130     /**
   131      * Attempts to reduce storage used for the character sequence.
   132      * If the buffer is larger than necessary to hold its current sequence of
   133      * characters, then it may be resized to become more space efficient.
   134      * Calling this method may, but is not required to, affect the value
   135      * returned by a subsequent call to the {@link #capacity()} method.
   136      */
   137     public void trimToSize() {
   138         if (count < value.length) {
   139             value = copyOf(value, count);
   140         }
   141     }
   142 
   143     /**
   144      * Sets the length of the character sequence.
   145      * The sequence is changed to a new character sequence
   146      * whose length is specified by the argument. For every nonnegative
   147      * index <i>k</i> less than <code>newLength</code>, the character at
   148      * index <i>k</i> in the new character sequence is the same as the
   149      * character at index <i>k</i> in the old sequence if <i>k</i> is less
   150      * than the length of the old character sequence; otherwise, it is the
   151      * null character <code>'&#92;u0000'</code>.
   152      *
   153      * In other words, if the <code>newLength</code> argument is less than
   154      * the current length, the length is changed to the specified length.
   155      * <p>
   156      * If the <code>newLength</code> argument is greater than or equal
   157      * to the current length, sufficient null characters
   158      * (<code>'&#92;u0000'</code>) are appended so that
   159      * length becomes the <code>newLength</code> argument.
   160      * <p>
   161      * The <code>newLength</code> argument must be greater than or equal
   162      * to <code>0</code>.
   163      *
   164      * @param      newLength   the new length
   165      * @throws     IndexOutOfBoundsException  if the
   166      *               <code>newLength</code> argument is negative.
   167      */
   168     public void setLength(int newLength) {
   169         if (newLength < 0)
   170             throw new StringIndexOutOfBoundsException(newLength);
   171         ensureCapacityInternal(newLength);
   172 
   173         if (count < newLength) {
   174             for (; count < newLength; count++)
   175                 value[count] = '\0';
   176         } else {
   177             count = newLength;
   178         }
   179     }
   180 
   181     /**
   182      * Returns the <code>char</code> value in this sequence at the specified index.
   183      * The first <code>char</code> value is at index <code>0</code>, the next at index
   184      * <code>1</code>, and so on, as in array indexing.
   185      * <p>
   186      * The index argument must be greater than or equal to
   187      * <code>0</code>, and less than the length of this sequence.
   188      *
   189      * <p>If the <code>char</code> value specified by the index is a
   190      * <a href="Character.html#unicode">surrogate</a>, the surrogate
   191      * value is returned.
   192      *
   193      * @param      index   the index of the desired <code>char</code> value.
   194      * @return     the <code>char</code> value at the specified index.
   195      * @throws     IndexOutOfBoundsException  if <code>index</code> is
   196      *             negative or greater than or equal to <code>length()</code>.
   197      */
   198     public char charAt(int index) {
   199         if ((index < 0) || (index >= count))
   200             throw new StringIndexOutOfBoundsException(index);
   201         return value[index];
   202     }
   203 
   204     /**
   205      * Returns the character (Unicode code point) at the specified
   206      * index. The index refers to <code>char</code> values
   207      * (Unicode code units) and ranges from <code>0</code> to
   208      * {@link #length()}<code> - 1</code>.
   209      *
   210      * <p> If the <code>char</code> value specified at the given index
   211      * is in the high-surrogate range, the following index is less
   212      * than the length of this sequence, and the
   213      * <code>char</code> value at the following index is in the
   214      * low-surrogate range, then the supplementary code point
   215      * corresponding to this surrogate pair is returned. Otherwise,
   216      * the <code>char</code> value at the given index is returned.
   217      *
   218      * @param      index the index to the <code>char</code> values
   219      * @return     the code point value of the character at the
   220      *             <code>index</code>
   221      * @exception  IndexOutOfBoundsException  if the <code>index</code>
   222      *             argument is negative or not less than the length of this
   223      *             sequence.
   224      */
   225     public int codePointAt(int index) {
   226         if ((index < 0) || (index >= count)) {
   227             throw new StringIndexOutOfBoundsException(index);
   228         }
   229         return Character.codePointAt(value, index);
   230     }
   231 
   232     /**
   233      * Returns the character (Unicode code point) before the specified
   234      * index. The index refers to <code>char</code> values
   235      * (Unicode code units) and ranges from <code>1</code> to {@link
   236      * #length()}.
   237      *
   238      * <p> If the <code>char</code> value at <code>(index - 1)</code>
   239      * is in the low-surrogate range, <code>(index - 2)</code> is not
   240      * negative, and the <code>char</code> value at <code>(index -
   241      * 2)</code> is in the high-surrogate range, then the
   242      * supplementary code point value of the surrogate pair is
   243      * returned. If the <code>char</code> value at <code>index -
   244      * 1</code> is an unpaired low-surrogate or a high-surrogate, the
   245      * surrogate value is returned.
   246      *
   247      * @param     index the index following the code point that should be returned
   248      * @return    the Unicode code point value before the given index.
   249      * @exception IndexOutOfBoundsException if the <code>index</code>
   250      *            argument is less than 1 or greater than the length
   251      *            of this sequence.
   252      */
   253     public int codePointBefore(int index) {
   254         int i = index - 1;
   255         if ((i < 0) || (i >= count)) {
   256             throw new StringIndexOutOfBoundsException(index);
   257         }
   258         return Character.codePointBefore(value, index);
   259     }
   260 
   261     /**
   262      * Returns the number of Unicode code points in the specified text
   263      * range of this sequence. The text range begins at the specified
   264      * <code>beginIndex</code> and extends to the <code>char</code> at
   265      * index <code>endIndex - 1</code>. Thus the length (in
   266      * <code>char</code>s) of the text range is
   267      * <code>endIndex-beginIndex</code>. Unpaired surrogates within
   268      * this sequence count as one code point each.
   269      *
   270      * @param beginIndex the index to the first <code>char</code> of
   271      * the text range.
   272      * @param endIndex the index after the last <code>char</code> of
   273      * the text range.
   274      * @return the number of Unicode code points in the specified text
   275      * range
   276      * @exception IndexOutOfBoundsException if the
   277      * <code>beginIndex</code> is negative, or <code>endIndex</code>
   278      * is larger than the length of this sequence, or
   279      * <code>beginIndex</code> is larger than <code>endIndex</code>.
   280      */
   281     public int codePointCount(int beginIndex, int endIndex) {
   282         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
   283             throw new IndexOutOfBoundsException();
   284         }
   285         return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
   286     }
   287 
   288     /**
   289      * Returns the index within this sequence that is offset from the
   290      * given <code>index</code> by <code>codePointOffset</code> code
   291      * points. Unpaired surrogates within the text range given by
   292      * <code>index</code> and <code>codePointOffset</code> count as
   293      * one code point each.
   294      *
   295      * @param index the index to be offset
   296      * @param codePointOffset the offset in code points
   297      * @return the index within this sequence
   298      * @exception IndexOutOfBoundsException if <code>index</code>
   299      *   is negative or larger then the length of this sequence,
   300      *   or if <code>codePointOffset</code> is positive and the subsequence
   301      *   starting with <code>index</code> has fewer than
   302      *   <code>codePointOffset</code> code points,
   303      *   or if <code>codePointOffset</code> is negative and the subsequence
   304      *   before <code>index</code> has fewer than the absolute value of
   305      *   <code>codePointOffset</code> code points.
   306      */
   307     public int offsetByCodePoints(int index, int codePointOffset) {
   308         if (index < 0 || index > count) {
   309             throw new IndexOutOfBoundsException();
   310         }
   311         return Character.offsetByCodePointsImpl(value, 0, count,
   312                                                 index, codePointOffset);
   313     }
   314 
   315     /**
   316      * Characters are copied from this sequence into the
   317      * destination character array <code>dst</code>. The first character to
   318      * be copied is at index <code>srcBegin</code>; the last character to
   319      * be copied is at index <code>srcEnd-1</code>. The total number of
   320      * characters to be copied is <code>srcEnd-srcBegin</code>. The
   321      * characters are copied into the subarray of <code>dst</code> starting
   322      * at index <code>dstBegin</code> and ending at index:
   323      * <p><blockquote><pre>
   324      * dstbegin + (srcEnd-srcBegin) - 1
   325      * </pre></blockquote>
   326      *
   327      * @param      srcBegin   start copying at this offset.
   328      * @param      srcEnd     stop copying at this offset.
   329      * @param      dst        the array to copy the data into.
   330      * @param      dstBegin   offset into <code>dst</code>.
   331      * @throws     NullPointerException if <code>dst</code> is
   332      *             <code>null</code>.
   333      * @throws     IndexOutOfBoundsException  if any of the following is true:
   334      *             <ul>
   335      *             <li><code>srcBegin</code> is negative
   336      *             <li><code>dstBegin</code> is negative
   337      *             <li>the <code>srcBegin</code> argument is greater than
   338      *             the <code>srcEnd</code> argument.
   339      *             <li><code>srcEnd</code> is greater than
   340      *             <code>this.length()</code>.
   341      *             <li><code>dstBegin+srcEnd-srcBegin</code> is greater than
   342      *             <code>dst.length</code>
   343      *             </ul>
   344      */
   345     public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
   346     {
   347         if (srcBegin < 0)
   348             throw new StringIndexOutOfBoundsException(srcBegin);
   349         if ((srcEnd < 0) || (srcEnd > count))
   350             throw new StringIndexOutOfBoundsException(srcEnd);
   351         if (srcBegin > srcEnd)
   352             throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
   353         arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
   354     }
   355 
   356     /**
   357      * The character at the specified index is set to <code>ch</code>. This
   358      * sequence is altered to represent a new character sequence that is
   359      * identical to the old character sequence, except that it contains the
   360      * character <code>ch</code> at position <code>index</code>.
   361      * <p>
   362      * The index argument must be greater than or equal to
   363      * <code>0</code>, and less than the length of this sequence.
   364      *
   365      * @param      index   the index of the character to modify.
   366      * @param      ch      the new character.
   367      * @throws     IndexOutOfBoundsException  if <code>index</code> is
   368      *             negative or greater than or equal to <code>length()</code>.
   369      */
   370     public void setCharAt(int index, char ch) {
   371         if ((index < 0) || (index >= count))
   372             throw new StringIndexOutOfBoundsException(index);
   373         value[index] = ch;
   374     }
   375 
   376     /**
   377      * Appends the string representation of the {@code Object} argument.
   378      * <p>
   379      * The overall effect is exactly as if the argument were converted
   380      * to a string by the method {@link String#valueOf(Object)},
   381      * and the characters of that string were then
   382      * {@link #append(String) appended} to this character sequence.
   383      *
   384      * @param   obj   an {@code Object}.
   385      * @return  a reference to this object.
   386      */
   387     public AbstractStringBuilder append(Object obj) {
   388         return append(String.valueOf(obj));
   389     }
   390 
   391     /**
   392      * Appends the specified string to this character sequence.
   393      * <p>
   394      * The characters of the {@code String} argument are appended, in
   395      * order, increasing the length of this sequence by the length of the
   396      * argument. If {@code str} is {@code null}, then the four
   397      * characters {@code "null"} are appended.
   398      * <p>
   399      * Let <i>n</i> be the length of this character sequence just prior to
   400      * execution of the {@code append} method. Then the character at
   401      * index <i>k</i> in the new character sequence is equal to the character
   402      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
   403      * than <i>n</i>; otherwise, it is equal to the character at index
   404      * <i>k-n</i> in the argument {@code str}.
   405      *
   406      * @param   str   a string.
   407      * @return  a reference to this object.
   408      */
   409     public AbstractStringBuilder append(String str) {
   410         if (str == null) str = "null";
   411         int len = str.length();
   412         ensureCapacityInternal(count + len);
   413         str.getChars(0, len, value, count);
   414         count += len;
   415         return this;
   416     }
   417 
   418     // Documentation in subclasses because of synchro difference
   419     public AbstractStringBuilder append(StringBuffer sb) {
   420         if (sb == null)
   421             return append("null");
   422         int len = sb.length();
   423         ensureCapacityInternal(count + len);
   424         sb.getChars(0, len, value, count);
   425         count += len;
   426         return this;
   427     }
   428 
   429     // Documentation in subclasses because of synchro difference
   430     public AbstractStringBuilder append(CharSequence s) {
   431         if (s == null)
   432             s = "null";
   433         if (s instanceof String)
   434             return this.append((String)s);
   435         if (s instanceof StringBuffer)
   436             return this.append((StringBuffer)s);
   437         return this.append(s, 0, s.length());
   438     }
   439 
   440     /**
   441      * Appends a subsequence of the specified {@code CharSequence} to this
   442      * sequence.
   443      * <p>
   444      * Characters of the argument {@code s}, starting at
   445      * index {@code start}, are appended, in order, to the contents of
   446      * this sequence up to the (exclusive) index {@code end}. The length
   447      * of this sequence is increased by the value of {@code end - start}.
   448      * <p>
   449      * Let <i>n</i> be the length of this character sequence just prior to
   450      * execution of the {@code append} method. Then the character at
   451      * index <i>k</i> in this character sequence becomes equal to the
   452      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
   453      * <i>n</i>; otherwise, it is equal to the character at index
   454      * <i>k+start-n</i> in the argument {@code s}.
   455      * <p>
   456      * If {@code s} is {@code null}, then this method appends
   457      * characters as if the s parameter was a sequence containing the four
   458      * characters {@code "null"}.
   459      *
   460      * @param   s the sequence to append.
   461      * @param   start   the starting index of the subsequence to be appended.
   462      * @param   end     the end index of the subsequence to be appended.
   463      * @return  a reference to this object.
   464      * @throws     IndexOutOfBoundsException if
   465      *             {@code start} is negative, or
   466      *             {@code start} is greater than {@code end} or
   467      *             {@code end} is greater than {@code s.length()}
   468      */
   469     public AbstractStringBuilder append(CharSequence s, int start, int end) {
   470         if (s == null)
   471             s = "null";
   472         if ((start < 0) || (start > end) || (end > s.length()))
   473             throw new IndexOutOfBoundsException(
   474                 "start " + start + ", end " + end + ", s.length() "
   475                 + s.length());
   476         int len = end - start;
   477         ensureCapacityInternal(count + len);
   478         for (int i = start, j = count; i < end; i++, j++)
   479             value[j] = s.charAt(i);
   480         count += len;
   481         return this;
   482     }
   483 
   484     /**
   485      * Appends the string representation of the {@code char} array
   486      * argument to this sequence.
   487      * <p>
   488      * The characters of the array argument are appended, in order, to
   489      * the contents of this sequence. The length of this sequence
   490      * increases by the length of the argument.
   491      * <p>
   492      * The overall effect is exactly as if the argument were converted
   493      * to a string by the method {@link String#valueOf(char[])},
   494      * and the characters of that string were then
   495      * {@link #append(String) appended} to this character sequence.
   496      *
   497      * @param   str   the characters to be appended.
   498      * @return  a reference to this object.
   499      */
   500     public AbstractStringBuilder append(char[] str) {
   501         int len = str.length;
   502         ensureCapacityInternal(count + len);
   503         arraycopy(str, 0, value, count, len);
   504         count += len;
   505         return this;
   506     }
   507 
   508     /**
   509      * Appends the string representation of a subarray of the
   510      * {@code char} array argument to this sequence.
   511      * <p>
   512      * Characters of the {@code char} array {@code str}, starting at
   513      * index {@code offset}, are appended, in order, to the contents
   514      * of this sequence. The length of this sequence increases
   515      * by the value of {@code len}.
   516      * <p>
   517      * The overall effect is exactly as if the arguments were converted
   518      * to a string by the method {@link String#valueOf(char[],int,int)},
   519      * and the characters of that string were then
   520      * {@link #append(String) appended} to this character sequence.
   521      *
   522      * @param   str      the characters to be appended.
   523      * @param   offset   the index of the first {@code char} to append.
   524      * @param   len      the number of {@code char}s to append.
   525      * @return  a reference to this object.
   526      * @throws IndexOutOfBoundsException
   527      *         if {@code offset < 0} or {@code len < 0}
   528      *         or {@code offset+len > str.length}
   529      */
   530     public AbstractStringBuilder append(char str[], int offset, int len) {
   531         if (len > 0)                // let arraycopy report AIOOBE for len < 0
   532             ensureCapacityInternal(count + len);
   533         arraycopy(str, offset, value, count, len);
   534         count += len;
   535         return this;
   536     }
   537 
   538     /**
   539      * Appends the string representation of the {@code boolean}
   540      * argument to the sequence.
   541      * <p>
   542      * The overall effect is exactly as if the argument were converted
   543      * to a string by the method {@link String#valueOf(boolean)},
   544      * and the characters of that string were then
   545      * {@link #append(String) appended} to this character sequence.
   546      *
   547      * @param   b   a {@code boolean}.
   548      * @return  a reference to this object.
   549      */
   550     public AbstractStringBuilder append(boolean b) {
   551         if (b) {
   552             ensureCapacityInternal(count + 4);
   553             value[count++] = 't';
   554             value[count++] = 'r';
   555             value[count++] = 'u';
   556             value[count++] = 'e';
   557         } else {
   558             ensureCapacityInternal(count + 5);
   559             value[count++] = 'f';
   560             value[count++] = 'a';
   561             value[count++] = 'l';
   562             value[count++] = 's';
   563             value[count++] = 'e';
   564         }
   565         return this;
   566     }
   567 
   568     /**
   569      * Appends the string representation of the {@code char}
   570      * argument to this sequence.
   571      * <p>
   572      * The argument is appended to the contents of this sequence.
   573      * The length of this sequence increases by {@code 1}.
   574      * <p>
   575      * The overall effect is exactly as if the argument were converted
   576      * to a string by the method {@link String#valueOf(char)},
   577      * and the character in that string were then
   578      * {@link #append(String) appended} to this character sequence.
   579      *
   580      * @param   c   a {@code char}.
   581      * @return  a reference to this object.
   582      */
   583     public AbstractStringBuilder append(char c) {
   584         ensureCapacityInternal(count + 1);
   585         value[count++] = c;
   586         return this;
   587     }
   588 
   589     /**
   590      * Appends the string representation of the {@code int}
   591      * argument to this sequence.
   592      * <p>
   593      * The overall effect is exactly as if the argument were converted
   594      * to a string by the method {@link String#valueOf(int)},
   595      * and the characters of that string were then
   596      * {@link #append(String) appended} to this character sequence.
   597      *
   598      * @param   i   an {@code int}.
   599      * @return  a reference to this object.
   600      */
   601     public AbstractStringBuilder append(int i) {
   602         return append(Integer.toString(i));
   603     }
   604 
   605     /**
   606      * Appends the string representation of the {@code long}
   607      * argument to this sequence.
   608      * <p>
   609      * The overall effect is exactly as if the argument were converted
   610      * to a string by the method {@link String#valueOf(long)},
   611      * and the characters of that string were then
   612      * {@link #append(String) appended} to this character sequence.
   613      *
   614      * @param   l   a {@code long}.
   615      * @return  a reference to this object.
   616      */
   617     public AbstractStringBuilder append(long l) {
   618         if (l == Long.MIN_VALUE) {
   619             append("-9223372036854775808");
   620             return this;
   621         }
   622         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
   623                                      : Long.stringSize(l);
   624         int spaceNeeded = count + appendedLength;
   625         ensureCapacityInternal(spaceNeeded);
   626         Long.getChars(l, spaceNeeded, value);
   627         count = spaceNeeded;
   628         return this;
   629     }
   630 
   631     /**
   632      * Appends the string representation of the {@code float}
   633      * argument to this sequence.
   634      * <p>
   635      * The overall effect is exactly as if the argument were converted
   636      * to a string by the method {@link String#valueOf(float)},
   637      * and the characters of that string were then
   638      * {@link #append(String) appended} to this character sequence.
   639      *
   640      * @param   f   a {@code float}.
   641      * @return  a reference to this object.
   642      */
   643     public AbstractStringBuilder append(float f) {
   644         return append(Float.toString(f));
   645     }
   646 
   647     /**
   648      * Appends the string representation of the {@code double}
   649      * argument to this sequence.
   650      * <p>
   651      * The overall effect is exactly as if the argument were converted
   652      * to a string by the method {@link String#valueOf(double)},
   653      * and the characters of that string were then
   654      * {@link #append(String) appended} to this character sequence.
   655      *
   656      * @param   d   a {@code double}.
   657      * @return  a reference to this object.
   658      */
   659     public AbstractStringBuilder append(double d) {
   660         return append(Double.toString(d));
   661     }
   662 
   663     /**
   664      * Removes the characters in a substring of this sequence.
   665      * The substring begins at the specified {@code start} and extends to
   666      * the character at index {@code end - 1} or to the end of the
   667      * sequence if no such character exists. If
   668      * {@code start} is equal to {@code end}, no changes are made.
   669      *
   670      * @param      start  The beginning index, inclusive.
   671      * @param      end    The ending index, exclusive.
   672      * @return     This object.
   673      * @throws     StringIndexOutOfBoundsException  if {@code start}
   674      *             is negative, greater than {@code length()}, or
   675      *             greater than {@code end}.
   676      */
   677     public AbstractStringBuilder delete(int start, int end) {
   678         if (start < 0)
   679             throw new StringIndexOutOfBoundsException(start);
   680         if (end > count)
   681             end = count;
   682         if (start > end)
   683             throw new StringIndexOutOfBoundsException();
   684         int len = end - start;
   685         if (len > 0) {
   686             arraycopy(value, start+len, value, start, count-end);
   687             count -= len;
   688         }
   689         return this;
   690     }
   691 
   692     /**
   693      * Appends the string representation of the {@code codePoint}
   694      * argument to this sequence.
   695      *
   696      * <p> The argument is appended to the contents of this sequence.
   697      * The length of this sequence increases by
   698      * {@link Character#charCount(int) Character.charCount(codePoint)}.
   699      *
   700      * <p> The overall effect is exactly as if the argument were
   701      * converted to a {@code char} array by the method
   702      * {@link Character#toChars(int)} and the character in that array
   703      * were then {@link #append(char[]) appended} to this character
   704      * sequence.
   705      *
   706      * @param   codePoint   a Unicode code point
   707      * @return  a reference to this object.
   708      * @exception IllegalArgumentException if the specified
   709      * {@code codePoint} isn't a valid Unicode code point
   710      */
   711     public AbstractStringBuilder appendCodePoint(int codePoint) {
   712         final int count = this.count;
   713 
   714         if (Character.isBmpCodePoint(codePoint)) {
   715             ensureCapacityInternal(count + 1);
   716             value[count] = (char) codePoint;
   717             this.count = count + 1;
   718         } else if (Character.isValidCodePoint(codePoint)) {
   719             ensureCapacityInternal(count + 2);
   720             Character.toSurrogates(codePoint, value, count);
   721             this.count = count + 2;
   722         } else {
   723             throw new IllegalArgumentException();
   724         }
   725         return this;
   726     }
   727 
   728     /**
   729      * Removes the <code>char</code> at the specified position in this
   730      * sequence. This sequence is shortened by one <code>char</code>.
   731      *
   732      * <p>Note: If the character at the given index is a supplementary
   733      * character, this method does not remove the entire character. If
   734      * correct handling of supplementary characters is required,
   735      * determine the number of <code>char</code>s to remove by calling
   736      * <code>Character.charCount(thisSequence.codePointAt(index))</code>,
   737      * where <code>thisSequence</code> is this sequence.
   738      *
   739      * @param       index  Index of <code>char</code> to remove
   740      * @return      This object.
   741      * @throws      StringIndexOutOfBoundsException  if the <code>index</code>
   742      *              is negative or greater than or equal to
   743      *              <code>length()</code>.
   744      */
   745     public AbstractStringBuilder deleteCharAt(int index) {
   746         if ((index < 0) || (index >= count))
   747             throw new StringIndexOutOfBoundsException(index);
   748         arraycopy(value, index+1, value, index, count-index-1);
   749         count--;
   750         return this;
   751     }
   752 
   753     /**
   754      * Replaces the characters in a substring of this sequence
   755      * with characters in the specified <code>String</code>. The substring
   756      * begins at the specified <code>start</code> and extends to the character
   757      * at index <code>end - 1</code> or to the end of the
   758      * sequence if no such character exists. First the
   759      * characters in the substring are removed and then the specified
   760      * <code>String</code> is inserted at <code>start</code>. (This
   761      * sequence will be lengthened to accommodate the
   762      * specified String if necessary.)
   763      *
   764      * @param      start    The beginning index, inclusive.
   765      * @param      end      The ending index, exclusive.
   766      * @param      str   String that will replace previous contents.
   767      * @return     This object.
   768      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
   769      *             is negative, greater than <code>length()</code>, or
   770      *             greater than <code>end</code>.
   771      */
   772     public AbstractStringBuilder replace(int start, int end, String str) {
   773         if (start < 0)
   774             throw new StringIndexOutOfBoundsException(start);
   775         if (start > count)
   776             throw new StringIndexOutOfBoundsException("start > length()");
   777         if (start > end)
   778             throw new StringIndexOutOfBoundsException("start > end");
   779 
   780         if (end > count)
   781             end = count;
   782         int len = str.length();
   783         int newCount = count + len - (end - start);
   784         ensureCapacityInternal(newCount);
   785 
   786         arraycopy(value, end, value, start + len, count - end);
   787         str.getChars(value, start);
   788         count = newCount;
   789         return this;
   790     }
   791 
   792     /**
   793      * Returns a new <code>String</code> that contains a subsequence of
   794      * characters currently contained in this character sequence. The
   795      * substring begins at the specified index and extends to the end of
   796      * this sequence.
   797      *
   798      * @param      start    The beginning index, inclusive.
   799      * @return     The new string.
   800      * @throws     StringIndexOutOfBoundsException  if <code>start</code> is
   801      *             less than zero, or greater than the length of this object.
   802      */
   803     public String substring(int start) {
   804         return substring(start, count);
   805     }
   806 
   807     /**
   808      * Returns a new character sequence that is a subsequence of this sequence.
   809      *
   810      * <p> An invocation of this method of the form
   811      *
   812      * <blockquote><pre>
   813      * sb.subSequence(begin,&nbsp;end)</pre></blockquote>
   814      *
   815      * behaves in exactly the same way as the invocation
   816      *
   817      * <blockquote><pre>
   818      * sb.substring(begin,&nbsp;end)</pre></blockquote>
   819      *
   820      * This method is provided so that this class can
   821      * implement the {@link CharSequence} interface. </p>
   822      *
   823      * @param      start   the start index, inclusive.
   824      * @param      end     the end index, exclusive.
   825      * @return     the specified subsequence.
   826      *
   827      * @throws  IndexOutOfBoundsException
   828      *          if <tt>start</tt> or <tt>end</tt> are negative,
   829      *          if <tt>end</tt> is greater than <tt>length()</tt>,
   830      *          or if <tt>start</tt> is greater than <tt>end</tt>
   831      * @spec JSR-51
   832      */
   833     public CharSequence subSequence(int start, int end) {
   834         return substring(start, end);
   835     }
   836 
   837     /**
   838      * Returns a new <code>String</code> that contains a subsequence of
   839      * characters currently contained in this sequence. The
   840      * substring begins at the specified <code>start</code> and
   841      * extends to the character at index <code>end - 1</code>.
   842      *
   843      * @param      start    The beginning index, inclusive.
   844      * @param      end      The ending index, exclusive.
   845      * @return     The new string.
   846      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
   847      *             or <code>end</code> are negative or greater than
   848      *             <code>length()</code>, or <code>start</code> is
   849      *             greater than <code>end</code>.
   850      */
   851     public String substring(int start, int end) {
   852         if (start < 0)
   853             throw new StringIndexOutOfBoundsException(start);
   854         if (end > count)
   855             throw new StringIndexOutOfBoundsException(end);
   856         if (start > end)
   857             throw new StringIndexOutOfBoundsException(end - start);
   858         return new String(value, start, end - start);
   859     }
   860 
   861     /**
   862      * Inserts the string representation of a subarray of the {@code str}
   863      * array argument into this sequence. The subarray begins at the
   864      * specified {@code offset} and extends {@code len} {@code char}s.
   865      * The characters of the subarray are inserted into this sequence at
   866      * the position indicated by {@code index}. The length of this
   867      * sequence increases by {@code len} {@code char}s.
   868      *
   869      * @param      index    position at which to insert subarray.
   870      * @param      str       A {@code char} array.
   871      * @param      offset   the index of the first {@code char} in subarray to
   872      *             be inserted.
   873      * @param      len      the number of {@code char}s in the subarray to
   874      *             be inserted.
   875      * @return     This object
   876      * @throws     StringIndexOutOfBoundsException  if {@code index}
   877      *             is negative or greater than {@code length()}, or
   878      *             {@code offset} or {@code len} are negative, or
   879      *             {@code (offset+len)} is greater than
   880      *             {@code str.length}.
   881      */
   882     public AbstractStringBuilder insert(int index, char[] str, int offset,
   883                                         int len)
   884     {
   885         if ((index < 0) || (index > length()))
   886             throw new StringIndexOutOfBoundsException(index);
   887         if ((offset < 0) || (len < 0) || (offset > str.length - len))
   888             throw new StringIndexOutOfBoundsException(
   889                 "offset " + offset + ", len " + len + ", str.length "
   890                 + str.length);
   891         ensureCapacityInternal(count + len);
   892         arraycopy(value, index, value, index + len, count - index);
   893         arraycopy(str, offset, value, index, len);
   894         count += len;
   895         return this;
   896     }
   897 
   898     /**
   899      * Inserts the string representation of the {@code Object}
   900      * argument into this character sequence.
   901      * <p>
   902      * The overall effect is exactly as if the second argument were
   903      * converted to a string by the method {@link String#valueOf(Object)},
   904      * and the characters of that string were then
   905      * {@link #insert(int,String) inserted} into this character
   906      * sequence at the indicated offset.
   907      * <p>
   908      * The {@code offset} argument must be greater than or equal to
   909      * {@code 0}, and less than or equal to the {@linkplain #length() length}
   910      * of this sequence.
   911      *
   912      * @param      offset   the offset.
   913      * @param      obj      an {@code Object}.
   914      * @return     a reference to this object.
   915      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
   916      */
   917     public AbstractStringBuilder insert(int offset, Object obj) {
   918         return insert(offset, String.valueOf(obj));
   919     }
   920 
   921     /**
   922      * Inserts the string into this character sequence.
   923      * <p>
   924      * The characters of the {@code String} argument are inserted, in
   925      * order, into this sequence at the indicated offset, moving up any
   926      * characters originally above that position and increasing the length
   927      * of this sequence by the length of the argument. If
   928      * {@code str} is {@code null}, then the four characters
   929      * {@code "null"} are inserted into this sequence.
   930      * <p>
   931      * The character at index <i>k</i> in the new character sequence is
   932      * equal to:
   933      * <ul>
   934      * <li>the character at index <i>k</i> in the old character sequence, if
   935      * <i>k</i> is less than {@code offset}
   936      * <li>the character at index <i>k</i>{@code -offset} in the
   937      * argument {@code str}, if <i>k</i> is not less than
   938      * {@code offset} but is less than {@code offset+str.length()}
   939      * <li>the character at index <i>k</i>{@code -str.length()} in the
   940      * old character sequence, if <i>k</i> is not less than
   941      * {@code offset+str.length()}
   942      * </ul><p>
   943      * The {@code offset} argument must be greater than or equal to
   944      * {@code 0}, and less than or equal to the {@linkplain #length() length}
   945      * of this sequence.
   946      *
   947      * @param      offset   the offset.
   948      * @param      str      a string.
   949      * @return     a reference to this object.
   950      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
   951      */
   952     public AbstractStringBuilder insert(int offset, String str) {
   953         if ((offset < 0) || (offset > length()))
   954             throw new StringIndexOutOfBoundsException(offset);
   955         if (str == null)
   956             str = "null";
   957         int len = str.length();
   958         ensureCapacityInternal(count + len);
   959         arraycopy(value, offset, value, offset + len, count - offset);
   960         str.getChars(value, offset);
   961         count += len;
   962         return this;
   963     }
   964 
   965     /**
   966      * Inserts the string representation of the {@code char} array
   967      * argument into this sequence.
   968      * <p>
   969      * The characters of the array argument are inserted into the
   970      * contents of this sequence at the position indicated by
   971      * {@code offset}. The length of this sequence increases by
   972      * the length of the argument.
   973      * <p>
   974      * The overall effect is exactly as if the second argument were
   975      * converted to a string by the method {@link String#valueOf(char[])},
   976      * and the characters of that string were then
   977      * {@link #insert(int,String) inserted} into this character
   978      * sequence at the indicated offset.
   979      * <p>
   980      * The {@code offset} argument must be greater than or equal to
   981      * {@code 0}, and less than or equal to the {@linkplain #length() length}
   982      * of this sequence.
   983      *
   984      * @param      offset   the offset.
   985      * @param      str      a character array.
   986      * @return     a reference to this object.
   987      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
   988      */
   989     public AbstractStringBuilder insert(int offset, char[] str) {
   990         if ((offset < 0) || (offset > length()))
   991             throw new StringIndexOutOfBoundsException(offset);
   992         int len = str.length;
   993         ensureCapacityInternal(count + len);
   994         arraycopy(value, offset, value, offset + len, count - offset);
   995         arraycopy(str, 0, value, offset, len);
   996         count += len;
   997         return this;
   998     }
   999 
  1000     /**
  1001      * Inserts the specified {@code CharSequence} into this sequence.
  1002      * <p>
  1003      * The characters of the {@code CharSequence} argument are inserted,
  1004      * in order, into this sequence at the indicated offset, moving up
  1005      * any characters originally above that position and increasing the length
  1006      * of this sequence by the length of the argument s.
  1007      * <p>
  1008      * The result of this method is exactly the same as if it were an
  1009      * invocation of this object's
  1010      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
  1011      * method.
  1012      *
  1013      * <p>If {@code s} is {@code null}, then the four characters
  1014      * {@code "null"} are inserted into this sequence.
  1015      *
  1016      * @param      dstOffset   the offset.
  1017      * @param      s the sequence to be inserted
  1018      * @return     a reference to this object.
  1019      * @throws     IndexOutOfBoundsException  if the offset is invalid.
  1020      */
  1021     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
  1022         if (s == null)
  1023             s = "null";
  1024         if (s instanceof String)
  1025             return this.insert(dstOffset, (String)s);
  1026         return this.insert(dstOffset, s, 0, s.length());
  1027     }
  1028 
  1029     /**
  1030      * Inserts a subsequence of the specified {@code CharSequence} into
  1031      * this sequence.
  1032      * <p>
  1033      * The subsequence of the argument {@code s} specified by
  1034      * {@code start} and {@code end} are inserted,
  1035      * in order, into this sequence at the specified destination offset, moving
  1036      * up any characters originally above that position. The length of this
  1037      * sequence is increased by {@code end - start}.
  1038      * <p>
  1039      * The character at index <i>k</i> in this sequence becomes equal to:
  1040      * <ul>
  1041      * <li>the character at index <i>k</i> in this sequence, if
  1042      * <i>k</i> is less than {@code dstOffset}
  1043      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
  1044      * the argument {@code s}, if <i>k</i> is greater than or equal to
  1045      * {@code dstOffset} but is less than {@code dstOffset+end-start}
  1046      * <li>the character at index <i>k</i>{@code -(end-start)} in this
  1047      * sequence, if <i>k</i> is greater than or equal to
  1048      * {@code dstOffset+end-start}
  1049      * </ul><p>
  1050      * The {@code dstOffset} argument must be greater than or equal to
  1051      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1052      * of this sequence.
  1053      * <p>The start argument must be nonnegative, and not greater than
  1054      * {@code end}.
  1055      * <p>The end argument must be greater than or equal to
  1056      * {@code start}, and less than or equal to the length of s.
  1057      *
  1058      * <p>If {@code s} is {@code null}, then this method inserts
  1059      * characters as if the s parameter was a sequence containing the four
  1060      * characters {@code "null"}.
  1061      *
  1062      * @param      dstOffset   the offset in this sequence.
  1063      * @param      s       the sequence to be inserted.
  1064      * @param      start   the starting index of the subsequence to be inserted.
  1065      * @param      end     the end index of the subsequence to be inserted.
  1066      * @return     a reference to this object.
  1067      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
  1068      *             is negative or greater than {@code this.length()}, or
  1069      *              {@code start} or {@code end} are negative, or
  1070      *              {@code start} is greater than {@code end} or
  1071      *              {@code end} is greater than {@code s.length()}
  1072      */
  1073      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
  1074                                          int start, int end) {
  1075         if (s == null)
  1076             s = "null";
  1077         if ((dstOffset < 0) || (dstOffset > this.length()))
  1078             throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
  1079         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
  1080             throw new IndexOutOfBoundsException(
  1081                 "start " + start + ", end " + end + ", s.length() "
  1082                 + s.length());
  1083         int len = end - start;
  1084         ensureCapacityInternal(count + len);
  1085         arraycopy(value, dstOffset, value, dstOffset + len,
  1086                          count - dstOffset);
  1087         for (int i=start; i<end; i++)
  1088             value[dstOffset++] = s.charAt(i);
  1089         count += len;
  1090         return this;
  1091     }
  1092 
  1093     /**
  1094      * Inserts the string representation of the {@code boolean}
  1095      * argument into this sequence.
  1096      * <p>
  1097      * The overall effect is exactly as if the second argument were
  1098      * converted to a string by the method {@link String#valueOf(boolean)},
  1099      * and the characters of that string were then
  1100      * {@link #insert(int,String) inserted} into this character
  1101      * sequence at the indicated offset.
  1102      * <p>
  1103      * The {@code offset} argument must be greater than or equal to
  1104      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1105      * of this sequence.
  1106      *
  1107      * @param      offset   the offset.
  1108      * @param      b        a {@code boolean}.
  1109      * @return     a reference to this object.
  1110      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1111      */
  1112     public AbstractStringBuilder insert(int offset, boolean b) {
  1113         return insert(offset, String.valueOf(b));
  1114     }
  1115 
  1116     /**
  1117      * Inserts the string representation of the {@code char}
  1118      * argument into this sequence.
  1119      * <p>
  1120      * The overall effect is exactly as if the second argument were
  1121      * converted to a string by the method {@link String#valueOf(char)},
  1122      * and the character in that string were then
  1123      * {@link #insert(int,String) inserted} into this character
  1124      * sequence at the indicated offset.
  1125      * <p>
  1126      * The {@code offset} argument must be greater than or equal to
  1127      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1128      * of this sequence.
  1129      *
  1130      * @param      offset   the offset.
  1131      * @param      c        a {@code char}.
  1132      * @return     a reference to this object.
  1133      * @throws     IndexOutOfBoundsException  if the offset is invalid.
  1134      */
  1135     public AbstractStringBuilder insert(int offset, char c) {
  1136         ensureCapacityInternal(count + 1);
  1137         arraycopy(value, offset, value, offset + 1, count - offset);
  1138         value[offset] = c;
  1139         count += 1;
  1140         return this;
  1141     }
  1142 
  1143     /**
  1144      * Inserts the string representation of the second {@code int}
  1145      * argument into this sequence.
  1146      * <p>
  1147      * The overall effect is exactly as if the second argument were
  1148      * converted to a string by the method {@link String#valueOf(int)},
  1149      * and the characters of that string were then
  1150      * {@link #insert(int,String) inserted} into this character
  1151      * sequence at the indicated offset.
  1152      * <p>
  1153      * The {@code offset} argument must be greater than or equal to
  1154      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1155      * of this sequence.
  1156      *
  1157      * @param      offset   the offset.
  1158      * @param      i        an {@code int}.
  1159      * @return     a reference to this object.
  1160      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1161      */
  1162     public AbstractStringBuilder insert(int offset, int i) {
  1163         return insert(offset, String.valueOf(i));
  1164     }
  1165 
  1166     /**
  1167      * Inserts the string representation of the {@code long}
  1168      * argument into this sequence.
  1169      * <p>
  1170      * The overall effect is exactly as if the second argument were
  1171      * converted to a string by the method {@link String#valueOf(long)},
  1172      * and the characters of that string were then
  1173      * {@link #insert(int,String) inserted} into this character
  1174      * sequence at the indicated offset.
  1175      * <p>
  1176      * The {@code offset} argument must be greater than or equal to
  1177      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1178      * of this sequence.
  1179      *
  1180      * @param      offset   the offset.
  1181      * @param      l        a {@code long}.
  1182      * @return     a reference to this object.
  1183      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1184      */
  1185     public AbstractStringBuilder insert(int offset, long l) {
  1186         return insert(offset, String.valueOf(l));
  1187     }
  1188 
  1189     /**
  1190      * Inserts the string representation of the {@code float}
  1191      * argument into this sequence.
  1192      * <p>
  1193      * The overall effect is exactly as if the second argument were
  1194      * converted to a string by the method {@link String#valueOf(float)},
  1195      * and the characters of that string were then
  1196      * {@link #insert(int,String) inserted} into this character
  1197      * sequence at the indicated offset.
  1198      * <p>
  1199      * The {@code offset} argument must be greater than or equal to
  1200      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1201      * of this sequence.
  1202      *
  1203      * @param      offset   the offset.
  1204      * @param      f        a {@code float}.
  1205      * @return     a reference to this object.
  1206      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1207      */
  1208     public AbstractStringBuilder insert(int offset, float f) {
  1209         return insert(offset, String.valueOf(f));
  1210     }
  1211 
  1212     /**
  1213      * Inserts the string representation of the {@code double}
  1214      * argument into this sequence.
  1215      * <p>
  1216      * The overall effect is exactly as if the second argument were
  1217      * converted to a string by the method {@link String#valueOf(double)},
  1218      * and the characters of that string were then
  1219      * {@link #insert(int,String) inserted} into this character
  1220      * sequence at the indicated offset.
  1221      * <p>
  1222      * The {@code offset} argument must be greater than or equal to
  1223      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1224      * of this sequence.
  1225      *
  1226      * @param      offset   the offset.
  1227      * @param      d        a {@code double}.
  1228      * @return     a reference to this object.
  1229      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1230      */
  1231     public AbstractStringBuilder insert(int offset, double d) {
  1232         return insert(offset, String.valueOf(d));
  1233     }
  1234 
  1235     /**
  1236      * Returns the index within this string of the first occurrence of the
  1237      * specified substring. The integer returned is the smallest value
  1238      * <i>k</i> such that:
  1239      * <blockquote><pre>
  1240      * this.toString().startsWith(str, <i>k</i>)
  1241      * </pre></blockquote>
  1242      * is <code>true</code>.
  1243      *
  1244      * @param   str   any string.
  1245      * @return  if the string argument occurs as a substring within this
  1246      *          object, then the index of the first character of the first
  1247      *          such substring is returned; if it does not occur as a
  1248      *          substring, <code>-1</code> is returned.
  1249      * @throws  java.lang.NullPointerException if <code>str</code> is
  1250      *          <code>null</code>.
  1251      */
  1252     public int indexOf(String str) {
  1253         return indexOf(str, 0);
  1254     }
  1255 
  1256     /**
  1257      * Returns the index within this string of the first occurrence of the
  1258      * specified substring, starting at the specified index.  The integer
  1259      * returned is the smallest value <tt>k</tt> for which:
  1260      * <blockquote><pre>
  1261      *     k >= Math.min(fromIndex, str.length()) &&
  1262      *                   this.toString().startsWith(str, k)
  1263      * </pre></blockquote>
  1264      * If no such value of <i>k</i> exists, then -1 is returned.
  1265      *
  1266      * @param   str         the substring for which to search.
  1267      * @param   fromIndex   the index from which to start the search.
  1268      * @return  the index within this string of the first occurrence of the
  1269      *          specified substring, starting at the specified index.
  1270      * @throws  java.lang.NullPointerException if <code>str</code> is
  1271      *            <code>null</code>.
  1272      */
  1273     public int indexOf(String str, int fromIndex) {
  1274         return toString().indexOf(str, fromIndex);
  1275     }
  1276 
  1277     /**
  1278      * Returns the index within this string of the rightmost occurrence
  1279      * of the specified substring.  The rightmost empty string "" is
  1280      * considered to occur at the index value <code>this.length()</code>.
  1281      * The returned index is the largest value <i>k</i> such that
  1282      * <blockquote><pre>
  1283      * this.toString().startsWith(str, k)
  1284      * </pre></blockquote>
  1285      * is true.
  1286      *
  1287      * @param   str   the substring to search for.
  1288      * @return  if the string argument occurs one or more times as a substring
  1289      *          within this object, then the index of the first character of
  1290      *          the last such substring is returned. If it does not occur as
  1291      *          a substring, <code>-1</code> is returned.
  1292      * @throws  java.lang.NullPointerException  if <code>str</code> is
  1293      *          <code>null</code>.
  1294      */
  1295     public int lastIndexOf(String str) {
  1296         return lastIndexOf(str, count);
  1297     }
  1298 
  1299     /**
  1300      * Returns the index within this string of the last occurrence of the
  1301      * specified substring. The integer returned is the largest value <i>k</i>
  1302      * such that:
  1303      * <blockquote><pre>
  1304      *     k <= Math.min(fromIndex, str.length()) &&
  1305      *                   this.toString().startsWith(str, k)
  1306      * </pre></blockquote>
  1307      * If no such value of <i>k</i> exists, then -1 is returned.
  1308      *
  1309      * @param   str         the substring to search for.
  1310      * @param   fromIndex   the index to start the search from.
  1311      * @return  the index within this sequence of the last occurrence of the
  1312      *          specified substring.
  1313      * @throws  java.lang.NullPointerException if <code>str</code> is
  1314      *          <code>null</code>.
  1315      */
  1316     public int lastIndexOf(String str, int fromIndex) {
  1317         return String.lastIndexOf(value, 0, count,
  1318                               str.toCharArray(), 0, str.length(), fromIndex);
  1319     }
  1320 
  1321     /**
  1322      * Causes this character sequence to be replaced by the reverse of
  1323      * the sequence. If there are any surrogate pairs included in the
  1324      * sequence, these are treated as single characters for the
  1325      * reverse operation. Thus, the order of the high-low surrogates
  1326      * is never reversed.
  1327      *
  1328      * Let <i>n</i> be the character length of this character sequence
  1329      * (not the length in <code>char</code> values) just prior to
  1330      * execution of the <code>reverse</code> method. Then the
  1331      * character at index <i>k</i> in the new character sequence is
  1332      * equal to the character at index <i>n-k-1</i> in the old
  1333      * character sequence.
  1334      *
  1335      * <p>Note that the reverse operation may result in producing
  1336      * surrogate pairs that were unpaired low-surrogates and
  1337      * high-surrogates before the operation. For example, reversing
  1338      * "&#92;uDC00&#92;uD800" produces "&#92;uD800&#92;uDC00" which is
  1339      * a valid surrogate pair.
  1340      *
  1341      * @return  a reference to this object.
  1342      */
  1343     public AbstractStringBuilder reverse() {
  1344         boolean hasSurrogate = false;
  1345         int n = count - 1;
  1346         for (int j = (n-1) >> 1; j >= 0; --j) {
  1347             char temp = value[j];
  1348             char temp2 = value[n - j];
  1349             if (!hasSurrogate) {
  1350                 hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
  1351                     || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
  1352             }
  1353             value[j] = temp2;
  1354             value[n - j] = temp;
  1355         }
  1356         if (hasSurrogate) {
  1357             // Reverse back all valid surrogate pairs
  1358             for (int i = 0; i < count - 1; i++) {
  1359                 char c2 = value[i];
  1360                 if (Character.isLowSurrogate(c2)) {
  1361                     char c1 = value[i + 1];
  1362                     if (Character.isHighSurrogate(c1)) {
  1363                         value[i++] = c1;
  1364                         value[i] = c2;
  1365                     }
  1366                 }
  1367             }
  1368         }
  1369         return this;
  1370     }
  1371 
  1372     /**
  1373      * Returns a string representing the data in this sequence.
  1374      * A new <code>String</code> object is allocated and initialized to
  1375      * contain the character sequence currently represented by this
  1376      * object. This <code>String</code> is then returned. Subsequent
  1377      * changes to this sequence do not affect the contents of the
  1378      * <code>String</code>.
  1379      *
  1380      * @return  a string representation of this sequence of characters.
  1381      */
  1382     public abstract String toString();
  1383 
  1384     /**
  1385      * Needed by <tt>String</tt> for the contentEquals method.
  1386      */
  1387     final char[] getValue() {
  1388         return value;
  1389     }
  1390 
  1391     static char[] copyOfRange(char[] original, int from, int to) {
  1392         int newLength = to - from;
  1393         if (newLength < 0) {
  1394             throw new IllegalArgumentException(from + " > " + to);
  1395         }
  1396         char[] copy = new char[newLength];
  1397         arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
  1398         return copy;
  1399     }
  1400 
  1401     static void arraycopy(char[] value, int srcBegin, char[] dst, int dstBegin, int count) {
  1402         if (srcBegin < dstBegin) {
  1403             while (count-- > 0) {
  1404                 dst[dstBegin + count] = value[srcBegin + count];
  1405             }
  1406         } else {
  1407             while (count-- > 0) {
  1408                 dst[dstBegin++] = value[srcBegin++];
  1409             }
  1410         }
  1411     }
  1412 
  1413     // access system property
  1414     static String getProperty(String nm) {
  1415         return null;
  1416     }
  1417 
  1418     static char[] copyOf(char[] original, int newLength) {
  1419         char[] copy = new char[newLength];
  1420         arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
  1421         return copy;
  1422     }
  1423     
  1424 }