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