rt/emul/mini/src/main/java/java/lang/AbstractStringBuilder.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 560 emul/mini/src/main/java/java/lang/AbstractStringBuilder.java@53fafe384803
child 835 24096bd2b38a
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
     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 }