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