emul/src/main/java/java/lang/AbstractStringBuilder.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 30 Sep 2012 17:10:32 -0700
branchemul
changeset 72 06bd18f34608
parent 61 4b334950499d
child 94 19497b4312bb
permissions -rw-r--r--
Centralize all calls to System.arraycopy under one method in String
     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 = String.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 = String.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         String.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         String.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         String.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         if (i == Integer.MIN_VALUE) {
   603             append("-2147483648");
   604             return this;
   605         }
   606         int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
   607                                      : Integer.stringSize(i);
   608         int spaceNeeded = count + appendedLength;
   609         ensureCapacityInternal(spaceNeeded);
   610         Integer.getChars(i, spaceNeeded, value);
   611         count = spaceNeeded;
   612         return this;
   613     }
   614 
   615     /**
   616      * Appends the string representation of the {@code long}
   617      * argument to this sequence.
   618      * <p>
   619      * The overall effect is exactly as if the argument were converted
   620      * to a string by the method {@link String#valueOf(long)},
   621      * and the characters of that string were then
   622      * {@link #append(String) appended} to this character sequence.
   623      *
   624      * @param   l   a {@code long}.
   625      * @return  a reference to this object.
   626      */
   627     public AbstractStringBuilder append(long l) {
   628         if (l == Long.MIN_VALUE) {
   629             append("-9223372036854775808");
   630             return this;
   631         }
   632         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
   633                                      : Long.stringSize(l);
   634         int spaceNeeded = count + appendedLength;
   635         ensureCapacityInternal(spaceNeeded);
   636         Long.getChars(l, spaceNeeded, value);
   637         count = spaceNeeded;
   638         return this;
   639     }
   640 
   641     /**
   642      * Appends the string representation of the {@code float}
   643      * argument to this sequence.
   644      * <p>
   645      * The overall effect is exactly as if the argument were converted
   646      * to a string by the method {@link String#valueOf(float)},
   647      * and the characters of that string were then
   648      * {@link #append(String) appended} to this character sequence.
   649      *
   650      * @param   f   a {@code float}.
   651      * @return  a reference to this object.
   652      */
   653     public AbstractStringBuilder append(float f) {
   654         throw new UnsupportedOperationException();
   655     }
   656 
   657     /**
   658      * Appends the string representation of the {@code double}
   659      * argument to this sequence.
   660      * <p>
   661      * The overall effect is exactly as if the argument were converted
   662      * to a string by the method {@link String#valueOf(double)},
   663      * and the characters of that string were then
   664      * {@link #append(String) appended} to this character sequence.
   665      *
   666      * @param   d   a {@code double}.
   667      * @return  a reference to this object.
   668      */
   669     public AbstractStringBuilder append(double d) {
   670         throw new UnsupportedOperationException();
   671     }
   672 
   673     /**
   674      * Removes the characters in a substring of this sequence.
   675      * The substring begins at the specified {@code start} and extends to
   676      * the character at index {@code end - 1} or to the end of the
   677      * sequence if no such character exists. If
   678      * {@code start} is equal to {@code end}, no changes are made.
   679      *
   680      * @param      start  The beginning index, inclusive.
   681      * @param      end    The ending index, exclusive.
   682      * @return     This object.
   683      * @throws     StringIndexOutOfBoundsException  if {@code start}
   684      *             is negative, greater than {@code length()}, or
   685      *             greater than {@code end}.
   686      */
   687     public AbstractStringBuilder delete(int start, int end) {
   688         if (start < 0)
   689             throw new StringIndexOutOfBoundsException(start);
   690         if (end > count)
   691             end = count;
   692         if (start > end)
   693             throw new StringIndexOutOfBoundsException();
   694         int len = end - start;
   695         if (len > 0) {
   696             String.arraycopy(value, start+len, value, start, count-end);
   697             count -= len;
   698         }
   699         return this;
   700     }
   701 
   702     /**
   703      * Appends the string representation of the {@code codePoint}
   704      * argument to this sequence.
   705      *
   706      * <p> The argument is appended to the contents of this sequence.
   707      * The length of this sequence increases by
   708      * {@link Character#charCount(int) Character.charCount(codePoint)}.
   709      *
   710      * <p> The overall effect is exactly as if the argument were
   711      * converted to a {@code char} array by the method
   712      * {@link Character#toChars(int)} and the character in that array
   713      * were then {@link #append(char[]) appended} to this character
   714      * sequence.
   715      *
   716      * @param   codePoint   a Unicode code point
   717      * @return  a reference to this object.
   718      * @exception IllegalArgumentException if the specified
   719      * {@code codePoint} isn't a valid Unicode code point
   720      */
   721     public AbstractStringBuilder appendCodePoint(int codePoint) {
   722         final int count = this.count;
   723 
   724         if (Character.isBmpCodePoint(codePoint)) {
   725             ensureCapacityInternal(count + 1);
   726             value[count] = (char) codePoint;
   727             this.count = count + 1;
   728         } else if (Character.isValidCodePoint(codePoint)) {
   729             ensureCapacityInternal(count + 2);
   730             Character.toSurrogates(codePoint, value, count);
   731             this.count = count + 2;
   732         } else {
   733             throw new IllegalArgumentException();
   734         }
   735         return this;
   736     }
   737 
   738     /**
   739      * Removes the <code>char</code> at the specified position in this
   740      * sequence. This sequence is shortened by one <code>char</code>.
   741      *
   742      * <p>Note: If the character at the given index is a supplementary
   743      * character, this method does not remove the entire character. If
   744      * correct handling of supplementary characters is required,
   745      * determine the number of <code>char</code>s to remove by calling
   746      * <code>Character.charCount(thisSequence.codePointAt(index))</code>,
   747      * where <code>thisSequence</code> is this sequence.
   748      *
   749      * @param       index  Index of <code>char</code> to remove
   750      * @return      This object.
   751      * @throws      StringIndexOutOfBoundsException  if the <code>index</code>
   752      *              is negative or greater than or equal to
   753      *              <code>length()</code>.
   754      */
   755     public AbstractStringBuilder deleteCharAt(int index) {
   756         if ((index < 0) || (index >= count))
   757             throw new StringIndexOutOfBoundsException(index);
   758         String.arraycopy(value, index+1, value, index, count-index-1);
   759         count--;
   760         return this;
   761     }
   762 
   763     /**
   764      * Replaces the characters in a substring of this sequence
   765      * with characters in the specified <code>String</code>. The substring
   766      * begins at the specified <code>start</code> and extends to the character
   767      * at index <code>end - 1</code> or to the end of the
   768      * sequence if no such character exists. First the
   769      * characters in the substring are removed and then the specified
   770      * <code>String</code> is inserted at <code>start</code>. (This
   771      * sequence will be lengthened to accommodate the
   772      * specified String if necessary.)
   773      *
   774      * @param      start    The beginning index, inclusive.
   775      * @param      end      The ending index, exclusive.
   776      * @param      str   String that will replace previous contents.
   777      * @return     This object.
   778      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
   779      *             is negative, greater than <code>length()</code>, or
   780      *             greater than <code>end</code>.
   781      */
   782     public AbstractStringBuilder replace(int start, int end, String str) {
   783         if (start < 0)
   784             throw new StringIndexOutOfBoundsException(start);
   785         if (start > count)
   786             throw new StringIndexOutOfBoundsException("start > length()");
   787         if (start > end)
   788             throw new StringIndexOutOfBoundsException("start > end");
   789 
   790         if (end > count)
   791             end = count;
   792         int len = str.length();
   793         int newCount = count + len - (end - start);
   794         ensureCapacityInternal(newCount);
   795 
   796         String.arraycopy(value, end, value, start + len, count - end);
   797         str.getChars(value, start);
   798         count = newCount;
   799         return this;
   800     }
   801 
   802     /**
   803      * Returns a new <code>String</code> that contains a subsequence of
   804      * characters currently contained in this character sequence. The
   805      * substring begins at the specified index and extends to the end of
   806      * this sequence.
   807      *
   808      * @param      start    The beginning index, inclusive.
   809      * @return     The new string.
   810      * @throws     StringIndexOutOfBoundsException  if <code>start</code> is
   811      *             less than zero, or greater than the length of this object.
   812      */
   813     public String substring(int start) {
   814         return substring(start, count);
   815     }
   816 
   817     /**
   818      * Returns a new character sequence that is a subsequence of this sequence.
   819      *
   820      * <p> An invocation of this method of the form
   821      *
   822      * <blockquote><pre>
   823      * sb.subSequence(begin,&nbsp;end)</pre></blockquote>
   824      *
   825      * behaves in exactly the same way as the invocation
   826      *
   827      * <blockquote><pre>
   828      * sb.substring(begin,&nbsp;end)</pre></blockquote>
   829      *
   830      * This method is provided so that this class can
   831      * implement the {@link CharSequence} interface. </p>
   832      *
   833      * @param      start   the start index, inclusive.
   834      * @param      end     the end index, exclusive.
   835      * @return     the specified subsequence.
   836      *
   837      * @throws  IndexOutOfBoundsException
   838      *          if <tt>start</tt> or <tt>end</tt> are negative,
   839      *          if <tt>end</tt> is greater than <tt>length()</tt>,
   840      *          or if <tt>start</tt> is greater than <tt>end</tt>
   841      * @spec JSR-51
   842      */
   843     public CharSequence subSequence(int start, int end) {
   844         return substring(start, end);
   845     }
   846 
   847     /**
   848      * Returns a new <code>String</code> that contains a subsequence of
   849      * characters currently contained in this sequence. The
   850      * substring begins at the specified <code>start</code> and
   851      * extends to the character at index <code>end - 1</code>.
   852      *
   853      * @param      start    The beginning index, inclusive.
   854      * @param      end      The ending index, exclusive.
   855      * @return     The new string.
   856      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
   857      *             or <code>end</code> are negative or greater than
   858      *             <code>length()</code>, or <code>start</code> is
   859      *             greater than <code>end</code>.
   860      */
   861     public String substring(int start, int end) {
   862         if (start < 0)
   863             throw new StringIndexOutOfBoundsException(start);
   864         if (end > count)
   865             throw new StringIndexOutOfBoundsException(end);
   866         if (start > end)
   867             throw new StringIndexOutOfBoundsException(end - start);
   868         return new String(value, start, end - start);
   869     }
   870 
   871     /**
   872      * Inserts the string representation of a subarray of the {@code str}
   873      * array argument into this sequence. The subarray begins at the
   874      * specified {@code offset} and extends {@code len} {@code char}s.
   875      * The characters of the subarray are inserted into this sequence at
   876      * the position indicated by {@code index}. The length of this
   877      * sequence increases by {@code len} {@code char}s.
   878      *
   879      * @param      index    position at which to insert subarray.
   880      * @param      str       A {@code char} array.
   881      * @param      offset   the index of the first {@code char} in subarray to
   882      *             be inserted.
   883      * @param      len      the number of {@code char}s in the subarray to
   884      *             be inserted.
   885      * @return     This object
   886      * @throws     StringIndexOutOfBoundsException  if {@code index}
   887      *             is negative or greater than {@code length()}, or
   888      *             {@code offset} or {@code len} are negative, or
   889      *             {@code (offset+len)} is greater than
   890      *             {@code str.length}.
   891      */
   892     public AbstractStringBuilder insert(int index, char[] str, int offset,
   893                                         int len)
   894     {
   895         if ((index < 0) || (index > length()))
   896             throw new StringIndexOutOfBoundsException(index);
   897         if ((offset < 0) || (len < 0) || (offset > str.length - len))
   898             throw new StringIndexOutOfBoundsException(
   899                 "offset " + offset + ", len " + len + ", str.length "
   900                 + str.length);
   901         ensureCapacityInternal(count + len);
   902         String.arraycopy(value, index, value, index + len, count - index);
   903         String.arraycopy(str, offset, value, index, len);
   904         count += len;
   905         return this;
   906     }
   907 
   908     /**
   909      * Inserts the string representation of the {@code Object}
   910      * argument into this character sequence.
   911      * <p>
   912      * The overall effect is exactly as if the second argument were
   913      * converted to a string by the method {@link String#valueOf(Object)},
   914      * and the characters of that string were then
   915      * {@link #insert(int,String) inserted} into this character
   916      * sequence at the indicated offset.
   917      * <p>
   918      * The {@code offset} argument must be greater than or equal to
   919      * {@code 0}, and less than or equal to the {@linkplain #length() length}
   920      * of this sequence.
   921      *
   922      * @param      offset   the offset.
   923      * @param      obj      an {@code Object}.
   924      * @return     a reference to this object.
   925      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
   926      */
   927     public AbstractStringBuilder insert(int offset, Object obj) {
   928         return insert(offset, String.valueOf(obj));
   929     }
   930 
   931     /**
   932      * Inserts the string into this character sequence.
   933      * <p>
   934      * The characters of the {@code String} argument are inserted, in
   935      * order, into this sequence at the indicated offset, moving up any
   936      * characters originally above that position and increasing the length
   937      * of this sequence by the length of the argument. If
   938      * {@code str} is {@code null}, then the four characters
   939      * {@code "null"} are inserted into this sequence.
   940      * <p>
   941      * The character at index <i>k</i> in the new character sequence is
   942      * equal to:
   943      * <ul>
   944      * <li>the character at index <i>k</i> in the old character sequence, if
   945      * <i>k</i> is less than {@code offset}
   946      * <li>the character at index <i>k</i>{@code -offset} in the
   947      * argument {@code str}, if <i>k</i> is not less than
   948      * {@code offset} but is less than {@code offset+str.length()}
   949      * <li>the character at index <i>k</i>{@code -str.length()} in the
   950      * old character sequence, if <i>k</i> is not less than
   951      * {@code offset+str.length()}
   952      * </ul><p>
   953      * The {@code offset} argument must be greater than or equal to
   954      * {@code 0}, and less than or equal to the {@linkplain #length() length}
   955      * of this sequence.
   956      *
   957      * @param      offset   the offset.
   958      * @param      str      a string.
   959      * @return     a reference to this object.
   960      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
   961      */
   962     public AbstractStringBuilder insert(int offset, String str) {
   963         if ((offset < 0) || (offset > length()))
   964             throw new StringIndexOutOfBoundsException(offset);
   965         if (str == null)
   966             str = "null";
   967         int len = str.length();
   968         ensureCapacityInternal(count + len);
   969         String.arraycopy(value, offset, value, offset + len, count - offset);
   970         str.getChars(value, offset);
   971         count += len;
   972         return this;
   973     }
   974 
   975     /**
   976      * Inserts the string representation of the {@code char} array
   977      * argument into this sequence.
   978      * <p>
   979      * The characters of the array argument are inserted into the
   980      * contents of this sequence at the position indicated by
   981      * {@code offset}. The length of this sequence increases by
   982      * the length of the argument.
   983      * <p>
   984      * The overall effect is exactly as if the second argument were
   985      * converted to a string by the method {@link String#valueOf(char[])},
   986      * and the characters of that string were then
   987      * {@link #insert(int,String) inserted} into this character
   988      * sequence at the indicated offset.
   989      * <p>
   990      * The {@code offset} argument must be greater than or equal to
   991      * {@code 0}, and less than or equal to the {@linkplain #length() length}
   992      * of this sequence.
   993      *
   994      * @param      offset   the offset.
   995      * @param      str      a character array.
   996      * @return     a reference to this object.
   997      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
   998      */
   999     public AbstractStringBuilder insert(int offset, char[] str) {
  1000         if ((offset < 0) || (offset > length()))
  1001             throw new StringIndexOutOfBoundsException(offset);
  1002         int len = str.length;
  1003         ensureCapacityInternal(count + len);
  1004         String.arraycopy(value, offset, value, offset + len, count - offset);
  1005         String.arraycopy(str, 0, value, offset, len);
  1006         count += len;
  1007         return this;
  1008     }
  1009 
  1010     /**
  1011      * Inserts the specified {@code CharSequence} into this sequence.
  1012      * <p>
  1013      * The characters of the {@code CharSequence} argument are inserted,
  1014      * in order, into this sequence at the indicated offset, moving up
  1015      * any characters originally above that position and increasing the length
  1016      * of this sequence by the length of the argument s.
  1017      * <p>
  1018      * The result of this method is exactly the same as if it were an
  1019      * invocation of this object's
  1020      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
  1021      * method.
  1022      *
  1023      * <p>If {@code s} is {@code null}, then the four characters
  1024      * {@code "null"} are inserted into this sequence.
  1025      *
  1026      * @param      dstOffset   the offset.
  1027      * @param      s the sequence to be inserted
  1028      * @return     a reference to this object.
  1029      * @throws     IndexOutOfBoundsException  if the offset is invalid.
  1030      */
  1031     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
  1032         if (s == null)
  1033             s = "null";
  1034         if (s instanceof String)
  1035             return this.insert(dstOffset, (String)s);
  1036         return this.insert(dstOffset, s, 0, s.length());
  1037     }
  1038 
  1039     /**
  1040      * Inserts a subsequence of the specified {@code CharSequence} into
  1041      * this sequence.
  1042      * <p>
  1043      * The subsequence of the argument {@code s} specified by
  1044      * {@code start} and {@code end} are inserted,
  1045      * in order, into this sequence at the specified destination offset, moving
  1046      * up any characters originally above that position. The length of this
  1047      * sequence is increased by {@code end - start}.
  1048      * <p>
  1049      * The character at index <i>k</i> in this sequence becomes equal to:
  1050      * <ul>
  1051      * <li>the character at index <i>k</i> in this sequence, if
  1052      * <i>k</i> is less than {@code dstOffset}
  1053      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
  1054      * the argument {@code s}, if <i>k</i> is greater than or equal to
  1055      * {@code dstOffset} but is less than {@code dstOffset+end-start}
  1056      * <li>the character at index <i>k</i>{@code -(end-start)} in this
  1057      * sequence, if <i>k</i> is greater than or equal to
  1058      * {@code dstOffset+end-start}
  1059      * </ul><p>
  1060      * The {@code dstOffset} argument must be greater than or equal to
  1061      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1062      * of this sequence.
  1063      * <p>The start argument must be nonnegative, and not greater than
  1064      * {@code end}.
  1065      * <p>The end argument must be greater than or equal to
  1066      * {@code start}, and less than or equal to the length of s.
  1067      *
  1068      * <p>If {@code s} is {@code null}, then this method inserts
  1069      * characters as if the s parameter was a sequence containing the four
  1070      * characters {@code "null"}.
  1071      *
  1072      * @param      dstOffset   the offset in this sequence.
  1073      * @param      s       the sequence to be inserted.
  1074      * @param      start   the starting index of the subsequence to be inserted.
  1075      * @param      end     the end index of the subsequence to be inserted.
  1076      * @return     a reference to this object.
  1077      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
  1078      *             is negative or greater than {@code this.length()}, or
  1079      *              {@code start} or {@code end} are negative, or
  1080      *              {@code start} is greater than {@code end} or
  1081      *              {@code end} is greater than {@code s.length()}
  1082      */
  1083      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
  1084                                          int start, int end) {
  1085         if (s == null)
  1086             s = "null";
  1087         if ((dstOffset < 0) || (dstOffset > this.length()))
  1088             throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
  1089         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
  1090             throw new IndexOutOfBoundsException(
  1091                 "start " + start + ", end " + end + ", s.length() "
  1092                 + s.length());
  1093         int len = end - start;
  1094         ensureCapacityInternal(count + len);
  1095         String.arraycopy(value, dstOffset, value, dstOffset + len,
  1096                          count - dstOffset);
  1097         for (int i=start; i<end; i++)
  1098             value[dstOffset++] = s.charAt(i);
  1099         count += len;
  1100         return this;
  1101     }
  1102 
  1103     /**
  1104      * Inserts the string representation of the {@code boolean}
  1105      * argument into this sequence.
  1106      * <p>
  1107      * The overall effect is exactly as if the second argument were
  1108      * converted to a string by the method {@link String#valueOf(boolean)},
  1109      * and the characters of that string were then
  1110      * {@link #insert(int,String) inserted} into this character
  1111      * sequence at the indicated offset.
  1112      * <p>
  1113      * The {@code offset} argument must be greater than or equal to
  1114      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1115      * of this sequence.
  1116      *
  1117      * @param      offset   the offset.
  1118      * @param      b        a {@code boolean}.
  1119      * @return     a reference to this object.
  1120      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1121      */
  1122     public AbstractStringBuilder insert(int offset, boolean b) {
  1123         return insert(offset, String.valueOf(b));
  1124     }
  1125 
  1126     /**
  1127      * Inserts the string representation of the {@code char}
  1128      * argument into this sequence.
  1129      * <p>
  1130      * The overall effect is exactly as if the second argument were
  1131      * converted to a string by the method {@link String#valueOf(char)},
  1132      * and the character in that string were then
  1133      * {@link #insert(int,String) inserted} into this character
  1134      * sequence at the indicated offset.
  1135      * <p>
  1136      * The {@code offset} argument must be greater than or equal to
  1137      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1138      * of this sequence.
  1139      *
  1140      * @param      offset   the offset.
  1141      * @param      c        a {@code char}.
  1142      * @return     a reference to this object.
  1143      * @throws     IndexOutOfBoundsException  if the offset is invalid.
  1144      */
  1145     public AbstractStringBuilder insert(int offset, char c) {
  1146         ensureCapacityInternal(count + 1);
  1147         String.arraycopy(value, offset, value, offset + 1, count - offset);
  1148         value[offset] = c;
  1149         count += 1;
  1150         return this;
  1151     }
  1152 
  1153     /**
  1154      * Inserts the string representation of the second {@code int}
  1155      * argument into this sequence.
  1156      * <p>
  1157      * The overall effect is exactly as if the second argument were
  1158      * converted to a string by the method {@link String#valueOf(int)},
  1159      * and the characters of that string were then
  1160      * {@link #insert(int,String) inserted} into this character
  1161      * sequence at the indicated offset.
  1162      * <p>
  1163      * The {@code offset} argument must be greater than or equal to
  1164      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1165      * of this sequence.
  1166      *
  1167      * @param      offset   the offset.
  1168      * @param      i        an {@code int}.
  1169      * @return     a reference to this object.
  1170      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1171      */
  1172     public AbstractStringBuilder insert(int offset, int i) {
  1173         return insert(offset, String.valueOf(i));
  1174     }
  1175 
  1176     /**
  1177      * Inserts the string representation of the {@code long}
  1178      * argument into this sequence.
  1179      * <p>
  1180      * The overall effect is exactly as if the second argument were
  1181      * converted to a string by the method {@link String#valueOf(long)},
  1182      * and the characters of that string were then
  1183      * {@link #insert(int,String) inserted} into this character
  1184      * sequence at the indicated offset.
  1185      * <p>
  1186      * The {@code offset} argument must be greater than or equal to
  1187      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1188      * of this sequence.
  1189      *
  1190      * @param      offset   the offset.
  1191      * @param      l        a {@code long}.
  1192      * @return     a reference to this object.
  1193      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1194      */
  1195     public AbstractStringBuilder insert(int offset, long l) {
  1196         return insert(offset, String.valueOf(l));
  1197     }
  1198 
  1199     /**
  1200      * Inserts the string representation of the {@code float}
  1201      * argument into this sequence.
  1202      * <p>
  1203      * The overall effect is exactly as if the second argument were
  1204      * converted to a string by the method {@link String#valueOf(float)},
  1205      * and the characters of that string were then
  1206      * {@link #insert(int,String) inserted} into this character
  1207      * sequence at the indicated offset.
  1208      * <p>
  1209      * The {@code offset} argument must be greater than or equal to
  1210      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1211      * of this sequence.
  1212      *
  1213      * @param      offset   the offset.
  1214      * @param      f        a {@code float}.
  1215      * @return     a reference to this object.
  1216      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1217      */
  1218     public AbstractStringBuilder insert(int offset, float f) {
  1219         return insert(offset, String.valueOf(f));
  1220     }
  1221 
  1222     /**
  1223      * Inserts the string representation of the {@code double}
  1224      * argument into this sequence.
  1225      * <p>
  1226      * The overall effect is exactly as if the second argument were
  1227      * converted to a string by the method {@link String#valueOf(double)},
  1228      * and the characters of that string were then
  1229      * {@link #insert(int,String) inserted} into this character
  1230      * sequence at the indicated offset.
  1231      * <p>
  1232      * The {@code offset} argument must be greater than or equal to
  1233      * {@code 0}, and less than or equal to the {@linkplain #length() length}
  1234      * of this sequence.
  1235      *
  1236      * @param      offset   the offset.
  1237      * @param      d        a {@code double}.
  1238      * @return     a reference to this object.
  1239      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
  1240      */
  1241     public AbstractStringBuilder insert(int offset, double d) {
  1242         return insert(offset, String.valueOf(d));
  1243     }
  1244 
  1245     /**
  1246      * Returns the index within this string of the first occurrence of the
  1247      * specified substring. The integer returned is the smallest value
  1248      * <i>k</i> such that:
  1249      * <blockquote><pre>
  1250      * this.toString().startsWith(str, <i>k</i>)
  1251      * </pre></blockquote>
  1252      * is <code>true</code>.
  1253      *
  1254      * @param   str   any string.
  1255      * @return  if the string argument occurs as a substring within this
  1256      *          object, then the index of the first character of the first
  1257      *          such substring is returned; if it does not occur as a
  1258      *          substring, <code>-1</code> is returned.
  1259      * @throws  java.lang.NullPointerException if <code>str</code> is
  1260      *          <code>null</code>.
  1261      */
  1262     public int indexOf(String str) {
  1263         return indexOf(str, 0);
  1264     }
  1265 
  1266     /**
  1267      * Returns the index within this string of the first occurrence of the
  1268      * specified substring, starting at the specified index.  The integer
  1269      * returned is the smallest value <tt>k</tt> for which:
  1270      * <blockquote><pre>
  1271      *     k >= Math.min(fromIndex, str.length()) &&
  1272      *                   this.toString().startsWith(str, k)
  1273      * </pre></blockquote>
  1274      * If no such value of <i>k</i> exists, then -1 is returned.
  1275      *
  1276      * @param   str         the substring for which to search.
  1277      * @param   fromIndex   the index from which to start the search.
  1278      * @return  the index within this string of the first occurrence of the
  1279      *          specified substring, starting at the specified index.
  1280      * @throws  java.lang.NullPointerException if <code>str</code> is
  1281      *            <code>null</code>.
  1282      */
  1283     public int indexOf(String str, int fromIndex) {
  1284         return String.indexOf(value, 0, count,
  1285                               str.toCharArray(), 0, str.length(), fromIndex);
  1286     }
  1287 
  1288     /**
  1289      * Returns the index within this string of the rightmost occurrence
  1290      * of the specified substring.  The rightmost empty string "" is
  1291      * considered to occur at the index value <code>this.length()</code>.
  1292      * The returned index is the largest value <i>k</i> such that
  1293      * <blockquote><pre>
  1294      * this.toString().startsWith(str, k)
  1295      * </pre></blockquote>
  1296      * is true.
  1297      *
  1298      * @param   str   the substring to search for.
  1299      * @return  if the string argument occurs one or more times as a substring
  1300      *          within this object, then the index of the first character of
  1301      *          the last such substring is returned. If it does not occur as
  1302      *          a substring, <code>-1</code> is returned.
  1303      * @throws  java.lang.NullPointerException  if <code>str</code> is
  1304      *          <code>null</code>.
  1305      */
  1306     public int lastIndexOf(String str) {
  1307         return lastIndexOf(str, count);
  1308     }
  1309 
  1310     /**
  1311      * Returns the index within this string of the last occurrence of the
  1312      * specified substring. The integer returned is the largest value <i>k</i>
  1313      * such that:
  1314      * <blockquote><pre>
  1315      *     k <= Math.min(fromIndex, str.length()) &&
  1316      *                   this.toString().startsWith(str, k)
  1317      * </pre></blockquote>
  1318      * If no such value of <i>k</i> exists, then -1 is returned.
  1319      *
  1320      * @param   str         the substring to search for.
  1321      * @param   fromIndex   the index to start the search from.
  1322      * @return  the index within this sequence of the last occurrence of the
  1323      *          specified substring.
  1324      * @throws  java.lang.NullPointerException if <code>str</code> is
  1325      *          <code>null</code>.
  1326      */
  1327     public int lastIndexOf(String str, int fromIndex) {
  1328         return String.lastIndexOf(value, 0, count,
  1329                               str.toCharArray(), 0, str.length(), fromIndex);
  1330     }
  1331 
  1332     /**
  1333      * Causes this character sequence to be replaced by the reverse of
  1334      * the sequence. If there are any surrogate pairs included in the
  1335      * sequence, these are treated as single characters for the
  1336      * reverse operation. Thus, the order of the high-low surrogates
  1337      * is never reversed.
  1338      *
  1339      * Let <i>n</i> be the character length of this character sequence
  1340      * (not the length in <code>char</code> values) just prior to
  1341      * execution of the <code>reverse</code> method. Then the
  1342      * character at index <i>k</i> in the new character sequence is
  1343      * equal to the character at index <i>n-k-1</i> in the old
  1344      * character sequence.
  1345      *
  1346      * <p>Note that the reverse operation may result in producing
  1347      * surrogate pairs that were unpaired low-surrogates and
  1348      * high-surrogates before the operation. For example, reversing
  1349      * "&#92;uDC00&#92;uD800" produces "&#92;uD800&#92;uDC00" which is
  1350      * a valid surrogate pair.
  1351      *
  1352      * @return  a reference to this object.
  1353      */
  1354     public AbstractStringBuilder reverse() {
  1355         boolean hasSurrogate = false;
  1356         int n = count - 1;
  1357         for (int j = (n-1) >> 1; j >= 0; --j) {
  1358             char temp = value[j];
  1359             char temp2 = value[n - j];
  1360             if (!hasSurrogate) {
  1361                 hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
  1362                     || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
  1363             }
  1364             value[j] = temp2;
  1365             value[n - j] = temp;
  1366         }
  1367         if (hasSurrogate) {
  1368             // Reverse back all valid surrogate pairs
  1369             for (int i = 0; i < count - 1; i++) {
  1370                 char c2 = value[i];
  1371                 if (Character.isLowSurrogate(c2)) {
  1372                     char c1 = value[i + 1];
  1373                     if (Character.isHighSurrogate(c1)) {
  1374                         value[i++] = c1;
  1375                         value[i] = c2;
  1376                     }
  1377                 }
  1378             }
  1379         }
  1380         return this;
  1381     }
  1382 
  1383     /**
  1384      * Returns a string representing the data in this sequence.
  1385      * A new <code>String</code> object is allocated and initialized to
  1386      * contain the character sequence currently represented by this
  1387      * object. This <code>String</code> is then returned. Subsequent
  1388      * changes to this sequence do not affect the contents of the
  1389      * <code>String</code>.
  1390      *
  1391      * @return  a string representation of this sequence of characters.
  1392      */
  1393     public abstract String toString();
  1394 
  1395     /**
  1396      * Needed by <tt>String</tt> for the contentEquals method.
  1397      */
  1398     final char[] getValue() {
  1399         return value;
  1400     }
  1401 
  1402 }