1 /*
   2  * Copyright (c) 2003, 2019, 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 jdk.internal.math.DoubleToDecimal;
  29 import jdk.internal.math.FloatToDecimal;
  30 
  31 import java.io.IOException;
  32 import java.util.Arrays;
  33 import java.util.Spliterator;
  34 import java.util.stream.IntStream;
  35 import java.util.stream.StreamSupport;
  36 
  37 import static java.lang.String.COMPACT_STRINGS;
  38 import static java.lang.String.UTF16;
  39 import static java.lang.String.LATIN1;
  40 import static java.lang.String.checkIndex;
  41 import static java.lang.String.checkOffset;
  42 
  43 /**
  44  * A mutable sequence of characters.
  45  * <p>
  46  * Implements a modifiable string. At any point in time it contains some
  47  * particular sequence of characters, but the length and content of the
  48  * sequence can be changed through certain method calls.
  49  *
  50  * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
  51  * or method in this class will cause a {@link NullPointerException} to be
  52  * thrown.
  53  *
  54  * @author      Michael McCloskey
  55  * @author      Martin Buchholz
  56  * @author      Ulf Zibis
  57  * @since       1.5
  58  */
  59 abstract class AbstractStringBuilder implements Appendable, CharSequence {
  60     /**
  61      * The value is used for character storage.
  62      */
  63     byte[] value;
  64 
  65     /**
  66      * The id of the encoding used to encode the bytes in {@code value}.
  67      */
  68     byte coder;
  69 
  70     /**
  71      * The count is the number of characters used.
  72      */
  73     int count;
  74 
  75     private static final byte[] EMPTYVALUE = new byte[0];
  76 
  77     /**
  78      * This no-arg constructor is necessary for serialization of subclasses.
  79      */
  80     AbstractStringBuilder() {
  81         value = EMPTYVALUE;
  82     }
  83 
  84     /**
  85      * Creates an AbstractStringBuilder of the specified capacity.
  86      */
  87     AbstractStringBuilder(int capacity) {
  88         if (COMPACT_STRINGS) {
  89             value = new byte[capacity];
  90             coder = LATIN1;
  91         } else {
  92             value = StringUTF16.newBytesFor(capacity);
  93             coder = UTF16;
  94         }
  95     }
  96 
  97     /**
  98      * Constructs an AbstractStringBuilder that contains the same characters
  99      * as the specified {@code String}. The initial capacity of
 100      * the string builder is {@code 16} plus the length of the
 101      * {@code String} argument.
 102      *
 103      * @param      str   the string to copy.
 104      */
 105     AbstractStringBuilder(String str) {
 106         int length = str.length();
 107         int capacity = (length < Integer.MAX_VALUE - 16)
 108                 ? length + 16 : Integer.MAX_VALUE;
 109         final byte initCoder = str.coder();
 110         coder = initCoder;
 111         value = (initCoder == LATIN1)
 112                 ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
 113         append(str);
 114     }
 115 
 116     /**
 117      * Constructs an AbstractStringBuilder that contains the same characters
 118      * as the specified {@code CharSequence}. The initial capacity of
 119      * the string builder is {@code 16} plus the length of the
 120      * {@code CharSequence} argument.
 121      *
 122      * @param      seq   the sequence to copy.
 123      */
 124     AbstractStringBuilder(CharSequence seq) {
 125         int length = seq.length();
 126         if (length < 0) {
 127             throw new NegativeArraySizeException("Negative length: " + length);
 128         }
 129         int capacity = (length < Integer.MAX_VALUE - 16)
 130                 ? length + 16 : Integer.MAX_VALUE;
 131 
 132         final byte initCoder;
 133         if (COMPACT_STRINGS) {
 134             if (seq instanceof AbstractStringBuilder) {
 135                 initCoder = ((AbstractStringBuilder)seq).getCoder();
 136             } else if (seq instanceof String) {
 137                 initCoder = ((String)seq).coder();
 138             } else {
 139                 initCoder = LATIN1;
 140             }
 141         } else {
 142             initCoder = UTF16;
 143         }
 144 
 145         coder = initCoder;
 146         value = (initCoder == LATIN1)
 147                 ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
 148         append(seq);
 149     }
 150 
 151     /**
 152      * Compares the objects of two AbstractStringBuilder implementations lexicographically.
 153      *
 154      * @since 11
 155      */
 156     int compareTo(AbstractStringBuilder another) {
 157         if (this == another) {
 158             return 0;
 159         }
 160 
 161         byte val1[] = value;
 162         byte val2[] = another.value;
 163         int count1 = this.count;
 164         int count2 = another.count;
 165 
 166         if (coder == another.coder) {
 167             return isLatin1() ? StringLatin1.compareTo(val1, val2, count1, count2)
 168                               : StringUTF16.compareTo(val1, val2, count1, count2);
 169         }
 170         return isLatin1() ? StringLatin1.compareToUTF16(val1, val2, count1, count2)
 171                           : StringUTF16.compareToLatin1(val1, val2, count1, count2);
 172     }
 173 
 174     /**
 175      * Returns the length (character count).
 176      *
 177      * @return  the length of the sequence of characters currently
 178      *          represented by this object
 179      */
 180     @Override
 181     public int length() {
 182         return count;
 183     }
 184 
 185     /**
 186      * Returns the current capacity. The capacity is the amount of storage
 187      * available for newly inserted characters, beyond which an allocation
 188      * will occur.
 189      *
 190      * @return  the current capacity
 191      */
 192     public int capacity() {
 193         return value.length >> coder;
 194     }
 195 
 196     /**
 197      * Ensures that the capacity is at least equal to the specified minimum.
 198      * If the current capacity is less than the argument, then a new internal
 199      * array is allocated with greater capacity. The new capacity is the
 200      * larger of:
 201      * <ul>
 202      * <li>The {@code minimumCapacity} argument.
 203      * <li>Twice the old capacity, plus {@code 2}.
 204      * </ul>
 205      * If the {@code minimumCapacity} argument is nonpositive, this
 206      * method takes no action and simply returns.
 207      * Note that subsequent operations on this object can reduce the
 208      * actual capacity below that requested here.
 209      *
 210      * @param   minimumCapacity   the minimum desired capacity.
 211      */
 212     public void ensureCapacity(int minimumCapacity) {
 213         if (minimumCapacity > 0) {
 214             ensureCapacityInternal(minimumCapacity);
 215         }
 216     }
 217 
 218     /**
 219      * For positive values of {@code minimumCapacity}, this method
 220      * behaves like {@code ensureCapacity}, however it is never
 221      * synchronized.
 222      * If {@code minimumCapacity} is non positive due to numeric
 223      * overflow, this method throws {@code OutOfMemoryError}.
 224      */
 225     private void ensureCapacityInternal(int minimumCapacity) {
 226         // overflow-conscious code
 227         int oldCapacity = value.length >> coder;
 228         if (minimumCapacity - oldCapacity > 0) {
 229             value = Arrays.copyOf(value,
 230                     newCapacity(minimumCapacity) << coder);
 231         }
 232     }
 233 
 234     /**
 235      * The maximum size of array to allocate (unless necessary).
 236      * Some VMs reserve some header words in an array.
 237      * Attempts to allocate larger arrays may result in
 238      * OutOfMemoryError: Requested array size exceeds VM limit
 239      */
 240     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 241 
 242     /**
 243      * Returns a capacity at least as large as the given minimum capacity.
 244      * Returns the current capacity increased by the same amount + 2 if
 245      * that suffices.
 246      * Will not return a capacity greater than
 247      * {@code (MAX_ARRAY_SIZE >> coder)} unless the given minimum capacity
 248      * is greater than that.
 249      *
 250      * @param  minCapacity the desired minimum capacity
 251      * @throws OutOfMemoryError if minCapacity is less than zero or
 252      *         greater than (Integer.MAX_VALUE >> coder)
 253      */
 254     private int newCapacity(int minCapacity) {
 255         // overflow-conscious code
 256         int oldCapacity = value.length >> coder;
 257         int newCapacity = (oldCapacity << 1) + 2;
 258         if (newCapacity - minCapacity < 0) {
 259             newCapacity = minCapacity;
 260         }
 261         int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
 262         return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
 263             ? hugeCapacity(minCapacity)
 264             : newCapacity;
 265     }
 266 
 267     private int hugeCapacity(int minCapacity) {
 268         int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
 269         int UNSAFE_BOUND = Integer.MAX_VALUE >> coder;
 270         if (UNSAFE_BOUND - minCapacity < 0) { // overflow
 271             throw new OutOfMemoryError();
 272         }
 273         return (minCapacity > SAFE_BOUND)
 274             ? minCapacity : SAFE_BOUND;
 275     }
 276 
 277     /**
 278      * If the coder is "isLatin1", this inflates the internal 8-bit storage
 279      * to 16-bit <hi=0, low> pair storage.
 280      */
 281     private void inflate() {
 282         if (!isLatin1()) {
 283             return;
 284         }
 285         byte[] buf = StringUTF16.newBytesFor(value.length);
 286         StringLatin1.inflate(value, 0, buf, 0, count);
 287         this.value = buf;
 288         this.coder = UTF16;
 289     }
 290 
 291     /**
 292      * Attempts to reduce storage used for the character sequence.
 293      * If the buffer is larger than necessary to hold its current sequence of
 294      * characters, then it may be resized to become more space efficient.
 295      * Calling this method may, but is not required to, affect the value
 296      * returned by a subsequent call to the {@link #capacity()} method.
 297      */
 298     public void trimToSize() {
 299         int length = count << coder;
 300         if (length < value.length) {
 301             value = Arrays.copyOf(value, length);
 302         }
 303     }
 304 
 305     /**
 306      * Sets the length of the character sequence.
 307      * The sequence is changed to a new character sequence
 308      * whose length is specified by the argument. For every nonnegative
 309      * index <i>k</i> less than {@code newLength}, the character at
 310      * index <i>k</i> in the new character sequence is the same as the
 311      * character at index <i>k</i> in the old sequence if <i>k</i> is less
 312      * than the length of the old character sequence; otherwise, it is the
 313      * null character {@code '\u005Cu0000'}.
 314      *
 315      * In other words, if the {@code newLength} argument is less than
 316      * the current length, the length is changed to the specified length.
 317      * <p>
 318      * If the {@code newLength} argument is greater than or equal
 319      * to the current length, sufficient null characters
 320      * ({@code '\u005Cu0000'}) are appended so that
 321      * length becomes the {@code newLength} argument.
 322      * <p>
 323      * The {@code newLength} argument must be greater than or equal
 324      * to {@code 0}.
 325      *
 326      * @param      newLength   the new length
 327      * @throws     IndexOutOfBoundsException  if the
 328      *               {@code newLength} argument is negative.
 329      */
 330     public void setLength(int newLength) {
 331         if (newLength < 0) {
 332             throw new StringIndexOutOfBoundsException(newLength);
 333         }
 334         ensureCapacityInternal(newLength);
 335         if (count < newLength) {
 336             if (isLatin1()) {
 337                 StringLatin1.fillNull(value, count, newLength);
 338             } else {
 339                 StringUTF16.fillNull(value, count, newLength);
 340             }
 341         }
 342         count = newLength;
 343     }
 344 
 345     /**
 346      * Returns the {@code char} value in this sequence at the specified index.
 347      * The first {@code char} value is at index {@code 0}, the next at index
 348      * {@code 1}, and so on, as in array indexing.
 349      * <p>
 350      * The index argument must be greater than or equal to
 351      * {@code 0}, and less than the length of this sequence.
 352      *
 353      * <p>If the {@code char} value specified by the index is a
 354      * <a href="Character.html#unicode">surrogate</a>, the surrogate
 355      * value is returned.
 356      *
 357      * @param      index   the index of the desired {@code char} value.
 358      * @return     the {@code char} value at the specified index.
 359      * @throws     IndexOutOfBoundsException  if {@code index} is
 360      *             negative or greater than or equal to {@code length()}.
 361      */
 362     @Override
 363     public char charAt(int index) {
 364         checkIndex(index, count);
 365         if (isLatin1()) {
 366             return (char)(value[index] & 0xff);
 367         }
 368         return StringUTF16.charAt(value, index);
 369     }
 370 
 371     /**
 372      * Returns the character (Unicode code point) at the specified
 373      * index. The index refers to {@code char} values
 374      * (Unicode code units) and ranges from {@code 0} to
 375      * {@link #length()}{@code  - 1}.
 376      *
 377      * <p> If the {@code char} value specified at the given index
 378      * is in the high-surrogate range, the following index is less
 379      * than the length of this sequence, and the
 380      * {@code char} value at the following index is in the
 381      * low-surrogate range, then the supplementary code point
 382      * corresponding to this surrogate pair is returned. Otherwise,
 383      * the {@code char} value at the given index is returned.
 384      *
 385      * @param      index the index to the {@code char} values
 386      * @return     the code point value of the character at the
 387      *             {@code index}
 388      * @throws     IndexOutOfBoundsException  if the {@code index}
 389      *             argument is negative or not less than the length of this
 390      *             sequence.
 391      */
 392     public int codePointAt(int index) {
 393         int count = this.count;
 394         byte[] value = this.value;
 395         checkIndex(index, count);
 396         if (isLatin1()) {
 397             return value[index] & 0xff;
 398         }
 399         return StringUTF16.codePointAtSB(value, index, count);
 400     }
 401 
 402     /**
 403      * Returns the character (Unicode code point) before the specified
 404      * index. The index refers to {@code char} values
 405      * (Unicode code units) and ranges from {@code 1} to {@link
 406      * #length()}.
 407      *
 408      * <p> If the {@code char} value at {@code (index - 1)}
 409      * is in the low-surrogate range, {@code (index - 2)} is not
 410      * negative, and the {@code char} value at {@code (index -
 411      * 2)} is in the high-surrogate range, then the
 412      * supplementary code point value of the surrogate pair is
 413      * returned. If the {@code char} value at {@code index -
 414      * 1} is an unpaired low-surrogate or a high-surrogate, the
 415      * surrogate value is returned.
 416      *
 417      * @param     index the index following the code point that should be returned
 418      * @return    the Unicode code point value before the given index.
 419      * @throws    IndexOutOfBoundsException if the {@code index}
 420      *            argument is less than 1 or greater than the length
 421      *            of this sequence.
 422      */
 423     public int codePointBefore(int index) {
 424         int i = index - 1;
 425         if (i < 0 || i >= count) {
 426             throw new StringIndexOutOfBoundsException(index);
 427         }
 428         if (isLatin1()) {
 429             return value[i] & 0xff;
 430         }
 431         return StringUTF16.codePointBeforeSB(value, index);
 432     }
 433 
 434     /**
 435      * Returns the number of Unicode code points in the specified text
 436      * range of this sequence. The text range begins at the specified
 437      * {@code beginIndex} and extends to the {@code char} at
 438      * index {@code endIndex - 1}. Thus the length (in
 439      * {@code char}s) of the text range is
 440      * {@code endIndex-beginIndex}. Unpaired surrogates within
 441      * this sequence count as one code point each.
 442      *
 443      * @param beginIndex the index to the first {@code char} of
 444      * the text range.
 445      * @param endIndex the index after the last {@code char} of
 446      * the text range.
 447      * @return the number of Unicode code points in the specified text
 448      * range
 449      * @throws    IndexOutOfBoundsException if the
 450      * {@code beginIndex} is negative, or {@code endIndex}
 451      * is larger than the length of this sequence, or
 452      * {@code beginIndex} is larger than {@code endIndex}.
 453      */
 454     public int codePointCount(int beginIndex, int endIndex) {
 455         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
 456             throw new IndexOutOfBoundsException();
 457         }
 458         if (isLatin1()) {
 459             return endIndex - beginIndex;
 460         }
 461         return StringUTF16.codePointCountSB(value, beginIndex, endIndex);
 462     }
 463 
 464     /**
 465      * Returns the index within this sequence that is offset from the
 466      * given {@code index} by {@code codePointOffset} code
 467      * points. Unpaired surrogates within the text range given by
 468      * {@code index} and {@code codePointOffset} count as
 469      * one code point each.
 470      *
 471      * @param index the index to be offset
 472      * @param codePointOffset the offset in code points
 473      * @return the index within this sequence
 474      * @throws    IndexOutOfBoundsException if {@code index}
 475      *   is negative or larger then the length of this sequence,
 476      *   or if {@code codePointOffset} is positive and the subsequence
 477      *   starting with {@code index} has fewer than
 478      *   {@code codePointOffset} code points,
 479      *   or if {@code codePointOffset} is negative and the subsequence
 480      *   before {@code index} has fewer than the absolute value of
 481      *   {@code codePointOffset} code points.
 482      */
 483     public int offsetByCodePoints(int index, int codePointOffset) {
 484         if (index < 0 || index > count) {
 485             throw new IndexOutOfBoundsException();
 486         }
 487         return Character.offsetByCodePoints(this,
 488                                             index, codePointOffset);
 489     }
 490 
 491     /**
 492      * Characters are copied from this sequence into the
 493      * destination character array {@code dst}. The first character to
 494      * be copied is at index {@code srcBegin}; the last character to
 495      * be copied is at index {@code srcEnd-1}. The total number of
 496      * characters to be copied is {@code srcEnd-srcBegin}. The
 497      * characters are copied into the subarray of {@code dst} starting
 498      * at index {@code dstBegin} and ending at index:
 499      * <pre>{@code
 500      * dstbegin + (srcEnd-srcBegin) - 1
 501      * }</pre>
 502      *
 503      * @param      srcBegin   start copying at this offset.
 504      * @param      srcEnd     stop copying at this offset.
 505      * @param      dst        the array to copy the data into.
 506      * @param      dstBegin   offset into {@code dst}.
 507      * @throws     IndexOutOfBoundsException  if any of the following is true:
 508      *             <ul>
 509      *             <li>{@code srcBegin} is negative
 510      *             <li>{@code dstBegin} is negative
 511      *             <li>the {@code srcBegin} argument is greater than
 512      *             the {@code srcEnd} argument.
 513      *             <li>{@code srcEnd} is greater than
 514      *             {@code this.length()}.
 515      *             <li>{@code dstBegin+srcEnd-srcBegin} is greater than
 516      *             {@code dst.length}
 517      *             </ul>
 518      */
 519     public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
 520     {
 521         checkRangeSIOOBE(srcBegin, srcEnd, count);  // compatible to old version
 522         int n = srcEnd - srcBegin;
 523         checkRange(dstBegin, dstBegin + n, dst.length);
 524         if (isLatin1()) {
 525             StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin);
 526         } else {
 527             StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
 528         }
 529     }
 530 
 531     /**
 532      * The character at the specified index is set to {@code ch}. This
 533      * sequence is altered to represent a new character sequence that is
 534      * identical to the old character sequence, except that it contains the
 535      * character {@code ch} at position {@code index}.
 536      * <p>
 537      * The index argument must be greater than or equal to
 538      * {@code 0}, and less than the length of this sequence.
 539      *
 540      * @param      index   the index of the character to modify.
 541      * @param      ch      the new character.
 542      * @throws     IndexOutOfBoundsException  if {@code index} is
 543      *             negative or greater than or equal to {@code length()}.
 544      */
 545     public void setCharAt(int index, char ch) {
 546         checkIndex(index, count);
 547         if (isLatin1() && StringLatin1.canEncode(ch)) {
 548             value[index] = (byte)ch;
 549         } else {
 550             if (isLatin1()) {
 551                 inflate();
 552             }
 553             StringUTF16.putCharSB(value, index, ch);
 554         }
 555     }
 556 
 557     /**
 558      * Appends the string representation of the {@code Object} argument.
 559      * <p>
 560      * The overall effect is exactly as if the argument were converted
 561      * to a string by the method {@link String#valueOf(Object)},
 562      * and the characters of that string were then
 563      * {@link #append(String) appended} to this character sequence.
 564      *
 565      * @param   obj   an {@code Object}.
 566      * @return  a reference to this object.
 567      */
 568     public AbstractStringBuilder append(Object obj) {
 569         return append(String.valueOf(obj));
 570     }
 571 
 572     /**
 573      * Appends the specified string to this character sequence.
 574      * <p>
 575      * The characters of the {@code String} argument are appended, in
 576      * order, increasing the length of this sequence by the length of the
 577      * argument. If {@code str} is {@code null}, then the four
 578      * characters {@code "null"} are appended.
 579      * <p>
 580      * Let <i>n</i> be the length of this character sequence just prior to
 581      * execution of the {@code append} method. Then the character at
 582      * index <i>k</i> in the new character sequence is equal to the character
 583      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
 584      * than <i>n</i>; otherwise, it is equal to the character at index
 585      * <i>k-n</i> in the argument {@code str}.
 586      *
 587      * @param   str   a string.
 588      * @return  a reference to this object.
 589      */
 590     public AbstractStringBuilder append(String str) {
 591         if (str == null) {
 592             return appendNull();
 593         }
 594         int len = str.length();
 595         ensureCapacityInternal(count + len);
 596         putStringAt(count, str);
 597         count += len;
 598         return this;
 599     }
 600 
 601     // Documentation in subclasses because of synchro difference
 602     public AbstractStringBuilder append(StringBuffer sb) {
 603         return this.append((AbstractStringBuilder)sb);
 604     }
 605 
 606     /**
 607      * @since 1.8
 608      */
 609     AbstractStringBuilder append(AbstractStringBuilder asb) {
 610         if (asb == null) {
 611             return appendNull();
 612         }
 613         int len = asb.length();
 614         ensureCapacityInternal(count + len);
 615         if (getCoder() != asb.getCoder()) {
 616             inflate();
 617         }
 618         asb.getBytes(value, count, coder);
 619         count += len;
 620         return this;
 621     }
 622 
 623     // Documentation in subclasses because of synchro difference
 624     @Override
 625     public AbstractStringBuilder append(CharSequence s) {
 626         if (s == null) {
 627             return appendNull();
 628         }
 629         if (s instanceof String) {
 630             return this.append((String)s);
 631         }
 632         if (s instanceof AbstractStringBuilder) {
 633             return this.append((AbstractStringBuilder)s);
 634         }
 635         return this.append(s, 0, s.length());
 636     }
 637 
 638     private AbstractStringBuilder appendNull() {
 639         ensureCapacityInternal(count + 4);
 640         int count = this.count;
 641         byte[] val = this.value;
 642         if (isLatin1()) {
 643             val[count++] = 'n';
 644             val[count++] = 'u';
 645             val[count++] = 'l';
 646             val[count++] = 'l';
 647         } else {
 648             count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
 649         }
 650         this.count = count;
 651         return this;
 652     }
 653 
 654     /**
 655      * Appends a subsequence of the specified {@code CharSequence} to this
 656      * sequence.
 657      * <p>
 658      * Characters of the argument {@code s}, starting at
 659      * index {@code start}, are appended, in order, to the contents of
 660      * this sequence up to the (exclusive) index {@code end}. The length
 661      * of this sequence is increased by the value of {@code end - start}.
 662      * <p>
 663      * Let <i>n</i> be the length of this character sequence just prior to
 664      * execution of the {@code append} method. Then the character at
 665      * index <i>k</i> in this character sequence becomes equal to the
 666      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
 667      * <i>n</i>; otherwise, it is equal to the character at index
 668      * <i>k+start-n</i> in the argument {@code s}.
 669      * <p>
 670      * If {@code s} is {@code null}, then this method appends
 671      * characters as if the s parameter was a sequence containing the four
 672      * characters {@code "null"}.
 673      *
 674      * @param   s the sequence to append.
 675      * @param   start   the starting index of the subsequence to be appended.
 676      * @param   end     the end index of the subsequence to be appended.
 677      * @return  a reference to this object.
 678      * @throws     IndexOutOfBoundsException if
 679      *             {@code start} is negative, or
 680      *             {@code start} is greater than {@code end} or
 681      *             {@code end} is greater than {@code s.length()}
 682      */
 683     @Override
 684     public AbstractStringBuilder append(CharSequence s, int start, int end) {
 685         if (s == null) {
 686             s = "null";
 687         }
 688         checkRange(start, end, s.length());
 689         int len = end - start;
 690         ensureCapacityInternal(count + len);
 691         appendChars(s, start, end);
 692         return this;
 693     }
 694 
 695     /**
 696      * Appends the string representation of the {@code char} array
 697      * argument to this sequence.
 698      * <p>
 699      * The characters of the array argument are appended, in order, to
 700      * the contents of this sequence. The length of this sequence
 701      * increases by the length of the argument.
 702      * <p>
 703      * The overall effect is exactly as if the argument were converted
 704      * to a string by the method {@link String#valueOf(char[])},
 705      * and the characters of that string were then
 706      * {@link #append(String) appended} to this character sequence.
 707      *
 708      * @param   str   the characters to be appended.
 709      * @return  a reference to this object.
 710      */
 711     public AbstractStringBuilder append(char[] str) {
 712         int len = str.length;
 713         ensureCapacityInternal(count + len);
 714         appendChars(str, 0, len);
 715         return this;
 716     }
 717 
 718     /**
 719      * Appends the string representation of a subarray of the
 720      * {@code char} array argument to this sequence.
 721      * <p>
 722      * Characters of the {@code char} array {@code str}, starting at
 723      * index {@code offset}, are appended, in order, to the contents
 724      * of this sequence. The length of this sequence increases
 725      * by the value of {@code len}.
 726      * <p>
 727      * The overall effect is exactly as if the arguments were converted
 728      * to a string by the method {@link String#valueOf(char[],int,int)},
 729      * and the characters of that string were then
 730      * {@link #append(String) appended} to this character sequence.
 731      *
 732      * @param   str      the characters to be appended.
 733      * @param   offset   the index of the first {@code char} to append.
 734      * @param   len      the number of {@code char}s to append.
 735      * @return  a reference to this object.
 736      * @throws IndexOutOfBoundsException
 737      *         if {@code offset < 0} or {@code len < 0}
 738      *         or {@code offset+len > str.length}
 739      */
 740     public AbstractStringBuilder append(char str[], int offset, int len) {
 741         int end = offset + len;
 742         checkRange(offset, end, str.length);
 743         ensureCapacityInternal(count + len);
 744         appendChars(str, offset, end);
 745         return this;
 746     }
 747 
 748     /**
 749      * Appends the string representation of the {@code boolean}
 750      * argument to the sequence.
 751      * <p>
 752      * The overall effect is exactly as if the argument were converted
 753      * to a string by the method {@link String#valueOf(boolean)},
 754      * and the characters of that string were then
 755      * {@link #append(String) appended} to this character sequence.
 756      *
 757      * @param   b   a {@code boolean}.
 758      * @return  a reference to this object.
 759      */
 760     public AbstractStringBuilder append(boolean b) {
 761         ensureCapacityInternal(count + (b ? 4 : 5));
 762         int count = this.count;
 763         byte[] val = this.value;
 764         if (isLatin1()) {
 765             if (b) {
 766                 val[count++] = 't';
 767                 val[count++] = 'r';
 768                 val[count++] = 'u';
 769                 val[count++] = 'e';
 770             } else {
 771                 val[count++] = 'f';
 772                 val[count++] = 'a';
 773                 val[count++] = 'l';
 774                 val[count++] = 's';
 775                 val[count++] = 'e';
 776             }
 777         } else {
 778             if (b) {
 779                 count = StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e');
 780             } else {
 781                 count = StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e');
 782             }
 783         }
 784         this.count = count;
 785         return this;
 786     }
 787 
 788     /**
 789      * Appends the string representation of the {@code char}
 790      * argument to this sequence.
 791      * <p>
 792      * The argument is appended to the contents of this sequence.
 793      * The length of this sequence increases by {@code 1}.
 794      * <p>
 795      * The overall effect is exactly as if the argument were converted
 796      * to a string by the method {@link String#valueOf(char)},
 797      * and the character in that string were then
 798      * {@link #append(String) appended} to this character sequence.
 799      *
 800      * @param   c   a {@code char}.
 801      * @return  a reference to this object.
 802      */
 803     @Override
 804     public AbstractStringBuilder append(char c) {
 805         ensureCapacityInternal(count + 1);
 806         if (isLatin1() && StringLatin1.canEncode(c)) {
 807             value[count++] = (byte)c;
 808         } else {
 809             if (isLatin1()) {
 810                 inflate();
 811             }
 812             StringUTF16.putCharSB(value, count++, c);
 813         }
 814         return this;
 815     }
 816 
 817     /**
 818      * Appends the string representation of the {@code int}
 819      * argument to this sequence.
 820      * <p>
 821      * The overall effect is exactly as if the argument were converted
 822      * to a string by the method {@link String#valueOf(int)},
 823      * and the characters of that string were then
 824      * {@link #append(String) appended} to this character sequence.
 825      *
 826      * @param   i   an {@code int}.
 827      * @return  a reference to this object.
 828      */
 829     public AbstractStringBuilder append(int i) {
 830         int count = this.count;
 831         int spaceNeeded = count + Integer.stringSize(i);
 832         ensureCapacityInternal(spaceNeeded);
 833         if (isLatin1()) {
 834             Integer.getChars(i, spaceNeeded, value);
 835         } else {
 836             StringUTF16.getChars(i, count, spaceNeeded, value);
 837         }
 838         this.count = spaceNeeded;
 839         return this;
 840     }
 841 
 842     /**
 843      * Appends the string representation of the {@code long}
 844      * argument to this sequence.
 845      * <p>
 846      * The overall effect is exactly as if the argument were converted
 847      * to a string by the method {@link String#valueOf(long)},
 848      * and the characters of that string were then
 849      * {@link #append(String) appended} to this character sequence.
 850      *
 851      * @param   l   a {@code long}.
 852      * @return  a reference to this object.
 853      */
 854     public AbstractStringBuilder append(long l) {
 855         int count = this.count;
 856         int spaceNeeded = count + Long.stringSize(l);
 857         ensureCapacityInternal(spaceNeeded);
 858         if (isLatin1()) {
 859             Long.getChars(l, spaceNeeded, value);
 860         } else {
 861             StringUTF16.getChars(l, count, spaceNeeded, value);
 862         }
 863         this.count = spaceNeeded;
 864         return this;
 865     }
 866 
 867     /**
 868      * Appends the string representation of the {@code float}
 869      * argument to this sequence.
 870      * <p>
 871      * The overall effect is exactly as if the argument were converted
 872      * to a string by the method {@link String#valueOf(float)},
 873      * and the characters of that string were then
 874      * {@link #append(String) appended} to this character sequence.
 875      *
 876      * @param   f   a {@code float}.
 877      * @return  a reference to this object.
 878      */
 879     public AbstractStringBuilder append(float f) {
 880         try {
 881             FloatToDecimal.appendTo(f, this);
 882         } catch (IOException ignored) {
 883             assert false;
 884         }
 885         return this;
 886     }
 887 
 888     /**
 889      * Appends the string representation of the {@code double}
 890      * argument to this sequence.
 891      * <p>
 892      * The overall effect is exactly as if the argument were converted
 893      * to a string by the method {@link String#valueOf(double)},
 894      * and the characters of that string were then
 895      * {@link #append(String) appended} to this character sequence.
 896      *
 897      * @param   d   a {@code double}.
 898      * @return  a reference to this object.
 899      */
 900     public AbstractStringBuilder append(double d) {
 901         try {
 902             DoubleToDecimal.appendTo(d, this);
 903         } catch (IOException ignored) {
 904             assert false;
 905         }
 906         return this;
 907     }
 908 
 909     /**
 910      * Removes the characters in a substring of this sequence.
 911      * The substring begins at the specified {@code start} and extends to
 912      * the character at index {@code end - 1} or to the end of the
 913      * sequence if no such character exists. If
 914      * {@code start} is equal to {@code end}, no changes are made.
 915      *
 916      * @param      start  The beginning index, inclusive.
 917      * @param      end    The ending index, exclusive.
 918      * @return     This object.
 919      * @throws     StringIndexOutOfBoundsException  if {@code start}
 920      *             is negative, greater than {@code length()}, or
 921      *             greater than {@code end}.
 922      */
 923     public AbstractStringBuilder delete(int start, int end) {
 924         int count = this.count;
 925         if (end > count) {
 926             end = count;
 927         }
 928         checkRangeSIOOBE(start, end, count);
 929         int len = end - start;
 930         if (len > 0) {
 931             shift(end, -len);
 932             this.count = count - len;
 933         }
 934         return this;
 935     }
 936 
 937     /**
 938      * Appends the string representation of the {@code codePoint}
 939      * argument to this sequence.
 940      *
 941      * <p> The argument is appended to the contents of this sequence.
 942      * The length of this sequence increases by
 943      * {@link Character#charCount(int) Character.charCount(codePoint)}.
 944      *
 945      * <p> The overall effect is exactly as if the argument were
 946      * converted to a {@code char} array by the method
 947      * {@link Character#toChars(int)} and the character in that array
 948      * were then {@link #append(char[]) appended} to this character
 949      * sequence.
 950      *
 951      * @param   codePoint   a Unicode code point
 952      * @return  a reference to this object.
 953      * @throws    IllegalArgumentException if the specified
 954      * {@code codePoint} isn't a valid Unicode code point
 955      */
 956     public AbstractStringBuilder appendCodePoint(int codePoint) {
 957         if (Character.isBmpCodePoint(codePoint)) {
 958             return append((char)codePoint);
 959         }
 960         return append(Character.toChars(codePoint));
 961     }
 962 
 963     /**
 964      * Removes the {@code char} at the specified position in this
 965      * sequence. This sequence is shortened by one {@code char}.
 966      *
 967      * <p>Note: If the character at the given index is a supplementary
 968      * character, this method does not remove the entire character. If
 969      * correct handling of supplementary characters is required,
 970      * determine the number of {@code char}s to remove by calling
 971      * {@code Character.charCount(thisSequence.codePointAt(index))},
 972      * where {@code thisSequence} is this sequence.
 973      *
 974      * @param       index  Index of {@code char} to remove
 975      * @return      This object.
 976      * @throws      StringIndexOutOfBoundsException  if the {@code index}
 977      *              is negative or greater than or equal to
 978      *              {@code length()}.
 979      */
 980     public AbstractStringBuilder deleteCharAt(int index) {
 981         checkIndex(index, count);
 982         shift(index + 1, -1);
 983         count--;
 984         return this;
 985     }
 986 
 987     /**
 988      * Replaces the characters in a substring of this sequence
 989      * with characters in the specified {@code String}. The substring
 990      * begins at the specified {@code start} and extends to the character
 991      * at index {@code end - 1} or to the end of the
 992      * sequence if no such character exists. First the
 993      * characters in the substring are removed and then the specified
 994      * {@code String} is inserted at {@code start}. (This
 995      * sequence will be lengthened to accommodate the
 996      * specified String if necessary.)
 997      *
 998      * @param      start    The beginning index, inclusive.
 999      * @param      end      The ending index, exclusive.
1000      * @param      str   String that will replace previous contents.
1001      * @return     This object.
1002      * @throws     StringIndexOutOfBoundsException  if {@code start}
1003      *             is negative, greater than {@code length()}, or
1004      *             greater than {@code end}.
1005      */
1006     public AbstractStringBuilder replace(int start, int end, String str) {
1007         int count = this.count;
1008         if (end > count) {
1009             end = count;
1010         }
1011         checkRangeSIOOBE(start, end, count);
1012         int len = str.length();
1013         int newCount = count + len - (end - start);
1014         ensureCapacityInternal(newCount);
1015         shift(end, newCount - count);
1016         this.count = newCount;
1017         putStringAt(start, str);
1018         return this;
1019     }
1020 
1021     /**
1022      * Returns a new {@code String} that contains a subsequence of
1023      * characters currently contained in this character sequence. The
1024      * substring begins at the specified index and extends to the end of
1025      * this sequence.
1026      *
1027      * @param      start    The beginning index, inclusive.
1028      * @return     The new string.
1029      * @throws     StringIndexOutOfBoundsException  if {@code start} is
1030      *             less than zero, or greater than the length of this object.
1031      */
1032     public String substring(int start) {
1033         return substring(start, count);
1034     }
1035 
1036     /**
1037      * Returns a new character sequence that is a subsequence of this sequence.
1038      *
1039      * <p> An invocation of this method of the form
1040      *
1041      * <pre>{@code
1042      * sb.subSequence(begin,&nbsp;end)}</pre>
1043      *
1044      * behaves in exactly the same way as the invocation
1045      *
1046      * <pre>{@code
1047      * sb.substring(begin,&nbsp;end)}</pre>
1048      *
1049      * This method is provided so that this class can
1050      * implement the {@link CharSequence} interface.
1051      *
1052      * @param      start   the start index, inclusive.
1053      * @param      end     the end index, exclusive.
1054      * @return     the specified subsequence.
1055      *
1056      * @throws  IndexOutOfBoundsException
1057      *          if {@code start} or {@code end} are negative,
1058      *          if {@code end} is greater than {@code length()},
1059      *          or if {@code start} is greater than {@code end}
1060      * @spec JSR-51
1061      */
1062     @Override
1063     public CharSequence subSequence(int start, int end) {
1064         return substring(start, end);
1065     }
1066 
1067     /**
1068      * Returns a new {@code String} that contains a subsequence of
1069      * characters currently contained in this sequence. The
1070      * substring begins at the specified {@code start} and
1071      * extends to the character at index {@code end - 1}.
1072      *
1073      * @param      start    The beginning index, inclusive.
1074      * @param      end      The ending index, exclusive.
1075      * @return     The new string.
1076      * @throws     StringIndexOutOfBoundsException  if {@code start}
1077      *             or {@code end} are negative or greater than
1078      *             {@code length()}, or {@code start} is
1079      *             greater than {@code end}.
1080      */
1081     public String substring(int start, int end) {
1082         checkRangeSIOOBE(start, end, count);
1083         if (isLatin1()) {
1084             return StringLatin1.newString(value, start, end - start);
1085         }
1086         return StringUTF16.newString(value, start, end - start);
1087     }
1088 
1089     private void shift(int offset, int n) {
1090         System.arraycopy(value, offset << coder,
1091                          value, (offset + n) << coder, (count - offset) << coder);
1092     }
1093 
1094     /**
1095      * Inserts the string representation of a subarray of the {@code str}
1096      * array argument into this sequence. The subarray begins at the
1097      * specified {@code offset} and extends {@code len} {@code char}s.
1098      * The characters of the subarray are inserted into this sequence at
1099      * the position indicated by {@code index}. The length of this
1100      * sequence increases by {@code len} {@code char}s.
1101      *
1102      * @param      index    position at which to insert subarray.
1103      * @param      str       A {@code char} array.
1104      * @param      offset   the index of the first {@code char} in subarray to
1105      *             be inserted.
1106      * @param      len      the number of {@code char}s in the subarray to
1107      *             be inserted.
1108      * @return     This object
1109      * @throws     StringIndexOutOfBoundsException  if {@code index}
1110      *             is negative or greater than {@code length()}, or
1111      *             {@code offset} or {@code len} are negative, or
1112      *             {@code (offset+len)} is greater than
1113      *             {@code str.length}.
1114      */
1115     public AbstractStringBuilder insert(int index, char[] str, int offset,
1116                                         int len)
1117     {
1118         checkOffset(index, count);
1119         checkRangeSIOOBE(offset, offset + len, str.length);
1120         ensureCapacityInternal(count + len);
1121         shift(index, len);
1122         count += len;
1123         putCharsAt(index, str, offset, offset + len);
1124         return this;
1125     }
1126 
1127     /**
1128      * Inserts the string representation of the {@code Object}
1129      * argument into this character sequence.
1130      * <p>
1131      * The overall effect is exactly as if the second argument were
1132      * converted to a string by the method {@link String#valueOf(Object)},
1133      * and the characters of that string were then
1134      * {@link #insert(int,String) inserted} into this character
1135      * sequence at the indicated offset.
1136      * <p>
1137      * The {@code offset} argument must be greater than or equal to
1138      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1139      * of this sequence.
1140      *
1141      * @param      offset   the offset.
1142      * @param      obj      an {@code Object}.
1143      * @return     a reference to this object.
1144      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1145      */
1146     public AbstractStringBuilder insert(int offset, Object obj) {
1147         return insert(offset, String.valueOf(obj));
1148     }
1149 
1150     /**
1151      * Inserts the string into this character sequence.
1152      * <p>
1153      * The characters of the {@code String} argument are inserted, in
1154      * order, into this sequence at the indicated offset, moving up any
1155      * characters originally above that position and increasing the length
1156      * of this sequence by the length of the argument. If
1157      * {@code str} is {@code null}, then the four characters
1158      * {@code "null"} are inserted into this sequence.
1159      * <p>
1160      * The character at index <i>k</i> in the new character sequence is
1161      * equal to:
1162      * <ul>
1163      * <li>the character at index <i>k</i> in the old character sequence, if
1164      * <i>k</i> is less than {@code offset}
1165      * <li>the character at index <i>k</i>{@code -offset} in the
1166      * argument {@code str}, if <i>k</i> is not less than
1167      * {@code offset} but is less than {@code offset+str.length()}
1168      * <li>the character at index <i>k</i>{@code -str.length()} in the
1169      * old character sequence, if <i>k</i> is not less than
1170      * {@code offset+str.length()}
1171      * </ul><p>
1172      * The {@code offset} argument must be greater than or equal to
1173      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1174      * of this sequence.
1175      *
1176      * @param      offset   the offset.
1177      * @param      str      a string.
1178      * @return     a reference to this object.
1179      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1180      */
1181     public AbstractStringBuilder insert(int offset, String str) {
1182         checkOffset(offset, count);
1183         if (str == null) {
1184             str = "null";
1185         }
1186         int len = str.length();
1187         ensureCapacityInternal(count + len);
1188         shift(offset, len);
1189         count += len;
1190         putStringAt(offset, str);
1191         return this;
1192     }
1193 
1194     /**
1195      * Inserts the string representation of the {@code char} array
1196      * argument into this sequence.
1197      * <p>
1198      * The characters of the array argument are inserted into the
1199      * contents of this sequence at the position indicated by
1200      * {@code offset}. The length of this sequence increases by
1201      * the length of the argument.
1202      * <p>
1203      * The overall effect is exactly as if the second argument were
1204      * converted to a string by the method {@link String#valueOf(char[])},
1205      * and the characters of that string were then
1206      * {@link #insert(int,String) inserted} into this character
1207      * sequence at the indicated offset.
1208      * <p>
1209      * The {@code offset} argument must be greater than or equal to
1210      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1211      * of this sequence.
1212      *
1213      * @param      offset   the offset.
1214      * @param      str      a character array.
1215      * @return     a reference to this object.
1216      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1217      */
1218     public AbstractStringBuilder insert(int offset, char[] str) {
1219         checkOffset(offset, count);
1220         int len = str.length;
1221         ensureCapacityInternal(count + len);
1222         shift(offset, len);
1223         count += len;
1224         putCharsAt(offset, str, 0, len);
1225         return this;
1226     }
1227 
1228     /**
1229      * Inserts the specified {@code CharSequence} into this sequence.
1230      * <p>
1231      * The characters of the {@code CharSequence} argument are inserted,
1232      * in order, into this sequence at the indicated offset, moving up
1233      * any characters originally above that position and increasing the length
1234      * of this sequence by the length of the argument s.
1235      * <p>
1236      * The result of this method is exactly the same as if it were an
1237      * invocation of this object's
1238      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
1239      * method.
1240      *
1241      * <p>If {@code s} is {@code null}, then the four characters
1242      * {@code "null"} are inserted into this sequence.
1243      *
1244      * @param      dstOffset   the offset.
1245      * @param      s the sequence to be inserted
1246      * @return     a reference to this object.
1247      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1248      */
1249     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
1250         if (s == null) {
1251             s = "null";
1252         }
1253         if (s instanceof String) {
1254             return this.insert(dstOffset, (String)s);
1255         }
1256         return this.insert(dstOffset, s, 0, s.length());
1257     }
1258 
1259     /**
1260      * Inserts a subsequence of the specified {@code CharSequence} into
1261      * this sequence.
1262      * <p>
1263      * The subsequence of the argument {@code s} specified by
1264      * {@code start} and {@code end} are inserted,
1265      * in order, into this sequence at the specified destination offset, moving
1266      * up any characters originally above that position. The length of this
1267      * sequence is increased by {@code end - start}.
1268      * <p>
1269      * The character at index <i>k</i> in this sequence becomes equal to:
1270      * <ul>
1271      * <li>the character at index <i>k</i> in this sequence, if
1272      * <i>k</i> is less than {@code dstOffset}
1273      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
1274      * the argument {@code s}, if <i>k</i> is greater than or equal to
1275      * {@code dstOffset} but is less than {@code dstOffset+end-start}
1276      * <li>the character at index <i>k</i>{@code -(end-start)} in this
1277      * sequence, if <i>k</i> is greater than or equal to
1278      * {@code dstOffset+end-start}
1279      * </ul><p>
1280      * The {@code dstOffset} argument must be greater than or equal to
1281      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1282      * of this sequence.
1283      * <p>The start argument must be nonnegative, and not greater than
1284      * {@code end}.
1285      * <p>The end argument must be greater than or equal to
1286      * {@code start}, and less than or equal to the length of s.
1287      *
1288      * <p>If {@code s} is {@code null}, then this method inserts
1289      * characters as if the s parameter was a sequence containing the four
1290      * characters {@code "null"}.
1291      *
1292      * @param      dstOffset   the offset in this sequence.
1293      * @param      s       the sequence to be inserted.
1294      * @param      start   the starting index of the subsequence to be inserted.
1295      * @param      end     the end index of the subsequence to be inserted.
1296      * @return     a reference to this object.
1297      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
1298      *             is negative or greater than {@code this.length()}, or
1299      *              {@code start} or {@code end} are negative, or
1300      *              {@code start} is greater than {@code end} or
1301      *              {@code end} is greater than {@code s.length()}
1302      */
1303     public AbstractStringBuilder insert(int dstOffset, CharSequence s,
1304                                         int start, int end)
1305     {
1306         if (s == null) {
1307             s = "null";
1308         }
1309         checkOffset(dstOffset, count);
1310         checkRange(start, end, s.length());
1311         int len = end - start;
1312         ensureCapacityInternal(count + len);
1313         shift(dstOffset, len);
1314         count += len;
1315         putCharsAt(dstOffset, s, start, end);
1316         return this;
1317     }
1318 
1319     /**
1320      * Inserts the string representation of the {@code boolean}
1321      * argument into this sequence.
1322      * <p>
1323      * The overall effect is exactly as if the second argument were
1324      * converted to a string by the method {@link String#valueOf(boolean)},
1325      * and the characters of that string were then
1326      * {@link #insert(int,String) inserted} into this character
1327      * sequence at the indicated offset.
1328      * <p>
1329      * The {@code offset} argument must be greater than or equal to
1330      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1331      * of this sequence.
1332      *
1333      * @param      offset   the offset.
1334      * @param      b        a {@code boolean}.
1335      * @return     a reference to this object.
1336      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1337      */
1338     public AbstractStringBuilder insert(int offset, boolean b) {
1339         return insert(offset, String.valueOf(b));
1340     }
1341 
1342     /**
1343      * Inserts the string representation of the {@code char}
1344      * argument into this sequence.
1345      * <p>
1346      * The overall effect is exactly as if the second argument were
1347      * converted to a string by the method {@link String#valueOf(char)},
1348      * and the character in that string were then
1349      * {@link #insert(int,String) inserted} into this character
1350      * sequence at the indicated offset.
1351      * <p>
1352      * The {@code offset} argument must be greater than or equal to
1353      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1354      * of this sequence.
1355      *
1356      * @param      offset   the offset.
1357      * @param      c        a {@code char}.
1358      * @return     a reference to this object.
1359      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1360      */
1361     public AbstractStringBuilder insert(int offset, char c) {
1362         checkOffset(offset, count);
1363         ensureCapacityInternal(count + 1);
1364         shift(offset, 1);
1365         count += 1;
1366         if (isLatin1() && StringLatin1.canEncode(c)) {
1367             value[offset] = (byte)c;
1368         } else {
1369             if (isLatin1()) {
1370                 inflate();
1371             }
1372             StringUTF16.putCharSB(value, offset, c);
1373         }
1374         return this;
1375     }
1376 
1377     /**
1378      * Inserts the string representation of the second {@code int}
1379      * argument into this sequence.
1380      * <p>
1381      * The overall effect is exactly as if the second argument were
1382      * converted to a string by the method {@link String#valueOf(int)},
1383      * and the characters of that string were then
1384      * {@link #insert(int,String) inserted} into this character
1385      * sequence at the indicated offset.
1386      * <p>
1387      * The {@code offset} argument must be greater than or equal to
1388      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1389      * of this sequence.
1390      *
1391      * @param      offset   the offset.
1392      * @param      i        an {@code int}.
1393      * @return     a reference to this object.
1394      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1395      */
1396     public AbstractStringBuilder insert(int offset, int i) {
1397         return insert(offset, String.valueOf(i));
1398     }
1399 
1400     /**
1401      * Inserts the string representation of the {@code long}
1402      * argument into this sequence.
1403      * <p>
1404      * The overall effect is exactly as if the second argument were
1405      * converted to a string by the method {@link String#valueOf(long)},
1406      * and the characters of that string were then
1407      * {@link #insert(int,String) inserted} into this character
1408      * sequence at the indicated offset.
1409      * <p>
1410      * The {@code offset} argument must be greater than or equal to
1411      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1412      * of this sequence.
1413      *
1414      * @param      offset   the offset.
1415      * @param      l        a {@code long}.
1416      * @return     a reference to this object.
1417      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1418      */
1419     public AbstractStringBuilder insert(int offset, long l) {
1420         return insert(offset, String.valueOf(l));
1421     }
1422 
1423     /**
1424      * Inserts the string representation of the {@code float}
1425      * argument into this sequence.
1426      * <p>
1427      * The overall effect is exactly as if the second argument were
1428      * converted to a string by the method {@link String#valueOf(float)},
1429      * and the characters of that string were then
1430      * {@link #insert(int,String) inserted} into this character
1431      * sequence at the indicated offset.
1432      * <p>
1433      * The {@code offset} argument must be greater than or equal to
1434      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1435      * of this sequence.
1436      *
1437      * @param      offset   the offset.
1438      * @param      f        a {@code float}.
1439      * @return     a reference to this object.
1440      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1441      */
1442     public AbstractStringBuilder insert(int offset, float f) {
1443         return insert(offset, String.valueOf(f));
1444     }
1445 
1446     /**
1447      * Inserts the string representation of the {@code double}
1448      * argument into this sequence.
1449      * <p>
1450      * The overall effect is exactly as if the second argument were
1451      * converted to a string by the method {@link String#valueOf(double)},
1452      * and the characters of that string were then
1453      * {@link #insert(int,String) inserted} into this character
1454      * sequence at the indicated offset.
1455      * <p>
1456      * The {@code offset} argument must be greater than or equal to
1457      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1458      * of this sequence.
1459      *
1460      * @param      offset   the offset.
1461      * @param      d        a {@code double}.
1462      * @return     a reference to this object.
1463      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1464      */
1465     public AbstractStringBuilder insert(int offset, double d) {
1466         return insert(offset, String.valueOf(d));
1467     }
1468 
1469     /**
1470      * Returns the index within this string of the first occurrence of the
1471      * specified substring.
1472      *
1473      * <p>The returned index is the smallest value {@code k} for which:
1474      * <pre>{@code
1475      * this.toString().startsWith(str, k)
1476      * }</pre>
1477      * If no such value of {@code k} exists, then {@code -1} is returned.
1478      *
1479      * @param   str   the substring to search for.
1480      * @return  the index of the first occurrence of the specified substring,
1481      *          or {@code -1} if there is no such occurrence.
1482      */
1483     public int indexOf(String str) {
1484         return indexOf(str, 0);
1485     }
1486 
1487     /**
1488      * Returns the index within this string of the first occurrence of the
1489      * specified substring, starting at the specified index.
1490      *
1491      * <p>The returned index is the smallest value {@code k} for which:
1492      * <pre>{@code
1493      *     k >= Math.min(fromIndex, this.length()) &&
1494      *                   this.toString().startsWith(str, k)
1495      * }</pre>
1496      * If no such value of {@code k} exists, then {@code -1} is returned.
1497      *
1498      * @param   str         the substring to search for.
1499      * @param   fromIndex   the index from which to start the search.
1500      * @return  the index of the first occurrence of the specified substring,
1501      *          starting at the specified index,
1502      *          or {@code -1} if there is no such occurrence.
1503      */
1504     public int indexOf(String str, int fromIndex) {
1505         return String.indexOf(value, coder, count, str, fromIndex);
1506     }
1507 
1508     /**
1509      * Returns the index within this string of the last occurrence of the
1510      * specified substring.  The last occurrence of the empty string "" is
1511      * considered to occur at the index value {@code this.length()}.
1512      *
1513      * <p>The returned index is the largest value {@code k} for which:
1514      * <pre>{@code
1515      * this.toString().startsWith(str, k)
1516      * }</pre>
1517      * If no such value of {@code k} exists, then {@code -1} is returned.
1518      *
1519      * @param   str   the substring to search for.
1520      * @return  the index of the last occurrence of the specified substring,
1521      *          or {@code -1} if there is no such occurrence.
1522      */
1523     public int lastIndexOf(String str) {
1524         return lastIndexOf(str, count);
1525     }
1526 
1527     /**
1528      * Returns the index within this string of the last occurrence of the
1529      * specified substring, searching backward starting at the specified index.
1530      *
1531      * <p>The returned index is the largest value {@code k} for which:
1532      * <pre>{@code
1533      *     k <= Math.min(fromIndex, this.length()) &&
1534      *                   this.toString().startsWith(str, k)
1535      * }</pre>
1536      * If no such value of {@code k} exists, then {@code -1} is returned.
1537      *
1538      * @param   str         the substring to search for.
1539      * @param   fromIndex   the index to start the search from.
1540      * @return  the index of the last occurrence of the specified substring,
1541      *          searching backward from the specified index,
1542      *          or {@code -1} if there is no such occurrence.
1543      */
1544     public int lastIndexOf(String str, int fromIndex) {
1545         return String.lastIndexOf(value, coder, count, str, fromIndex);
1546     }
1547 
1548     /**
1549      * Causes this character sequence to be replaced by the reverse of
1550      * the sequence. If there are any surrogate pairs included in the
1551      * sequence, these are treated as single characters for the
1552      * reverse operation. Thus, the order of the high-low surrogates
1553      * is never reversed.
1554      *
1555      * Let <i>n</i> be the character length of this character sequence
1556      * (not the length in {@code char} values) just prior to
1557      * execution of the {@code reverse} method. Then the
1558      * character at index <i>k</i> in the new character sequence is
1559      * equal to the character at index <i>n-k-1</i> in the old
1560      * character sequence.
1561      *
1562      * <p>Note that the reverse operation may result in producing
1563      * surrogate pairs that were unpaired low-surrogates and
1564      * high-surrogates before the operation. For example, reversing
1565      * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
1566      * a valid surrogate pair.
1567      *
1568      * @return  a reference to this object.
1569      */
1570     public AbstractStringBuilder reverse() {
1571         byte[] val = this.value;
1572         int count = this.count;
1573         int coder = this.coder;
1574         int n = count - 1;
1575         if (COMPACT_STRINGS && coder == LATIN1) {
1576             for (int j = (n-1) >> 1; j >= 0; j--) {
1577                 int k = n - j;
1578                 byte cj = val[j];
1579                 val[j] = val[k];
1580                 val[k] = cj;
1581             }
1582         } else {
1583             StringUTF16.reverse(val, count);
1584         }
1585         return this;
1586     }
1587 
1588     /**
1589      * Returns a string representing the data in this sequence.
1590      * A new {@code String} object is allocated and initialized to
1591      * contain the character sequence currently represented by this
1592      * object. This {@code String} is then returned. Subsequent
1593      * changes to this sequence do not affect the contents of the
1594      * {@code String}.
1595      *
1596      * @return  a string representation of this sequence of characters.
1597      */
1598     @Override
1599     public abstract String toString();
1600 
1601     /**
1602      * {@inheritDoc}
1603      * @since 9
1604      */
1605     @Override
1606     public IntStream chars() {
1607         // Reuse String-based spliterator. This requires a supplier to
1608         // capture the value and count when the terminal operation is executed
1609         return StreamSupport.intStream(
1610                 () -> {
1611                     // The combined set of field reads are not atomic and thread
1612                     // safe but bounds checks will ensure no unsafe reads from
1613                     // the byte array
1614                     byte[] val = this.value;
1615                     int count = this.count;
1616                     byte coder = this.coder;
1617                     return coder == LATIN1
1618                            ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
1619                            : new StringUTF16.CharsSpliterator(val, 0, count, 0);
1620                 },
1621                 Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
1622                 false);
1623     }
1624 
1625     /**
1626      * {@inheritDoc}
1627      * @since 9
1628      */
1629     @Override
1630     public IntStream codePoints() {
1631         // Reuse String-based spliterator. This requires a supplier to
1632         // capture the value and count when the terminal operation is executed
1633         return StreamSupport.intStream(
1634                 () -> {
1635                     // The combined set of field reads are not atomic and thread
1636                     // safe but bounds checks will ensure no unsafe reads from
1637                     // the byte array
1638                     byte[] val = this.value;
1639                     int count = this.count;
1640                     byte coder = this.coder;
1641                     return coder == LATIN1
1642                            ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
1643                            : new StringUTF16.CodePointsSpliterator(val, 0, count, 0);
1644                 },
1645                 Spliterator.ORDERED,
1646                 false);
1647     }
1648 
1649     /**
1650      * Needed by {@code String} for the contentEquals method.
1651      */
1652     final byte[] getValue() {
1653         return value;
1654     }
1655 
1656     /*
1657      * Invoker guarantees it is in UTF16 (inflate itself for asb), if two
1658      * coders are different and the dstBegin has enough space
1659      *
1660      * @param dstBegin  the char index, not offset of byte[]
1661      * @param coder     the coder of dst[]
1662      */
1663     void getBytes(byte dst[], int dstBegin, byte coder) {
1664         if (this.coder == coder) {
1665             System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
1666         } else {        // this.coder == LATIN && coder == UTF16
1667             StringLatin1.inflate(value, 0, dst, dstBegin, count);
1668         }
1669     }
1670 
1671     /* for readObject() */
1672     void initBytes(char[] value, int off, int len) {
1673         if (String.COMPACT_STRINGS) {
1674             this.value = StringUTF16.compress(value, off, len);
1675             if (this.value != null) {
1676                 this.coder = LATIN1;
1677                 return;
1678             }
1679         }
1680         this.coder = UTF16;
1681         this.value = StringUTF16.toBytes(value, off, len);
1682     }
1683 
1684     final byte getCoder() {
1685         return COMPACT_STRINGS ? coder : UTF16;
1686     }
1687 
1688     final boolean isLatin1() {
1689         return COMPACT_STRINGS && coder == LATIN1;
1690     }
1691 
1692     private final void putCharsAt(int index, char[] s, int off, int end) {
1693         if (isLatin1()) {
1694             byte[] val = this.value;
1695             for (int i = off, j = index; i < end; i++) {
1696                 char c = s[i];
1697                 if (StringLatin1.canEncode(c)) {
1698                     val[j++] = (byte)c;
1699                 } else {
1700                     inflate();
1701                     StringUTF16.putCharsSB(this.value, j, s, i, end);
1702                     return;
1703                 }
1704             }
1705         } else {
1706             StringUTF16.putCharsSB(this.value, index, s, off, end);
1707         }
1708     }
1709 
1710     private final void putCharsAt(int index, CharSequence s, int off, int end) {
1711         if (isLatin1()) {
1712             byte[] val = this.value;
1713             for (int i = off, j = index; i < end; i++) {
1714                 char c = s.charAt(i);
1715                 if (StringLatin1.canEncode(c)) {
1716                     val[j++] = (byte)c;
1717                 } else {
1718                     inflate();
1719                     StringUTF16.putCharsSB(this.value, j, s, i, end);
1720                     return;
1721                 }
1722             }
1723         } else {
1724             StringUTF16.putCharsSB(this.value, index, s, off, end);
1725         }
1726     }
1727 
1728     private final void putStringAt(int index, String str) {
1729         if (getCoder() != str.coder()) {
1730             inflate();
1731         }
1732         str.getBytes(value, index, coder);
1733     }
1734 
1735     private final void appendChars(char[] s, int off, int end) {
1736         int count = this.count;
1737         if (isLatin1()) {
1738             byte[] val = this.value;
1739             for (int i = off, j = count; i < end; i++) {
1740                 char c = s[i];
1741                 if (StringLatin1.canEncode(c)) {
1742                     val[j++] = (byte)c;
1743                 } else {
1744                     this.count = count = j;
1745                     inflate();
1746                     StringUTF16.putCharsSB(this.value, j, s, i, end);
1747                     this.count = count + end - i;
1748                     return;
1749                 }
1750             }
1751         } else {
1752             StringUTF16.putCharsSB(this.value, count, s, off, end);
1753         }
1754         this.count = count + end - off;
1755     }
1756 
1757     private final void appendChars(CharSequence s, int off, int end) {
1758         if (isLatin1()) {
1759             byte[] val = this.value;
1760             for (int i = off, j = count; i < end; i++) {
1761                 char c = s.charAt(i);
1762                 if (StringLatin1.canEncode(c)) {
1763                     val[j++] = (byte)c;
1764                 } else {
1765                     count = j;
1766                     inflate();
1767                     StringUTF16.putCharsSB(this.value, j, s, i, end);
1768                     count += end - i;
1769                     return;
1770                 }
1771             }
1772         } else {
1773             StringUTF16.putCharsSB(this.value, count, s, off, end);
1774         }
1775         count += end - off;
1776     }
1777 
1778     /* IndexOutOfBoundsException, if out of bounds */
1779     private static void checkRange(int start, int end, int len) {
1780         if (start < 0 || start > end || end > len) {
1781             throw new IndexOutOfBoundsException(
1782                 "start " + start + ", end " + end + ", length " + len);
1783         }
1784     }
1785 
1786     /* StringIndexOutOfBoundsException, if out of bounds */
1787     private static void checkRangeSIOOBE(int start, int end, int len) {
1788         if (start < 0 || start > end || end > len) {
1789             throw new StringIndexOutOfBoundsException(
1790                 "start " + start + ", end " + end + ", length " + len);
1791         }
1792     }
1793 }