• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.lang;
27 
28 import jdk.internal.math.FloatingDecimal;
29 import 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  * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
39  * or method in this class will cause a {@link NullPointerException} to be
40  * thrown.
41  *
42  * @author      Michael McCloskey
43  * @author      Martin Buchholz
44  * @author      Ulf Zibis
45  * @since       1.5
46  */
47 abstract class AbstractStringBuilder implements Appendable, CharSequence {
48     // TODO: remove java.lang.Integer.getChars(int, int, char[]) once updated to byte[] from 11.
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      */
append(Object obj)423     public AbstractStringBuilder append(Object obj) {
424         return append(String.valueOf(obj));
425     }
426 
427     /**
428      * Appends the specified string to this character sequence.
429      * <p>
430      * The characters of the {@code String} argument are appended, in
431      * order, increasing the length of this sequence by the length of the
432      * argument. If {@code str} is {@code null}, then the four
433      * characters {@code "null"} are appended.
434      * <p>
435      * Let <i>n</i> be the length of this character sequence just prior to
436      * execution of the {@code append} method. Then the character at
437      * index <i>k</i> in the new character sequence is equal to the character
438      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
439      * than <i>n</i>; otherwise, it is equal to the character at index
440      * <i>k-n</i> in the argument {@code str}.
441      *
442      * @param   str   a string.
443      * @return  a reference to this object.
444      */
append(String str)445     public AbstractStringBuilder append(String str) {
446         if (str == null)
447             return appendNull();
448         int len = str.length();
449         ensureCapacityInternal(count + len);
450         str.getChars(0, len, value, count);
451         count += len;
452         return this;
453     }
454 
455     // Documentation in subclasses because of synchro difference
append(StringBuffer sb)456     public AbstractStringBuilder append(StringBuffer sb) {
457         if (sb == null)
458             return appendNull();
459         int len = sb.length();
460         ensureCapacityInternal(count + len);
461         sb.getChars(0, len, value, count);
462         count += len;
463         return this;
464     }
465 
466     /**
467      * @since 1.8
468      */
append(AbstractStringBuilder asb)469     AbstractStringBuilder append(AbstractStringBuilder asb) {
470         if (asb == null)
471             return appendNull();
472         int len = asb.length();
473         ensureCapacityInternal(count + len);
474         asb.getChars(0, len, value, count);
475         count += len;
476         return this;
477     }
478 
479     // Documentation in subclasses because of synchro difference
480     @Override
append(CharSequence s)481     public AbstractStringBuilder append(CharSequence s) {
482         if (s == null)
483             return appendNull();
484         if (s instanceof String)
485             return this.append((String)s);
486         if (s instanceof AbstractStringBuilder)
487             return this.append((AbstractStringBuilder)s);
488 
489         return this.append(s, 0, s.length());
490     }
491 
appendNull()492     private AbstractStringBuilder appendNull() {
493         int c = count;
494         ensureCapacityInternal(c + 4);
495         final char[] value = this.value;
496         value[c++] = 'n';
497         value[c++] = 'u';
498         value[c++] = 'l';
499         value[c++] = 'l';
500         count = c;
501         return this;
502     }
503 
504     /**
505      * Appends a subsequence of the specified {@code CharSequence} to this
506      * sequence.
507      * <p>
508      * Characters of the argument {@code s}, starting at
509      * index {@code start}, are appended, in order, to the contents of
510      * this sequence up to the (exclusive) index {@code end}. The length
511      * of this sequence is increased by the value of {@code end - start}.
512      * <p>
513      * Let <i>n</i> be the length of this character sequence just prior to
514      * execution of the {@code append} method. Then the character at
515      * index <i>k</i> in this character sequence becomes equal to the
516      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
517      * <i>n</i>; otherwise, it is equal to the character at index
518      * <i>k+start-n</i> in the argument {@code s}.
519      * <p>
520      * If {@code s} is {@code null}, then this method appends
521      * characters as if the s parameter was a sequence containing the four
522      * characters {@code "null"}.
523      *
524      * @param   s the sequence to append.
525      * @param   start   the starting index of the subsequence to be appended.
526      * @param   end     the end index of the subsequence to be appended.
527      * @return  a reference to this object.
528      * @throws     IndexOutOfBoundsException if
529      *             {@code start} is negative, or
530      *             {@code start} is greater than {@code end} or
531      *             {@code end} is greater than {@code s.length()}
532      */
533     @Override
append(CharSequence s, int start, int end)534     public AbstractStringBuilder append(CharSequence s, int start, int end) {
535         if (s == null)
536             s = "null";
537         if ((start < 0) || (start > end) || (end > s.length()))
538             throw new IndexOutOfBoundsException(
539                 "start " + start + ", end " + end + ", s.length() "
540                 + s.length());
541         int len = end - start;
542         ensureCapacityInternal(count + len);
543         for (int i = start, j = count; i < end; i++, j++)
544             value[j] = s.charAt(i);
545         count += len;
546         return this;
547     }
548 
549     /**
550      * Appends the string representation of the {@code char} array
551      * argument to this sequence.
552      * <p>
553      * The characters of the array argument are appended, in order, to
554      * the contents of this sequence. The length of this sequence
555      * increases by the length of the argument.
556      * <p>
557      * The overall effect is exactly as if the argument were converted
558      * to a string by the method {@link String#valueOf(char[])},
559      * and the characters of that string were then
560      * {@link #append(String) appended} to this character sequence.
561      *
562      * @param   str   the characters to be appended.
563      * @return  a reference to this object.
564      */
append(char[] str)565     public AbstractStringBuilder append(char[] str) {
566         int len = str.length;
567         ensureCapacityInternal(count + len);
568         System.arraycopy(str, 0, value, count, len);
569         count += len;
570         return this;
571     }
572 
573     /**
574      * Appends the string representation of a subarray of the
575      * {@code char} array argument to this sequence.
576      * <p>
577      * Characters of the {@code char} array {@code str}, starting at
578      * index {@code offset}, are appended, in order, to the contents
579      * of this sequence. The length of this sequence increases
580      * by the value of {@code len}.
581      * <p>
582      * The overall effect is exactly as if the arguments were converted
583      * to a string by the method {@link String#valueOf(char[],int,int)},
584      * and the characters of that string were then
585      * {@link #append(String) appended} to this character sequence.
586      *
587      * @param   str      the characters to be appended.
588      * @param   offset   the index of the first {@code char} to append.
589      * @param   len      the number of {@code char}s to append.
590      * @return  a reference to this object.
591      * @throws IndexOutOfBoundsException
592      *         if {@code offset < 0} or {@code len < 0}
593      *         or {@code offset+len > str.length}
594      */
append(char str[], int offset, int len)595     public AbstractStringBuilder append(char str[], int offset, int len) {
596         if (len > 0)                // let arraycopy report AIOOBE for len < 0
597             ensureCapacityInternal(count + len);
598         System.arraycopy(str, offset, value, count, len);
599         count += len;
600         return this;
601     }
602 
603     /**
604      * Appends the string representation of the {@code boolean}
605      * argument to the sequence.
606      * <p>
607      * The overall effect is exactly as if the argument were converted
608      * to a string by the method {@link String#valueOf(boolean)},
609      * and the characters of that string were then
610      * {@link #append(String) appended} to this character sequence.
611      *
612      * @param   b   a {@code boolean}.
613      * @return  a reference to this object.
614      */
append(boolean b)615     public AbstractStringBuilder append(boolean b) {
616         if (b) {
617             ensureCapacityInternal(count + 4);
618             value[count++] = 't';
619             value[count++] = 'r';
620             value[count++] = 'u';
621             value[count++] = 'e';
622         } else {
623             ensureCapacityInternal(count + 5);
624             value[count++] = 'f';
625             value[count++] = 'a';
626             value[count++] = 'l';
627             value[count++] = 's';
628             value[count++] = 'e';
629         }
630         return this;
631     }
632 
633     /**
634      * Appends the string representation of the {@code char}
635      * argument to this sequence.
636      * <p>
637      * The argument is appended to the contents of this sequence.
638      * The length of this sequence increases by {@code 1}.
639      * <p>
640      * The overall effect is exactly as if the argument were converted
641      * to a string by the method {@link String#valueOf(char)},
642      * and the character in that string were then
643      * {@link #append(String) appended} to this character sequence.
644      *
645      * @param   c   a {@code char}.
646      * @return  a reference to this object.
647      */
648     @Override
append(char c)649     public AbstractStringBuilder append(char c) {
650         ensureCapacityInternal(count + 1);
651         value[count++] = c;
652         return this;
653     }
654 
655     /**
656      * Appends the string representation of the {@code int}
657      * argument to this sequence.
658      * <p>
659      * The overall effect is exactly as if the argument were converted
660      * to a string by the method {@link String#valueOf(int)},
661      * and the characters of that string were then
662      * {@link #append(String) appended} to this character sequence.
663      *
664      * @param   i   an {@code int}.
665      * @return  a reference to this object.
666      */
append(int i)667     public AbstractStringBuilder append(int i) {
668         if (i == Integer.MIN_VALUE) {
669             append("-2147483648");
670             return this;
671         }
672         int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
673                                      : Integer.stringSize(i);
674         int spaceNeeded = count + appendedLength;
675         ensureCapacityInternal(spaceNeeded);
676         Integer.getChars(i, spaceNeeded, value);
677         count = spaceNeeded;
678         return this;
679     }
680 
681     /**
682      * Appends the string representation of the {@code long}
683      * argument to this sequence.
684      * <p>
685      * The overall effect is exactly as if the argument were converted
686      * to a string by the method {@link String#valueOf(long)},
687      * and the characters of that string were then
688      * {@link #append(String) appended} to this character sequence.
689      *
690      * @param   l   a {@code long}.
691      * @return  a reference to this object.
692      */
append(long l)693     public AbstractStringBuilder append(long l) {
694         if (l == Long.MIN_VALUE) {
695             append("-9223372036854775808");
696             return this;
697         }
698         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
699                                      : Long.stringSize(l);
700         int spaceNeeded = count + appendedLength;
701         ensureCapacityInternal(spaceNeeded);
702         Long.getChars(l, spaceNeeded, value);
703         count = spaceNeeded;
704         return this;
705     }
706 
707     /**
708      * Appends the string representation of the {@code float}
709      * argument to this sequence.
710      * <p>
711      * The overall effect is exactly as if the argument were converted
712      * to a string by the method {@link String#valueOf(float)},
713      * and the characters of that string were then
714      * {@link #append(String) appended} to this character sequence.
715      *
716      * @param   f   a {@code float}.
717      * @return  a reference to this object.
718      */
append(float f)719     public AbstractStringBuilder append(float f) {
720         FloatingDecimal.appendTo(f,this);
721         return this;
722     }
723 
724     /**
725      * Appends the string representation of the {@code double}
726      * argument to this sequence.
727      * <p>
728      * The overall effect is exactly as if the argument were converted
729      * to a string by the method {@link String#valueOf(double)},
730      * and the characters of that string were then
731      * {@link #append(String) appended} to this character sequence.
732      *
733      * @param   d   a {@code double}.
734      * @return  a reference to this object.
735      */
append(double d)736     public AbstractStringBuilder append(double d) {
737         FloatingDecimal.appendTo(d,this);
738         return this;
739     }
740 
741     /**
742      * Removes the characters in a substring of this sequence.
743      * The substring begins at the specified {@code start} and extends to
744      * the character at index {@code end - 1} or to the end of the
745      * sequence if no such character exists. If
746      * {@code start} is equal to {@code end}, no changes are made.
747      *
748      * @param      start  The beginning index, inclusive.
749      * @param      end    The ending index, exclusive.
750      * @return     This object.
751      * @throws     StringIndexOutOfBoundsException  if {@code start}
752      *             is negative, greater than {@code length()}, or
753      *             greater than {@code end}.
754      */
delete(int start, int end)755     public AbstractStringBuilder delete(int start, int end) {
756         if (start < 0)
757             throw new StringIndexOutOfBoundsException(start);
758         if (end > count)
759             end = count;
760         if (start > end)
761             throw new StringIndexOutOfBoundsException();
762         int len = end - start;
763         if (len > 0) {
764             System.arraycopy(value, start+len, value, start, count-end);
765             count -= len;
766         }
767         return this;
768     }
769 
770     /**
771      * Appends the string representation of the {@code codePoint}
772      * argument to this sequence.
773      *
774      * <p> The argument is appended to the contents of this sequence.
775      * The length of this sequence increases by
776      * {@link Character#charCount(int) Character.charCount(codePoint)}.
777      *
778      * <p> The overall effect is exactly as if the argument were
779      * converted to a {@code char} array by the method
780      * {@link Character#toChars(int)} and the character in that array
781      * were then {@link #append(char[]) appended} to this character
782      * sequence.
783      *
784      * @param   codePoint   a Unicode code point
785      * @return  a reference to this object.
786      * @exception IllegalArgumentException if the specified
787      * {@code codePoint} isn't a valid Unicode code point
788      */
appendCodePoint(int codePoint)789     public AbstractStringBuilder appendCodePoint(int codePoint) {
790         final int count = this.count;
791 
792         if (Character.isBmpCodePoint(codePoint)) {
793             ensureCapacityInternal(count + 1);
794             value[count] = (char) codePoint;
795             this.count = count + 1;
796         } else if (Character.isValidCodePoint(codePoint)) {
797             ensureCapacityInternal(count + 2);
798             Character.toSurrogates(codePoint, value, count);
799             this.count = count + 2;
800         } else {
801             throw new IllegalArgumentException();
802         }
803         return this;
804     }
805 
806     /**
807      * Removes the {@code char} at the specified position in this
808      * sequence. This sequence is shortened by one {@code char}.
809      *
810      * <p>Note: If the character at the given index is a supplementary
811      * character, this method does not remove the entire character. If
812      * correct handling of supplementary characters is required,
813      * determine the number of {@code char}s to remove by calling
814      * {@code Character.charCount(thisSequence.codePointAt(index))},
815      * where {@code thisSequence} is this sequence.
816      *
817      * @param       index  Index of {@code char} to remove
818      * @return      This object.
819      * @throws      StringIndexOutOfBoundsException  if the {@code index}
820      *              is negative or greater than or equal to
821      *              {@code length()}.
822      */
deleteCharAt(int index)823     public AbstractStringBuilder deleteCharAt(int index) {
824         if ((index < 0) || (index >= count))
825             throw new StringIndexOutOfBoundsException(index);
826         System.arraycopy(value, index+1, value, index, count-index-1);
827         count--;
828         return this;
829     }
830 
831     /**
832      * Replaces the characters in a substring of this sequence
833      * with characters in the specified {@code String}. The substring
834      * begins at the specified {@code start} and extends to the character
835      * at index {@code end - 1} or to the end of the
836      * sequence if no such character exists. First the
837      * characters in the substring are removed and then the specified
838      * {@code String} is inserted at {@code start}. (This
839      * sequence will be lengthened to accommodate the
840      * specified String if necessary.)
841      *
842      * @param      start    The beginning index, inclusive.
843      * @param      end      The ending index, exclusive.
844      * @param      str   String that will replace previous contents.
845      * @return     This object.
846      * @throws     StringIndexOutOfBoundsException  if {@code start}
847      *             is negative, greater than {@code length()}, or
848      *             greater than {@code end}.
849      */
replace(int start, int end, String str)850     public AbstractStringBuilder replace(int start, int end, String str) {
851         if (start < 0)
852             throw new StringIndexOutOfBoundsException(start);
853         if (start > count)
854             throw new StringIndexOutOfBoundsException("start > length()");
855         if (start > end)
856             throw new StringIndexOutOfBoundsException("start > end");
857 
858         if (end > count)
859             end = count;
860         int len = str.length();
861         int newCount = count + len - (end - start);
862         ensureCapacityInternal(newCount);
863 
864         System.arraycopy(value, end, value, start + len, count - end);
865         str.getChars(value, start);
866         count = newCount;
867         return this;
868     }
869 
870     /**
871      * Returns a new {@code String} that contains a subsequence of
872      * characters currently contained in this character sequence. The
873      * substring begins at the specified index and extends to the end of
874      * this sequence.
875      *
876      * @param      start    The beginning index, inclusive.
877      * @return     The new string.
878      * @throws     StringIndexOutOfBoundsException  if {@code start} is
879      *             less than zero, or greater than the length of this object.
880      */
substring(int start)881     public String substring(int start) {
882         return substring(start, count);
883     }
884 
885     /**
886      * Returns a new character sequence that is a subsequence of this sequence.
887      *
888      * <p> An invocation of this method of the form
889      *
890      * <pre>{@code
891      * sb.subSequence(begin,&nbsp;end)}</pre>
892      *
893      * behaves in exactly the same way as the invocation
894      *
895      * <pre>{@code
896      * sb.substring(begin,&nbsp;end)}</pre>
897      *
898      * This method is provided so that this class can
899      * implement the {@link CharSequence} interface.
900      *
901      * @param      start   the start index, inclusive.
902      * @param      end     the end index, exclusive.
903      * @return     the specified subsequence.
904      *
905      * @throws  IndexOutOfBoundsException
906      *          if {@code start} or {@code end} are negative,
907      *          if {@code end} is greater than {@code length()},
908      *          or if {@code start} is greater than {@code end}
909      * @spec JSR-51
910      */
911     @Override
subSequence(int start, int end)912     public CharSequence subSequence(int start, int end) {
913         return substring(start, end);
914     }
915 
916     /**
917      * Returns a new {@code String} that contains a subsequence of
918      * characters currently contained in this sequence. The
919      * substring begins at the specified {@code start} and
920      * extends to the character at index {@code end - 1}.
921      *
922      * @param      start    The beginning index, inclusive.
923      * @param      end      The ending index, exclusive.
924      * @return     The new string.
925      * @throws     StringIndexOutOfBoundsException  if {@code start}
926      *             or {@code end} are negative or greater than
927      *             {@code length()}, or {@code start} is
928      *             greater than {@code end}.
929      */
substring(int start, int end)930     public String substring(int start, int end) {
931         if (start < 0)
932             throw new StringIndexOutOfBoundsException(start);
933         if (end > count)
934             throw new StringIndexOutOfBoundsException(end);
935         if (start > end)
936             throw new StringIndexOutOfBoundsException(end - start);
937         return new String(value, start, end - start);
938     }
939 
940     /**
941      * Inserts the string representation of a subarray of the {@code str}
942      * array argument into this sequence. The subarray begins at the
943      * specified {@code offset} and extends {@code len} {@code char}s.
944      * The characters of the subarray are inserted into this sequence at
945      * the position indicated by {@code index}. The length of this
946      * sequence increases by {@code len} {@code char}s.
947      *
948      * @param      index    position at which to insert subarray.
949      * @param      str       A {@code char} array.
950      * @param      offset   the index of the first {@code char} in subarray to
951      *             be inserted.
952      * @param      len      the number of {@code char}s in the subarray to
953      *             be inserted.
954      * @return     This object
955      * @throws     StringIndexOutOfBoundsException  if {@code index}
956      *             is negative or greater than {@code length()}, or
957      *             {@code offset} or {@code len} are negative, or
958      *             {@code (offset+len)} is greater than
959      *             {@code str.length}.
960      */
insert(int index, char[] str, int offset, int len)961     public AbstractStringBuilder insert(int index, char[] str, int offset,
962                                         int len)
963     {
964         if ((index < 0) || (index > length()))
965             throw new StringIndexOutOfBoundsException(index);
966         if ((offset < 0) || (len < 0) || (offset > str.length - len))
967             throw new StringIndexOutOfBoundsException(
968                 "offset " + offset + ", len " + len + ", str.length "
969                 + str.length);
970         ensureCapacityInternal(count + len);
971         System.arraycopy(value, index, value, index + len, count - index);
972         System.arraycopy(str, offset, value, index, len);
973         count += len;
974         return this;
975     }
976 
977     /**
978      * Inserts the string representation of the {@code Object}
979      * argument into this character sequence.
980      * <p>
981      * The overall effect is exactly as if the second argument were
982      * converted to a string by the method {@link String#valueOf(Object)},
983      * and the characters of that string were then
984      * {@link #insert(int,String) inserted} into this character
985      * sequence at the indicated offset.
986      * <p>
987      * The {@code offset} argument must be greater than or equal to
988      * {@code 0}, and less than or equal to the {@linkplain #length() length}
989      * of this sequence.
990      *
991      * @param      offset   the offset.
992      * @param      obj      an {@code Object}.
993      * @return     a reference to this object.
994      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
995      */
insert(int offset, Object obj)996     public AbstractStringBuilder insert(int offset, Object obj) {
997         return insert(offset, String.valueOf(obj));
998     }
999 
1000     /**
1001      * Inserts the string into this character sequence.
1002      * <p>
1003      * The characters of the {@code String} argument are inserted, in
1004      * order, into this sequence at the indicated offset, moving up any
1005      * characters originally above that position and increasing the length
1006      * of this sequence by the length of the argument. If
1007      * {@code str} is {@code null}, then the four characters
1008      * {@code "null"} are inserted into this sequence.
1009      * <p>
1010      * The character at index <i>k</i> in the new character sequence is
1011      * equal to:
1012      * <ul>
1013      * <li>the character at index <i>k</i> in the old character sequence, if
1014      * <i>k</i> is less than {@code offset}
1015      * <li>the character at index <i>k</i>{@code -offset} in the
1016      * argument {@code str}, if <i>k</i> is not less than
1017      * {@code offset} but is less than {@code offset+str.length()}
1018      * <li>the character at index <i>k</i>{@code -str.length()} in the
1019      * old character sequence, if <i>k</i> is not less than
1020      * {@code offset+str.length()}
1021      * </ul><p>
1022      * The {@code offset} argument must be greater than or equal to
1023      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1024      * of this sequence.
1025      *
1026      * @param      offset   the offset.
1027      * @param      str      a string.
1028      * @return     a reference to this object.
1029      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1030      */
insert(int offset, String str)1031     public AbstractStringBuilder insert(int offset, String str) {
1032         if ((offset < 0) || (offset > length()))
1033             throw new StringIndexOutOfBoundsException(offset);
1034         if (str == null)
1035             str = "null";
1036         int len = str.length();
1037         ensureCapacityInternal(count + len);
1038         System.arraycopy(value, offset, value, offset + len, count - offset);
1039         str.getChars(value, offset);
1040         count += len;
1041         return this;
1042     }
1043 
1044     /**
1045      * Inserts the string representation of the {@code char} array
1046      * argument into this sequence.
1047      * <p>
1048      * The characters of the array argument are inserted into the
1049      * contents of this sequence at the position indicated by
1050      * {@code offset}. The length of this sequence increases by
1051      * the length of the argument.
1052      * <p>
1053      * The overall effect is exactly as if the second argument were
1054      * converted to a string by the method {@link String#valueOf(char[])},
1055      * and the characters of that string were then
1056      * {@link #insert(int,String) inserted} into this character
1057      * sequence at the indicated offset.
1058      * <p>
1059      * The {@code offset} argument must be greater than or equal to
1060      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1061      * of this sequence.
1062      *
1063      * @param      offset   the offset.
1064      * @param      str      a character array.
1065      * @return     a reference to this object.
1066      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1067      */
insert(int offset, char[] str)1068     public AbstractStringBuilder insert(int offset, char[] str) {
1069         if ((offset < 0) || (offset > length()))
1070             throw new StringIndexOutOfBoundsException(offset);
1071         int len = str.length;
1072         ensureCapacityInternal(count + len);
1073         System.arraycopy(value, offset, value, offset + len, count - offset);
1074         System.arraycopy(str, 0, value, offset, len);
1075         count += len;
1076         return this;
1077     }
1078 
1079     /**
1080      * Inserts the specified {@code CharSequence} into this sequence.
1081      * <p>
1082      * The characters of the {@code CharSequence} argument are inserted,
1083      * in order, into this sequence at the indicated offset, moving up
1084      * any characters originally above that position and increasing the length
1085      * of this sequence by the length of the argument s.
1086      * <p>
1087      * The result of this method is exactly the same as if it were an
1088      * invocation of this object's
1089      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
1090      * method.
1091      *
1092      * <p>If {@code s} is {@code null}, then the four characters
1093      * {@code "null"} are inserted into this sequence.
1094      *
1095      * @param      dstOffset   the offset.
1096      * @param      s the sequence to be inserted
1097      * @return     a reference to this object.
1098      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1099      */
insert(int dstOffset, CharSequence s)1100     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
1101         if (s == null)
1102             s = "null";
1103         if (s instanceof String)
1104             return this.insert(dstOffset, (String)s);
1105         return this.insert(dstOffset, s, 0, s.length());
1106     }
1107 
1108     /**
1109      * Inserts a subsequence of the specified {@code CharSequence} into
1110      * this sequence.
1111      * <p>
1112      * The subsequence of the argument {@code s} specified by
1113      * {@code start} and {@code end} are inserted,
1114      * in order, into this sequence at the specified destination offset, moving
1115      * up any characters originally above that position. The length of this
1116      * sequence is increased by {@code end - start}.
1117      * <p>
1118      * The character at index <i>k</i> in this sequence becomes equal to:
1119      * <ul>
1120      * <li>the character at index <i>k</i> in this sequence, if
1121      * <i>k</i> is less than {@code dstOffset}
1122      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
1123      * the argument {@code s}, if <i>k</i> is greater than or equal to
1124      * {@code dstOffset} but is less than {@code dstOffset+end-start}
1125      * <li>the character at index <i>k</i>{@code -(end-start)} in this
1126      * sequence, if <i>k</i> is greater than or equal to
1127      * {@code dstOffset+end-start}
1128      * </ul><p>
1129      * The {@code dstOffset} argument must be greater than or equal to
1130      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1131      * of this sequence.
1132      * <p>The start argument must be nonnegative, and not greater than
1133      * {@code end}.
1134      * <p>The end argument must be greater than or equal to
1135      * {@code start}, and less than or equal to the length of s.
1136      *
1137      * <p>If {@code s} is {@code null}, then this method inserts
1138      * characters as if the s parameter was a sequence containing the four
1139      * characters {@code "null"}.
1140      *
1141      * @param      dstOffset   the offset in this sequence.
1142      * @param      s       the sequence to be inserted.
1143      * @param      start   the starting index of the subsequence to be inserted.
1144      * @param      end     the end index of the subsequence to be inserted.
1145      * @return     a reference to this object.
1146      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
1147      *             is negative or greater than {@code this.length()}, or
1148      *              {@code start} or {@code end} are negative, or
1149      *              {@code start} is greater than {@code end} or
1150      *              {@code end} is greater than {@code s.length()}
1151      */
insert(int dstOffset, CharSequence s, int start, int end)1152      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
1153                                          int start, int end) {
1154         if (s == null)
1155             s = "null";
1156         if ((dstOffset < 0) || (dstOffset > this.length()))
1157             throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
1158         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
1159             throw new IndexOutOfBoundsException(
1160                 "start " + start + ", end " + end + ", s.length() "
1161                 + s.length());
1162         int len = end - start;
1163         ensureCapacityInternal(count + len);
1164         System.arraycopy(value, dstOffset, value, dstOffset + len,
1165                          count - dstOffset);
1166         for (int i=start; i<end; i++)
1167             value[dstOffset++] = s.charAt(i);
1168         count += len;
1169         return this;
1170     }
1171 
1172     /**
1173      * Inserts the string representation of the {@code boolean}
1174      * argument into this sequence.
1175      * <p>
1176      * The overall effect is exactly as if the second argument were
1177      * converted to a string by the method {@link String#valueOf(boolean)},
1178      * and the characters of that string were then
1179      * {@link #insert(int,String) inserted} into this character
1180      * sequence at the indicated offset.
1181      * <p>
1182      * The {@code offset} argument must be greater than or equal to
1183      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1184      * of this sequence.
1185      *
1186      * @param      offset   the offset.
1187      * @param      b        a {@code boolean}.
1188      * @return     a reference to this object.
1189      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1190      */
insert(int offset, boolean b)1191     public AbstractStringBuilder insert(int offset, boolean b) {
1192         return insert(offset, String.valueOf(b));
1193     }
1194 
1195     /**
1196      * Inserts the string representation of the {@code char}
1197      * argument into this sequence.
1198      * <p>
1199      * The overall effect is exactly as if the second argument were
1200      * converted to a string by the method {@link String#valueOf(char)},
1201      * and the character in that string were then
1202      * {@link #insert(int,String) inserted} into this character
1203      * sequence at the indicated offset.
1204      * <p>
1205      * The {@code offset} argument must be greater than or equal to
1206      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1207      * of this sequence.
1208      *
1209      * @param      offset   the offset.
1210      * @param      c        a {@code char}.
1211      * @return     a reference to this object.
1212      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1213      */
insert(int offset, char c)1214     public AbstractStringBuilder insert(int offset, char c) {
1215         ensureCapacityInternal(count + 1);
1216         System.arraycopy(value, offset, value, offset + 1, count - offset);
1217         value[offset] = c;
1218         count += 1;
1219         return this;
1220     }
1221 
1222     /**
1223      * Inserts the string representation of the second {@code int}
1224      * argument into this sequence.
1225      * <p>
1226      * The overall effect is exactly as if the second argument were
1227      * converted to a string by the method {@link String#valueOf(int)},
1228      * and the characters of that string were then
1229      * {@link #insert(int,String) inserted} into this character
1230      * sequence at the indicated offset.
1231      * <p>
1232      * The {@code offset} argument must be greater than or equal to
1233      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1234      * of this sequence.
1235      *
1236      * @param      offset   the offset.
1237      * @param      i        an {@code int}.
1238      * @return     a reference to this object.
1239      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1240      */
insert(int offset, int i)1241     public AbstractStringBuilder insert(int offset, int i) {
1242         return insert(offset, String.valueOf(i));
1243     }
1244 
1245     /**
1246      * Inserts the string representation of the {@code long}
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(long)},
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      l        a {@code long}.
1261      * @return     a reference to this object.
1262      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1263      */
insert(int offset, long l)1264     public AbstractStringBuilder insert(int offset, long l) {
1265         return insert(offset, String.valueOf(l));
1266     }
1267 
1268     /**
1269      * Inserts the string representation of the {@code float}
1270      * argument into this sequence.
1271      * <p>
1272      * The overall effect is exactly as if the second argument were
1273      * converted to a string by the method {@link String#valueOf(float)},
1274      * and the characters of that string were then
1275      * {@link #insert(int,String) inserted} into this character
1276      * sequence at the indicated offset.
1277      * <p>
1278      * The {@code offset} argument must be greater than or equal to
1279      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1280      * of this sequence.
1281      *
1282      * @param      offset   the offset.
1283      * @param      f        a {@code float}.
1284      * @return     a reference to this object.
1285      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1286      */
insert(int offset, float f)1287     public AbstractStringBuilder insert(int offset, float f) {
1288         return insert(offset, String.valueOf(f));
1289     }
1290 
1291     /**
1292      * Inserts the string representation of the {@code double}
1293      * argument into this sequence.
1294      * <p>
1295      * The overall effect is exactly as if the second argument were
1296      * converted to a string by the method {@link String#valueOf(double)},
1297      * and the characters of that string were then
1298      * {@link #insert(int,String) inserted} into this character
1299      * sequence at the indicated offset.
1300      * <p>
1301      * The {@code offset} argument must be greater than or equal to
1302      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1303      * of this sequence.
1304      *
1305      * @param      offset   the offset.
1306      * @param      d        a {@code double}.
1307      * @return     a reference to this object.
1308      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1309      */
insert(int offset, double d)1310     public AbstractStringBuilder insert(int offset, double d) {
1311         return insert(offset, String.valueOf(d));
1312     }
1313 
1314     /**
1315      * Returns the index within this string of the first occurrence of the
1316      * specified substring. The integer returned is the smallest value
1317      * <i>k</i> such that:
1318      * <pre>{@code
1319      * this.toString().startsWith(str, <i>k</i>)
1320      * }</pre>
1321      * is {@code true}.
1322      *
1323      * @param   str   any string.
1324      * @return  if the string argument occurs as a substring within this
1325      *          object, then the index of the first character of the first
1326      *          such substring is returned; if it does not occur as a
1327      *          substring, {@code -1} is returned.
1328      */
indexOf(String str)1329     public int indexOf(String str) {
1330         return indexOf(str, 0);
1331     }
1332 
1333     /**
1334      * Returns the index within this string of the first occurrence of the
1335      * specified substring, starting at the specified index.  The integer
1336      * returned is the smallest value {@code k} for which:
1337      * <pre>{@code
1338      *     k >= Math.min(fromIndex, this.length()) &&
1339      *                   this.toString().startsWith(str, k)
1340      * }</pre>
1341      * If no such value of <i>k</i> exists, then -1 is returned.
1342      *
1343      * @param   str         the substring for which to search.
1344      * @param   fromIndex   the index from which to start the search.
1345      * @return  the index within this string of the first occurrence of the
1346      *          specified substring, starting at the specified index.
1347      */
indexOf(String str, int fromIndex)1348     public int indexOf(String str, int fromIndex) {
1349         return String.indexOf(value, 0, count, str, fromIndex);
1350     }
1351 
1352     /**
1353      * Returns the index within this string of the rightmost occurrence
1354      * of the specified substring.  The rightmost empty string "" is
1355      * considered to occur at the index value {@code this.length()}.
1356      * The returned index is the largest value <i>k</i> such that
1357      * <pre>{@code
1358      * this.toString().startsWith(str, k)
1359      * }</pre>
1360      * is true.
1361      *
1362      * @param   str   the substring to search for.
1363      * @return  if the string argument occurs one or more times as a substring
1364      *          within this object, then the index of the first character of
1365      *          the last such substring is returned. If it does not occur as
1366      *          a substring, {@code -1} is returned.
1367      */
lastIndexOf(String str)1368     public int lastIndexOf(String str) {
1369         return lastIndexOf(str, count);
1370     }
1371 
1372     /**
1373      * Returns the index within this string of the last occurrence of the
1374      * specified substring. The integer returned is the largest value <i>k</i>
1375      * such that:
1376      * <pre>{@code
1377      *     k <= Math.min(fromIndex, this.length()) &&
1378      *                   this.toString().startsWith(str, k)
1379      * }</pre>
1380      * If no such value of <i>k</i> exists, then -1 is returned.
1381      *
1382      * @param   str         the substring to search for.
1383      * @param   fromIndex   the index to start the search from.
1384      * @return  the index within this sequence of the last occurrence of the
1385      *          specified substring.
1386      */
lastIndexOf(String str, int fromIndex)1387     public int lastIndexOf(String str, int fromIndex) {
1388         return String.lastIndexOf(value, 0, count, str, fromIndex);
1389     }
1390 
1391     /**
1392      * Causes this character sequence to be replaced by the reverse of
1393      * the sequence. If there are any surrogate pairs included in the
1394      * sequence, these are treated as single characters for the
1395      * reverse operation. Thus, the order of the high-low surrogates
1396      * is never reversed.
1397      *
1398      * Let <i>n</i> be the character length of this character sequence
1399      * (not the length in {@code char} values) just prior to
1400      * execution of the {@code reverse} method. Then the
1401      * character at index <i>k</i> in the new character sequence is
1402      * equal to the character at index <i>n-k-1</i> in the old
1403      * character sequence.
1404      *
1405      * <p>Note that the reverse operation may result in producing
1406      * surrogate pairs that were unpaired low-surrogates and
1407      * high-surrogates before the operation. For example, reversing
1408      * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
1409      * a valid surrogate pair.
1410      *
1411      * @return  a reference to this object.
1412      */
reverse()1413     public AbstractStringBuilder reverse() {
1414         boolean hasSurrogates = false;
1415         int n = count - 1;
1416         for (int j = (n-1) >> 1; j >= 0; j--) {
1417             int k = n - j;
1418             char cj = value[j];
1419             char ck = value[k];
1420             value[j] = ck;
1421             value[k] = cj;
1422             if (Character.isSurrogate(cj) ||
1423                 Character.isSurrogate(ck)) {
1424                 hasSurrogates = true;
1425             }
1426         }
1427         if (hasSurrogates) {
1428             reverseAllValidSurrogatePairs();
1429         }
1430         return this;
1431     }
1432 
1433     /** Outlined helper method for reverse() */
reverseAllValidSurrogatePairs()1434     private void reverseAllValidSurrogatePairs() {
1435         for (int i = 0; i < count - 1; i++) {
1436             char c2 = value[i];
1437             if (Character.isLowSurrogate(c2)) {
1438                 char c1 = value[i + 1];
1439                 if (Character.isHighSurrogate(c1)) {
1440                     value[i++] = c1;
1441                     value[i] = c2;
1442                 }
1443             }
1444         }
1445     }
1446 
1447     /**
1448      * Returns a string representing the data in this sequence.
1449      * A new {@code String} object is allocated and initialized to
1450      * contain the character sequence currently represented by this
1451      * object. This {@code String} is then returned. Subsequent
1452      * changes to this sequence do not affect the contents of the
1453      * {@code String}.
1454      *
1455      * @return  a string representation of this sequence of characters.
1456      */
1457     @Override
toString()1458     public abstract String toString();
1459 
1460     /**
1461      * Needed by {@code String} for the contentEquals method.
1462      */
getValue()1463     final char[] getValue() {
1464         return value;
1465     }
1466 
1467 }
1468