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