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