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