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