• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 package java.lang;
28 
29 import sun.misc.FloatingDecimal;
30 import 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  */
48 abstract 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      */
AbstractStringBuilder()62     AbstractStringBuilder() {
63     }
64 
65     /**
66      * Creates an AbstractStringBuilder of the specified capacity.
67      */
AbstractStringBuilder(int capacity)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
length()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      */
capacity()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      */
ensureCapacity(int minimumCapacity)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      */
ensureCapacityInternal(int minimumCapacity)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      */
newCapacity(int minCapacity)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 
hugeCapacity(int minCapacity)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      */
trimToSize()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      */
setLength(int newLength)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
charAt(int index)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      */
codePointAt(int index)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      */
codePointBefore(int index)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      */
codePointCount(int beginIndex, int endIndex)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      */
offsetByCodePoints(int index, int codePointOffset)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      */
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)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      */
setCharAt(int index, char ch)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      */
append(Object obj)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      */
append(String str)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 */
append(StringBuffer sb)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      */
append(AbstractStringBuilder asb)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
append(CharSequence s)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 
appendNull()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
append(CharSequence s, int start, int end)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      */
append(char[] str)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      */
append(char str[], int offset, int len)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      */
append(boolean b)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
append(char c)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      */
append(int i)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      */
append(long l)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      */
append(float f)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      */
append(double d)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      */
delete(int start, int end)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      */
appendCodePoint(int codePoint)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      */
deleteCharAt(int index)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      */
replace(int start, int end, String str)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      */
substring(int start)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
subSequence(int start, int end)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      */
substring(int start, int end)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      */
insert(int index, char[] str, int offset, int len)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      */
insert(int offset, Object obj)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      */
insert(int offset, String str)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      */
insert(int offset, char[] str)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      */
insert(int dstOffset, CharSequence s)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      */
insert(int dstOffset, CharSequence s, int start, int end)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      */
insert(int offset, boolean b)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      */
insert(int offset, char c)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      */
insert(int offset, int i)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      */
insert(int offset, long l)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      */
insert(int offset, float f)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      */
insert(int offset, double d)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      */
indexOf(String str)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      */
indexOf(String str, int fromIndex)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      */
lastIndexOf(String str)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      */
lastIndexOf(String str, int fromIndex)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      */
reverse()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() */
reverseAllValidSurrogatePairs()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
toString()1491     public abstract String toString();
1492 
1493     /**
1494      * Needed by {@code String} for the contentEquals method.
1495      */
getValue()1496     final char[] getValue() {
1497         return value;
1498     }
1499 
1500 }
1501