       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.FloatingDecimal;
      29
      30 import java.util.Arrays;
      31 import java.util.Spliterator;
      32 import java.util.stream.IntStream;
      33 import java.util.stream.StreamSupport;
      34 import jdk.internal.util.ArraysSupport;
      35
      36 import static java.lang.String.COMPACT_STRINGS;
      37 import static java.lang.String.UTF16;
      38 import static java.lang.String.LATIN1;
      39 import static java.lang.String.checkIndex;
      40 import static java.lang.String.checkOffset;
      41
      42 /**
      43  * A mutable sequence of characters.
      44  * <p>
      45  * Implements a modifiable string. At any point in time it contains some
      46  * particular sequence of characters, but the length and content of the
      47  * sequence can be changed through certain method calls.
      48  *
      49  * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
      50  * or method in this class will cause a {@link NullPointerException} to be
      51  * thrown.
      52  *
      53  * @author      Michael McCloskey
      54  * @author      Martin Buchholz
      55  * @author      Ulf Zibis
      56  * @since       1.5
      57  */
      58 abstract class AbstractStringBuilder implements Appendable, CharSequence {
      59     /**
      60      * The value is used for character storage.
      61      */
      62     byte[] value;
      63
      64     /**
      65      * The id of the encoding used to encode the bytes in {@code value}.
      66      */
      67     byte coder;
      68
      69     /**
      70      * The count is the number of characters used.
      71      */
      72     int count;
      73
      74     private static final byte[] EMPTYVALUE = new byte[0];
      75
      76     /**
      77      * This no-arg constructor is necessary for serialization of subclasses.
      78      */
      79     AbstractStringBuilder() {
      80         value = EMPTYVALUE;
      81     }
      82
      83     /**
      84      * Creates an AbstractStringBuilder of the specified capacity.
      85      */
      86     AbstractStringBuilder(int capacity) {
      87         if (COMPACT_STRINGS) {
      88             value = new byte[capacity];
      89             coder = LATIN1;
      90         } else {
      91             value = StringUTF16.newBytesFor(capacity);
      92             coder = UTF16;
      93         }
      94     }
      95
      96     /**
      97      * Constructs an AbstractStringBuilder that contains the same characters
      98      * as the specified {@code String}. The initial capacity of
      99      * the string builder is {@code 16} plus the length of the
     100      * {@code String} argument.
     101      *
     102      * @param      str   the string to copy.
     103      */
     104     AbstractStringBuilder(String str) {
     105         int length = str.length();
     106         int capacity = (length < Integer.MAX_VALUE - 16)
     107                 ? length + 16 : Integer.MAX_VALUE;
     108         final byte initCoder = str.coder();
     109         coder = initCoder;
     110         value = (initCoder == LATIN1)
     111                 ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
     112         append(str);
     113     }
     114
     115     /**
     116      * Constructs an AbstractStringBuilder that contains the same characters
     117      * as the specified {@code CharSequence}. The initial capacity of
     118      * the string builder is {@code 16} plus the length of the
     119      * {@code CharSequence} argument.
     120      *
     121      * @param      seq   the sequence to copy.
     122      */
     123     AbstractStringBuilder(CharSequence seq) {
     124         int length = seq.length();
     125         if (length < 0) {
     126             throw new NegativeArraySizeException("Negative length: " + length);
     127         }
     128         int capacity = (length < Integer.MAX_VALUE - 16)
     129                 ? length + 16 : Integer.MAX_VALUE;
     130
     131         final byte initCoder;
     132         if (COMPACT_STRINGS) {
     133             if (seq instanceof AbstractStringBuilder) {
     134                 initCoder = ((AbstractStringBuilder)seq).getCoder();
     135             } else if (seq instanceof String) {
     136                 initCoder = ((String)seq).coder();
     137             } else {
     138                 initCoder = LATIN1;
     139             }
     140         } else {
     141             initCoder = UTF16;
     142         }
     143
     144         coder = initCoder;
     145         value = (initCoder == LATIN1)
     146                 ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
     147         append(seq);
     148     }
     149
     150     /**
     151      * Compares the objects of two AbstractStringBuilder implementations lexicographically.
     152      *
     153      * @since 11
     154      */
     155     int compareTo(AbstractStringBuilder another) {
     156         if (this == another) {
     157             return 0;
     158         }
     159
     160         byte val1[] = value;
     161         byte val2[] = another.value;
     162         int count1 = this.count;
     163         int count2 = another.count;
     164
     165         if (coder == another.coder) {
     166             return isLatin1() ? StringLatin1.compareTo(val1, val2, count1, count2)
     167                               : StringUTF16.compareTo(val1, val2, count1, count2);
     168         }
     169         return isLatin1() ? StringLatin1.compareToUTF16(val1, val2, count1, count2)
     170                           : StringUTF16.compareToLatin1(val1, val2, count1, count2);
     171     }
     172
     173     /**
     174      * Returns the length (character count).
     175      *
     176      * @return  the length of the sequence of characters currently
     177      *          represented by this object
     178      */
     179     @Override
     180     public int length() {
     181         return count;
     182     }
     183
     184     /**
     185      * Returns the current capacity. The capacity is the number of characters
     186      * that can be stored (including already written characters), beyond which
     187      * an allocation will occur.
     188      *
     189      * @return  the current capacity
     190      */
     191     public int capacity() {
     192         return value.length >> coder;
     193     }
     194
     195     /**
     196      * Ensures that the capacity is at least equal to the specified minimum.
     197      * If the current capacity is less than the argument, then a new internal
     198      * array is allocated with greater capacity. The new capacity is the
     199      * larger of:
     200      * <ul>
     201      * <li>The {@code minimumCapacity} argument.
     202      * <li>Twice the old capacity, plus {@code 2}.
     203      * </ul>
     204      * If the {@code minimumCapacity} argument is nonpositive, this
     205      * method takes no action and simply returns.
     206      * Note that subsequent operations on this object can reduce the
     207      * actual capacity below that requested here.
     208      *
     209      * @param   minimumCapacity   the minimum desired capacity.
     210      */
     211     public void ensureCapacity(int minimumCapacity) {
     212         if (minimumCapacity > 0) {
     213             ensureCapacityInternal(minimumCapacity);
     214         }
     215     }
     216
     217     /**
     218      * For positive values of {@code minimumCapacity}, this method
     219      * behaves like {@code ensureCapacity}, however it is never
     220      * synchronized.
     221      * If {@code minimumCapacity} is non positive due to numeric
     222      * overflow, this method throws {@code OutOfMemoryError}.
     223      */
     224     private void ensureCapacityInternal(int minimumCapacity) {
     225         // overflow-conscious code
     226         int oldCapacity = value.length >> coder;
     227         if (minimumCapacity - oldCapacity > 0) {
     228             value = Arrays.copyOf(value,
     229                     newCapacity(minimumCapacity) << coder);
     230         }
     231     }
     232
     233     /**
     234      * The maximum size of array to allocate (unless necessary).
     235      * Some VMs reserve some header words in an array.
     236      * Attempts to allocate larger arrays may result in
     237      * OutOfMemoryError: Requested array size exceeds VM limit
     238      */
     239     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
     240
     241     /**
     242      * Returns a capacity at least as large as the given minimum capacity.
     243      * Returns the current capacity increased by the current length + 2 if
     244      * that suffices.
     245      * Will not return a capacity greater than
     246      * {@code (MAX_ARRAY_SIZE >> coder)} unless the given minimum capacity
     247      * is greater than that.
     248      *
     249      * @param  minCapacity the desired minimum capacity
     250      * @throws OutOfMemoryError if minCapacity is less than zero or
     251      *         greater than (Integer.MAX_VALUE >> coder)
     252      */
     253     private int newCapacity(int minCapacity) {
     254         int oldLength = value.length;
     255         int newLength = minCapacity << coder;
     256         int growth = newLength - oldLength;
     257         int length = ArraysSupport.newLength(oldLength, growth, oldLength + (2 << coder));
     258         if (length == Integer.MAX_VALUE) {
     259             throw new OutOfMemoryError("Required length exceeds implementation limit");
     260         }
     261         return length >> coder;
     262     }
     263
     264     /**
     265      * If the coder is "isLatin1", this inflates the internal 8-bit storage
     266      * to 16-bit <hi=0, low> pair storage.
     267      */
     268     private void inflate() {
     269         if (!isLatin1()) {
     270             return;
     271         }
     272         byte[] buf = StringUTF16.newBytesFor(value.length);
     273         StringLatin1.inflate(value, 0, buf, 0, count);
     274         this.value = buf;
     275         this.coder = UTF16;
     276     }
     277
     278     /**
     279      * Attempts to reduce storage used for the character sequence.
     280      * If the buffer is larger than necessary to hold its current sequence of
     281      * characters, then it may be resized to become more space efficient.
     282      * Calling this method may, but is not required to, affect the value
     283      * returned by a subsequent call to the {@link #capacity()} method.
     284      */
     285     public void trimToSize() {
     286         int length = count << coder;
     287         if (length < value.length) {
     288             value = Arrays.copyOf(value, length);
     289         }
     290     }
     291
     292     /**
     293      * Sets the length of the character sequence.
     294      * The sequence is changed to a new character sequence
     295      * whose length is specified by the argument. For every nonnegative
     296      * index <i>k</i> less than {@code newLength}, the character at
     297      * index <i>k</i> in the new character sequence is the same as the
     298      * character at index <i>k</i> in the old sequence if <i>k</i> is less
     299      * than the length of the old character sequence; otherwise, it is the
     300      * null character {@code '\u005Cu0000'}.
     301      *
     302      * In other words, if the {@code newLength} argument is less than
     303      * the current length, the length is changed to the specified length.
     304      * <p>
     305      * If the {@code newLength} argument is greater than or equal
     306      * to the current length, sufficient null characters
     307      * ({@code '\u005Cu0000'}) are appended so that
     308      * length becomes the {@code newLength} argument.
     309      * <p>
     310      * The {@code newLength} argument must be greater than or equal
     311      * to {@code 0}.
     312      *
     313      * @param      newLength   the new length
     314      * @throws     IndexOutOfBoundsException  if the
     315      *               {@code newLength} argument is negative.
     316      */
     317     public void setLength(int newLength) {
     318         if (newLength < 0) {
     319             throw new StringIndexOutOfBoundsException(newLength);
     320         }
     321         ensureCapacityInternal(newLength);
     322         if (count < newLength) {
     323             if (isLatin1()) {
     324                 StringLatin1.fillNull(value, count, newLength);
     325             } else {
     326                 StringUTF16.fillNull(value, count, newLength);
     327             }
     328         }
     329         count = newLength;
     330     }
     331
     332     /**
     333      * Returns the {@code char} value in this sequence at the specified index.
     334      * The first {@code char} value is at index {@code 0}, the next at index
     335      * {@code 1}, and so on, as in array indexing.
     336      * <p>
     337      * The index argument must be greater than or equal to
     338      * {@code 0}, and less than the length of this sequence.
     339      *
     340      * <p>If the {@code char} value specified by the index is a
     341      * <a href="Character.html#unicode">surrogate</a>, the surrogate
     342      * value is returned.
     343      *
     344      * @param      index   the index of the desired {@code char} value.
     345      * @return     the {@code char} value at the specified index.
     346      * @throws     IndexOutOfBoundsException  if {@code index} is
     347      *             negative or greater than or equal to {@code length()}.
     348      */
     349     @Override
     350     public char charAt(int index) {
     351         checkIndex(index, count);
     352         if (isLatin1()) {
     353             return (char)(value[index] & 0xff);
     354         }
     355         return StringUTF16.charAt(value, index);
     356     }
     357
     358     /**
     359      * Returns the character (Unicode code point) at the specified
     360      * index. The index refers to {@code char} values
     361      * (Unicode code units) and ranges from {@code 0} to
     362      * {@link #length()}{@code  - 1}.
     363      *
     364      * <p> If the {@code char} value specified at the given index
     365      * is in the high-surrogate range, the following index is less
     366      * than the length of this sequence, and the
     367      * {@code char} value at the following index is in the
     368      * low-surrogate range, then the supplementary code point
     369      * corresponding to this surrogate pair is returned. Otherwise,
     370      * the {@code char} value at the given index is returned.
     371      *
     372      * @param      index the index to the {@code char} values
     373      * @return     the code point value of the character at the
     374      *             {@code index}
     375      * @throws     IndexOutOfBoundsException  if the {@code index}
     376      *             argument is negative or not less than the length of this
     377      *             sequence.
     378      */
     379     public int codePointAt(int index) {
     380         int count = this.count;
     381         byte[] value = this.value;
     382         checkIndex(index, count);
     383         if (isLatin1()) {
     384             return value[index] & 0xff;
     385         }
     386         return StringUTF16.codePointAtSB(value, index, count);
     387     }
     388
     389     /**
     390      * Returns the character (Unicode code point) before the specified
     391      * index. The index refers to {@code char} values
     392      * (Unicode code units) and ranges from {@code 1} to {@link
     393      * #length()}.
     394      *
     395      * <p> If the {@code char} value at {@code (index - 1)}
     396      * is in the low-surrogate range, {@code (index - 2)} is not
     397      * negative, and the {@code char} value at {@code (index -
     398      * 2)} is in the high-surrogate range, then the
     399      * supplementary code point value of the surrogate pair is
     400      * returned. If the {@code char} value at {@code index -
     401      * 1} is an unpaired low-surrogate or a high-surrogate, the
     402      * surrogate value is returned.
     403      *
     404      * @param     index the index following the code point that should be returned
     405      * @return    the Unicode code point value before the given index.
     406      * @throws    IndexOutOfBoundsException if the {@code index}
     407      *            argument is less than 1 or greater than the length
     408      *            of this sequence.
     409      */
     410     public int codePointBefore(int index) {
     411         int i = index - 1;
     412         if (i < 0 || i >= count) {
     413             throw new StringIndexOutOfBoundsException(index);
     414         }
     415         if (isLatin1()) {
     416             return value[i] & 0xff;
     417         }
     418         return StringUTF16.codePointBeforeSB(value, index);
     419     }
     420
     421     /**
     422      * Returns the number of Unicode code points in the specified text
     423      * range of this sequence. The text range begins at the specified
     424      * {@code beginIndex} and extends to the {@code char} at
     425      * index {@code endIndex - 1}. Thus the length (in
     426      * {@code char}s) of the text range is
     427      * {@code endIndex-beginIndex}. Unpaired surrogates within
     428      * this sequence count as one code point each.
     429      *
     430      * @param beginIndex the index to the first {@code char} of
     431      * the text range.
     432      * @param endIndex the index after the last {@code char} of
     433      * the text range.
     434      * @return the number of Unicode code points in the specified text
     435      * range
     436      * @throws    IndexOutOfBoundsException if the
     437      * {@code beginIndex} is negative, or {@code endIndex}
     438      * is larger than the length of this sequence, or
     439      * {@code beginIndex} is larger than {@code endIndex}.
     440      */
     441     public int codePointCount(int beginIndex, int endIndex) {
     442         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
     443             throw new IndexOutOfBoundsException();
     444         }
     445         if (isLatin1()) {
     446             return endIndex - beginIndex;
     447         }
     448         return StringUTF16.codePointCountSB(value, beginIndex, endIndex);
     449     }
     450
     451     /**
     452      * Returns the index within this sequence that is offset from the
     453      * given {@code index} by {@code codePointOffset} code
     454      * points. Unpaired surrogates within the text range given by
     455      * {@code index} and {@code codePointOffset} count as
     456      * one code point each.
     457      *
     458      * @param index the index to be offset
     459      * @param codePointOffset the offset in code points
     460      * @return the index within this sequence
     461      * @throws    IndexOutOfBoundsException if {@code index}
     462      *   is negative or larger then the length of this sequence,
     463      *   or if {@code codePointOffset} is positive and the subsequence
     464      *   starting with {@code index} has fewer than
     465      *   {@code codePointOffset} code points,
     466      *   or if {@code codePointOffset} is negative and the subsequence
     467      *   before {@code index} has fewer than the absolute value of
     468      *   {@code codePointOffset} code points.
     469      */
     470     public int offsetByCodePoints(int index, int codePointOffset) {
     471         if (index < 0 || index > count) {
     472             throw new IndexOutOfBoundsException();
     473         }
     474         return Character.offsetByCodePoints(this,
     475                                             index, codePointOffset);
     476     }
     477
     478     /**
     479      * Characters are copied from this sequence into the
     480      * destination character array {@code dst}. The first character to
     481      * be copied is at index {@code srcBegin}; the last character to
     482      * be copied is at index {@code srcEnd-1}. The total number of
     483      * characters to be copied is {@code srcEnd-srcBegin}. The
     484      * characters are copied into the subarray of {@code dst} starting
     485      * at index {@code dstBegin} and ending at index:
     486      * <pre>{@code
     487      * dstbegin + (srcEnd-srcBegin) - 1
     488      * }</pre>
     489      *
     490      * @param      srcBegin   start copying at this offset.
     491      * @param      srcEnd     stop copying at this offset.
     492      * @param      dst        the array to copy the data into.
     493      * @param      dstBegin   offset into {@code dst}.
     494      * @throws     IndexOutOfBoundsException  if any of the following is true:
     495      *             <ul>
     496      *             <li>{@code srcBegin} is negative
     497      *             <li>{@code dstBegin} is negative
     498      *             <li>the {@code srcBegin} argument is greater than
     499      *             the {@code srcEnd} argument.
     500      *             <li>{@code srcEnd} is greater than
     501      *             {@code this.length()}.
     502      *             <li>{@code dstBegin+srcEnd-srcBegin} is greater than
     503      *             {@code dst.length}
     504      *             </ul>
     505      */
     506     public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
     507     {
     508         checkRangeSIOOBE(srcBegin, srcEnd, count);  // compatible to old version
     509         int n = srcEnd - srcBegin;
     510         checkRange(dstBegin, dstBegin + n, dst.length);
     511         if (isLatin1()) {
     512             StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin);
     513         } else {
     514             StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
     515         }
     516     }
     517
     518     /**
     519      * The character at the specified index is set to {@code ch}. This
     520      * sequence is altered to represent a new character sequence that is
     521      * identical to the old character sequence, except that it contains the
     522      * character {@code ch} at position {@code index}.
     523      * <p>
     524      * The index argument must be greater than or equal to
     525      * {@code 0}, and less than the length of this sequence.
     526      *
     527      * @param      index   the index of the character to modify.
     528      * @param      ch      the new character.
     529      * @throws     IndexOutOfBoundsException  if {@code index} is
     530      *             negative or greater than or equal to {@code length()}.
     531      */
     532     public void setCharAt(int index, char ch) {
     533         checkIndex(index, count);
     534         if (isLatin1() && StringLatin1.canEncode(ch)) {
     535             value[index] = (byte)ch;
     536         } else {
     537             if (isLatin1()) {
     538                 inflate();
     539             }
     540             StringUTF16.putCharSB(value, index, ch);
     541         }
     542     }
     543
     544     /**
     545      * Appends the string representation of the {@code Object} argument.
     546      * <p>
     547      * The overall effect is exactly as if the argument were converted
     548      * to a string by the method {@link String#valueOf(Object)},
     549      * and the characters of that string were then
     550      * {@link #append(String) appended} to this character sequence.
     551      *
     552      * @param   obj   an {@code Object}.
     553      * @return  a reference to this object.
     554      */
     555     public AbstractStringBuilder append(Object obj) {
     556         return append(String.valueOf(obj));
     557     }
     558
     559     /**
     560      * Appends the specified string to this character sequence.
     561      * <p>
     562      * The characters of the {@code String} argument are appended, in
     563      * order, increasing the length of this sequence by the length of the
     564      * argument. If {@code str} is {@code null}, then the four
     565      * characters {@code "null"} are appended.
     566      * <p>
     567      * Let <i>n</i> be the length of this character sequence just prior to
     568      * execution of the {@code append} method. Then the character at
     569      * index <i>k</i> in the new character sequence is equal to the character
     570      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
     571      * than <i>n</i>; otherwise, it is equal to the character at index
     572      * <i>k-n</i> in the argument {@code str}.
     573      *
     574      * @param   str   a string.
     575      * @return  a reference to this object.
     576      */
     577     public AbstractStringBuilder append(String str) {
     578         if (str == null) {
     579             return appendNull();
     580         }
     581         int len = str.length();
     582         ensureCapacityInternal(count + len);
     583         putStringAt(count, str);
     584         count += len;
     585         return this;
     586     }
     587
     588     // Documentation in subclasses because of synchro difference

     589     public AbstractStringBuilder append(StringBuffer sb) {
     590         return this.append((AbstractStringBuilder)sb);
     591     }
     592
     593     /**
     594      * @since 1.8
     595      */
     596     AbstractStringBuilder append(AbstractStringBuilder asb) {
     597         if (asb == null) {
     598             return appendNull();
     599         }
     600         int len = asb.length();
     601         ensureCapacityInternal(count + len);
     602         if (getCoder() != asb.getCoder()) {
     603             inflate();
     604         }
     605         asb.getBytes(value, count, coder);
     606         count += len;
     607         return this;
     608     }
     609
     610     // Documentation in subclasses because of synchro difference
     611     @Override
     612     public AbstractStringBuilder append(CharSequence s) {
     613         if (s == null) {
     614             return appendNull();
     615         }
     616         if (s instanceof String) {
     617             return this.append((String)s);
     618         }
     619         if (s instanceof AbstractStringBuilder) {
     620             return this.append((AbstractStringBuilder)s);
     621         }
     622         return this.append(s, 0, s.length());
     623     }
     624
     625     private AbstractStringBuilder appendNull() {
     626         ensureCapacityInternal(count + 4);
     627         int count = this.count;
     628         byte[] val = this.value;
     629         if (isLatin1()) {
     630             val[count++] = 'n';
     631             val[count++] = 'u';
     632             val[count++] = 'l';
     633             val[count++] = 'l';
     634         } else {
     635             count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
     636         }
     637         this.count = count;
     638         return this;
     639     }
     640
     641     /**
     642      * Appends a subsequence of the specified {@code CharSequence} to this
     643      * sequence.
     644      * <p>
     645      * Characters of the argument {@code s}, starting at
     646      * index {@code start}, are appended, in order, to the contents of
     647      * this sequence up to the (exclusive) index {@code end}. The length
     648      * of this sequence is increased by the value of {@code end - start}.
     649      * <p>
     650      * Let <i>n</i> be the length of this character sequence just prior to
     651      * execution of the {@code append} method. Then the character at
     652      * index <i>k</i> in this character sequence becomes equal to the
     653      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
     654      * <i>n</i>; otherwise, it is equal to the character at index
     655      * <i>k+start-n</i> in the argument {@code s}.
     656      * <p>
     657      * If {@code s} is {@code null}, then this method appends
     658      * characters as if the s parameter was a sequence containing the four
     659      * characters {@code "null"}.
     660      *
     661      * @param   s the sequence to append.
     662      * @param   start   the starting index of the subsequence to be appended.
     663      * @param   end     the end index of the subsequence to be appended.
     664      * @return  a reference to this object.
     665      * @throws     IndexOutOfBoundsException if
     666      *             {@code start} is negative, or
     667      *             {@code start} is greater than {@code end} or
     668      *             {@code end} is greater than {@code s.length()}
     669      */
     670     @Override
     671     public AbstractStringBuilder append(CharSequence s, int start, int end) {
     672         if (s == null) {
     673             s = "null";
     674         }
     675         checkRange(start, end, s.length());
     676         int len = end - start;
     677         ensureCapacityInternal(count + len);
     678         if (s instanceof String) {
     679             appendChars((String)s, start, end);
     680         } else {
     681             appendChars(s, start, end);
     682         }
     683         return this;
     684     }
     685
     686
     687     /**
     688      * Appends the string representation of the {@code char} array
     689      * argument to this sequence.
     690      * <p>
     691      * The characters of the array argument are appended, in order, to
     692      * the contents of this sequence. The length of this sequence
     693      * increases by the length of the argument.
     694      * <p>
     695      * The overall effect is exactly as if the argument were converted
     696      * to a string by the method {@link String#valueOf(char[])},
     697      * and the characters of that string were then
     698      * {@link #append(String) appended} to this character sequence.
     699      *
     700      * @param   str   the characters to be appended.
     701      * @return  a reference to this object.
     702      */
     703     public AbstractStringBuilder append(char[] str) {
     704         int len = str.length;
     705         ensureCapacityInternal(count + len);
     706         appendChars(str, 0, len);
     707         return this;
     708     }
     709
     710     /**
     711      * Appends the string representation of a subarray of the
     712      * {@code char} array argument to this sequence.
     713      * <p>
     714      * Characters of the {@code char} array {@code str}, starting at
     715      * index {@code offset}, are appended, in order, to the contents
     716      * of this sequence. The length of this sequence increases
     717      * by the value of {@code len}.
     718      * <p>
     719      * The overall effect is exactly as if the arguments were converted
     720      * to a string by the method {@link String#valueOf(char[],int,int)},
     721      * and the characters of that string were then
     722      * {@link #append(String) appended} to this character sequence.
     723      *
     724      * @param   str      the characters to be appended.
     725      * @param   offset   the index of the first {@code char} to append.
     726      * @param   len      the number of {@code char}s to append.
     727      * @return  a reference to this object.
     728      * @throws IndexOutOfBoundsException
     729      *         if {@code offset < 0} or {@code len < 0}
     730      *         or {@code offset+len > str.length}
     731      */
     732     public AbstractStringBuilder append(char str[], int offset, int len) {
     733         int end = offset + len;
     734         checkRange(offset, end, str.length);
     735         ensureCapacityInternal(count + len);
     736         appendChars(str, offset, end);
     737         return this;
     738     }
     739
     740     /**
     741      * Appends the string representation of the {@code boolean}
     742      * argument to the sequence.
     743      * <p>
     744      * The overall effect is exactly as if the argument were converted
     745      * to a string by the method {@link String#valueOf(boolean)},
     746      * and the characters of that string were then
     747      * {@link #append(String) appended} to this character sequence.
     748      *
     749      * @param   b   a {@code boolean}.
     750      * @return  a reference to this object.
     751      */
     752     public AbstractStringBuilder append(boolean b) {
     753         ensureCapacityInternal(count + (b ? 4 : 5));
     754         int count = this.count;
     755         byte[] val = this.value;
     756         if (isLatin1()) {
     757             if (b) {
     758                 val[count++] = 't';
     759                 val[count++] = 'r';
     760                 val[count++] = 'u';
     761                 val[count++] = 'e';
     762             } else {
     763                 val[count++] = 'f';
     764                 val[count++] = 'a';
     765                 val[count++] = 'l';
     766                 val[count++] = 's';
     767                 val[count++] = 'e';
     768             }
     769         } else {
     770             if (b) {
     771                 count = StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e');
     772             } else {
     773                 count = StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e');
     774             }
     775         }
     776         this.count = count;
     777         return this;
     778     }
     779
     780     /**
     781      * Appends the string representation of the {@code char}
     782      * argument to this sequence.
     783      * <p>
     784      * The argument is appended to the contents of this sequence.
     785      * The length of this sequence increases by {@code 1}.
     786      * <p>
     787      * The overall effect is exactly as if the argument were converted
     788      * to a string by the method {@link String#valueOf(char)},
     789      * and the character in that string were then
     790      * {@link #append(String) appended} to this character sequence.
     791      *
     792      * @param   c   a {@code char}.
     793      * @return  a reference to this object.
     794      */
     795     @Override
     796     public AbstractStringBuilder append(char c) {
     797         ensureCapacityInternal(count + 1);
     798         if (isLatin1() && StringLatin1.canEncode(c)) {
     799             value[count++] = (byte)c;
     800         } else {
     801             if (isLatin1()) {
     802                 inflate();
     803             }
     804             StringUTF16.putCharSB(value, count++, c);
     805         }
     806         return this;
     807     }
     808
     809     /**
     810      * Appends the string representation of the {@code int}
     811      * argument to this sequence.
     812      * <p>
     813      * The overall effect is exactly as if the argument were converted
     814      * to a string by the method {@link String#valueOf(int)},
     815      * and the characters of that string were then
     816      * {@link #append(String) appended} to this character sequence.
     817      *
     818      * @param   i   an {@code int}.
     819      * @return  a reference to this object.
     820      */
     821     public AbstractStringBuilder append(int i) {
     822         int count = this.count;
     823         int spaceNeeded = count + Integer.stringSize(i);
     824         ensureCapacityInternal(spaceNeeded);
     825         if (isLatin1()) {
     826             Integer.getChars(i, spaceNeeded, value);
     827         } else {
     828             StringUTF16.getChars(i, count, spaceNeeded, value);
     829         }
     830         this.count = spaceNeeded;
     831         return this;
     832     }
     833
     834     /**
     835      * Appends the string representation of the {@code long}
     836      * argument to this sequence.
     837      * <p>
     838      * The overall effect is exactly as if the argument were converted
     839      * to a string by the method {@link String#valueOf(long)},
     840      * and the characters of that string were then
     841      * {@link #append(String) appended} to this character sequence.
     842      *
     843      * @param   l   a {@code long}.
     844      * @return  a reference to this object.
     845      */
     846     public AbstractStringBuilder append(long l) {
     847         int count = this.count;
     848         int spaceNeeded = count + Long.stringSize(l);
     849         ensureCapacityInternal(spaceNeeded);
     850         if (isLatin1()) {
     851             Long.getChars(l, spaceNeeded, value);
     852         } else {
     853             StringUTF16.getChars(l, count, spaceNeeded, value);
     854         }
     855         this.count = spaceNeeded;
     856         return this;
     857     }
     858
     859     /**
     860      * Appends the string representation of the {@code float}
     861      * argument to this sequence.
     862      * <p>
     863      * The overall effect is exactly as if the argument were converted
     864      * to a string by the method {@link String#valueOf(float)},
     865      * and the characters of that string were then
     866      * {@link #append(String) appended} to this character sequence.
     867      *
     868      * @param   f   a {@code float}.
     869      * @return  a reference to this object.
     870      */
     871     public AbstractStringBuilder append(float f) {
     872         FloatingDecimal.appendTo(f,this);
     873         return this;
     874     }
     875
     876     /**
     877      * Appends the string representation of the {@code double}
     878      * argument to this sequence.
     879      * <p>
     880      * The overall effect is exactly as if the argument were converted
     881      * to a string by the method {@link String#valueOf(double)},
     882      * and the characters of that string were then
     883      * {@link #append(String) appended} to this character sequence.
     884      *
     885      * @param   d   a {@code double}.
     886      * @return  a reference to this object.
     887      */
     888     public AbstractStringBuilder append(double d) {
     889         FloatingDecimal.appendTo(d,this);
     890         return this;
     891     }
     892
     893     /**
     894      * Removes the characters in a substring of this sequence.
     895      * The substring begins at the specified {@code start} and extends to
     896      * the character at index {@code end - 1} or to the end of the
     897      * sequence if no such character exists. If
     898      * {@code start} is equal to {@code end}, no changes are made.
     899      *
     900      * @param      start  The beginning index, inclusive.
     901      * @param      end    The ending index, exclusive.
     902      * @return     This object.
     903      * @throws     StringIndexOutOfBoundsException  if {@code start}
     904      *             is negative, greater than {@code length()}, or
     905      *             greater than {@code end}.
     906      */
     907     public AbstractStringBuilder delete(int start, int end) {
     908         int count = this.count;
     909         if (end > count) {
     910             end = count;
     911         }
     912         checkRangeSIOOBE(start, end, count);
     913         int len = end - start;
     914         if (len > 0) {
     915             shift(end, -len);
     916             this.count = count - len;
     917         }
     918         return this;
     919     }
     920
     921     /**
     922      * Appends the string representation of the {@code codePoint}
     923      * argument to this sequence.
     924      *
     925      * <p> The argument is appended to the contents of this sequence.
     926      * The length of this sequence increases by
     927      * {@link Character#charCount(int) Character.charCount(codePoint)}.
     928      *
     929      * <p> The overall effect is exactly as if the argument were
     930      * converted to a {@code char} array by the method
     931      * {@link Character#toChars(int)} and the character in that array
     932      * were then {@link #append(char[]) appended} to this character
     933      * sequence.
     934      *
     935      * @param   codePoint   a Unicode code point
     936      * @return  a reference to this object.
     937      * @throws    IllegalArgumentException if the specified
     938      * {@code codePoint} isn't a valid Unicode code point
     939      */
     940     public AbstractStringBuilder appendCodePoint(int codePoint) {
     941         if (Character.isBmpCodePoint(codePoint)) {
     942             return append((char)codePoint);
     943         }
     944         return append(Character.toChars(codePoint));
     945     }
     946
     947     /**
     948      * Removes the {@code char} at the specified position in this
     949      * sequence. This sequence is shortened by one {@code char}.
     950      *
     951      * <p>Note: If the character at the given index is a supplementary
     952      * character, this method does not remove the entire character. If
     953      * correct handling of supplementary characters is required,
     954      * determine the number of {@code char}s to remove by calling
     955      * {@code Character.charCount(thisSequence.codePointAt(index))},
     956      * where {@code thisSequence} is this sequence.
     957      *
     958      * @param       index  Index of {@code char} to remove
     959      * @return      This object.
     960      * @throws      StringIndexOutOfBoundsException  if the {@code index}
     961      *              is negative or greater than or equal to
     962      *              {@code length()}.
     963      */
     964     public AbstractStringBuilder deleteCharAt(int index) {
     965         checkIndex(index, count);
     966         shift(index + 1, -1);
     967         count--;
     968         return this;
     969     }
     970
     971     /**
     972      * Replaces the characters in a substring of this sequence
     973      * with characters in the specified {@code String}. The substring
     974      * begins at the specified {@code start} and extends to the character
     975      * at index {@code end - 1} or to the end of the
     976      * sequence if no such character exists. First the
     977      * characters in the substring are removed and then the specified
     978      * {@code String} is inserted at {@code start}. (This
     979      * sequence will be lengthened to accommodate the
     980      * specified String if necessary.)
     981      *
     982      * @param      start    The beginning index, inclusive.
     983      * @param      end      The ending index, exclusive.
     984      * @param      str   String that will replace previous contents.
     985      * @return     This object.
     986      * @throws     StringIndexOutOfBoundsException  if {@code start}
     987      *             is negative, greater than {@code length()}, or
     988      *             greater than {@code end}.
     989      */
     990     public AbstractStringBuilder replace(int start, int end, String str) {
     991         int count = this.count;
     992         if (end > count) {
     993             end = count;
     994         }
     995         checkRangeSIOOBE(start, end, count);
     996         int len = str.length();
     997         int newCount = count + len - (end - start);
     998         ensureCapacityInternal(newCount);
     999         shift(end, newCount - count);
    1000         this.count = newCount;
    1001         putStringAt(start, str);
    1002         return this;
    1003     }
    1004
    1005     /**
    1006      * Returns a new {@code String} that contains a subsequence of
    1007      * characters currently contained in this character sequence. The
    1008      * substring begins at the specified index and extends to the end of
    1009      * this sequence.
    1010      *
    1011      * @param      start    The beginning index, inclusive.
    1012      * @return     The new string.
    1013      * @throws     StringIndexOutOfBoundsException  if {@code start} is
    1014      *             less than zero, or greater than the length of this object.
    1015      */
    1016     public String substring(int start) {
    1017         return substring(start, count);
    1018     }
    1019
    1020     /**
    1021      * Returns a new character sequence that is a subsequence of this sequence.
    1022      *
    1023      * <p> An invocation of this method of the form
    1024      *
    1025      * <pre>{@code
    1026      * sb.subSequence(begin,&nbsp;end)}</pre>
    1027      *
    1028      * behaves in exactly the same way as the invocation
    1029      *
    1030      * <pre>{@code
    1031      * sb.substring(begin,&nbsp;end)}</pre>
    1032      *
    1033      * This method is provided so that this class can
    1034      * implement the {@link CharSequence} interface.
    1035      *
    1036      * @param      start   the start index, inclusive.
    1037      * @param      end     the end index, exclusive.
    1038      * @return     the specified subsequence.
    1039      *
    1040      * @throws  IndexOutOfBoundsException
    1041      *          if {@code start} or {@code end} are negative,
    1042      *          if {@code end} is greater than {@code length()},
    1043      *          or if {@code start} is greater than {@code end}
    1044      * @spec JSR-51
    1045      */
    1046     @Override
    1047     public CharSequence subSequence(int start, int end) {
    1048         return substring(start, end);
    1049     }
    1050
    1051     /**
    1052      * Returns a new {@code String} that contains a subsequence of
    1053      * characters currently contained in this sequence. The
    1054      * substring begins at the specified {@code start} and
    1055      * extends to the character at index {@code end - 1}.
    1056      *
    1057      * @param      start    The beginning index, inclusive.
    1058      * @param      end      The ending index, exclusive.
    1059      * @return     The new string.
    1060      * @throws     StringIndexOutOfBoundsException  if {@code start}
    1061      *             or {@code end} are negative or greater than
    1062      *             {@code length()}, or {@code start} is
    1063      *             greater than {@code end}.
    1064      */
    1065     public String substring(int start, int end) {
    1066         checkRangeSIOOBE(start, end, count);
    1067         if (isLatin1()) {
    1068             return StringLatin1.newString(value, start, end - start);
    1069         }
    1070         return StringUTF16.newString(value, start, end - start);
    1071     }
    1072
    1073     private void shift(int offset, int n) {
    1074         System.arraycopy(value, offset << coder,
    1075                          value, (offset + n) << coder, (count - offset) << coder);
    1076     }
    1077
    1078     /**
    1079      * Inserts the string representation of a subarray of the {@code str}
    1080      * array argument into this sequence. The subarray begins at the
    1081      * specified {@code offset} and extends {@code len} {@code char}s.
    1082      * The characters of the subarray are inserted into this sequence at
    1083      * the position indicated by {@code index}. The length of this
    1084      * sequence increases by {@code len} {@code char}s.
    1085      *
    1086      * @param      index    position at which to insert subarray.
    1087      * @param      str       A {@code char} array.
    1088      * @param      offset   the index of the first {@code char} in subarray to
    1089      *             be inserted.
    1090      * @param      len      the number of {@code char}s in the subarray to
    1091      *             be inserted.
    1092      * @return     This object
    1093      * @throws     StringIndexOutOfBoundsException  if {@code index}
    1094      *             is negative or greater than {@code length()}, or
    1095      *             {@code offset} or {@code len} are negative, or
    1096      *             {@code (offset+len)} is greater than
    1097      *             {@code str.length}.
    1098      */
    1099     public AbstractStringBuilder insert(int index, char[] str, int offset,
    1100                                         int len)
    1101     {
    1102         checkOffset(index, count);
    1103         checkRangeSIOOBE(offset, offset + len, str.length);
    1104         ensureCapacityInternal(count + len);
    1105         shift(index, len);
    1106         count += len;
    1107         putCharsAt(index, str, offset, offset + len);
    1108         return this;
    1109     }
    1110
    1111     /**
    1112      * Inserts the string representation of the {@code Object}
    1113      * argument into this character sequence.
    1114      * <p>
    1115      * The overall effect is exactly as if the second argument were
    1116      * converted to a string by the method {@link String#valueOf(Object)},
    1117      * and the characters of that string were then
    1118      * {@link #insert(int,String) inserted} into this character
    1119      * sequence at the indicated offset.
    1120      * <p>
    1121      * The {@code offset} argument must be greater than or equal to
    1122      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1123      * of this sequence.
    1124      *
    1125      * @param      offset   the offset.
    1126      * @param      obj      an {@code Object}.
    1127      * @return     a reference to this object.
    1128      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1129      */
    1130     public AbstractStringBuilder insert(int offset, Object obj) {
    1131         return insert(offset, String.valueOf(obj));
    1132     }
    1133
    1134     /**
    1135      * Inserts the string into this character sequence.
    1136      * <p>
    1137      * The characters of the {@code String} argument are inserted, in
    1138      * order, into this sequence at the indicated offset, moving up any
    1139      * characters originally above that position and increasing the length
    1140      * of this sequence by the length of the argument. If
    1141      * {@code str} is {@code null}, then the four characters
    1142      * {@code "null"} are inserted into this sequence.
    1143      * <p>
    1144      * The character at index <i>k</i> in the new character sequence is
    1145      * equal to:
    1146      * <ul>
    1147      * <li>the character at index <i>k</i> in the old character sequence, if
    1148      * <i>k</i> is less than {@code offset}
    1149      * <li>the character at index <i>k</i>{@code -offset} in the
    1150      * argument {@code str}, if <i>k</i> is not less than
    1151      * {@code offset} but is less than {@code offset+str.length()}
    1152      * <li>the character at index <i>k</i>{@code -str.length()} in the
    1153      * old character sequence, if <i>k</i> is not less than
    1154      * {@code offset+str.length()}
    1155      * </ul><p>
    1156      * The {@code offset} argument must be greater than or equal to
    1157      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1158      * of this sequence.
    1159      *
    1160      * @param      offset   the offset.
    1161      * @param      str      a string.
    1162      * @return     a reference to this object.
    1163      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1164      */
    1165     public AbstractStringBuilder insert(int offset, String str) {
    1166         checkOffset(offset, count);
    1167         if (str == null) {
    1168             str = "null";
    1169         }
    1170         int len = str.length();
    1171         ensureCapacityInternal(count + len);
    1172         shift(offset, len);
    1173         count += len;
    1174         putStringAt(offset, str);
    1175         return this;
    1176     }
    1177
    1178     /**
    1179      * Inserts the string representation of the {@code char} array
    1180      * argument into this sequence.
    1181      * <p>
    1182      * The characters of the array argument are inserted into the
    1183      * contents of this sequence at the position indicated by
    1184      * {@code offset}. The length of this sequence increases by
    1185      * the length of the argument.
    1186      * <p>
    1187      * The overall effect is exactly as if the second argument were
    1188      * converted to a string by the method {@link String#valueOf(char[])},
    1189      * and the characters of that string were then
    1190      * {@link #insert(int,String) inserted} into this character
    1191      * sequence at the indicated offset.
    1192      * <p>
    1193      * The {@code offset} argument must be greater than or equal to
    1194      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1195      * of this sequence.
    1196      *
    1197      * @param      offset   the offset.
    1198      * @param      str      a character array.
    1199      * @return     a reference to this object.
    1200      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1201      */
    1202     public AbstractStringBuilder insert(int offset, char[] str) {
    1203         checkOffset(offset, count);
    1204         int len = str.length;
    1205         ensureCapacityInternal(count + len);
    1206         shift(offset, len);
    1207         count += len;
    1208         putCharsAt(offset, str, 0, len);
    1209         return this;
    1210     }
    1211
    1212     /**
    1213      * Inserts the specified {@code CharSequence} into this sequence.
    1214      * <p>
    1215      * The characters of the {@code CharSequence} argument are inserted,
    1216      * in order, into this sequence at the indicated offset, moving up
    1217      * any characters originally above that position and increasing the length
    1218      * of this sequence by the length of the argument s.
    1219      * <p>
    1220      * The result of this method is exactly the same as if it were an
    1221      * invocation of this object's
    1222      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
    1223      * method.
    1224      *
    1225      * <p>If {@code s} is {@code null}, then the four characters
    1226      * {@code "null"} are inserted into this sequence.
    1227      *
    1228      * @param      dstOffset   the offset.
    1229      * @param      s the sequence to be inserted
    1230      * @return     a reference to this object.
    1231      * @throws     IndexOutOfBoundsException  if the offset is invalid.
    1232      */
    1233     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
    1234         if (s == null) {
    1235             s = "null";
    1236         }
    1237         if (s instanceof String) {
    1238             return this.insert(dstOffset, (String)s);
    1239         }
    1240         return this.insert(dstOffset, s, 0, s.length());
    1241     }
    1242
    1243     /**
    1244      * Inserts a subsequence of the specified {@code CharSequence} into
    1245      * this sequence.
    1246      * <p>
    1247      * The subsequence of the argument {@code s} specified by
    1248      * {@code start} and {@code end} are inserted,
    1249      * in order, into this sequence at the specified destination offset, moving
    1250      * up any characters originally above that position. The length of this
    1251      * sequence is increased by {@code end - start}.
    1252      * <p>
    1253      * The character at index <i>k</i> in this sequence becomes equal to:
    1254      * <ul>
    1255      * <li>the character at index <i>k</i> in this sequence, if
    1256      * <i>k</i> is less than {@code dstOffset}
    1257      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
    1258      * the argument {@code s}, if <i>k</i> is greater than or equal to
    1259      * {@code dstOffset} but is less than {@code dstOffset+end-start}
    1260      * <li>the character at index <i>k</i>{@code -(end-start)} in this
    1261      * sequence, if <i>k</i> is greater than or equal to
    1262      * {@code dstOffset+end-start}
    1263      * </ul><p>
    1264      * The {@code dstOffset} argument must be greater than or equal to
    1265      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1266      * of this sequence.
    1267      * <p>The start argument must be nonnegative, and not greater than
    1268      * {@code end}.
    1269      * <p>The end argument must be greater than or equal to
    1270      * {@code start}, and less than or equal to the length of s.
    1271      *
    1272      * <p>If {@code s} is {@code null}, then this method inserts
    1273      * characters as if the s parameter was a sequence containing the four
    1274      * characters {@code "null"}.
    1275      *
    1276      * @param      dstOffset   the offset in this sequence.
    1277      * @param      s       the sequence to be inserted.
    1278      * @param      start   the starting index of the subsequence to be inserted.
    1279      * @param      end     the end index of the subsequence to be inserted.
    1280      * @return     a reference to this object.
    1281      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
    1282      *             is negative or greater than {@code this.length()}, or
    1283      *              {@code start} or {@code end} are negative, or
    1284      *              {@code start} is greater than {@code end} or
    1285      *              {@code end} is greater than {@code s.length()}
    1286      */
    1287     public AbstractStringBuilder insert(int dstOffset, CharSequence s,
    1288                                         int start, int end)
    1289     {
    1290         if (s == null) {
    1291             s = "null";
    1292         }
    1293         checkOffset(dstOffset, count);
    1294         checkRange(start, end, s.length());
    1295         int len = end - start;
    1296         ensureCapacityInternal(count + len);
    1297         shift(dstOffset, len);
    1298         count += len;
    1299         putCharsAt(dstOffset, s, start, end);
    1300         return this;
    1301     }
    1302
    1303     /**
    1304      * Inserts the string representation of the {@code boolean}
    1305      * argument into this sequence.
    1306      * <p>
    1307      * The overall effect is exactly as if the second argument were
    1308      * converted to a string by the method {@link String#valueOf(boolean)},
    1309      * and the characters of that string were then
    1310      * {@link #insert(int,String) inserted} into this character
    1311      * sequence at the indicated offset.
    1312      * <p>
    1313      * The {@code offset} argument must be greater than or equal to
    1314      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1315      * of this sequence.
    1316      *
    1317      * @param      offset   the offset.
    1318      * @param      b        a {@code boolean}.
    1319      * @return     a reference to this object.
    1320      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1321      */
    1322     public AbstractStringBuilder insert(int offset, boolean b) {
    1323         return insert(offset, String.valueOf(b));
    1324     }
    1325
    1326     /**
    1327      * Inserts the string representation of the {@code char}
    1328      * argument into this sequence.
    1329      * <p>
    1330      * The overall effect is exactly as if the second argument were
    1331      * converted to a string by the method {@link String#valueOf(char)},
    1332      * and the character in that string were then
    1333      * {@link #insert(int,String) inserted} into this character
    1334      * sequence at the indicated offset.
    1335      * <p>
    1336      * The {@code offset} argument must be greater than or equal to
    1337      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1338      * of this sequence.
    1339      *
    1340      * @param      offset   the offset.
    1341      * @param      c        a {@code char}.
    1342      * @return     a reference to this object.
    1343      * @throws     IndexOutOfBoundsException  if the offset is invalid.
    1344      */
    1345     public AbstractStringBuilder insert(int offset, char c) {
    1346         checkOffset(offset, count);
    1347         ensureCapacityInternal(count + 1);
    1348         shift(offset, 1);
    1349         count += 1;
    1350         if (isLatin1() && StringLatin1.canEncode(c)) {
    1351             value[offset] = (byte)c;
    1352         } else {
    1353             if (isLatin1()) {
    1354                 inflate();
    1355             }
    1356             StringUTF16.putCharSB(value, offset, c);
    1357         }
    1358         return this;
    1359     }
    1360
    1361     /**
    1362      * Inserts the string representation of the second {@code int}
    1363      * argument into this sequence.
    1364      * <p>
    1365      * The overall effect is exactly as if the second argument were
    1366      * converted to a string by the method {@link String#valueOf(int)},
    1367      * and the characters of that string were then
    1368      * {@link #insert(int,String) inserted} into this character
    1369      * sequence at the indicated offset.
    1370      * <p>
    1371      * The {@code offset} argument must be greater than or equal to
    1372      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1373      * of this sequence.
    1374      *
    1375      * @param      offset   the offset.
    1376      * @param      i        an {@code int}.
    1377      * @return     a reference to this object.
    1378      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1379      */
    1380     public AbstractStringBuilder insert(int offset, int i) {
    1381         return insert(offset, String.valueOf(i));
    1382     }
    1383
    1384     /**
    1385      * Inserts the string representation of the {@code long}
    1386      * argument into this sequence.
    1387      * <p>
    1388      * The overall effect is exactly as if the second argument were
    1389      * converted to a string by the method {@link String#valueOf(long)},
    1390      * and the characters of that string were then
    1391      * {@link #insert(int,String) inserted} into this character
    1392      * sequence at the indicated offset.
    1393      * <p>
    1394      * The {@code offset} argument must be greater than or equal to
    1395      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1396      * of this sequence.
    1397      *
    1398      * @param      offset   the offset.
    1399      * @param      l        a {@code long}.
    1400      * @return     a reference to this object.
    1401      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1402      */
    1403     public AbstractStringBuilder insert(int offset, long l) {
    1404         return insert(offset, String.valueOf(l));
    1405     }
    1406
    1407     /**
    1408      * Inserts the string representation of the {@code float}
    1409      * argument into this sequence.
    1410      * <p>
    1411      * The overall effect is exactly as if the second argument were
    1412      * converted to a string by the method {@link String#valueOf(float)},
    1413      * and the characters of that string were then
    1414      * {@link #insert(int,String) inserted} into this character
    1415      * sequence at the indicated offset.
    1416      * <p>
    1417      * The {@code offset} argument must be greater than or equal to
    1418      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1419      * of this sequence.
    1420      *
    1421      * @param      offset   the offset.
    1422      * @param      f        a {@code float}.
    1423      * @return     a reference to this object.
    1424      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1425      */
    1426     public AbstractStringBuilder insert(int offset, float f) {
    1427         return insert(offset, String.valueOf(f));
    1428     }
    1429
    1430     /**
    1431      * Inserts the string representation of the {@code double}
    1432      * argument into this sequence.
    1433      * <p>
    1434      * The overall effect is exactly as if the second argument were
    1435      * converted to a string by the method {@link String#valueOf(double)},
    1436      * and the characters of that string were then
    1437      * {@link #insert(int,String) inserted} into this character
    1438      * sequence at the indicated offset.
    1439      * <p>
    1440      * The {@code offset} argument must be greater than or equal to
    1441      * {@code 0}, and less than or equal to the {@linkplain #length() length}
    1442      * of this sequence.
    1443      *
    1444      * @param      offset   the offset.
    1445      * @param      d        a {@code double}.
    1446      * @return     a reference to this object.
    1447      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
    1448      */
    1449     public AbstractStringBuilder insert(int offset, double d) {
    1450         return insert(offset, String.valueOf(d));
    1451     }
    1452
    1453     /**
    1454      * Returns the index within this string of the first occurrence of the
    1455      * specified substring.
    1456      *
    1457      * <p>The returned index is the smallest value {@code k} for which:
    1458      * <pre>{@code
    1459      * this.toString().startsWith(str, k)
    1460      * }</pre>
    1461      * If no such value of {@code k} exists, then {@code -1} is returned.
    1462      *
    1463      * @param   str   the substring to search for.
    1464      * @return  the index of the first occurrence of the specified substring,
    1465      *          or {@code -1} if there is no such occurrence.
    1466      */
    1467     public int indexOf(String str) {
    1468         return indexOf(str, 0);
    1469     }
    1470
    1471     /**
    1472      * Returns the index within this string of the first occurrence of the
    1473      * specified substring, starting at the specified index.
    1474      *
    1475      * <p>The returned index is the smallest value {@code k} for which:
    1476      * <pre>{@code
    1477      *     k >= Math.min(fromIndex, this.length()) &&
    1478      *                   this.toString().startsWith(str, k)
    1479      * }</pre>
    1480      * If no such value of {@code k} exists, then {@code -1} is returned.
    1481      *
    1482      * @param   str         the substring to search for.
    1483      * @param   fromIndex   the index from which to start the search.
    1484      * @return  the index of the first occurrence of the specified substring,
    1485      *          starting at the specified index,
    1486      *          or {@code -1} if there is no such occurrence.
    1487      */
    1488     public int indexOf(String str, int fromIndex) {
    1489         return String.indexOf(value, coder, count, str, fromIndex);
    1490     }
    1491
    1492     /**
    1493      * Returns the index within this string of the last occurrence of the
    1494      * specified substring.  The last occurrence of the empty string "" is
    1495      * considered to occur at the index value {@code this.length()}.
    1496      *
    1497      * <p>The returned index is the largest value {@code k} for which:
    1498      * <pre>{@code
    1499      * this.toString().startsWith(str, k)
    1500      * }</pre>
    1501      * If no such value of {@code k} exists, then {@code -1} is returned.
    1502      *
    1503      * @param   str   the substring to search for.
    1504      * @return  the index of the last occurrence of the specified substring,
    1505      *          or {@code -1} if there is no such occurrence.
    1506      */
    1507     public int lastIndexOf(String str) {
    1508         return lastIndexOf(str, count);
    1509     }
    1510
    1511     /**
    1512      * Returns the index within this string of the last occurrence of the
    1513      * specified substring, searching backward starting at the specified index.
    1514      *
    1515      * <p>The returned index is the largest value {@code k} for which:
    1516      * <pre>{@code
    1517      *     k <= Math.min(fromIndex, this.length()) &&
    1518      *                   this.toString().startsWith(str, k)
    1519      * }</pre>
    1520      * If no such value of {@code k} exists, then {@code -1} is returned.
    1521      *
    1522      * @param   str         the substring to search for.
    1523      * @param   fromIndex   the index to start the search from.
    1524      * @return  the index of the last occurrence of the specified substring,
    1525      *          searching backward from the specified index,
    1526      *          or {@code -1} if there is no such occurrence.
    1527      */
    1528     public int lastIndexOf(String str, int fromIndex) {
    1529         return String.lastIndexOf(value, coder, count, str, fromIndex);
    1530     }
    1531
    1532     /**
    1533      * Causes this character sequence to be replaced by the reverse of
    1534      * the sequence. If there are any surrogate pairs included in the
    1535      * sequence, these are treated as single characters for the
    1536      * reverse operation. Thus, the order of the high-low surrogates
    1537      * is never reversed.
    1538      *
    1539      * Let <i>n</i> be the character length of this character sequence
    1540      * (not the length in {@code char} values) just prior to
    1541      * execution of the {@code reverse} method. Then the
    1542      * character at index <i>k</i> in the new character sequence is
    1543      * equal to the character at index <i>n-k-1</i> in the old
    1544      * character sequence.
    1545      *
    1546      * <p>Note that the reverse operation may result in producing
    1547      * surrogate pairs that were unpaired low-surrogates and
    1548      * high-surrogates before the operation. For example, reversing
    1549      * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
    1550      * a valid surrogate pair.
    1551      *
    1552      * @return  a reference to this object.
    1553      */
    1554     public AbstractStringBuilder reverse() {
    1555         byte[] val = this.value;
    1556         int count = this.count;
    1557         int coder = this.coder;
    1558         int n = count - 1;
    1559         if (COMPACT_STRINGS && coder == LATIN1) {
    1560             for (int j = (n-1) >> 1; j >= 0; j--) {
    1561                 int k = n - j;
    1562                 byte cj = val[j];
    1563                 val[j] = val[k];
    1564                 val[k] = cj;
    1565             }
    1566         } else {
    1567             StringUTF16.reverse(val, count);
    1568         }
    1569         return this;
    1570     }
    1571
    1572     /**
    1573      * Returns a string representing the data in this sequence.
    1574      * A new {@code String} object is allocated and initialized to
    1575      * contain the character sequence currently represented by this
    1576      * object. This {@code String} is then returned. Subsequent
    1577      * changes to this sequence do not affect the contents of the
    1578      * {@code String}.
    1579      *
    1580      * @return  a string representation of this sequence of characters.
    1581      */
    1582     @Override
    1583     public abstract String toString();
    1584
    1585     /**
    1586      * {@inheritDoc}
    1587      * @since 9
    1588      */
    1589     @Override
    1590     public IntStream chars() {
    1591         // Reuse String-based spliterator. This requires a supplier to
    1592         // capture the value and count when the terminal operation is executed
    1593         return StreamSupport.intStream(
    1594                 () -> {
    1595                     // The combined set of field reads are not atomic and thread
    1596                     // safe but bounds checks will ensure no unsafe reads from
    1597                     // the byte array
    1598                     byte[] val = this.value;
    1599                     int count = this.count;
    1600                     byte coder = this.coder;
    1601                     return coder == LATIN1
    1602                            ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
    1603                            : new StringUTF16.CharsSpliterator(val, 0, count, 0);
    1604                 },
    1605                 Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
    1606                 false);
    1607     }
    1608
    1609     /**
    1610      * {@inheritDoc}
    1611      * @since 9
    1612      */
    1613     @Override
    1614     public IntStream codePoints() {
    1615         // Reuse String-based spliterator. This requires a supplier to
    1616         // capture the value and count when the terminal operation is executed
    1617         return StreamSupport.intStream(
    1618                 () -> {
    1619                     // The combined set of field reads are not atomic and thread
    1620                     // safe but bounds checks will ensure no unsafe reads from
    1621                     // the byte array
    1622                     byte[] val = this.value;
    1623                     int count = this.count;
    1624                     byte coder = this.coder;
    1625                     return coder == LATIN1
    1626                            ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
    1627                            : new StringUTF16.CodePointsSpliterator(val, 0, count, 0);
    1628                 },
    1629                 Spliterator.ORDERED,
    1630                 false);
    1631     }
    1632
    1633     /**
    1634      * Needed by {@code String} for the contentEquals method.
    1635      */
    1636     final byte[] getValue() {
    1637         return value;
    1638     }
    1639
    1640     /*
    1641      * Invoker guarantees it is in UTF16 (inflate itself for asb), if two
    1642      * coders are different and the dstBegin has enough space
    1643      *
    1644      * @param dstBegin  the char index, not offset of byte[]
    1645      * @param coder     the coder of dst[]
    1646      */
    1647     void getBytes(byte dst[], int dstBegin, byte coder) {
    1648         if (this.coder == coder) {
    1649             System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
    1650         } else {        // this.coder == LATIN && coder == UTF16
    1651             StringLatin1.inflate(value, 0, dst, dstBegin, count);
    1652         }
    1653     }
    1654
    1655     /* for readObject() */
    1656     void initBytes(char[] value, int off, int len) {
    1657         if (String.COMPACT_STRINGS) {
    1658             this.value = StringUTF16.compress(value, off, len);
    1659             if (this.value != null) {
    1660                 this.coder = LATIN1;
    1661                 return;
    1662             }
    1663         }
    1664         this.coder = UTF16;
    1665         this.value = StringUTF16.toBytes(value, off, len);
    1666     }
    1667
    1668     final byte getCoder() {
    1669         return COMPACT_STRINGS ? coder : UTF16;
    1670     }
    1671
    1672     final boolean isLatin1() {
    1673         return COMPACT_STRINGS && coder == LATIN1;
    1674     }
    1675
    1676     private final void putCharsAt(int index, char[] s, int off, int end) {
    1677         if (isLatin1()) {
    1678             byte[] val = this.value;
    1679             for (int i = off, j = index; i < end; i++) {
    1680                 char c = s[i];
    1681                 if (StringLatin1.canEncode(c)) {
    1682                     val[j++] = (byte)c;
    1683                 } else {
    1684                     inflate();
    1685                     StringUTF16.putCharsSB(this.value, j, s, i, end);
    1686                     return;
    1687                 }
    1688             }
    1689         } else {
    1690             StringUTF16.putCharsSB(this.value, index, s, off, end);
    1691         }
    1692     }
    1693
    1694     private final void putCharsAt(int index, CharSequence s, int off, int end) {
    1695         if (isLatin1()) {
    1696             byte[] val = this.value;
    1697             for (int i = off, j = index; i < end; i++) {
    1698                 char c = s.charAt(i);
    1699                 if (StringLatin1.canEncode(c)) {
    1700                     val[j++] = (byte)c;
    1701                 } else {
    1702                     inflate();
    1703                     StringUTF16.putCharsSB(this.value, j, s, i, end);
    1704                     return;
    1705                 }
    1706             }
    1707         } else {
    1708             StringUTF16.putCharsSB(this.value, index, s, off, end);
    1709         }
    1710     }
    1711
    1712     private final void putStringAt(int index, String str) {
    1713         if (getCoder() != str.coder()) {
    1714             inflate();
    1715         }
    1716         str.getBytes(value, index, coder);
    1717     }
    1718
    1719     private final void appendChars(char[] s, int off, int end) {
    1720         int count = this.count;
    1721         if (isLatin1()) {
    1722             byte[] val = this.value;
    1723             for (int i = off, j = count; i < end; i++) {
    1724                 char c = s[i];
    1725                 if (StringLatin1.canEncode(c)) {
    1726                     val[j++] = (byte)c;
    1727                 } else {
    1728                     this.count = count = j;
    1729                     inflate();
    1730                     StringUTF16.putCharsSB(this.value, j, s, i, end);
    1731                     this.count = count + end - i;
    1732                     return;
    1733                 }
    1734             }
    1735         } else {
    1736             StringUTF16.putCharsSB(this.value, count, s, off, end);
    1737         }
    1738         this.count = count + end - off;
    1739     }
    1740
    1741     private final void appendChars(String s, int off, int end) {
    1742         if (isLatin1()) {
    1743             if (s.isLatin1()) {
    1744                 System.arraycopy(s.value(), off, this.value, this.count, end - off);
    1745             } else {
    1746                 // We might need to inflate, but do it as late as possible since
    1747                 // the range of characters we're copying might all be latin1
    1748                 byte[] val = this.value;
    1749                 for (int i = off, j = count; i < end; i++) {
    1750                     char c = s.charAt(i);
    1751                     if (StringLatin1.canEncode(c)) {
    1752                         val[j++] = (byte) c;
    1753                     } else {
    1754                         count = j;
    1755                         inflate();
    1756                         System.arraycopy(s.value(), i << UTF16, this.value, j << UTF16, (end - i) << UTF16);
    1757                         count += end - i;
    1758                         return;
    1759                     }
    1760                 }
    1761             }
    1762         } else if (s.isLatin1()) {
    1763             StringUTF16.putCharsSB(this.value, this.count, s, off, end);
    1764         } else { // both UTF16
    1765             System.arraycopy(s.value(), off << UTF16, this.value, this.count << UTF16, (end - off) << UTF16);
    1766         }
    1767         count += end - off;
    1768     }
    1769
    1770     private final void appendChars(CharSequence s, int off, int end) {
    1771         if (isLatin1()) {
    1772             byte[] val = this.value;
    1773             for (int i = off, j = count; i < end; i++) {
    1774                 char c = s.charAt(i);
    1775                 if (StringLatin1.canEncode(c)) {
    1776                     val[j++] = (byte)c;
    1777                 } else {
    1778                     count = j;
    1779                     inflate();
    1780                     StringUTF16.putCharsSB(this.value, j, s, i, end);
    1781                     count += end - i;
    1782                     return;
    1783                 }
    1784             }
    1785         } else {
    1786             StringUTF16.putCharsSB(this.value, count, s, off, end);
    1787         }
    1788         count += end - off;
    1789     }
    1790
    1791     /* IndexOutOfBoundsException, if out of bounds */
    1792     private static void checkRange(int start, int end, int len) {
    1793         if (start < 0 || start > end || end > len) {
    1794             throw new IndexOutOfBoundsException(
    1795                 "start " + start + ", end " + end + ", length " + len);
    1796         }
    1797     }
    1798
    1799     /* StringIndexOutOfBoundsException, if out of bounds */
    1800     private static void checkRangeSIOOBE(int start, int end, int len) {
    1801         if (start < 0 || start > end || end > len) {
    1802             throw new StringIndexOutOfBoundsException(
    1803                 "start " + start + ", end " + end + ", length " + len);
    1804         }
    1805     }
    1806 }
    --- EOF ---