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