1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 import dalvik.annotation.optimization.FastNative; 30 import dalvik.annotation.optimization.NeverInline; 31 import java.io.ObjectStreamField; 32 import java.io.UnsupportedEncodingException; 33 import java.lang.annotation.Native; 34 import java.nio.charset.Charset; 35 import java.nio.ByteBuffer; 36 import java.util.Comparator; 37 import java.util.Formatter; 38 import java.util.List; 39 import java.util.Locale; 40 import java.util.Objects; 41 import java.util.Spliterator; 42 import java.util.StringJoiner; 43 import java.util.function.Function; 44 import java.util.regex.Pattern; 45 import java.util.regex.PatternSyntaxException; 46 import java.util.stream.Collectors; 47 import java.util.stream.IntStream; 48 import java.util.stream.Stream; 49 import java.util.stream.StreamSupport; 50 import jdk.internal.vm.annotation.IntrinsicCandidate; 51 52 import libcore.util.CharsetUtils; 53 54 /** 55 * The {@code String} class represents character strings. All 56 * string literals in Java programs, such as {@code "abc"}, are 57 * implemented as instances of this class. 58 * <p> 59 * Strings are constant; their values cannot be changed after they 60 * are created. String buffers support mutable strings. 61 * Because String objects are immutable they can be shared. For example: 62 * <blockquote><pre> 63 * String str = "abc"; 64 * </pre></blockquote><p> 65 * is equivalent to: 66 * <blockquote><pre> 67 * char data[] = {'a', 'b', 'c'}; 68 * String str = new String(data); 69 * </pre></blockquote><p> 70 * Here are some more examples of how strings can be used: 71 * <blockquote><pre> 72 * System.out.println("abc"); 73 * String cde = "cde"; 74 * System.out.println("abc" + cde); 75 * String c = "abc".substring(2,3); 76 * String d = cde.substring(1, 2); 77 * </pre></blockquote> 78 * <p> 79 * The class {@code String} includes methods for examining 80 * individual characters of the sequence, for comparing strings, for 81 * searching strings, for extracting substrings, and for creating a 82 * copy of a string with all characters translated to uppercase or to 83 * lowercase. Case mapping is based on the Unicode Standard version 84 * specified by the {@link java.lang.Character Character} class. 85 * <p> 86 * The Java language provides special support for the string 87 * concatenation operator ( + ), and for conversion of 88 * other objects to strings. For additional information on string 89 * concatenation and conversion, see <i>The Java™ Language Specification</i>. 90 * 91 * <p> Unless otherwise noted, passing a {@code null} argument to a constructor 92 * or method in this class will cause a {@link NullPointerException} to be 93 * thrown. 94 * 95 * <p>A {@code String} represents a string in the UTF-16 format 96 * in which <em>supplementary characters</em> are represented by <em>surrogate 97 * pairs</em> (see the section <a href="Character.html#unicode">Unicode 98 * Character Representations</a> in the {@code Character} class for 99 * more information). 100 * Index values refer to {@code char} code units, so a supplementary 101 * character uses two positions in a {@code String}. 102 * <p>The {@code String} class provides methods for dealing with 103 * Unicode code points (i.e., characters), in addition to those for 104 * dealing with Unicode code units (i.e., {@code char} values). 105 * 106 * <p>Unless otherwise noted, methods for comparing Strings do not take locale 107 * into account. The {@link java.text.Collator} class provides methods for 108 * finer-grain, locale-sensitive String comparison. 109 * 110 * @implNote The implementation of the string concatenation operator is left to 111 * the discretion of a Java compiler, as long as the compiler ultimately conforms 112 * to <i>The Java™ Language Specification</i>. For example, the {@code javac} compiler 113 * may implement the operator with {@code StringBuffer}, {@code StringBuilder}, 114 * or {@code java.lang.invoke.StringConcatFactory} depending on the JDK version. The 115 * implementation of string conversion is typically through the method {@code toString}, 116 * defined by {@code Object} and inherited by all classes in Java. 117 * 118 * @author Lee Boynton 119 * @author Arthur van Hoff 120 * @author Martin Buchholz 121 * @author Ulf Zibis 122 * @see java.lang.Object#toString() 123 * @see java.lang.StringBuffer 124 * @see java.lang.StringBuilder 125 * @see java.nio.charset.Charset 126 * @since 1.0 127 * @jls 15.18.1 String Concatenation Operator + 128 */ 129 130 public final class String 131 implements java.io.Serializable, Comparable<String>, CharSequence { 132 // BEGIN Android-changed: The character data is managed by the runtime. 133 /* 134 We only keep track of the length here and compression here. This has several consequences 135 throughout this class: 136 - References to value[i] are replaced by charAt(i). 137 - References to value.length are replaced by calls to length(). 138 - Sometimes the result of length() is assigned to a local variable to avoid repeated calls. 139 - We skip several attempts at optimization where the values field was assigned to a local 140 variable to avoid the getfield opcode. 141 These changes are not all marked individually. 142 143 If STRING_COMPRESSION_ENABLED, count stores the length shifted one bit to the left with the 144 lowest bit used to indicate whether or not the bytes are compressed (see GetFlaggedCount in 145 the native code). 146 /** 147 * The value is used for character storage. 148 * 149 * @implNote This field is trusted by the VM, and is a subject to 150 * constant folding if String instance is constant. Overwriting this 151 * field after construction will cause problems. 152 * 153 * Additionally, it is marked with {@link Stable} to trust the contents 154 * of the array. No other facility in JDK provides this functionality (yet). 155 * {@link Stable} is safe here, because value is never null. 156 * 157 @Stable 158 private final byte[] value; 159 */ 160 private final int count; 161 // END Android-changed: The character data is managed by the runtime. 162 163 // Android-changed: We make use of new StringIndexOutOfBoundsException constructor signatures. 164 // These improve some error messages. These changes are not all marked individually. 165 166 /** Cache the hash code for the string */ 167 private int hash; // Default to 0 168 169 /** use serialVersionUID from JDK 1.0.2 for interoperability */ 170 private static final long serialVersionUID = -6849794470754667710L; 171 172 // Android-changed: Modified the javadoc for the ART environment. 173 // Note that this COMPACT_STRINGS value is mainly used by the StringBuilder, not by String. 174 /** 175 * If String compaction is disabled, the bytes in {@code value} are 176 * always encoded in UTF16. 177 * 178 * For methods with several possible implementation paths, when String 179 * compaction is disabled, only one code path is taken. 180 * 181 * The instance field value is generally opaque to optimizing JIT 182 * compilers. Therefore, in performance-sensitive place, an explicit 183 * check of the static boolean {@code COMPACT_STRINGS} is done first 184 * before checking the {@code coder} field since the static boolean 185 * {@code COMPACT_STRINGS} would be constant folded away by an 186 * optimizing JIT compiler. The idioms for these cases are as follows. 187 * 188 * For code such as: 189 * 190 * if (coder == LATIN1) { ... } 191 * 192 * can be written more optimally as 193 * 194 * if (coder() == LATIN1) { ... } 195 * 196 * or: 197 * 198 * if (COMPACT_STRINGS && coder == LATIN1) { ... } 199 * 200 * An optimizing JIT compiler can fold the above conditional as: 201 * 202 * COMPACT_STRINGS == true => if (coder == LATIN1) { ... } 203 * COMPACT_STRINGS == false => if (false) { ... } 204 */ 205 // Android-changed: Inline the constant on ART. 206 static final boolean COMPACT_STRINGS = true; 207 208 @Native static final byte LATIN1 = 0; 209 @Native static final byte UTF16 = 1; 210 211 /** 212 * Class String is special cased within the Serialization Stream Protocol. 213 * 214 * A String instance is written into an ObjectOutputStream according to 215 * <a href="{@docRoot}/../specs/serialization/protocol.html#stream-elements"> 216 * Object Serialization Specification, Section 6.2, "Stream Elements"</a> 217 */ 218 private static final ObjectStreamField[] serialPersistentFields = 219 new ObjectStreamField[0]; 220 221 /** 222 * Initializes a newly created {@code String} object so that it represents 223 * an empty character sequence. Note that use of this constructor is 224 * unnecessary since Strings are immutable. 225 */ String()226 public String() { 227 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 228 /* 229 this.value = "".value; 230 this.coder = "".coder; 231 */ 232 throw new UnsupportedOperationException("Use StringFactory instead."); 233 // END Android-changed: Implemented as compiler and runtime intrinsics. 234 } 235 236 /** 237 * Initializes a newly created {@code String} object so that it represents 238 * the same sequence of characters as the argument; in other words, the 239 * newly created string is a copy of the argument string. Unless an 240 * explicit copy of {@code original} is needed, use of this constructor is 241 * unnecessary since Strings are immutable. 242 * 243 * @param original 244 * A {@code String} 245 */ 246 @IntrinsicCandidate String(String original)247 public String(String original) { 248 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 249 /* 250 this.value = original.value; 251 this.coder = original.coder; 252 this.hash = original.hash; 253 */ 254 throw new UnsupportedOperationException("Use StringFactory instead."); 255 // END Android-changed: Implemented as compiler and runtime intrinsics. 256 } 257 258 /** 259 * Allocates a new {@code String} so that it represents the sequence of 260 * characters currently contained in the character array argument. The 261 * contents of the character array are copied; subsequent modification of 262 * the character array does not affect the newly created string. 263 * 264 * @param value 265 * The initial value of the string 266 */ String(char value[])267 public String(char value[]) { 268 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 269 /* 270 this(value, 0, value.length, null); 271 */ 272 throw new UnsupportedOperationException("Use StringFactory instead."); 273 // END Android-changed: Implemented as compiler and runtime intrinsics. 274 } 275 276 /** 277 * Allocates a new {@code String} that contains characters from a subarray 278 * of the character array argument. The {@code offset} argument is the 279 * index of the first character of the subarray and the {@code count} 280 * argument specifies the length of the subarray. The contents of the 281 * subarray are copied; subsequent modification of the character array does 282 * not affect the newly created string. 283 * 284 * @param value 285 * Array that is the source of characters 286 * 287 * @param offset 288 * The initial offset 289 * 290 * @param count 291 * The length 292 * 293 * @throws IndexOutOfBoundsException 294 * If {@code offset} is negative, {@code count} is negative, or 295 * {@code offset} is greater than {@code value.length - count} 296 */ String(char value[], int offset, int count)297 public String(char value[], int offset, int count) { 298 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 299 /* 300 this(value, offset, count, rangeCheck(value, offset, count)); 301 } 302 303 private static Void rangeCheck(char[] value, int offset, int count) { 304 checkBoundsOffCount(offset, count, value.length); 305 return null; 306 */ 307 throw new UnsupportedOperationException("Use StringFactory instead."); 308 // END Android-changed: Implemented as compiler and runtime intrinsics. 309 } 310 311 /** 312 * Allocates a new {@code String} that contains characters from a subarray 313 * of the <a href="Character.html#unicode">Unicode code point</a> array 314 * argument. The {@code offset} argument is the index of the first code 315 * point of the subarray and the {@code count} argument specifies the 316 * length of the subarray. The contents of the subarray are converted to 317 * {@code char}s; subsequent modification of the {@code int} array does not 318 * affect the newly created string. 319 * 320 * @param codePoints 321 * Array that is the source of Unicode code points 322 * 323 * @param offset 324 * The initial offset 325 * 326 * @param count 327 * The length 328 * 329 * @throws IllegalArgumentException 330 * If any invalid Unicode code point is found in {@code 331 * codePoints} 332 * 333 * @throws IndexOutOfBoundsException 334 * If {@code offset} is negative, {@code count} is negative, or 335 * {@code offset} is greater than {@code codePoints.length - count} 336 * 337 * @since 1.5 338 */ String(int[] codePoints, int offset, int count)339 public String(int[] codePoints, int offset, int count) { 340 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 341 /* 342 checkBoundsOffCount(offset, count, codePoints.length); 343 if (count == 0) { 344 this.value = "".value; 345 this.coder = "".coder; 346 return; 347 } 348 if (COMPACT_STRINGS) { 349 byte[] val = StringLatin1.toBytes(codePoints, offset, count); 350 if (val != null) { 351 this.coder = LATIN1; 352 this.value = val; 353 return; 354 } 355 } 356 this.coder = UTF16; 357 this.value = StringUTF16.toBytes(codePoints, offset, count); 358 */ 359 throw new UnsupportedOperationException("Use StringFactory instead."); 360 // END Android-changed: Implemented as compiler and runtime intrinsics. 361 } 362 363 /** 364 * Allocates a new {@code String} constructed from a subarray of an array 365 * of 8-bit integer values. 366 * 367 * <p> The {@code offset} argument is the index of the first byte of the 368 * subarray, and the {@code count} argument specifies the length of the 369 * subarray. 370 * 371 * <p> Each {@code byte} in the subarray is converted to a {@code char} as 372 * specified in the {@link #String(byte[],int) String(byte[],int)} constructor. 373 * 374 * @deprecated This method does not properly convert bytes into characters. 375 * As of JDK 1.1, the preferred way to do this is via the 376 * {@code String} constructors that take a {@link 377 * java.nio.charset.Charset}, charset name, or that use the platform's 378 * default charset. 379 * 380 * @param ascii 381 * The bytes to be converted to characters 382 * 383 * @param hibyte 384 * The top 8 bits of each 16-bit Unicode code unit 385 * 386 * @param offset 387 * The initial offset 388 * @param count 389 * The length 390 * 391 * @throws IndexOutOfBoundsException 392 * If {@code offset} is negative, {@code count} is negative, or 393 * {@code offset} is greater than {@code ascii.length - count} 394 * 395 * @see #String(byte[], int) 396 * @see #String(byte[], int, int, java.lang.String) 397 * @see #String(byte[], int, int, java.nio.charset.Charset) 398 * @see #String(byte[], int, int) 399 * @see #String(byte[], java.lang.String) 400 * @see #String(byte[], java.nio.charset.Charset) 401 * @see #String(byte[]) 402 */ 403 @Deprecated(since="1.1") String(byte ascii[], int hibyte, int offset, int count)404 public String(byte ascii[], int hibyte, int offset, int count) { 405 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 406 /* 407 checkBoundsOffCount(offset, count, ascii.length); 408 if (count == 0) { 409 this.value = "".value; 410 this.coder = "".coder; 411 return; 412 } 413 if (COMPACT_STRINGS && (byte)hibyte == 0) { 414 this.value = Arrays.copyOfRange(ascii, offset, offset + count); 415 this.coder = LATIN1; 416 } else { 417 hibyte <<= 8; 418 byte[] val = StringUTF16.newBytesFor(count); 419 for (int i = 0; i < count; i++) { 420 StringUTF16.putChar(val, i, hibyte | (ascii[offset++] & 0xff)); 421 } 422 this.value = val; 423 this.coder = UTF16; 424 } 425 */ 426 throw new UnsupportedOperationException("Use StringFactory instead."); 427 // END Android-changed: Implemented as compiler and runtime intrinsics. 428 } 429 430 /** 431 * Allocates a new {@code String} containing characters constructed from 432 * an array of 8-bit integer values. Each character <i>c</i> in the 433 * resulting string is constructed from the corresponding component 434 * <i>b</i> in the byte array such that: 435 * 436 * <blockquote><pre> 437 * <b><i>c</i></b> == (char)(((hibyte & 0xff) << 8) 438 * | (<b><i>b</i></b> & 0xff)) 439 * </pre></blockquote> 440 * 441 * @deprecated This method does not properly convert bytes into 442 * characters. As of JDK 1.1, the preferred way to do this is via the 443 * {@code String} constructors that take a {@link 444 * java.nio.charset.Charset}, charset name, or that use the platform's 445 * default charset. 446 * 447 * @param ascii 448 * The bytes to be converted to characters 449 * 450 * @param hibyte 451 * The top 8 bits of each 16-bit Unicode code unit 452 * 453 * @see #String(byte[], int, int, java.lang.String) 454 * @see #String(byte[], int, int, java.nio.charset.Charset) 455 * @see #String(byte[], int, int) 456 * @see #String(byte[], java.lang.String) 457 * @see #String(byte[], java.nio.charset.Charset) 458 * @see #String(byte[]) 459 */ 460 @Deprecated(since="1.1") String(byte ascii[], int hibyte)461 public String(byte ascii[], int hibyte) { 462 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 463 /* 464 this(ascii, hibyte, 0, ascii.length); 465 */ 466 throw new UnsupportedOperationException("Use StringFactory instead."); 467 // END Android-changed: Implemented as compiler and runtime intrinsics. 468 } 469 470 // BEGIN Android-removed: checkBounds(byte[] bytes, int offset, int length) utility method. 471 /* Common private utility method used to bounds check the byte array 472 * and requested offset & length values used by the String(byte[],..) 473 * constructors. 474 * 475 private static void checkBounds(byte[] bytes, int offset, int length) { 476 if (length < 0) 477 throw new StringIndexOutOfBoundsException(length); 478 if (offset < 0) 479 throw new StringIndexOutOfBoundsException(offset); 480 if (offset > bytes.length - length) 481 throw new StringIndexOutOfBoundsException(offset + length); 482 } 483 // END Android-removed: checkBounds(byte[] bytes, int offset, int length) utility method. 484 485 /** 486 * Constructs a new {@code String} by decoding the specified subarray of 487 * bytes using the specified charset. The length of the new {@code String} 488 * is a function of the charset, and hence may not be equal to the length 489 * of the subarray. 490 * 491 * <p> The behavior of this constructor when the given bytes are not valid 492 * in the given charset is unspecified. The {@link 493 * java.nio.charset.CharsetDecoder} class should be used when more control 494 * over the decoding process is required. 495 * 496 * @param bytes 497 * The bytes to be decoded into characters 498 * 499 * @param offset 500 * The index of the first byte to decode 501 * 502 * @param length 503 * The number of bytes to decode 504 505 * @param charsetName 506 * The name of a supported {@linkplain java.nio.charset.Charset 507 * charset} 508 * 509 * @throws UnsupportedEncodingException 510 * If the named charset is not supported 511 * 512 * @throws IndexOutOfBoundsException 513 * If {@code offset} is negative, {@code length} is negative, or 514 * {@code offset} is greater than {@code bytes.length - length} 515 * 516 * @since 1.1 517 */ String(byte bytes[], int offset, int length, String charsetName)518 public String(byte bytes[], int offset, int length, String charsetName) 519 throws UnsupportedEncodingException { 520 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 521 /* 522 if (charsetName == null) 523 throw new NullPointerException("charsetName"); 524 checkBoundsOffCount(offset, length, bytes.length); 525 StringCoding.Result ret = 526 StringCoding.decode(charsetName, bytes, offset, length); 527 this.value = ret.value; 528 this.coder = ret.coder; 529 */ 530 throw new UnsupportedOperationException("Use StringFactory instead."); 531 // END Android-changed: Implemented as compiler and runtime intrinsics. 532 } 533 534 /** 535 * Constructs a new {@code String} by decoding the specified subarray of 536 * bytes using the specified {@linkplain java.nio.charset.Charset charset}. 537 * The length of the new {@code String} is a function of the charset, and 538 * hence may not be equal to the length of the subarray. 539 * 540 * <p> This method always replaces malformed-input and unmappable-character 541 * sequences with this charset's default replacement string. The {@link 542 * java.nio.charset.CharsetDecoder} class should be used when more control 543 * over the decoding process is required. 544 * 545 * @param bytes 546 * The bytes to be decoded into characters 547 * 548 * @param offset 549 * The index of the first byte to decode 550 * 551 * @param length 552 * The number of bytes to decode 553 * 554 * @param charset 555 * The {@linkplain java.nio.charset.Charset charset} to be used to 556 * decode the {@code bytes} 557 * 558 * @throws IndexOutOfBoundsException 559 * If {@code offset} is negative, {@code length} is negative, or 560 * {@code offset} is greater than {@code bytes.length - length} 561 * 562 * @since 1.6 563 */ String(byte bytes[], int offset, int length, Charset charset)564 public String(byte bytes[], int offset, int length, Charset charset) { 565 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 566 /* 567 if (charset == null) 568 throw new NullPointerException("charset"); 569 checkBoundsOffCount(offset, length, bytes.length); 570 StringCoding.Result ret = 571 StringCoding.decode(charset, bytes, offset, length); 572 this.value = ret.value; 573 this.coder = ret.coder; 574 */ 575 throw new UnsupportedOperationException("Use StringFactory instead."); 576 // END Android-changed: Implemented as compiler and runtime intrinsics. 577 } 578 579 /** 580 * Constructs a new {@code String} by decoding the specified array of bytes 581 * using the specified {@linkplain java.nio.charset.Charset charset}. The 582 * length of the new {@code String} is a function of the charset, and hence 583 * may not be equal to the length of the byte array. 584 * 585 * <p> The behavior of this constructor when the given bytes are not valid 586 * in the given charset is unspecified. The {@link 587 * java.nio.charset.CharsetDecoder} class should be used when more control 588 * over the decoding process is required. 589 * 590 * @param bytes 591 * The bytes to be decoded into characters 592 * 593 * @param charsetName 594 * The name of a supported {@linkplain java.nio.charset.Charset 595 * charset} 596 * 597 * @throws UnsupportedEncodingException 598 * If the named charset is not supported 599 * 600 * @since 1.1 601 */ String(byte bytes[], String charsetName)602 public String(byte bytes[], String charsetName) 603 throws UnsupportedEncodingException { 604 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 605 /* 606 this(bytes, 0, bytes.length, charsetName); 607 */ 608 throw new UnsupportedOperationException("Use StringFactory instead."); 609 // END Android-changed: Implemented as compiler and runtime intrinsics. 610 } 611 612 /** 613 * Constructs a new {@code String} by decoding the specified array of 614 * bytes using the specified {@linkplain java.nio.charset.Charset charset}. 615 * The length of the new {@code String} is a function of the charset, and 616 * hence may not be equal to the length of the byte array. 617 * 618 * <p> This method always replaces malformed-input and unmappable-character 619 * sequences with this charset's default replacement string. The {@link 620 * java.nio.charset.CharsetDecoder} class should be used when more control 621 * over the decoding process is required. 622 * 623 * @param bytes 624 * The bytes to be decoded into characters 625 * 626 * @param charset 627 * The {@linkplain java.nio.charset.Charset charset} to be used to 628 * decode the {@code bytes} 629 * 630 * @since 1.6 631 */ String(byte bytes[], Charset charset)632 public String(byte bytes[], Charset charset) { 633 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 634 /* 635 this(bytes, 0, bytes.length, charset); 636 */ 637 throw new UnsupportedOperationException("Use StringFactory instead."); 638 // END Android-changed: Implemented as compiler and runtime intrinsics. 639 } 640 641 /** 642 * Constructs a new {@code String} by decoding the specified subarray of 643 * bytes using the platform's default charset. The length of the new 644 * {@code String} is a function of the charset, and hence may not be equal 645 * to the length of the subarray. 646 * 647 * <p> The behavior of this constructor when the given bytes are not valid 648 * in the default charset is unspecified. The {@link 649 * java.nio.charset.CharsetDecoder} class should be used when more control 650 * over the decoding process is required. 651 * 652 * @param bytes 653 * The bytes to be decoded into characters 654 * 655 * @param offset 656 * The index of the first byte to decode 657 * 658 * @param length 659 * The number of bytes to decode 660 * 661 * @throws IndexOutOfBoundsException 662 * If {@code offset} is negative, {@code length} is negative, or 663 * {@code offset} is greater than {@code bytes.length - length} 664 * 665 * @since 1.1 666 */ String(byte bytes[], int offset, int length)667 public String(byte bytes[], int offset, int length) { 668 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 669 /* 670 checkBoundsOffCount(offset, length, bytes.length); 671 StringCoding.Result ret = StringCoding.decode(bytes, offset, length); 672 this.value = ret.value; 673 this.coder = ret.coder; 674 */ 675 throw new UnsupportedOperationException("Use StringFactory instead."); 676 // END Android-changed: Implemented as compiler and runtime intrinsics. 677 } 678 679 /** 680 * Constructs a new {@code String} by decoding the specified array of bytes 681 * using the platform's default charset. The length of the new {@code 682 * String} is a function of the charset, and hence may not be equal to the 683 * length of the byte array. 684 * 685 * <p> The behavior of this constructor when the given bytes are not valid 686 * in the default charset is unspecified. The {@link 687 * java.nio.charset.CharsetDecoder} class should be used when more control 688 * over the decoding process is required. 689 * 690 * @param bytes 691 * The bytes to be decoded into characters 692 * 693 * @since 1.1 694 */ String(byte[] bytes)695 public String(byte[] bytes) { 696 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 697 /* 698 this(bytes, 0, bytes.length); 699 */ 700 throw new UnsupportedOperationException("Use StringFactory instead."); 701 // END Android-changed: Implemented as compiler and runtime intrinsics. 702 } 703 704 /** 705 * Allocates a new string that contains the sequence of characters 706 * currently contained in the string buffer argument. The contents of the 707 * string buffer are copied; subsequent modification of the string buffer 708 * does not affect the newly created string. 709 * 710 * @param buffer 711 * A {@code StringBuffer} 712 */ String(StringBuffer buffer)713 public String(StringBuffer buffer) { 714 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 715 /* 716 this(buffer.toString()); 717 */ 718 throw new UnsupportedOperationException("Use StringFactory instead."); 719 // END Android-changed: Implemented as compiler and runtime intrinsics. 720 } 721 722 /** 723 * Allocates a new string that contains the sequence of characters 724 * currently contained in the string builder argument. The contents of the 725 * string builder are copied; subsequent modification of the string builder 726 * does not affect the newly created string. 727 * 728 * <p> This constructor is provided to ease migration to {@code 729 * StringBuilder}. Obtaining a string from a string builder via the {@code 730 * toString} method is likely to run faster and is generally preferred. 731 * 732 * @param builder 733 * A {@code StringBuilder} 734 * 735 * @since 1.5 736 */ String(StringBuilder builder)737 public String(StringBuilder builder) { 738 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 739 /* 740 this(builder, null); 741 */ 742 throw new UnsupportedOperationException("Use StringFactory instead."); 743 // END Android-changed: Implemented as compiler and runtime intrinsics. 744 } 745 746 // BEGIN Android-removed: Unused package-private constructor String(char[] value, boolean share). 747 /* 748 /* 749 * Package private constructor which shares value array for speed. 750 * this constructor is always expected to be called with share==true. 751 * a separate constructor is needed because we already have a public 752 * String(char[]) constructor that makes a copy of the given char[]. 753 * 754 String(char[] value, boolean share) { 755 // assert share : "unshared not supported"; 756 this.value = value; 757 } 758 */ 759 // END Android-removed: Unused package-private constructor String(char[] value, boolean share). 760 761 // BEGIN Android-added: Constructor for internal use. 762 // Not implemented in java as all calls are intercepted by the runtime. 763 /** 764 * Package private constructor 765 * 766 * @deprecated Use {@link #String(char[],int,int)} instead. 767 */ 768 @Deprecated String(int offset, int count, char[] value)769 String(int offset, int count, char[] value) { 770 throw new UnsupportedOperationException("Use StringFactory instead."); 771 } 772 // END Android-added: Constructor for internal use. 773 774 /** 775 * Returns the length of this string. 776 * The length is equal to the number of <a href="Character.html#unicode">Unicode 777 * code units</a> in the string. 778 * 779 * @return the length of the sequence of characters represented by this 780 * object. 781 */ length()782 public int length() { 783 // BEGIN Android-changed: Get length from count field rather than value array (see above). 784 /* 785 return value.length >> coder(); 786 */ 787 final boolean STRING_COMPRESSION_ENABLED = true; 788 if (STRING_COMPRESSION_ENABLED) { 789 // For the compression purposes (save the characters as 8-bit if all characters 790 // are ASCII), the least significant bit of "count" is used as the compression flag. 791 return (count >>> 1); 792 } else { 793 return count; 794 } 795 // END Android-changed: Get length from count field rather than value array (see above). 796 } 797 798 /** 799 * Returns {@code true} if, and only if, {@link #length()} is {@code 0}. 800 * 801 * @return {@code true} if {@link #length()} is {@code 0}, otherwise 802 * {@code false} 803 * 804 * @since 1.6 805 */ isEmpty()806 public boolean isEmpty() { 807 // BEGIN Android-changed: Get length from count field rather than value array (see above). 808 // Empty string has {@code count == 0} with or without string compression enabled. 809 /* 810 return value.length == 0; 811 */ 812 return count == 0; 813 // END Android-changed: Get length from count field rather than value array (see above). 814 } 815 816 /** 817 * Returns the {@code char} value at the 818 * specified index. An index ranges from {@code 0} to 819 * {@code length() - 1}. The first {@code char} value of the sequence 820 * is at index {@code 0}, the next at index {@code 1}, 821 * and so on, as for array indexing. 822 * 823 * <p>If the {@code char} value specified by the index is a 824 * <a href="Character.html#unicode">surrogate</a>, the surrogate 825 * value is returned. 826 * 827 * @param index the index of the {@code char} value. 828 * @return the {@code char} value at the specified index of this string. 829 * The first {@code char} value is at index {@code 0}. 830 * @exception IndexOutOfBoundsException if the {@code index} 831 * argument is negative or not less than the length of this 832 * string. 833 */ 834 // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above). 835 /* 836 public char charAt(int index) { 837 if (isLatin1()) { 838 return StringLatin1.charAt(value, index); 839 } else { 840 return StringUTF16.charAt(value, index); 841 } 842 } 843 */ 844 @FastNative charAt(int index)845 public native char charAt(int index); 846 // END Android-changed: Replace with implementation in runtime to access chars (see above). 847 848 /** 849 * Returns the character (Unicode code point) at the specified 850 * index. The index refers to {@code char} values 851 * (Unicode code units) and ranges from {@code 0} to 852 * {@link #length()}{@code - 1}. 853 * 854 * <p> If the {@code char} value specified at the given index 855 * is in the high-surrogate range, the following index is less 856 * than the length of this {@code String}, and the 857 * {@code char} value at the following index is in the 858 * low-surrogate range, then the supplementary code point 859 * corresponding to this surrogate pair is returned. Otherwise, 860 * the {@code char} value at the given index is returned. 861 * 862 * @param index the index to the {@code char} values 863 * @return the code point value of the character at the 864 * {@code index} 865 * @exception IndexOutOfBoundsException if the {@code index} 866 * argument is negative or not less than the length of this 867 * string. 868 * @since 1.5 869 */ codePointAt(int index)870 public int codePointAt(int index) { 871 // BEGIN Android-changed: delegate codePointAt() to Character class. 872 /* 873 if (isLatin1()) { 874 checkIndex(index, value.length); 875 return value[index] & 0xff; 876 } 877 int length = value.length >> 1; 878 checkIndex(index, length); 879 return StringUTF16.codePointAt(value, index, length); 880 */ 881 checkIndex(index, length()); 882 return Character.codePointAt(this, index); 883 } 884 885 /** 886 * Returns the character (Unicode code point) before the specified 887 * index. The index refers to {@code char} values 888 * (Unicode code units) and ranges from {@code 1} to {@link 889 * CharSequence#length() length}. 890 * 891 * <p> If the {@code char} value at {@code (index - 1)} 892 * is in the low-surrogate range, {@code (index - 2)} is not 893 * negative, and the {@code char} value at {@code (index - 894 * 2)} is in the high-surrogate range, then the 895 * supplementary code point value of the surrogate pair is 896 * returned. If the {@code char} value at {@code index - 897 * 1} is an unpaired low-surrogate or a high-surrogate, the 898 * surrogate value is returned. 899 * 900 * @param index the index following the code point that should be returned 901 * @return the Unicode code point value before the given index. 902 * @exception IndexOutOfBoundsException if the {@code index} 903 * argument is less than 1 or greater than the length 904 * of this string. 905 * @since 1.5 906 */ codePointBefore(int index)907 public int codePointBefore(int index) { 908 int i = index - 1; 909 if (i < 0 || i >= length()) { 910 throw new StringIndexOutOfBoundsException(index); 911 } 912 // BEGIN Android-changed: delegate codePointBefore to Character class. 913 /* 914 if (isLatin1()) { 915 return (value[i] & 0xff); 916 } 917 return StringUTF16.codePointBefore(value, index); 918 */ 919 return Character.codePointBefore(this, index); 920 } 921 922 /** 923 * Returns the number of Unicode code points in the specified text 924 * range of this {@code String}. The text range begins at the 925 * specified {@code beginIndex} and extends to the 926 * {@code char} at index {@code endIndex - 1}. Thus the 927 * length (in {@code char}s) of the text range is 928 * {@code endIndex-beginIndex}. Unpaired surrogates within 929 * the text range count as one code point each. 930 * 931 * @param beginIndex the index to the first {@code char} of 932 * the text range. 933 * @param endIndex the index after the last {@code char} of 934 * the text range. 935 * @return the number of Unicode code points in the specified text 936 * range 937 * @exception IndexOutOfBoundsException if the 938 * {@code beginIndex} is negative, or {@code endIndex} 939 * is larger than the length of this {@code String}, or 940 * {@code beginIndex} is larger than {@code endIndex}. 941 * @since 1.5 942 */ codePointCount(int beginIndex, int endIndex)943 public int codePointCount(int beginIndex, int endIndex) { 944 if (beginIndex < 0 || beginIndex > endIndex || 945 endIndex > length()) { 946 throw new IndexOutOfBoundsException(); 947 } 948 // BEGIN Android-changed: delegate codePointCount to Character class. 949 /* 950 if (isLatin1()) { 951 return endIndex - beginIndex; 952 } 953 return StringUTF16.codePointCount(value, beginIndex, endIndex); 954 */ 955 return Character.codePointCount(this, beginIndex, endIndex); 956 // END Android-changed: delegate codePointCount to Character class. 957 } 958 959 /** 960 * Returns the index within this {@code String} that is 961 * offset from the given {@code index} by 962 * {@code codePointOffset} code points. Unpaired surrogates 963 * within the text range given by {@code index} and 964 * {@code codePointOffset} count as one code point each. 965 * 966 * @param index the index to be offset 967 * @param codePointOffset the offset in code points 968 * @return the index within this {@code String} 969 * @exception IndexOutOfBoundsException if {@code index} 970 * is negative or larger then the length of this 971 * {@code String}, or if {@code codePointOffset} is positive 972 * and the substring starting with {@code index} has fewer 973 * than {@code codePointOffset} code points, 974 * or if {@code codePointOffset} is negative and the substring 975 * before {@code index} has fewer than the absolute value 976 * of {@code codePointOffset} code points. 977 * @since 1.5 978 */ offsetByCodePoints(int index, int codePointOffset)979 public int offsetByCodePoints(int index, int codePointOffset) { 980 if (index < 0 || index > length()) { 981 throw new IndexOutOfBoundsException(); 982 } 983 return Character.offsetByCodePoints(this, index, codePointOffset); 984 } 985 986 /** 987 * Copy characters from this string into dst starting at dstBegin. 988 * This method doesn't perform any range checking. 989 */ getChars(char dst[], int dstBegin)990 void getChars(char dst[], int dstBegin) { 991 // Android-changed: Replace arraycopy with native call since chars are managed by runtime. 992 // System.arraycopy(value, 0, dst, dstBegin, value.length); 993 getCharsNoCheck(0, length(), dst, dstBegin); 994 } 995 996 /** 997 * Copies characters from this string into the destination character 998 * array. 999 * <p> 1000 * The first character to be copied is at index {@code srcBegin}; 1001 * the last character to be copied is at index {@code srcEnd-1} 1002 * (thus the total number of characters to be copied is 1003 * {@code srcEnd-srcBegin}). The characters are copied into the 1004 * subarray of {@code dst} starting at index {@code dstBegin} 1005 * and ending at index: 1006 * <blockquote><pre> 1007 * dstBegin + (srcEnd-srcBegin) - 1 1008 * </pre></blockquote> 1009 * 1010 * @param srcBegin index of the first character in the string 1011 * to copy. 1012 * @param srcEnd index after the last character in the string 1013 * to copy. 1014 * @param dst the destination array. 1015 * @param dstBegin the start offset in the destination array. 1016 * @exception IndexOutOfBoundsException If any of the following 1017 * is true: 1018 * <ul><li>{@code srcBegin} is negative. 1019 * <li>{@code srcBegin} is greater than {@code srcEnd} 1020 * <li>{@code srcEnd} is greater than the length of this 1021 * string 1022 * <li>{@code dstBegin} is negative 1023 * <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than 1024 * {@code dst.length}</ul> 1025 */ getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)1026 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { 1027 // BEGIN Android-added: Null pointer check. 1028 if (dst == null) { 1029 throw new NullPointerException("dst == null"); 1030 } 1031 // END Android-added: Null pointer check. 1032 checkBoundsBeginEnd(srcBegin, srcEnd, length()); 1033 // BEGIN Android-changed: Implement in terms of length() and native getCharsNoCheck method. 1034 /* 1035 checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length); 1036 if (isLatin1()) { 1037 StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin); 1038 } else { 1039 StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin); 1040 } 1041 */ 1042 if (dstBegin < 0) { 1043 throw new ArrayIndexOutOfBoundsException("dstBegin < 0. dstBegin=" + dstBegin); 1044 } 1045 // dstBegin can be equal to dst.length, but only in the case where zero chars are to be 1046 // copied. 1047 if (dstBegin > dst.length) { 1048 throw new ArrayIndexOutOfBoundsException( 1049 "dstBegin > dst.length. dstBegin=" + dstBegin + ", dst.length=" + dst.length); 1050 } 1051 1052 int n = srcEnd - srcBegin; 1053 if (n > dst.length - dstBegin) { 1054 throw new ArrayIndexOutOfBoundsException( 1055 "n > dst.length - dstBegin. n=" + n + ", dst.length=" + dst.length 1056 + "dstBegin=" + dstBegin); 1057 } 1058 1059 getCharsNoCheck(srcBegin, srcEnd, dst, dstBegin); 1060 // END Android-changed: Implement in terms of length() and native getCharsNoCheck method. 1061 } 1062 1063 // BEGIN Android-added: Native method to access char storage managed by runtime. 1064 /** 1065 * getChars without bounds checks, for use by other classes 1066 * within the java.lang package only. The caller is responsible for 1067 * ensuring that start >= 0 && start <= end && end <= count. 1068 */ 1069 @FastNative getCharsNoCheck(int start, int end, char[] buffer, int index)1070 native void getCharsNoCheck(int start, int end, char[] buffer, int index); 1071 // END Android-added: Native method to access char storage managed by runtime. 1072 1073 /** 1074 * Copies characters from this string into the destination byte array. Each 1075 * byte receives the 8 low-order bits of the corresponding character. The 1076 * eight high-order bits of each character are not copied and do not 1077 * participate in the transfer in any way. 1078 * 1079 * <p> The first character to be copied is at index {@code srcBegin}; the 1080 * last character to be copied is at index {@code srcEnd-1}. The total 1081 * number of characters to be copied is {@code srcEnd-srcBegin}. The 1082 * characters, converted to bytes, are copied into the subarray of {@code 1083 * dst} starting at index {@code dstBegin} and ending at index: 1084 * 1085 * <blockquote><pre> 1086 * dstBegin + (srcEnd-srcBegin) - 1 1087 * </pre></blockquote> 1088 * 1089 * @deprecated This method does not properly convert characters into 1090 * bytes. As of JDK 1.1, the preferred way to do this is via the 1091 * {@link #getBytes()} method, which uses the platform's default charset. 1092 * 1093 * @param srcBegin 1094 * Index of the first character in the string to copy 1095 * 1096 * @param srcEnd 1097 * Index after the last character in the string to copy 1098 * 1099 * @param dst 1100 * The destination array 1101 * 1102 * @param dstBegin 1103 * The start offset in the destination array 1104 * 1105 * @throws IndexOutOfBoundsException 1106 * If any of the following is true: 1107 * <ul> 1108 * <li> {@code srcBegin} is negative 1109 * <li> {@code srcBegin} is greater than {@code srcEnd} 1110 * <li> {@code srcEnd} is greater than the length of this String 1111 * <li> {@code dstBegin} is negative 1112 * <li> {@code dstBegin+(srcEnd-srcBegin)} is larger than {@code 1113 * dst.length} 1114 * </ul> 1115 */ 1116 @Deprecated(since="1.1") getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)1117 public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) { 1118 checkBoundsBeginEnd(srcBegin, srcEnd, length()); 1119 Objects.requireNonNull(dst); 1120 checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length); 1121 // BEGIN Android-changed: Implement in terms of charAt(). 1122 /* 1123 if (isLatin1()) { 1124 StringLatin1.getBytes(value, srcBegin, srcEnd, dst, dstBegin); 1125 } else { 1126 StringUTF16.getBytes(value, srcBegin, srcEnd, dst, dstBegin); 1127 } 1128 */ 1129 int j = dstBegin; 1130 int n = srcEnd; 1131 int i = srcBegin; 1132 1133 while (i < n) { 1134 dst[j++] = (byte)charAt(i++); 1135 } 1136 // END Android-changed: Implement in terms of charAt(). 1137 } 1138 1139 /** 1140 * Encodes this {@code String} into a sequence of bytes using the named 1141 * charset, storing the result into a new byte array. 1142 * 1143 * <p> The behavior of this method when this string cannot be encoded in 1144 * the given charset is unspecified. The {@link 1145 * java.nio.charset.CharsetEncoder} class should be used when more control 1146 * over the encoding process is required. 1147 * 1148 * @param charsetName 1149 * The name of a supported {@linkplain java.nio.charset.Charset 1150 * charset} 1151 * 1152 * @return The resultant byte array 1153 * 1154 * @throws UnsupportedEncodingException 1155 * If the named charset is not supported 1156 * 1157 * @since 1.1 1158 */ getBytes(String charsetName)1159 public byte[] getBytes(String charsetName) 1160 throws UnsupportedEncodingException { 1161 if (charsetName == null) throw new NullPointerException(); 1162 // BEGIN Android-changed: Skip StringCoding optimization that needs access to java chars. 1163 /* 1164 return StringCoding.encode(charsetName, coder(), value); 1165 */ 1166 return getBytes(Charset.forNameUEE(charsetName)); 1167 // END Android-changed: Skip StringCoding optimization that needs access to java chars. 1168 } 1169 1170 /** 1171 * Encodes this {@code String} into a sequence of bytes using the given 1172 * {@linkplain java.nio.charset.Charset charset}, storing the result into a 1173 * new byte array. 1174 * 1175 * <p> This method always replaces malformed-input and unmappable-character 1176 * sequences with this charset's default replacement byte array. The 1177 * {@link java.nio.charset.CharsetEncoder} class should be used when more 1178 * control over the encoding process is required. 1179 * 1180 * @param charset 1181 * The {@linkplain java.nio.charset.Charset} to be used to encode 1182 * the {@code String} 1183 * 1184 * @return The resultant byte array 1185 * 1186 * @since 1.6 1187 */ getBytes(Charset charset)1188 public byte[] getBytes(Charset charset) { 1189 if (charset == null) throw new NullPointerException(); 1190 // BEGIN Android-changed: Skip StringCoding optimization that needs access to java chars. 1191 /* 1192 return StringCoding.encode(charset, coder(), value); 1193 */ 1194 final int len = length(); 1195 final String name = charset.name(); 1196 if ("UTF-8".equals(name)) { 1197 return CharsetUtils.toUtf8Bytes(this, 0, len); 1198 } else if ("ISO-8859-1".equals(name)) { 1199 return CharsetUtils.toIsoLatin1Bytes(this, 0, len); 1200 } else if ("US-ASCII".equals(name)) { 1201 return CharsetUtils.toAsciiBytes(this, 0, len); 1202 } else if ("UTF-16BE".equals(name)) { 1203 return CharsetUtils.toBigEndianUtf16Bytes(this, 0, len); 1204 } 1205 1206 ByteBuffer buffer = charset.encode(this); 1207 byte[] bytes = new byte[buffer.limit()]; 1208 buffer.get(bytes); 1209 return bytes; 1210 // END Android-changed: Skip StringCoding optimization that needs access to java chars. 1211 } 1212 1213 /** 1214 * Encodes this {@code String} into a sequence of bytes using the 1215 * platform's default charset, storing the result into a new byte array. 1216 * 1217 * <p> The behavior of this method when this string cannot be encoded in 1218 * the default charset is unspecified. The {@link 1219 * java.nio.charset.CharsetEncoder} class should be used when more control 1220 * over the encoding process is required. 1221 * 1222 * @return The resultant byte array 1223 * 1224 * @since 1.1 1225 */ getBytes()1226 public byte[] getBytes() { 1227 // BEGIN Android-changed: Skip StringCoding optimization that needs access to java chars. 1228 /* 1229 return StringCoding.encode(coder(), value); 1230 */ 1231 return getBytes(Charset.defaultCharset()); 1232 // END Android-changed: Skip StringCoding optimization that needs access to java chars. 1233 } 1234 1235 /** 1236 * Compares this string to the specified object. The result is {@code 1237 * true} if and only if the argument is not {@code null} and is a {@code 1238 * String} object that represents the same sequence of characters as this 1239 * object. 1240 * 1241 * <p>For finer-grained String comparison, refer to 1242 * {@link java.text.Collator}. 1243 * 1244 * @param anObject 1245 * The object to compare this {@code String} against 1246 * 1247 * @return {@code true} if the given object represents a {@code String} 1248 * equivalent to this string, {@code false} otherwise 1249 * 1250 * @see #compareTo(String) 1251 * @see #equalsIgnoreCase(String) 1252 */ equals(Object anObject)1253 public boolean equals(Object anObject) { 1254 if (this == anObject) { 1255 return true; 1256 } 1257 if (anObject instanceof String) { 1258 // BEGIN Android-changed: Implement in terms of charAt(). 1259 /* 1260 String aString = (String)anObject; 1261 if (coder() == aString.coder()) { 1262 return isLatin1() ? StringLatin1.equals(value, aString.value) 1263 : StringUTF16.equals(value, aString.value); 1264 } 1265 */ 1266 String anotherString = (String)anObject; 1267 int n = length(); 1268 if (n == anotherString.length()) { 1269 int i = 0; 1270 while (n-- != 0) { 1271 if (charAt(i) != anotherString.charAt(i)) 1272 return false; 1273 i++; 1274 } 1275 return true; 1276 } 1277 // END Android-changed: Implement in terms of charAt(). 1278 } 1279 return false; 1280 } 1281 1282 /** 1283 * Compares this string to the specified {@code StringBuffer}. The result 1284 * is {@code true} if and only if this {@code String} represents the same 1285 * sequence of characters as the specified {@code StringBuffer}. This method 1286 * synchronizes on the {@code StringBuffer}. 1287 * 1288 * <p>For finer-grained String comparison, refer to 1289 * {@link java.text.Collator}. 1290 * 1291 * @param sb 1292 * The {@code StringBuffer} to compare this {@code String} against 1293 * 1294 * @return {@code true} if this {@code String} represents the same 1295 * sequence of characters as the specified {@code StringBuffer}, 1296 * {@code false} otherwise 1297 * 1298 * @since 1.4 1299 */ contentEquals(StringBuffer sb)1300 public boolean contentEquals(StringBuffer sb) { 1301 return contentEquals((CharSequence)sb); 1302 } 1303 nonSyncContentEquals(AbstractStringBuilder sb)1304 private boolean nonSyncContentEquals(AbstractStringBuilder sb) { 1305 int len = length(); 1306 if (len != sb.length()) { 1307 return false; 1308 } 1309 // BEGIN Android-changed: Implement in terms of charAt(). 1310 /* 1311 byte v1[] = value; 1312 byte v2[] = sb.getValue(); 1313 if (coder() == sb.getCoder()) { 1314 int n = v1.length; 1315 for (int i = 0; i < n; i++) { 1316 if (v1[i] != v2[i]) { 1317 return false; 1318 } 1319 } 1320 } else { 1321 if (!isLatin1()) { // utf16 str and latin1 abs can never be "equal" 1322 return false; 1323 } 1324 return StringUTF16.contentEquals(v1, v2, len); 1325 } 1326 */ 1327 for (int i = 0; i < len; i++) { 1328 if (charAt(i) != sb.charAt(i)) { 1329 return false; 1330 } 1331 } 1332 // END Android-changed: Implement in terms of charAt(). 1333 return true; 1334 } 1335 1336 /** 1337 * Compares this string to the specified {@code CharSequence}. The 1338 * result is {@code true} if and only if this {@code String} represents the 1339 * same sequence of char values as the specified sequence. Note that if the 1340 * {@code CharSequence} is a {@code StringBuffer} then the method 1341 * synchronizes on it. 1342 * 1343 * <p>For finer-grained String comparison, refer to 1344 * {@link java.text.Collator}. 1345 * 1346 * @param cs 1347 * The sequence to compare this {@code String} against 1348 * 1349 * @return {@code true} if this {@code String} represents the same 1350 * sequence of char values as the specified sequence, {@code 1351 * false} otherwise 1352 * 1353 * @since 1.5 1354 */ contentEquals(CharSequence cs)1355 public boolean contentEquals(CharSequence cs) { 1356 // Argument is a StringBuffer, StringBuilder 1357 if (cs instanceof AbstractStringBuilder) { 1358 if (cs instanceof StringBuffer) { 1359 synchronized(cs) { 1360 return nonSyncContentEquals((AbstractStringBuilder)cs); 1361 } 1362 } else { 1363 return nonSyncContentEquals((AbstractStringBuilder)cs); 1364 } 1365 } 1366 // Argument is a String 1367 if (cs instanceof String) { 1368 return equals(cs); 1369 } 1370 // Argument is a generic CharSequence 1371 int n = cs.length(); 1372 if (n != length()) { 1373 return false; 1374 } 1375 // BEGIN Android-changed: Implement in terms of charAt(). 1376 /* 1377 byte[] val = this.value; 1378 if (isLatin1()) { 1379 for (int i = 0; i < n; i++) { 1380 if ((val[i] & 0xff) != cs.charAt(i)) { 1381 return false; 1382 } 1383 } 1384 } else { 1385 if (!StringUTF16.contentEquals(val, cs, n)) { 1386 */ 1387 for (int i = 0; i < n; i++) { 1388 if (charAt(i) != cs.charAt(i)) { 1389 // END Android-changed: Implement in terms of charAt(). 1390 return false; 1391 } 1392 } 1393 return true; 1394 } 1395 1396 /** 1397 * Compares this {@code String} to another {@code String}, ignoring case 1398 * considerations. Two strings are considered equal ignoring case if they 1399 * are of the same length and corresponding characters in the two strings 1400 * are equal ignoring case. 1401 * 1402 * <p> Two characters {@code c1} and {@code c2} are considered the same 1403 * ignoring case if at least one of the following is true: 1404 * <ul> 1405 * <li> The two characters are the same (as compared by the 1406 * {@code ==} operator) 1407 * <li> Calling {@code Character.toLowerCase(Character.toUpperCase(char))} 1408 * on each character produces the same result 1409 * </ul> 1410 * 1411 * <p>Note that this method does <em>not</em> take locale into account, and 1412 * will result in unsatisfactory results for certain locales. The 1413 * {@link java.text.Collator} class provides locale-sensitive comparison. 1414 * 1415 * @param anotherString 1416 * The {@code String} to compare this {@code String} against 1417 * 1418 * @return {@code true} if the argument is not {@code null} and it 1419 * represents an equivalent {@code String} ignoring case; {@code 1420 * false} otherwise 1421 * 1422 * @see #equals(Object) 1423 */ equalsIgnoreCase(String anotherString)1424 public boolean equalsIgnoreCase(String anotherString) { 1425 // Android-added: Cache length() result so it's called once. 1426 final int len = length(); 1427 return (this == anotherString) ? true 1428 : (anotherString != null) 1429 && (anotherString.length() == len) 1430 && regionMatches(true, 0, anotherString, 0, len); 1431 } 1432 1433 /** 1434 * Compares two strings lexicographically. 1435 * The comparison is based on the Unicode value of each character in 1436 * the strings. The character sequence represented by this 1437 * {@code String} object is compared lexicographically to the 1438 * character sequence represented by the argument string. The result is 1439 * a negative integer if this {@code String} object 1440 * lexicographically precedes the argument string. The result is a 1441 * positive integer if this {@code String} object lexicographically 1442 * follows the argument string. The result is zero if the strings 1443 * are equal; {@code compareTo} returns {@code 0} exactly when 1444 * the {@link #equals(Object)} method would return {@code true}. 1445 * <p> 1446 * This is the definition of lexicographic ordering. If two strings are 1447 * different, then either they have different characters at some index 1448 * that is a valid index for both strings, or their lengths are different, 1449 * or both. If they have different characters at one or more index 1450 * positions, let <i>k</i> be the smallest such index; then the string 1451 * whose character at position <i>k</i> has the smaller value, as 1452 * determined by using the {@code <} operator, lexicographically precedes the 1453 * other string. In this case, {@code compareTo} returns the 1454 * difference of the two character values at position {@code k} in 1455 * the two string -- that is, the value: 1456 * <blockquote><pre> 1457 * this.charAt(k)-anotherString.charAt(k) 1458 * </pre></blockquote> 1459 * If there is no index position at which they differ, then the shorter 1460 * string lexicographically precedes the longer string. In this case, 1461 * {@code compareTo} returns the difference of the lengths of the 1462 * strings -- that is, the value: 1463 * <blockquote><pre> 1464 * this.length()-anotherString.length() 1465 * </pre></blockquote> 1466 * 1467 * <p>For finer-grained String comparison, refer to 1468 * {@link java.text.Collator}. 1469 * 1470 * @param anotherString the {@code String} to be compared. 1471 * @return the value {@code 0} if the argument string is equal to 1472 * this string; a value less than {@code 0} if this string 1473 * is lexicographically less than the string argument; and a 1474 * value greater than {@code 0} if this string is 1475 * lexicographically greater than the string argument. 1476 */ 1477 // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above). 1478 /* 1479 public int compareTo(String anotherString) { 1480 byte v1[] = value; 1481 byte v2[] = anotherString.value; 1482 if (coder() == anotherString.coder()) { 1483 return isLatin1() ? StringLatin1.compareTo(v1, v2) 1484 : StringUTF16.compareTo(v1, v2); 1485 } 1486 return isLatin1() ? StringLatin1.compareToUTF16(v1, v2) 1487 : StringUTF16.compareToLatin1(v1, v2); 1488 } 1489 */ 1490 @FastNative compareTo(String anotherString)1491 public native int compareTo(String anotherString); 1492 // END Android-changed: Replace with implementation in runtime to access chars (see above). 1493 1494 /** 1495 * A Comparator that orders {@code String} objects as by 1496 * {@code compareToIgnoreCase}. This comparator is serializable. 1497 * <p> 1498 * Note that this Comparator does <em>not</em> take locale into account, 1499 * and will result in an unsatisfactory ordering for certain locales. 1500 * The {@link java.text.Collator} class provides locale-sensitive comparison. 1501 * 1502 * @see java.text.Collator 1503 * @since 1.2 1504 */ 1505 public static final Comparator<String> CASE_INSENSITIVE_ORDER 1506 = new CaseInsensitiveComparator(); 1507 private static class CaseInsensitiveComparator 1508 implements Comparator<String>, java.io.Serializable { 1509 // use serialVersionUID from JDK 1.2.2 for interoperability 1510 private static final long serialVersionUID = 8575799808933029326L; 1511 compare(String s1, String s2)1512 public int compare(String s1, String s2) { 1513 // BEGIN Android-changed: Implement in terms of charAt(). 1514 /* 1515 byte v1[] = s1.value; 1516 byte v2[] = s2.value; 1517 if (s1.coder() == s2.coder()) { 1518 return s1.isLatin1() ? StringLatin1.compareToCI(v1, v2) 1519 : StringUTF16.compareToCI(v1, v2); 1520 } 1521 return s1.isLatin1() ? StringLatin1.compareToCI_UTF16(v1, v2) 1522 : StringUTF16.compareToCI_Latin1(v1, v2); 1523 */ 1524 int n1 = s1.length(); 1525 int n2 = s2.length(); 1526 int min = Math.min(n1, n2); 1527 for (int i = 0; i < min; i++) { 1528 char c1 = s1.charAt(i); 1529 char c2 = s2.charAt(i); 1530 if (c1 != c2) { 1531 c1 = Character.toUpperCase(c1); 1532 c2 = Character.toUpperCase(c2); 1533 if (c1 != c2) { 1534 c1 = Character.toLowerCase(c1); 1535 c2 = Character.toLowerCase(c2); 1536 if (c1 != c2) { 1537 // No overflow because of numeric promotion 1538 return c1 - c2; 1539 } 1540 } 1541 } 1542 } 1543 return n1 - n2; 1544 // END Android-changed: Implement in terms of charAt(). 1545 } 1546 1547 /** Replaces the de-serialized object. */ readResolve()1548 private Object readResolve() { return CASE_INSENSITIVE_ORDER; } 1549 } 1550 1551 /** 1552 * Compares two strings lexicographically, ignoring case 1553 * differences. This method returns an integer whose sign is that of 1554 * calling {@code compareTo} with normalized versions of the strings 1555 * where case differences have been eliminated by calling 1556 * {@code Character.toLowerCase(Character.toUpperCase(character))} on 1557 * each character. 1558 * <p> 1559 * Note that this method does <em>not</em> take locale into account, 1560 * and will result in an unsatisfactory ordering for certain locales. 1561 * The {@link java.text.Collator} class provides locale-sensitive comparison. 1562 * 1563 * @param str the {@code String} to be compared. 1564 * @return a negative integer, zero, or a positive integer as the 1565 * specified String is greater than, equal to, or less 1566 * than this String, ignoring case considerations. 1567 * @see java.text.Collator 1568 * @since 1.2 1569 */ compareToIgnoreCase(String str)1570 public int compareToIgnoreCase(String str) { 1571 return CASE_INSENSITIVE_ORDER.compare(this, str); 1572 } 1573 1574 /** 1575 * Tests if two string regions are equal. 1576 * <p> 1577 * A substring of this {@code String} object is compared to a substring 1578 * of the argument other. The result is true if these substrings 1579 * represent identical character sequences. The substring of this 1580 * {@code String} object to be compared begins at index {@code toffset} 1581 * and has length {@code len}. The substring of other to be compared 1582 * begins at index {@code ooffset} and has length {@code len}. The 1583 * result is {@code false} if and only if at least one of the following 1584 * is true: 1585 * <ul><li>{@code toffset} is negative. 1586 * <li>{@code ooffset} is negative. 1587 * <li>{@code toffset+len} is greater than the length of this 1588 * {@code String} object. 1589 * <li>{@code ooffset+len} is greater than the length of the other 1590 * argument. 1591 * <li>There is some nonnegative integer <i>k</i> less than {@code len} 1592 * such that: 1593 * {@code this.charAt(toffset + }<i>k</i>{@code ) != other.charAt(ooffset + } 1594 * <i>k</i>{@code )} 1595 * </ul> 1596 * 1597 * <p>Note that this method does <em>not</em> take locale into account. The 1598 * {@link java.text.Collator} class provides locale-sensitive comparison. 1599 * 1600 * @param toffset the starting offset of the subregion in this string. 1601 * @param other the string argument. 1602 * @param ooffset the starting offset of the subregion in the string 1603 * argument. 1604 * @param len the number of characters to compare. 1605 * @return {@code true} if the specified subregion of this string 1606 * exactly matches the specified subregion of the string argument; 1607 * {@code false} otherwise. 1608 */ regionMatches(int toffset, String other, int ooffset, int len)1609 public boolean regionMatches(int toffset, String other, int ooffset, int len) { 1610 // BEGIN Android-removed: Implement in terms of charAt(). 1611 /* 1612 byte tv[] = value; 1613 byte ov[] = other.value; 1614 */ 1615 // Note: toffset, ooffset, or len might be near -1>>>1. 1616 if ((ooffset < 0) || (toffset < 0) || 1617 (toffset > (long)length() - len) || 1618 (ooffset > (long)other.length() - len)) { 1619 return false; 1620 } 1621 // BEGIN Android-removed: Implement in terms of charAt(). 1622 /* 1623 if (coder() == other.coder()) { 1624 if (!isLatin1() && (len > 0)) { 1625 toffset = toffset << 1; 1626 ooffset = ooffset << 1; 1627 len = len << 1; 1628 } 1629 while (len-- > 0) { 1630 if (tv[toffset++] != ov[ooffset++]) { 1631 return false; 1632 } 1633 } 1634 } else { 1635 if (coder() == LATIN1) { 1636 while (len-- > 0) { 1637 if (StringLatin1.getChar(tv, toffset++) != 1638 StringUTF16.getChar(ov, ooffset++)) { 1639 return false; 1640 } 1641 } 1642 } else { 1643 while (len-- > 0) { 1644 if (StringUTF16.getChar(tv, toffset++) != 1645 StringLatin1.getChar(ov, ooffset++)) { 1646 return false; 1647 } 1648 } 1649 */ 1650 while (len-- > 0) { 1651 if (charAt(toffset++) != other.charAt(ooffset++)) { 1652 return false; 1653 // END Android-removed: Implement in terms of charAt(). 1654 } 1655 } 1656 return true; 1657 } 1658 1659 /** 1660 * Tests if two string regions are equal. 1661 * <p> 1662 * A substring of this {@code String} object is compared to a substring 1663 * of the argument {@code other}. The result is {@code true} if these 1664 * substrings represent character sequences that are the same, ignoring 1665 * case if and only if {@code ignoreCase} is true. The substring of 1666 * this {@code String} object to be compared begins at index 1667 * {@code toffset} and has length {@code len}. The substring of 1668 * {@code other} to be compared begins at index {@code ooffset} and 1669 * has length {@code len}. The result is {@code false} if and only if 1670 * at least one of the following is true: 1671 * <ul><li>{@code toffset} is negative. 1672 * <li>{@code ooffset} is negative. 1673 * <li>{@code toffset+len} is greater than the length of this 1674 * {@code String} object. 1675 * <li>{@code ooffset+len} is greater than the length of the other 1676 * argument. 1677 * <li>{@code ignoreCase} is {@code false} and there is some nonnegative 1678 * integer <i>k</i> less than {@code len} such that: 1679 * <blockquote><pre> 1680 * this.charAt(toffset+k) != other.charAt(ooffset+k) 1681 * </pre></blockquote> 1682 * <li>{@code ignoreCase} is {@code true} and there is some nonnegative 1683 * integer <i>k</i> less than {@code len} such that: 1684 * <blockquote><pre> 1685 * Character.toLowerCase(Character.toUpperCase(this.charAt(toffset+k))) != 1686 Character.toLowerCase(Character.toUpperCase(other.charAt(ooffset+k))) 1687 * </pre></blockquote> 1688 * </ul> 1689 * 1690 * <p>Note that this method does <em>not</em> take locale into account, 1691 * and will result in unsatisfactory results for certain locales when 1692 * {@code ignoreCase} is {@code true}. The {@link java.text.Collator} class 1693 * provides locale-sensitive comparison. 1694 * 1695 * @param ignoreCase if {@code true}, ignore case when comparing 1696 * characters. 1697 * @param toffset the starting offset of the subregion in this 1698 * string. 1699 * @param other the string argument. 1700 * @param ooffset the starting offset of the subregion in the string 1701 * argument. 1702 * @param len the number of characters to compare. 1703 * @return {@code true} if the specified subregion of this string 1704 * matches the specified subregion of the string argument; 1705 * {@code false} otherwise. Whether the matching is exact 1706 * or case insensitive depends on the {@code ignoreCase} 1707 * argument. 1708 */ regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)1709 public boolean regionMatches(boolean ignoreCase, int toffset, 1710 String other, int ooffset, int len) { 1711 if (!ignoreCase) { 1712 return regionMatches(toffset, other, ooffset, len); 1713 } 1714 // Note: toffset, ooffset, or len might be near -1>>>1. 1715 if ((ooffset < 0) || (toffset < 0) 1716 || (toffset > (long)length() - len) 1717 || (ooffset > (long)other.length() - len)) { 1718 return false; 1719 } 1720 // BEGIN Android-changed: Implement in terms of charAt(). 1721 /* 1722 byte tv[] = value; 1723 byte ov[] = other.value; 1724 if (coder() == other.coder()) { 1725 return isLatin1() 1726 ? StringLatin1.regionMatchesCI(tv, toffset, ov, ooffset, len) 1727 : StringUTF16.regionMatchesCI(tv, toffset, ov, ooffset, len); 1728 } 1729 return isLatin1() 1730 ? StringLatin1.regionMatchesCI_UTF16(tv, toffset, ov, ooffset, len) 1731 : StringUTF16.regionMatchesCI_Latin1(tv, toffset, ov, ooffset, len); 1732 */ 1733 while (len-- > 0) { 1734 char c1 = charAt(toffset++); 1735 char c2 = other.charAt(ooffset++); 1736 if (c1 == c2) { 1737 continue; 1738 } 1739 if (ignoreCase) { 1740 // If characters don't match but case may be ignored, 1741 // try converting both characters to uppercase. 1742 // If the results match, then the comparison scan should 1743 // continue. 1744 char u1 = Character.toUpperCase(c1); 1745 char u2 = Character.toUpperCase(c2); 1746 if (u1 == u2) { 1747 continue; 1748 } 1749 // Unfortunately, conversion to uppercase does not work properly 1750 // for the Georgian alphabet, which has strange rules about case 1751 // conversion. So we need to make one last check before 1752 // exiting. 1753 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { 1754 continue; 1755 } 1756 } 1757 return false; 1758 } 1759 return true; 1760 // END Android-changed: Implement in terms of charAt(). 1761 } 1762 1763 /** 1764 * Tests if the substring of this string beginning at the 1765 * specified index starts with the specified prefix. 1766 * 1767 * @param prefix the prefix. 1768 * @param toffset where to begin looking in this string. 1769 * @return {@code true} if the character sequence represented by the 1770 * argument is a prefix of the substring of this object starting 1771 * at index {@code toffset}; {@code false} otherwise. 1772 * The result is {@code false} if {@code toffset} is 1773 * negative or greater than the length of this 1774 * {@code String} object; otherwise the result is the same 1775 * as the result of the expression 1776 * <pre> 1777 * this.substring(toffset).startsWith(prefix) 1778 * </pre> 1779 */ startsWith(String prefix, int toffset)1780 public boolean startsWith(String prefix, int toffset) { 1781 // Android-added: Cache length() result so it's called once. 1782 int pc = prefix.length(); 1783 // Note: toffset might be near -1>>>1. 1784 if (toffset < 0 || toffset > length() - pc) { 1785 return false; 1786 } 1787 // BEGIN Android-changed: Implement in terms of charAt(). 1788 /* 1789 byte ta[] = value; 1790 byte pa[] = prefix.value; 1791 int po = 0; 1792 int pc = pa.length; 1793 if (coder() == prefix.coder()) { 1794 int to = isLatin1() ? toffset : toffset << 1; 1795 while (po < pc) { 1796 if (ta[to++] != pa[po++]) { 1797 return false; 1798 } 1799 } 1800 } else { 1801 if (isLatin1()) { // && pcoder == UTF16 1802 return false; 1803 } 1804 // coder == UTF16 && pcoder == LATIN1) 1805 while (po < pc) { 1806 if (StringUTF16.getChar(ta, toffset++) != (pa[po++] & 0xff)) { 1807 return false; 1808 } 1809 } 1810 */ 1811 int po = 0; 1812 while (--pc >= 0) { 1813 if (charAt(toffset++) != prefix.charAt(po++)) { 1814 return false; 1815 } 1816 // END Android-changed: Implement in terms of charAt(). 1817 } 1818 return true; 1819 } 1820 1821 /** 1822 * Tests if this string starts with the specified prefix. 1823 * 1824 * @param prefix the prefix. 1825 * @return {@code true} if the character sequence represented by the 1826 * argument is a prefix of the character sequence represented by 1827 * this string; {@code false} otherwise. 1828 * Note also that {@code true} will be returned if the 1829 * argument is an empty string or is equal to this 1830 * {@code String} object as determined by the 1831 * {@link #equals(Object)} method. 1832 * @since 1.0 1833 */ startsWith(String prefix)1834 public boolean startsWith(String prefix) { 1835 return startsWith(prefix, 0); 1836 } 1837 1838 /** 1839 * Tests if this string ends with the specified suffix. 1840 * 1841 * @param suffix the suffix. 1842 * @return {@code true} if the character sequence represented by the 1843 * argument is a suffix of the character sequence represented by 1844 * this object; {@code false} otherwise. Note that the 1845 * result will be {@code true} if the argument is the 1846 * empty string or is equal to this {@code String} object 1847 * as determined by the {@link #equals(Object)} method. 1848 */ endsWith(String suffix)1849 public boolean endsWith(String suffix) { 1850 return startsWith(suffix, length() - suffix.length()); 1851 } 1852 1853 /** 1854 * Returns a hash code for this string. The hash code for a 1855 * {@code String} object is computed as 1856 * <blockquote><pre> 1857 * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 1858 * </pre></blockquote> 1859 * using {@code int} arithmetic, where {@code s[i]} is the 1860 * <i>i</i>th character of the string, {@code n} is the length of 1861 * the string, and {@code ^} indicates exponentiation. 1862 * (The hash value of the empty string is zero.) 1863 * 1864 * @return a hash code value for this object. 1865 */ hashCode()1866 public int hashCode() { 1867 int h = hash; 1868 // BEGIN Android-changed: Implement in terms of charAt(). 1869 /* 1870 if (h == 0 && value.length > 0) { 1871 hash = h = isLatin1() ? StringLatin1.hashCode(value) 1872 : StringUTF16.hashCode(value); 1873 */ 1874 final int len = length(); 1875 if (h == 0 && len > 0) { 1876 for (int i = 0; i < len; i++) { 1877 h = 31 * h + charAt(i); 1878 } 1879 hash = h; 1880 // END Android-changed: Implement in terms of charAt(). 1881 } 1882 return h; 1883 } 1884 1885 /** 1886 * Returns the index within this string of the first occurrence of 1887 * the specified character. If a character with value 1888 * {@code ch} occurs in the character sequence represented by 1889 * this {@code String} object, then the index (in Unicode 1890 * code units) of the first such occurrence is returned. For 1891 * values of {@code ch} in the range from 0 to 0xFFFF 1892 * (inclusive), this is the smallest value <i>k</i> such that: 1893 * <blockquote><pre> 1894 * this.charAt(<i>k</i>) == ch 1895 * </pre></blockquote> 1896 * is true. For other values of {@code ch}, it is the 1897 * smallest value <i>k</i> such that: 1898 * <blockquote><pre> 1899 * this.codePointAt(<i>k</i>) == ch 1900 * </pre></blockquote> 1901 * is true. In either case, if no such character occurs in this 1902 * string, then {@code -1} is returned. 1903 * 1904 * @param ch a character (Unicode code point). 1905 * @return the index of the first occurrence of the character in the 1906 * character sequence represented by this object, or 1907 * {@code -1} if the character does not occur. 1908 */ indexOf(int ch)1909 public int indexOf(int ch) { 1910 return indexOf(ch, 0); 1911 } 1912 1913 /** 1914 * Returns the index within this string of the first occurrence of the 1915 * specified character, starting the search at the specified index. 1916 * <p> 1917 * If a character with value {@code ch} occurs in the 1918 * character sequence represented by this {@code String} 1919 * object at an index no smaller than {@code fromIndex}, then 1920 * the index of the first such occurrence is returned. For values 1921 * of {@code ch} in the range from 0 to 0xFFFF (inclusive), 1922 * this is the smallest value <i>k</i> such that: 1923 * <blockquote><pre> 1924 * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> >= fromIndex) 1925 * </pre></blockquote> 1926 * is true. For other values of {@code ch}, it is the 1927 * smallest value <i>k</i> such that: 1928 * <blockquote><pre> 1929 * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> >= fromIndex) 1930 * </pre></blockquote> 1931 * is true. In either case, if no such character occurs in this 1932 * string at or after position {@code fromIndex}, then 1933 * {@code -1} is returned. 1934 * 1935 * <p> 1936 * There is no restriction on the value of {@code fromIndex}. If it 1937 * is negative, it has the same effect as if it were zero: this entire 1938 * string may be searched. If it is greater than the length of this 1939 * string, it has the same effect as if it were equal to the length of 1940 * this string: {@code -1} is returned. 1941 * 1942 * <p>All indices are specified in {@code char} values 1943 * (Unicode code units). 1944 * 1945 * @param ch a character (Unicode code point). 1946 * @param fromIndex the index to start the search from. 1947 * @return the index of the first occurrence of the character in the 1948 * character sequence represented by this object that is greater 1949 * than or equal to {@code fromIndex}, or {@code -1} 1950 * if the character does not occur. 1951 */ indexOf(int ch, int fromIndex)1952 public int indexOf(int ch, int fromIndex) { 1953 // BEGIN Android-changed: Implement in terms of charAt(). 1954 /* 1955 return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex) 1956 : StringUTF16.indexOf(value, ch, fromIndex); 1957 */ 1958 final int max = length(); 1959 if (fromIndex < 0) { 1960 fromIndex = 0; 1961 } else if (fromIndex >= max) { 1962 // Note: fromIndex might be near -1>>>1. 1963 return -1; 1964 } 1965 1966 if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { 1967 // handle most cases here (ch is a BMP code point or a 1968 // negative value (invalid code point)) 1969 for (int i = fromIndex; i < max; i++) { 1970 if (charAt(i) == ch) { 1971 return i; 1972 } 1973 } 1974 return -1; 1975 } else { 1976 return indexOfSupplementary(ch, fromIndex); 1977 } 1978 } 1979 1980 /** 1981 * Handles (rare) calls of indexOf with a supplementary character. 1982 */ indexOfSupplementary(int ch, int fromIndex)1983 private int indexOfSupplementary(int ch, int fromIndex) { 1984 if (Character.isValidCodePoint(ch)) { 1985 final char hi = Character.highSurrogate(ch); 1986 final char lo = Character.lowSurrogate(ch); 1987 final int max = length() - 1; 1988 for (int i = fromIndex; i < max; i++) { 1989 if (charAt(i) == hi && charAt(i + 1) == lo) { 1990 return i; 1991 } 1992 } 1993 } 1994 return -1; 1995 // END Android-changed: Implement in terms of charAt(). 1996 } 1997 1998 /** 1999 * Returns the index within this string of the last occurrence of 2000 * the specified character. For values of {@code ch} in the 2001 * range from 0 to 0xFFFF (inclusive), the index (in Unicode code 2002 * units) returned is the largest value <i>k</i> such that: 2003 * <blockquote><pre> 2004 * this.charAt(<i>k</i>) == ch 2005 * </pre></blockquote> 2006 * is true. For other values of {@code ch}, it is the 2007 * largest value <i>k</i> such that: 2008 * <blockquote><pre> 2009 * this.codePointAt(<i>k</i>) == ch 2010 * </pre></blockquote> 2011 * is true. In either case, if no such character occurs in this 2012 * string, then {@code -1} is returned. The 2013 * {@code String} is searched backwards starting at the last 2014 * character. 2015 * 2016 * @param ch a character (Unicode code point). 2017 * @return the index of the last occurrence of the character in the 2018 * character sequence represented by this object, or 2019 * {@code -1} if the character does not occur. 2020 */ lastIndexOf(int ch)2021 public int lastIndexOf(int ch) { 2022 return lastIndexOf(ch, length() - 1); 2023 } 2024 2025 /** 2026 * Returns the index within this string of the last occurrence of 2027 * the specified character, searching backward starting at the 2028 * specified index. For values of {@code ch} in the range 2029 * from 0 to 0xFFFF (inclusive), the index returned is the largest 2030 * value <i>k</i> such that: 2031 * <blockquote><pre> 2032 * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> <= fromIndex) 2033 * </pre></blockquote> 2034 * is true. For other values of {@code ch}, it is the 2035 * largest value <i>k</i> such that: 2036 * <blockquote><pre> 2037 * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> <= fromIndex) 2038 * </pre></blockquote> 2039 * is true. In either case, if no such character occurs in this 2040 * string at or before position {@code fromIndex}, then 2041 * {@code -1} is returned. 2042 * 2043 * <p>All indices are specified in {@code char} values 2044 * (Unicode code units). 2045 * 2046 * @param ch a character (Unicode code point). 2047 * @param fromIndex the index to start the search from. There is no 2048 * restriction on the value of {@code fromIndex}. If it is 2049 * greater than or equal to the length of this string, it has 2050 * the same effect as if it were equal to one less than the 2051 * length of this string: this entire string may be searched. 2052 * If it is negative, it has the same effect as if it were -1: 2053 * -1 is returned. 2054 * @return the index of the last occurrence of the character in the 2055 * character sequence represented by this object that is less 2056 * than or equal to {@code fromIndex}, or {@code -1} 2057 * if the character does not occur before that point. 2058 */ lastIndexOf(int ch, int fromIndex)2059 public int lastIndexOf(int ch, int fromIndex) { 2060 // BEGIN Android-changed: Implement in terms of charAt(). 2061 /* 2062 return isLatin1() ? StringLatin1.lastIndexOf(value, ch, fromIndex) 2063 : StringUTF16.lastIndexOf(value, ch, fromIndex); 2064 */ 2065 if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { 2066 // handle most cases here (ch is a BMP code point or a 2067 // negative value (invalid code point)) 2068 int i = Math.min(fromIndex, length() - 1); 2069 for (; i >= 0; i--) { 2070 if (charAt(i) == ch) { 2071 return i; 2072 } 2073 } 2074 return -1; 2075 } else { 2076 return lastIndexOfSupplementary(ch, fromIndex); 2077 } 2078 } 2079 2080 /** 2081 * Handles (rare) calls of lastIndexOf with a supplementary character. 2082 */ lastIndexOfSupplementary(int ch, int fromIndex)2083 private int lastIndexOfSupplementary(int ch, int fromIndex) { 2084 if (Character.isValidCodePoint(ch)) { 2085 char hi = Character.highSurrogate(ch); 2086 char lo = Character.lowSurrogate(ch); 2087 int i = Math.min(fromIndex, length() - 2); 2088 for (; i >= 0; i--) { 2089 if (charAt(i) == hi && charAt(i + 1) == lo) { 2090 return i; 2091 } 2092 } 2093 } 2094 return -1; 2095 // END Android-changed: Implement in terms of charAt(). 2096 } 2097 2098 /** 2099 * Returns the index within this string of the first occurrence of the 2100 * specified substring. 2101 * 2102 * <p>The returned index is the smallest value {@code k} for which: 2103 * <pre>{@code 2104 * this.startsWith(str, k) 2105 * }</pre> 2106 * If no such value of {@code k} exists, then {@code -1} is returned. 2107 * 2108 * @param str the substring to search for. 2109 * @return the index of the first occurrence of the specified substring, 2110 * or {@code -1} if there is no such occurrence. 2111 */ 2112 @NeverInline indexOf(String str)2113 public int indexOf(String str) { 2114 // BEGIN Android-changed: Implement with indexOf() method that takes String parameters. 2115 /* 2116 if (coder() == str.coder()) { 2117 return isLatin1() ? StringLatin1.indexOf(value, str.value) 2118 : StringUTF16.indexOf(value, str.value); 2119 } 2120 if (coder() == LATIN1) { // str.coder == UTF16 2121 return -1; 2122 } 2123 return StringUTF16.indexOfLatin1(value, str.value); 2124 */ 2125 return indexOf(str, 0); 2126 // END Android-changed: Implement with indexOf() method that takes String parameters. 2127 } 2128 2129 /** 2130 * Returns the index within this string of the first occurrence of the 2131 * specified substring, starting at the specified index. 2132 * 2133 * <p>The returned index is the smallest value {@code k} for which: 2134 * <pre>{@code 2135 * k >= Math.min(fromIndex, this.length()) && 2136 * this.startsWith(str, k) 2137 * }</pre> 2138 * If no such value of {@code k} exists, then {@code -1} is returned. 2139 * 2140 * @param str the substring to search for. 2141 * @param fromIndex the index from which to start the search. 2142 * @return the index of the first occurrence of the specified substring, 2143 * starting at the specified index, 2144 * or {@code -1} if there is no such occurrence. 2145 */ 2146 @NeverInline indexOf(String str, int fromIndex)2147 public int indexOf(String str, int fromIndex) { 2148 // BEGIN Android-changed: Implement with indexOf() method that takes String parameters. 2149 /* 2150 return indexOf(value, coder(), length(), str, fromIndex); 2151 */ 2152 return indexOf(this, str, fromIndex); 2153 // END Android-changed: Implement with indexOf() method that takes String parameters. 2154 } 2155 2156 // BEGIN Android-added: Private static indexOf method that takes String parameters. 2157 // The use of length(), charAt(), etc. makes it more efficient for compressed strings. 2158 /** 2159 * The source is the string being searched, and the target is the string being searched for. 2160 * 2161 * @param source the characters being searched. 2162 * @param target the characters being searched for. 2163 * @param fromIndex the index to begin searching from. 2164 */ indexOf(String source, String target, int fromIndex)2165 private static int indexOf(String source, String target, int fromIndex) { 2166 final int sourceLength = source.length(); 2167 final int targetLength = target.length(); 2168 if (fromIndex >= sourceLength) { 2169 return (targetLength == 0 ? sourceLength : -1); 2170 } 2171 if (fromIndex < 0) { 2172 fromIndex = 0; 2173 } 2174 if (targetLength == 0) { 2175 return fromIndex; 2176 } 2177 2178 char first = target.charAt(0); 2179 int max = (sourceLength - targetLength); 2180 2181 for (int i = fromIndex; i <= max; i++) { 2182 /* Look for first character. */ 2183 if (source.charAt(i)!= first) { 2184 while (++i <= max && source.charAt(i) != first); 2185 } 2186 2187 /* Found first character, now look at the rest of v2 */ 2188 if (i <= max) { 2189 int j = i + 1; 2190 int end = j + targetLength - 1; 2191 for (int k = 1; j < end && source.charAt(j) 2192 == target.charAt(k); j++, k++); 2193 2194 if (j == end) { 2195 /* Found whole string. */ 2196 return i; 2197 } 2198 } 2199 } 2200 return -1; 2201 } 2202 // END Android-added: Private static indexOf method that takes String parameters. 2203 2204 /** 2205 * Code shared by String and AbstractStringBuilder to do searches. The 2206 * source is the character array being searched, and the target 2207 * is the string being searched for. 2208 * 2209 * @param src the characters being searched. 2210 * @param srcCoder the coder of the source string. 2211 * @param srcCount length of the source string. 2212 * @param tgtStr the characters being searched for. 2213 * @param fromIndex the index to begin searching from. 2214 */ indexOf(byte[] src, byte srcCoder, int srcCount, String tgtStr, int fromIndex)2215 static int indexOf(byte[] src, byte srcCoder, int srcCount, 2216 String tgtStr, int fromIndex) { 2217 // byte[] tgt = tgtStr.value; 2218 byte tgtCoder = tgtStr.coder(); 2219 int tgtCount = tgtStr.length(); 2220 2221 if (fromIndex >= srcCount) { 2222 return (tgtCount == 0 ? srcCount : -1); 2223 } 2224 if (fromIndex < 0) { 2225 fromIndex = 0; 2226 } 2227 if (tgtCount == 0) { 2228 return fromIndex; 2229 } 2230 if (tgtCount > srcCount) { 2231 return -1; 2232 } 2233 if (srcCoder == tgtCoder) { 2234 return srcCoder == LATIN1 2235 // Android-changed: libcore doesn't store String as Latin1 or UTF16 byte[] field. 2236 // ? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex) 2237 // : StringUTF16.indexOf(src, srcCount, tgt, tgtCount, fromIndex); 2238 ? StringLatin1.indexOf(src, srcCount, tgtStr, tgtCount, fromIndex) 2239 : StringUTF16.indexOf(src, srcCount, tgtStr, tgtCount, fromIndex); 2240 } 2241 if (srcCoder == LATIN1) { // && tgtCoder == UTF16 2242 return -1; 2243 } 2244 // srcCoder == UTF16 && tgtCoder == LATIN1) { 2245 // return StringUTF16.indexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex); 2246 return StringUTF16.indexOfLatin1(src, srcCount, tgtStr, tgtCount, fromIndex); 2247 } 2248 2249 /** 2250 * Returns the index within this string of the last occurrence of the 2251 * specified substring. The last occurrence of the empty string "" 2252 * is considered to occur at the index value {@code this.length()}. 2253 * 2254 * <p>The returned index is the largest value {@code k} for which: 2255 * <pre>{@code 2256 * this.startsWith(str, k) 2257 * }</pre> 2258 * If no such value of {@code k} exists, then {@code -1} is returned. 2259 * 2260 * @param str the substring to search for. 2261 * @return the index of the last occurrence of the specified substring, 2262 * or {@code -1} if there is no such occurrence. 2263 */ lastIndexOf(String str)2264 public int lastIndexOf(String str) { 2265 return lastIndexOf(str, length()); 2266 } 2267 2268 /** 2269 * Returns the index within this string of the last occurrence of the 2270 * specified substring, searching backward starting at the specified index. 2271 * 2272 * <p>The returned index is the largest value {@code k} for which: 2273 * <pre>{@code 2274 * k <= Math.min(fromIndex, this.length()) && 2275 * this.startsWith(str, k) 2276 * }</pre> 2277 * If no such value of {@code k} exists, then {@code -1} is returned. 2278 * 2279 * @param str the substring to search for. 2280 * @param fromIndex the index to start the search from. 2281 * @return the index of the last occurrence of the specified substring, 2282 * searching backward from the specified index, 2283 * or {@code -1} if there is no such occurrence. 2284 */ lastIndexOf(String str, int fromIndex)2285 public int lastIndexOf(String str, int fromIndex) { 2286 // BEGIN Android-changed: Implement with static lastIndexOf() that takes String parameters. 2287 /* 2288 return lastIndexOf(value, coder(), length(), str, fromIndex); 2289 */ 2290 return lastIndexOf(this, str, fromIndex); 2291 // END Android-changed: Implement with static lastIndexOf() that takes String parameters. 2292 } 2293 2294 // BEGIN Android-added: Private static lastIndexOf method that takes String parameters. 2295 // The use of length(), charAt(), etc. makes it more efficient for compressed strings. 2296 /** 2297 * The source is the string being searched, and the target is the string being searched for. 2298 * 2299 * @param source the characters being searched. 2300 * @param target the characters being searched for. 2301 * @param fromIndex the index to begin searching from. 2302 */ lastIndexOf(String source, String target, int fromIndex)2303 private static int lastIndexOf(String source, String target, int fromIndex) { 2304 /* 2305 * Check arguments; return immediately where possible. For 2306 * consistency, don't check for null str. 2307 */ 2308 final int sourceLength = source.length(); 2309 final int targetLength = target.length(); 2310 int rightIndex = sourceLength - targetLength; 2311 if (fromIndex < 0) { 2312 return -1; 2313 } 2314 if (fromIndex > rightIndex) { 2315 fromIndex = rightIndex; 2316 } 2317 /* Empty string always matches. */ 2318 if (targetLength == 0) { 2319 return fromIndex; 2320 } 2321 2322 int strLastIndex = targetLength - 1; 2323 char strLastChar = target.charAt(strLastIndex); 2324 int min = targetLength - 1; 2325 int i = min + fromIndex; 2326 2327 startSearchForLastChar: 2328 while (true) { 2329 while (i >= min && source.charAt(i) != strLastChar) { 2330 i--; 2331 } 2332 if (i < min) { 2333 return -1; 2334 } 2335 int j = i - 1; 2336 int start = j - (targetLength - 1); 2337 int k = strLastIndex - 1; 2338 2339 while (j > start) { 2340 if (source.charAt(j--) != target.charAt(k--)) { 2341 i--; 2342 continue startSearchForLastChar; 2343 } 2344 } 2345 return start + 1; 2346 } 2347 } 2348 // END Android-added: Private static lastIndexOf method that takes String parameters. 2349 2350 /** 2351 * Code shared by String and AbstractStringBuilder to do searches. The 2352 * source is the character array being searched, and the target 2353 * is the string being searched for. 2354 * 2355 * @param src the characters being searched. 2356 * @param srcCoder coder handles the mapping between bytes/chars 2357 * @param srcCount count of the source string. 2358 * @param tgtStr the characters being searched for. 2359 * @param fromIndex the index to begin searching from. 2360 */ lastIndexOf(byte[] src, byte srcCoder, int srcCount, String tgtStr, int fromIndex)2361 static int lastIndexOf(byte[] src, byte srcCoder, int srcCount, 2362 String tgtStr, int fromIndex) { 2363 // byte[] tgt = tgtStr.value; 2364 byte tgtCoder = tgtStr.coder(); 2365 int tgtCount = tgtStr.length(); 2366 /* 2367 * Check arguments; return immediately where possible. For 2368 * consistency, don't check for null str. 2369 */ 2370 int rightIndex = srcCount - tgtCount; 2371 if (fromIndex > rightIndex) { 2372 fromIndex = rightIndex; 2373 } 2374 if (fromIndex < 0) { 2375 return -1; 2376 } 2377 /* Empty string always matches. */ 2378 if (tgtCount == 0) { 2379 return fromIndex; 2380 } 2381 if (srcCoder == tgtCoder) { 2382 return srcCoder == LATIN1 2383 // Android-changed: libcore doesn't store String as Latin1 or UTF16 byte[] field. 2384 // ? StringLatin1.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex) 2385 // : StringUTF16.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex); 2386 ? StringLatin1.lastIndexOf(src, srcCount, tgtStr, tgtCount, fromIndex) 2387 : StringUTF16.lastIndexOf(src, srcCount, tgtStr, tgtCount, fromIndex); 2388 } 2389 if (srcCoder == LATIN1) { // && tgtCoder == UTF16 2390 return -1; 2391 } 2392 // srcCoder == UTF16 && tgtCoder == LATIN1 2393 // return StringUTF16.lastIndexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex); 2394 return StringUTF16.lastIndexOfLatin1(src, srcCount, tgtStr, tgtCount, fromIndex); 2395 } 2396 2397 /** 2398 * Code shared by String and StringBuffer to do searches. The 2399 * source is the character array being searched, and the target 2400 * is the string being searched for. 2401 * 2402 * @param source the characters being searched. 2403 * @param sourceOffset offset of the source string. 2404 * @param sourceCount count of the source string. 2405 * @param target the characters being searched for. 2406 * @param targetOffset offset of the target string. 2407 * @param targetCount count of the target string. 2408 * @param fromIndex the index to begin searching from. 2409 */ lastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex)2410 static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, 2411 char[] target, int targetOffset, int targetCount, 2412 int fromIndex) { 2413 /* 2414 * Check arguments; return immediately where possible. For 2415 * consistency, don't check for null str. 2416 */ 2417 int rightIndex = sourceCount - targetCount; 2418 if (fromIndex < 0) { 2419 return -1; 2420 } 2421 if (fromIndex > rightIndex) { 2422 fromIndex = rightIndex; 2423 } 2424 /* Empty string always matches. */ 2425 if (targetCount == 0) { 2426 return fromIndex; 2427 } 2428 2429 int strLastIndex = targetOffset + targetCount - 1; 2430 char strLastChar = target[strLastIndex]; 2431 int min = sourceOffset + targetCount - 1; 2432 int i = min + fromIndex; 2433 2434 startSearchForLastChar: 2435 while (true) { 2436 while (i >= min && source[i] != strLastChar) { 2437 i--; 2438 } 2439 if (i < min) { 2440 return -1; 2441 } 2442 int j = i - 1; 2443 int start = j - (targetCount - 1); 2444 int k = strLastIndex - 1; 2445 2446 while (j > start) { 2447 if (source[j--] != target[k--]) { 2448 i--; 2449 continue startSearchForLastChar; 2450 } 2451 } 2452 return start - sourceOffset + 1; 2453 } 2454 } 2455 2456 /** 2457 * Returns a string that is a substring of this string. The 2458 * substring begins with the character at the specified index and 2459 * extends to the end of this string. <p> 2460 * Examples: 2461 * <blockquote><pre> 2462 * "unhappy".substring(2) returns "happy" 2463 * "Harbison".substring(3) returns "bison" 2464 * "emptiness".substring(9) returns "" (an empty string) 2465 * </pre></blockquote> 2466 * 2467 * @param beginIndex the beginning index, inclusive. 2468 * @return the specified substring. 2469 * @exception IndexOutOfBoundsException if 2470 * {@code beginIndex} is negative or larger than the 2471 * length of this {@code String} object. 2472 */ substring(int beginIndex)2473 public String substring(int beginIndex) { 2474 if (beginIndex < 0) { 2475 throw new StringIndexOutOfBoundsException(this, beginIndex); 2476 } 2477 int subLen = length() - beginIndex; 2478 if (subLen < 0) { 2479 throw new StringIndexOutOfBoundsException(this, beginIndex); 2480 } 2481 if (beginIndex == 0) { 2482 return this; 2483 } 2484 // BEGIN Android-changed: Use native fastSubstring instead of String constructor. 2485 /* 2486 return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen) 2487 : StringUTF16.newString(value, beginIndex, subLen); 2488 */ 2489 return fastSubstring(beginIndex, subLen); 2490 // END Android-changed: Use native fastSubstring instead of String constructor. 2491 } 2492 2493 /** 2494 * Returns a string that is a substring of this string. The 2495 * substring begins at the specified {@code beginIndex} and 2496 * extends to the character at index {@code endIndex - 1}. 2497 * Thus the length of the substring is {@code endIndex-beginIndex}. 2498 * <p> 2499 * Examples: 2500 * <blockquote><pre> 2501 * "hamburger".substring(4, 8) returns "urge" 2502 * "smiles".substring(1, 5) returns "mile" 2503 * </pre></blockquote> 2504 * 2505 * @param beginIndex the beginning index, inclusive. 2506 * @param endIndex the ending index, exclusive. 2507 * @return the specified substring. 2508 * @exception IndexOutOfBoundsException if the 2509 * {@code beginIndex} is negative, or 2510 * {@code endIndex} is larger than the length of 2511 * this {@code String} object, or 2512 * {@code beginIndex} is larger than 2513 * {@code endIndex}. 2514 */ substring(int beginIndex, int endIndex)2515 public String substring(int beginIndex, int endIndex) { 2516 int length = length(); 2517 checkBoundsBeginEnd(beginIndex, endIndex, length); 2518 int subLen = endIndex - beginIndex; 2519 if (beginIndex == 0 && endIndex == length) { 2520 return this; 2521 } 2522 2523 // BEGIN Android-changed: Use native fastSubstring instead of String constructor. 2524 /* 2525 return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen) 2526 : StringUTF16.newString(value, beginIndex, subLen); 2527 */ 2528 return fastSubstring(beginIndex, subLen); 2529 // END Android-changed: Use native fastSubstring instead of String constructor. 2530 } 2531 2532 // BEGIN Android-added: Native method to access char storage managed by runtime. 2533 @FastNative fastSubstring(int start, int length)2534 private native String fastSubstring(int start, int length); 2535 // END Android-added: Native method to access char storage managed by runtime. 2536 2537 /** 2538 * Returns a character sequence that is a subsequence of this sequence. 2539 * 2540 * <p> An invocation of this method of the form 2541 * 2542 * <blockquote><pre> 2543 * str.subSequence(begin, end)</pre></blockquote> 2544 * 2545 * behaves in exactly the same way as the invocation 2546 * 2547 * <blockquote><pre> 2548 * str.substring(begin, end)</pre></blockquote> 2549 * 2550 * @apiNote 2551 * This method is defined so that the {@code String} class can implement 2552 * the {@link CharSequence} interface. 2553 * 2554 * @param beginIndex the begin index, inclusive. 2555 * @param endIndex the end index, exclusive. 2556 * @return the specified subsequence. 2557 * 2558 * @throws IndexOutOfBoundsException 2559 * if {@code beginIndex} or {@code endIndex} is negative, 2560 * if {@code endIndex} is greater than {@code length()}, 2561 * or if {@code beginIndex} is greater than {@code endIndex} 2562 * 2563 * @since 1.4 2564 * @spec JSR-51 2565 */ subSequence(int beginIndex, int endIndex)2566 public CharSequence subSequence(int beginIndex, int endIndex) { 2567 return this.substring(beginIndex, endIndex); 2568 } 2569 2570 /** 2571 * Concatenates the specified string to the end of this string. 2572 * <p> 2573 * If the length of the argument string is {@code 0}, then this 2574 * {@code String} object is returned. Otherwise, a 2575 * {@code String} object is returned that represents a character 2576 * sequence that is the concatenation of the character sequence 2577 * represented by this {@code String} object and the character 2578 * sequence represented by the argument string.<p> 2579 * Examples: 2580 * <blockquote><pre> 2581 * "cares".concat("s") returns "caress" 2582 * "to".concat("get").concat("her") returns "together" 2583 * </pre></blockquote> 2584 * 2585 * @param str the {@code String} that is concatenated to the end 2586 * of this {@code String}. 2587 * @return a string that represents the concatenation of this object's 2588 * characters followed by the string argument's characters. 2589 */ 2590 // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above). 2591 /* 2592 public String concat(String str) { 2593 if (str.isEmpty()) { 2594 return this; 2595 } 2596 if (coder() == str.coder()) { 2597 byte[] val = this.value; 2598 byte[] oval = str.value; 2599 int len = val.length + oval.length; 2600 byte[] buf = Arrays.copyOf(val, len); 2601 System.arraycopy(oval, 0, buf, val.length, oval.length); 2602 return new String(buf, coder); 2603 } 2604 int len = length(); 2605 int olen = str.length(); 2606 byte[] buf = StringUTF16.newBytesFor(len + olen); 2607 getBytes(buf, 0, UTF16); 2608 str.getBytes(buf, len, UTF16); 2609 return new String(buf, UTF16); 2610 } 2611 */ 2612 @FastNative concat(String str)2613 public native String concat(String str); 2614 // END Android-changed: Replace with implementation in runtime to access chars (see above). 2615 2616 /** 2617 * Returns a string resulting from replacing all occurrences of 2618 * {@code oldChar} in this string with {@code newChar}. 2619 * <p> 2620 * If the character {@code oldChar} does not occur in the 2621 * character sequence represented by this {@code String} object, 2622 * then a reference to this {@code String} object is returned. 2623 * Otherwise, a {@code String} object is returned that 2624 * represents a character sequence identical to the character sequence 2625 * represented by this {@code String} object, except that every 2626 * occurrence of {@code oldChar} is replaced by an occurrence 2627 * of {@code newChar}. 2628 * <p> 2629 * Examples: 2630 * <blockquote><pre> 2631 * "mesquite in your cellar".replace('e', 'o') 2632 * returns "mosquito in your collar" 2633 * "the war of baronets".replace('r', 'y') 2634 * returns "the way of bayonets" 2635 * "sparring with a purple porpoise".replace('p', 't') 2636 * returns "starring with a turtle tortoise" 2637 * "JonL".replace('q', 'x') returns "JonL" (no change) 2638 * </pre></blockquote> 2639 * 2640 * @param oldChar the old character. 2641 * @param newChar the new character. 2642 * @return a string derived from this string by replacing every 2643 * occurrence of {@code oldChar} with {@code newChar}. 2644 */ replace(char oldChar, char newChar)2645 public String replace(char oldChar, char newChar) { 2646 // BEGIN Android-changed: Replace with implementation using native doReplace method. 2647 if (oldChar != newChar) { 2648 /* 2649 String ret = isLatin1() ? StringLatin1.replace(value, oldChar, newChar) 2650 : StringUTF16.replace(value, oldChar, newChar); 2651 if (ret != null) { 2652 return ret; 2653 } 2654 */ 2655 final int len = length(); 2656 for (int i = 0; i < len; ++i) { 2657 if (charAt(i) == oldChar) { 2658 return doReplace(oldChar, newChar); 2659 } 2660 } 2661 } 2662 // END Android-changed: Replace with implementation using native doReplace method. 2663 return this; 2664 } 2665 2666 // BEGIN Android-added: Native method to access char storage managed by runtime. 2667 // Implementation of replace(char oldChar, char newChar) called when we found a match. 2668 @FastNative doReplace(char oldChar, char newChar)2669 private native String doReplace(char oldChar, char newChar); 2670 // END Android-added: Native method to access char storage managed by runtime. 2671 2672 /** 2673 * Tells whether or not this string matches the given <a 2674 * href="../util/regex/Pattern.html#sum">regular expression</a>. 2675 * 2676 * <p> An invocation of this method of the form 2677 * <i>str</i>{@code .matches(}<i>regex</i>{@code )} yields exactly the 2678 * same result as the expression 2679 * 2680 * <blockquote> 2681 * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence) 2682 * matches(<i>regex</i>, <i>str</i>)} 2683 * </blockquote> 2684 * 2685 * @param regex 2686 * the regular expression to which this string is to be matched 2687 * 2688 * @return {@code true} if, and only if, this string matches the 2689 * given regular expression 2690 * 2691 * @throws PatternSyntaxException 2692 * if the regular expression's syntax is invalid 2693 * 2694 * @see java.util.regex.Pattern 2695 * 2696 * @since 1.4 2697 * @spec JSR-51 2698 */ matches(String regex)2699 public boolean matches(String regex) { 2700 return Pattern.matches(regex, this); 2701 } 2702 2703 /** 2704 * Returns true if and only if this string contains the specified 2705 * sequence of char values. 2706 * 2707 * @param s the sequence to search for 2708 * @return true if this string contains {@code s}, false otherwise 2709 * @since 1.5 2710 */ contains(CharSequence s)2711 public boolean contains(CharSequence s) { 2712 return indexOf(s.toString()) >= 0; 2713 } 2714 2715 /** 2716 * Replaces the first substring of this string that matches the given <a 2717 * href="../util/regex/Pattern.html#sum">regular expression</a> with the 2718 * given replacement. 2719 * 2720 * <p> An invocation of this method of the form 2721 * <i>str</i>{@code .replaceFirst(}<i>regex</i>{@code ,} <i>repl</i>{@code )} 2722 * yields exactly the same result as the expression 2723 * 2724 * <blockquote> 2725 * <code> 2726 * {@link java.util.regex.Pattern}.{@link 2727 * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link 2728 * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link 2729 * java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>) 2730 * </code> 2731 * </blockquote> 2732 * 2733 *<p> 2734 * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the 2735 * replacement string may cause the results to be different than if it were 2736 * being treated as a literal replacement string; see 2737 * {@link java.util.regex.Matcher#replaceFirst}. 2738 * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special 2739 * meaning of these characters, if desired. 2740 * 2741 * @param regex 2742 * the regular expression to which this string is to be matched 2743 * @param replacement 2744 * the string to be substituted for the first match 2745 * 2746 * @return The resulting {@code String} 2747 * 2748 * @throws PatternSyntaxException 2749 * if the regular expression's syntax is invalid 2750 * 2751 * @see java.util.regex.Pattern 2752 * 2753 * @since 1.4 2754 * @spec JSR-51 2755 */ replaceFirst(String regex, String replacement)2756 public String replaceFirst(String regex, String replacement) { 2757 return Pattern.compile(regex).matcher(this).replaceFirst(replacement); 2758 } 2759 2760 /** 2761 * Replaces each substring of this string that matches the given <a 2762 * href="../util/regex/Pattern.html#sum">regular expression</a> with the 2763 * given replacement. 2764 * 2765 * <p> An invocation of this method of the form 2766 * <i>str</i>{@code .replaceAll(}<i>regex</i>{@code ,} <i>repl</i>{@code )} 2767 * yields exactly the same result as the expression 2768 * 2769 * <blockquote> 2770 * <code> 2771 * {@link java.util.regex.Pattern}.{@link 2772 * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link 2773 * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link 2774 * java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>) 2775 * </code> 2776 * </blockquote> 2777 * 2778 *<p> 2779 * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the 2780 * replacement string may cause the results to be different than if it were 2781 * being treated as a literal replacement string; see 2782 * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}. 2783 * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special 2784 * meaning of these characters, if desired. 2785 * 2786 * @param regex 2787 * the regular expression to which this string is to be matched 2788 * @param replacement 2789 * the string to be substituted for each match 2790 * 2791 * @return The resulting {@code String} 2792 * 2793 * @throws PatternSyntaxException 2794 * if the regular expression's syntax is invalid 2795 * 2796 * @see java.util.regex.Pattern 2797 * 2798 * @since 1.4 2799 * @spec JSR-51 2800 */ replaceAll(String regex, String replacement)2801 public String replaceAll(String regex, String replacement) { 2802 return Pattern.compile(regex).matcher(this).replaceAll(replacement); 2803 } 2804 2805 /** 2806 * Replaces each substring of this string that matches the literal target 2807 * sequence with the specified literal replacement sequence. The 2808 * replacement proceeds from the beginning of the string to the end, for 2809 * example, replacing "aa" with "b" in the string "aaa" will result in 2810 * "ba" rather than "ab". 2811 * 2812 * @param target The sequence of char values to be replaced 2813 * @param replacement The replacement sequence of char values 2814 * @return The resulting string 2815 * @since 1.5 2816 */ replace(CharSequence target, CharSequence replacement)2817 public String replace(CharSequence target, CharSequence replacement) { 2818 // BEGIN Android-added: Additional null check for parameters. 2819 Objects.requireNonNull(target); 2820 Objects.requireNonNull(replacement); 2821 // END Android-added: Additional null check for parameters. 2822 2823 String tgtStr = target.toString(); 2824 String replStr = replacement.toString(); 2825 int j = indexOf(tgtStr); 2826 if (j < 0) { 2827 return this; 2828 } 2829 int tgtLen = tgtStr.length(); 2830 int tgtLen1 = Math.max(tgtLen, 1); 2831 int thisLen = length(); 2832 2833 int newLenHint = thisLen - tgtLen + replStr.length(); 2834 if (newLenHint < 0) { 2835 throw new OutOfMemoryError(); 2836 } 2837 StringBuilder sb = new StringBuilder(newLenHint); 2838 int i = 0; 2839 do { 2840 sb.append(this, i, j).append(replStr); 2841 i = j + tgtLen; 2842 } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0); 2843 return sb.append(this, i, thisLen).toString(); 2844 } 2845 2846 /** 2847 * Splits this string around matches of the given 2848 * <a href="../util/regex/Pattern.html#sum">regular expression</a>. 2849 * 2850 * <p> The array returned by this method contains each substring of this 2851 * string that is terminated by another substring that matches the given 2852 * expression or is terminated by the end of the string. The substrings in 2853 * the array are in the order in which they occur in this string. If the 2854 * expression does not match any part of the input then the resulting array 2855 * has just one element, namely this string. 2856 * 2857 * <p> When there is a positive-width match at the beginning of this 2858 * string then an empty leading substring is included at the beginning 2859 * of the resulting array. A zero-width match at the beginning however 2860 * never produces such empty leading substring. 2861 * 2862 * <p> The {@code limit} parameter controls the number of times the 2863 * pattern is applied and therefore affects the length of the resulting 2864 * array. 2865 * <ul> 2866 * <li><p> 2867 * If the <i>limit</i> is positive then the pattern will be applied 2868 * at most <i>limit</i> - 1 times, the array's length will be 2869 * no greater than <i>limit</i>, and the array's last entry will contain 2870 * all input beyond the last matched delimiter.</p></li> 2871 * 2872 * <li><p> 2873 * If the <i>limit</i> is zero then the pattern will be applied as 2874 * many times as possible, the array can have any length, and trailing 2875 * empty strings will be discarded.</p></li> 2876 * 2877 * <li><p> 2878 * If the <i>limit</i> is negative then the pattern will be applied 2879 * as many times as possible and the array can have any length.</p></li> 2880 * </ul> 2881 * 2882 * <p> The string {@code "boo:and:foo"}, for example, yields the 2883 * following results with these parameters: 2884 * 2885 * <blockquote><table class="plain"> 2886 * <caption style="display:none">Split example showing regex, limit, and result</caption> 2887 * <thead> 2888 * <tr> 2889 * <th scope="col">Regex</th> 2890 * <th scope="col">Limit</th> 2891 * <th scope="col">Result</th> 2892 * </tr> 2893 * </thead> 2894 * <tbody> 2895 * <tr><th scope="row" rowspan="3" style="font-weight:normal">:</th> 2896 * <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">2</th> 2897 * <td>{@code { "boo", "and:foo" }}</td></tr> 2898 * <tr><!-- : --> 2899 * <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">5</th> 2900 * <td>{@code { "boo", "and", "foo" }}</td></tr> 2901 * <tr><!-- : --> 2902 * <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">-2</th> 2903 * <td>{@code { "boo", "and", "foo" }}</td></tr> 2904 * <tr><th scope="row" rowspan="3" style="font-weight:normal">o</th> 2905 * <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">5</th> 2906 * <td>{@code { "b", "", ":and:f", "", "" }}</td></tr> 2907 * <tr><!-- o --> 2908 * <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">-2</th> 2909 * <td>{@code { "b", "", ":and:f", "", "" }}</td></tr> 2910 * <tr><!-- o --> 2911 * <th scope="row" style="font-weight:normal; text-align:right; padding-right:1em">0</th> 2912 * <td>{@code { "b", "", ":and:f" }}</td></tr> 2913 * </tbody> 2914 * </table></blockquote> 2915 * 2916 * <p> An invocation of this method of the form 2917 * <i>str.</i>{@code split(}<i>regex</i>{@code ,} <i>n</i>{@code )} 2918 * yields the same result as the expression 2919 * 2920 * <blockquote> 2921 * <code> 2922 * {@link java.util.regex.Pattern}.{@link 2923 * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link 2924 * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>, <i>n</i>) 2925 * </code> 2926 * </blockquote> 2927 * 2928 * 2929 * @param regex 2930 * the delimiting regular expression 2931 * 2932 * @param limit 2933 * the result threshold, as described above 2934 * 2935 * @return the array of strings computed by splitting this string 2936 * around matches of the given regular expression 2937 * 2938 * @throws PatternSyntaxException 2939 * if the regular expression's syntax is invalid 2940 * 2941 * @see java.util.regex.Pattern 2942 * 2943 * @since 1.4 2944 * @spec JSR-51 2945 */ split(String regex, int limit)2946 public String[] split(String regex, int limit) { 2947 // BEGIN Android-changed: Replace custom fast-path with use of new Pattern.fastSplit method. 2948 // Try fast splitting without allocating Pattern object 2949 /* 2950 /* fastpath if the regex is a 2951 (1)one-char String and this character is not one of the 2952 RegEx's meta characters ".$|()[{^?*+\\", or 2953 (2)two-char String and the first char is the backslash and 2954 the second is not the ascii digit or ascii letter. 2955 * 2956 char ch = 0; 2957 if (((regex.length() == 1 && 2958 ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || 2959 (regex.length() == 2 && 2960 regex.charAt(0) == '\\' && 2961 (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && 2962 ((ch-'a')|('z'-ch)) < 0 && 2963 ((ch-'A')|('Z'-ch)) < 0)) && 2964 (ch < Character.MIN_HIGH_SURROGATE || 2965 ch > Character.MAX_LOW_SURROGATE)) 2966 { 2967 int off = 0; 2968 int next = 0; 2969 boolean limited = limit > 0; 2970 ArrayList<String> list = new ArrayList<>(); 2971 while ((next = indexOf(ch, off)) != -1) { 2972 if (!limited || list.size() < limit - 1) { 2973 list.add(substring(off, next)); 2974 off = next + 1; 2975 } else { // last one 2976 //assert (list.size() == limit - 1); 2977 int last = length(); 2978 list.add(substring(off, last)); 2979 off = last; 2980 break; 2981 } 2982 } 2983 // If no match was found, return this 2984 if (off == 0) 2985 return new String[]{this}; 2986 2987 // Add remaining segment 2988 if (!limited || list.size() < limit) 2989 list.add(substring(off, length())); 2990 2991 // Construct result 2992 int resultSize = list.size(); 2993 if (limit == 0) { 2994 while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) { 2995 resultSize--; 2996 } 2997 } 2998 String[] result = new String[resultSize]; 2999 return list.subList(0, resultSize).toArray(result); 3000 } 3001 */ 3002 String[] fast = Pattern.fastSplit(regex, this, limit); 3003 if (fast != null) { 3004 return fast; 3005 } 3006 // END Android-changed: Replace custom fast-path with use of new Pattern.fastSplit method. 3007 return Pattern.compile(regex).split(this, limit); 3008 } 3009 3010 /** 3011 * Splits this string around matches of the given <a 3012 * href="../util/regex/Pattern.html#sum">regular expression</a>. 3013 * 3014 * <p> This method works as if by invoking the two-argument {@link 3015 * #split(String, int) split} method with the given expression and a limit 3016 * argument of zero. Trailing empty strings are therefore not included in 3017 * the resulting array. 3018 * 3019 * <p> The string {@code "boo:and:foo"}, for example, yields the following 3020 * results with these expressions: 3021 * 3022 * <blockquote><table class="plain"> 3023 * <caption style="display:none">Split examples showing regex and result</caption> 3024 * <thead> 3025 * <tr> 3026 * <th scope="col">Regex</th> 3027 * <th scope="col">Result</th> 3028 * </tr> 3029 * </thead> 3030 * <tbody> 3031 * <tr><th scope="row" style="text-weight:normal">:</th> 3032 * <td>{@code { "boo", "and", "foo" }}</td></tr> 3033 * <tr><th scope="row" style="text-weight:normal">o</th> 3034 * <td>{@code { "b", "", ":and:f" }}</td></tr> 3035 * </tbody> 3036 * </table></blockquote> 3037 * 3038 * 3039 * @param regex 3040 * the delimiting regular expression 3041 * 3042 * @return the array of strings computed by splitting this string 3043 * around matches of the given regular expression 3044 * 3045 * @throws PatternSyntaxException 3046 * if the regular expression's syntax is invalid 3047 * 3048 * @see java.util.regex.Pattern 3049 * 3050 * @since 1.4 3051 * @spec JSR-51 3052 */ split(String regex)3053 public String[] split(String regex) { 3054 return split(regex, 0); 3055 } 3056 3057 /** 3058 * Returns a new String composed of copies of the 3059 * {@code CharSequence elements} joined together with a copy of 3060 * the specified {@code delimiter}. 3061 * 3062 * <blockquote>For example, 3063 * <pre>{@code 3064 * String message = String.join("-", "Java", "is", "cool"); 3065 * // message returned is: "Java-is-cool" 3066 * }</pre></blockquote> 3067 * 3068 * Note that if an element is null, then {@code "null"} is added. 3069 * 3070 * @param delimiter the delimiter that separates each element 3071 * @param elements the elements to join together. 3072 * 3073 * @return a new {@code String} that is composed of the {@code elements} 3074 * separated by the {@code delimiter} 3075 * 3076 * @throws NullPointerException If {@code delimiter} or {@code elements} 3077 * is {@code null} 3078 * 3079 * @see java.util.StringJoiner 3080 * @since 1.8 3081 */ join(CharSequence delimiter, CharSequence... elements)3082 public static String join(CharSequence delimiter, CharSequence... elements) { 3083 Objects.requireNonNull(delimiter); 3084 Objects.requireNonNull(elements); 3085 // Number of elements not likely worth Arrays.stream overhead. 3086 StringJoiner joiner = new StringJoiner(delimiter); 3087 for (CharSequence cs: elements) { 3088 joiner.add(cs); 3089 } 3090 return joiner.toString(); 3091 } 3092 3093 /** 3094 * Returns a new {@code String} composed of copies of the 3095 * {@code CharSequence elements} joined together with a copy of the 3096 * specified {@code delimiter}. 3097 * 3098 * <blockquote>For example, 3099 * <pre>{@code 3100 * List<String> strings = List.of("Java", "is", "cool"); 3101 * String message = String.join(" ", strings); 3102 * //message returned is: "Java is cool" 3103 * 3104 * Set<String> strings = 3105 * new LinkedHashSet<>(List.of("Java", "is", "very", "cool")); 3106 * String message = String.join("-", strings); 3107 * //message returned is: "Java-is-very-cool" 3108 * }</pre></blockquote> 3109 * 3110 * Note that if an individual element is {@code null}, then {@code "null"} is added. 3111 * 3112 * @param delimiter a sequence of characters that is used to separate each 3113 * of the {@code elements} in the resulting {@code String} 3114 * @param elements an {@code Iterable} that will have its {@code elements} 3115 * joined together. 3116 * 3117 * @return a new {@code String} that is composed from the {@code elements} 3118 * argument 3119 * 3120 * @throws NullPointerException If {@code delimiter} or {@code elements} 3121 * is {@code null} 3122 * 3123 * @see #join(CharSequence,CharSequence...) 3124 * @see java.util.StringJoiner 3125 * @since 1.8 3126 */ join(CharSequence delimiter, Iterable<? extends CharSequence> elements)3127 public static String join(CharSequence delimiter, 3128 Iterable<? extends CharSequence> elements) { 3129 Objects.requireNonNull(delimiter); 3130 Objects.requireNonNull(elements); 3131 StringJoiner joiner = new StringJoiner(delimiter); 3132 for (CharSequence cs: elements) { 3133 joiner.add(cs); 3134 } 3135 return joiner.toString(); 3136 } 3137 3138 /** 3139 * Converts all of the characters in this {@code String} to lower 3140 * case using the rules of the given {@code Locale}. Case mapping is based 3141 * on the Unicode Standard version specified by the {@link java.lang.Character Character} 3142 * class. Since case mappings are not always 1:1 char mappings, the resulting 3143 * {@code String} may be a different length than the original {@code String}. 3144 * <p> 3145 * Examples of lowercase mappings are in the following table: 3146 * <table class="plain"> 3147 * <caption style="display:none">Lowercase mapping examples showing language code of locale, upper case, lower case, and description</caption> 3148 * <thead> 3149 * <tr> 3150 * <th scope="col">Language Code of Locale</th> 3151 * <th scope="col">Upper Case</th> 3152 * <th scope="col">Lower Case</th> 3153 * <th scope="col">Description</th> 3154 * </tr> 3155 * </thead> 3156 * <tbody> 3157 * <tr> 3158 * <td>tr (Turkish)</td> 3159 * <th scope="row" style="font-weight:normal; text-align:left">\u0130</th> 3160 * <td>\u0069</td> 3161 * <td>capital letter I with dot above -> small letter i</td> 3162 * </tr> 3163 * <tr> 3164 * <td>tr (Turkish)</td> 3165 * <th scope="row" style="font-weight:normal; text-align:left">\u0049</th> 3166 * <td>\u0131</td> 3167 * <td>capital letter I -> small letter dotless i </td> 3168 * </tr> 3169 * <tr> 3170 * <td>(all)</td> 3171 * <th scope="row" style="font-weight:normal; text-align:left">French Fries</th> 3172 * <td>french fries</td> 3173 * <td>lowercased all chars in String</td> 3174 * </tr> 3175 * <tr> 3176 * <td>(all)</td> 3177 * <th scope="row" style="font-weight:normal; text-align:left"> 3178 * ΙΧΘΥΣ</th> 3179 * <td>ιχθυσ</td> 3180 * <td>lowercased all chars in String</td> 3181 * </tr> 3182 * </tbody> 3183 * </table> 3184 * 3185 * @param locale use the case transformation rules for this locale 3186 * @return the {@code String}, converted to lowercase. 3187 * @see java.lang.String#toLowerCase() 3188 * @see java.lang.String#toUpperCase() 3189 * @see java.lang.String#toUpperCase(Locale) 3190 * @since 1.1 3191 */ toLowerCase(Locale locale)3192 public String toLowerCase(Locale locale) { 3193 // BEGIN Android-changed: Replace custom code with call to new CaseMapper class. 3194 /* 3195 return isLatin1() ? StringLatin1.toLowerCase(this, value, locale) 3196 : StringUTF16.toLowerCase(this, value, locale); 3197 */ 3198 return CaseMapper.toLowerCase(locale, this); 3199 // END Android-changed: Replace custom code with call to new CaseMapper class. 3200 } 3201 3202 /** 3203 * Converts all of the characters in this {@code String} to lower 3204 * case using the rules of the default locale. This is equivalent to calling 3205 * {@code toLowerCase(Locale.getDefault())}. 3206 * <p> 3207 * <b>Note:</b> This method is locale sensitive, and may produce unexpected 3208 * results if used for strings that are intended to be interpreted locale 3209 * independently. 3210 * Examples are programming language identifiers, protocol keys, and HTML 3211 * tags. 3212 * For instance, {@code "TITLE".toLowerCase()} in a Turkish locale 3213 * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the 3214 * LATIN SMALL LETTER DOTLESS I character. 3215 * To obtain correct results for locale insensitive strings, use 3216 * {@code toLowerCase(Locale.ROOT)}. 3217 * 3218 * @return the {@code String}, converted to lowercase. 3219 * @see java.lang.String#toLowerCase(Locale) 3220 */ toLowerCase()3221 public String toLowerCase() { 3222 return toLowerCase(Locale.getDefault()); 3223 } 3224 3225 /** 3226 * Converts all of the characters in this {@code String} to upper 3227 * case using the rules of the given {@code Locale}. Case mapping is based 3228 * on the Unicode Standard version specified by the {@link java.lang.Character Character} 3229 * class. Since case mappings are not always 1:1 char mappings, the resulting 3230 * {@code String} may be a different length than the original {@code String}. 3231 * <p> 3232 * Examples of locale-sensitive and 1:M case mappings are in the following table. 3233 * 3234 * <table class="plain"> 3235 * <caption style="display:none">Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description.</caption> 3236 * <thead> 3237 * <tr> 3238 * <th scope="col">Language Code of Locale</th> 3239 * <th scope="col">Lower Case</th> 3240 * <th scope="col">Upper Case</th> 3241 * <th scope="col">Description</th> 3242 * </tr> 3243 * </thead> 3244 * <tbody> 3245 * <tr> 3246 * <td>tr (Turkish)</td> 3247 * <th scope="row" style="font-weight:normal; text-align:left">\u0069</th> 3248 * <td>\u0130</td> 3249 * <td>small letter i -> capital letter I with dot above</td> 3250 * </tr> 3251 * <tr> 3252 * <td>tr (Turkish)</td> 3253 * <th scope="row" style="font-weight:normal; text-align:left">\u0131</th> 3254 * <td>\u0049</td> 3255 * <td>small letter dotless i -> capital letter I</td> 3256 * </tr> 3257 * <tr> 3258 * <td>(all)</td> 3259 * <th scope="row" style="font-weight:normal; text-align:left">\u00df</th> 3260 * <td>\u0053 \u0053</td> 3261 * <td>small letter sharp s -> two letters: SS</td> 3262 * </tr> 3263 * <tr> 3264 * <td>(all)</td> 3265 * <th scope="row" style="font-weight:normal; text-align:left">Fahrvergnügen</th> 3266 * <td>FAHRVERGNÜGEN</td> 3267 * <td></td> 3268 * </tr> 3269 * </tbody> 3270 * </table> 3271 * @param locale use the case transformation rules for this locale 3272 * @return the {@code String}, converted to uppercase. 3273 * @see java.lang.String#toUpperCase() 3274 * @see java.lang.String#toLowerCase() 3275 * @see java.lang.String#toLowerCase(Locale) 3276 * @since 1.1 3277 */ toUpperCase(Locale locale)3278 public String toUpperCase(Locale locale) { 3279 // BEGIN Android-changed: Replace custom code with call to new CaseMapper class. 3280 /* 3281 return isLatin1() ? StringLatin1.toUpperCase(this, value, locale) 3282 : StringUTF16.toUpperCase(this, value, locale); 3283 */ 3284 return CaseMapper.toUpperCase(locale, this, length()); 3285 // END Android-changed: Replace custom code with call to new CaseMapper class. 3286 } 3287 3288 /** 3289 * Converts all of the characters in this {@code String} to upper 3290 * case using the rules of the default locale. This method is equivalent to 3291 * {@code toUpperCase(Locale.getDefault())}. 3292 * <p> 3293 * <b>Note:</b> This method is locale sensitive, and may produce unexpected 3294 * results if used for strings that are intended to be interpreted locale 3295 * independently. 3296 * Examples are programming language identifiers, protocol keys, and HTML 3297 * tags. 3298 * For instance, {@code "title".toUpperCase()} in a Turkish locale 3299 * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the 3300 * LATIN CAPITAL LETTER I WITH DOT ABOVE character. 3301 * To obtain correct results for locale insensitive strings, use 3302 * {@code toUpperCase(Locale.ROOT)}. 3303 * 3304 * @return the {@code String}, converted to uppercase. 3305 * @see java.lang.String#toUpperCase(Locale) 3306 */ toUpperCase()3307 public String toUpperCase() { 3308 return toUpperCase(Locale.getDefault()); 3309 } 3310 3311 /** 3312 * Returns a string whose value is this string, with all leading 3313 * and trailing space removed, where space is defined 3314 * as any character whose codepoint is less than or equal to 3315 * {@code 'U+0020'} (the space character). 3316 * <p> 3317 * If this {@code String} object represents an empty character 3318 * sequence, or the first and last characters of character sequence 3319 * represented by this {@code String} object both have codes 3320 * that are not space (as defined above), then a 3321 * reference to this {@code String} object is returned. 3322 * <p> 3323 * Otherwise, if all characters in this string are space (as 3324 * defined above), then a {@code String} object representing an 3325 * empty string is returned. 3326 * <p> 3327 * Otherwise, let <i>k</i> be the index of the first character in the 3328 * string whose code is not a space (as defined above) and let 3329 * <i>m</i> be the index of the last character in the string whose code 3330 * is not a space (as defined above). A {@code String} 3331 * object is returned, representing the substring of this string that 3332 * begins with the character at index <i>k</i> and ends with the 3333 * character at index <i>m</i>-that is, the result of 3334 * {@code this.substring(k, m + 1)}. 3335 * <p> 3336 * This method may be used to trim space (as defined above) from 3337 * the beginning and end of a string. 3338 * 3339 * @return a string whose value is this string, with all leading 3340 * and trailing space removed, or this string if it 3341 * has no leading or trailing space. 3342 */ trim()3343 public String trim() { 3344 // BEGIN Android-changed: Implement in terms of charAt(). 3345 /* 3346 String ret = isLatin1() ? StringLatin1.trim(value) 3347 : StringUTF16.trim(value); 3348 return ret == null ? this : ret; 3349 */ 3350 int len = length(); 3351 int st = 0; 3352 3353 while ((st < len) && (charAt(st) <= ' ')) { 3354 st++; 3355 } 3356 while ((st < len) && (charAt(len - 1) <= ' ')) { 3357 len--; 3358 } 3359 return ((st > 0) || (len < length())) ? substring(st, len) : this; 3360 // END Android-changed: Implement in terms of charAt(). 3361 } 3362 3363 /** 3364 * Returns a string whose value is this string, with all leading 3365 * and trailing {@link Character#isWhitespace(int) white space} 3366 * removed. 3367 * <p> 3368 * If this {@code String} object represents an empty string, 3369 * or if all code points in this string are 3370 * {@link Character#isWhitespace(int) white space}, then an empty string 3371 * is returned. 3372 * <p> 3373 * Otherwise, returns a substring of this string beginning with the first 3374 * code point that is not a {@link Character#isWhitespace(int) white space} 3375 * up to and including the last code point that is not a 3376 * {@link Character#isWhitespace(int) white space}. 3377 * <p> 3378 * This method may be used to strip 3379 * {@link Character#isWhitespace(int) white space} from 3380 * the beginning and end of a string. 3381 * 3382 * @return a string whose value is this string, with all leading 3383 * and trailing white space removed 3384 * 3385 * @see Character#isWhitespace(int) 3386 * 3387 * @since 11 3388 */ strip()3389 public String strip() { 3390 // BEGIN Android-changed: Delegate to StringUTF16. 3391 /* 3392 String ret = isLatin1() ? StringLatin1.strip(value) 3393 : StringUTF16.strip(value); 3394 */ 3395 String ret = StringUTF16.strip(this); 3396 // END Android-changed: Delegate to StringUTF16. 3397 return ret == null ? this : ret; 3398 } 3399 3400 /** 3401 * Returns a string whose value is this string, with all leading 3402 * {@link Character#isWhitespace(int) white space} removed. 3403 * <p> 3404 * If this {@code String} object represents an empty string, 3405 * or if all code points in this string are 3406 * {@link Character#isWhitespace(int) white space}, then an empty string 3407 * is returned. 3408 * <p> 3409 * Otherwise, returns a substring of this string beginning with the first 3410 * code point that is not a {@link Character#isWhitespace(int) white space} 3411 * up to to and including the last code point of this string. 3412 * <p> 3413 * This method may be used to trim 3414 * {@link Character#isWhitespace(int) white space} from 3415 * the beginning of a string. 3416 * 3417 * @return a string whose value is this string, with all leading white 3418 * space removed 3419 * 3420 * @see Character#isWhitespace(int) 3421 * 3422 * @since 11 3423 */ stripLeading()3424 public String stripLeading() { 3425 // BEGIN Android-changed: Delegate to StringUTF16. 3426 /* 3427 String ret = isLatin1() ? StringLatin1.stripLeading(value) 3428 : StringUTF16.stripLeading(value); 3429 */ 3430 String ret = StringUTF16.stripLeading(this); 3431 // END Android-changed: Delegate to StringUTF16. 3432 return ret == null ? this : ret; 3433 } 3434 3435 /** 3436 * Returns a string whose value is this string, with all trailing 3437 * {@link Character#isWhitespace(int) white space} removed. 3438 * <p> 3439 * If this {@code String} object represents an empty string, 3440 * or if all characters in this string are 3441 * {@link Character#isWhitespace(int) white space}, then an empty string 3442 * is returned. 3443 * <p> 3444 * Otherwise, returns a substring of this string beginning with the first 3445 * code point of this string up to and including the last code point 3446 * that is not a {@link Character#isWhitespace(int) white space}. 3447 * <p> 3448 * This method may be used to trim 3449 * {@link Character#isWhitespace(int) white space} from 3450 * the end of a string. 3451 * 3452 * @return a string whose value is this string, with all trailing white 3453 * space removed 3454 * 3455 * @see Character#isWhitespace(int) 3456 * 3457 * @since 11 3458 */ stripTrailing()3459 public String stripTrailing() { 3460 // BEGIN Android-changed: Delegate to StringUTF16. 3461 /* 3462 String ret = isLatin1() ? StringLatin1.stripTrailing(value) 3463 : StringUTF16.stripTrailing(value); 3464 */ 3465 String ret = StringUTF16.stripTrailing(this); 3466 // END Android-changed: Delegate to StringUTF16. 3467 return ret == null ? this : ret; 3468 } 3469 3470 /** 3471 * Returns {@code true} if the string is empty or contains only 3472 * {@link Character#isWhitespace(int) white space} codepoints, 3473 * otherwise {@code false}. 3474 * 3475 * @return {@code true} if the string is empty or contains only 3476 * {@link Character#isWhitespace(int) white space} codepoints, 3477 * otherwise {@code false} 3478 * 3479 * @see Character#isWhitespace(int) 3480 * 3481 * @since 11 3482 */ isBlank()3483 public boolean isBlank() { 3484 return indexOfNonWhitespace() == length(); 3485 } 3486 3487 /** 3488 * Returns a stream of lines extracted from this string, 3489 * separated by line terminators. 3490 * <p> 3491 * A <i>line terminator</i> is one of the following: 3492 * a line feed character {@code "\n"} (U+000A), 3493 * a carriage return character {@code "\r"} (U+000D), 3494 * or a carriage return followed immediately by a line feed 3495 * {@code "\r\n"} (U+000D U+000A). 3496 * <p> 3497 * A <i>line</i> is either a sequence of zero or more characters 3498 * followed by a line terminator, or it is a sequence of one or 3499 * more characters followed by the end of the string. A 3500 * line does not include the line terminator. 3501 * <p> 3502 * The stream returned by this method contains the lines from 3503 * this string in the order in which they occur. 3504 * 3505 * @apiNote This definition of <i>line</i> implies that an empty 3506 * string has zero lines and that there is no empty line 3507 * following a line terminator at the end of a string. 3508 * 3509 * @implNote This method provides better performance than 3510 * split("\R") by supplying elements lazily and 3511 * by faster search of new line terminators. 3512 * 3513 * @return the stream of lines extracted from this string 3514 * 3515 * @since 11 3516 */ lines()3517 public Stream<String> lines() { 3518 // BEGIN Android-removed: Delegate to StringUTF16. 3519 /* 3520 return isLatin1() ? StringLatin1.lines(value) 3521 : StringUTF16.lines(value); 3522 */ 3523 return StringUTF16.lines(this); 3524 // END Android-removed: Delegate to StringUTF16. 3525 } 3526 3527 /** 3528 * Adjusts the indentation of each line of this string based on the value of 3529 * {@code n}, and normalizes line termination characters. 3530 * <p> 3531 * This string is conceptually separated into lines using 3532 * {@link String#lines()}. Each line is then adjusted as described below 3533 * and then suffixed with a line feed {@code "\n"} (U+000A). The resulting 3534 * lines are then concatenated and returned. 3535 * <p> 3536 * If {@code n > 0} then {@code n} spaces (U+0020) are inserted at the 3537 * beginning of each line. 3538 * <p> 3539 * If {@code n < 0} then up to {@code n} 3540 * {@linkplain Character#isWhitespace(int) white space characters} are removed 3541 * from the beginning of each line. If a given line does not contain 3542 * sufficient white space then all leading 3543 * {@linkplain Character#isWhitespace(int) white space characters} are removed. 3544 * Each white space character is treated as a single character. In 3545 * particular, the tab character {@code "\t"} (U+0009) is considered a 3546 * single character; it is not expanded. 3547 * <p> 3548 * If {@code n == 0} then the line remains unchanged. However, line 3549 * terminators are still normalized. 3550 * 3551 * @param n number of leading 3552 * {@linkplain Character#isWhitespace(int) white space characters} 3553 * to add or remove 3554 * 3555 * @return string with indentation adjusted and line endings normalized 3556 * 3557 * @see String#lines() 3558 * @see String#isBlank() 3559 * @see Character#isWhitespace(int) 3560 * 3561 * @since 12 3562 */ indent(int n)3563 public String indent(int n) { 3564 if (isEmpty()) { 3565 return ""; 3566 } 3567 Stream<String> stream = lines(); 3568 if (n > 0) { 3569 final String spaces = " ".repeat(n); 3570 stream = stream.map(s -> spaces + s); 3571 } else if (n == Integer.MIN_VALUE) { 3572 stream = stream.map(s -> s.stripLeading()); 3573 } else if (n < 0) { 3574 stream = stream.map(s -> s.substring(Math.min(-n, s.indexOfNonWhitespace()))); 3575 } 3576 return stream.collect(Collectors.joining("\n", "", "\n")); 3577 } 3578 indexOfNonWhitespace()3579 private int indexOfNonWhitespace() { 3580 // BEGIN Android-removed: Delegate to StringUTF16. 3581 /* 3582 return isLatin1() ? StringLatin1.indexOfNonWhitespace(value) 3583 : StringUTF16.indexOfNonWhitespace(value); 3584 */ 3585 return StringUTF16.indexOfNonWhitespace(this); 3586 // END Android-removed: Delegate to StringUTF16. 3587 } 3588 lastIndexOfNonWhitespace()3589 private int lastIndexOfNonWhitespace() { 3590 // BEGIN Android-changed: Delegate to StringUTF16. 3591 /* 3592 return isLatin1() ? StringLatin1.lastIndexOfNonWhitespace(value) 3593 : StringUTF16.lastIndexOfNonWhitespace(value); 3594 */ 3595 return StringUTF16.lastIndexOfNonWhitespace(this); 3596 // END Android-changed: Delegate to StringUTF16. 3597 } 3598 3599 /** 3600 * Returns a string whose value is this string, with incidental 3601 * {@linkplain Character#isWhitespace(int) white space} removed from 3602 * the beginning and end of every line. 3603 * <p> 3604 * Incidental {@linkplain Character#isWhitespace(int) white space} 3605 * is often present in a text block to align the content with the opening 3606 * delimiter. For example, in the following code, dots represent incidental 3607 * {@linkplain Character#isWhitespace(int) white space}: 3608 * <blockquote><pre> 3609 * String html = """ 3610 * ..............<html> 3611 * .............. <body> 3612 * .............. <p>Hello, world</p> 3613 * .............. </body> 3614 * ..............</html> 3615 * .............."""; 3616 * </pre></blockquote> 3617 * This method treats the incidental 3618 * {@linkplain Character#isWhitespace(int) white space} as indentation to be 3619 * stripped, producing a string that preserves the relative indentation of 3620 * the content. Using | to visualize the start of each line of the string: 3621 * <blockquote><pre> 3622 * |<html> 3623 * | <body> 3624 * | <p>Hello, world</p> 3625 * | </body> 3626 * |</html> 3627 * </pre></blockquote> 3628 * First, the individual lines of this string are extracted. A <i>line</i> 3629 * is a sequence of zero or more characters followed by either a line 3630 * terminator or the end of the string. 3631 * If the string has at least one line terminator, the last line consists 3632 * of the characters between the last terminator and the end of the string. 3633 * Otherwise, if the string has no terminators, the last line is the start 3634 * of the string to the end of the string, in other words, the entire 3635 * string. 3636 * A line does not include the line terminator. 3637 * <p> 3638 * Then, the <i>minimum indentation</i> (min) is determined as follows: 3639 * <ul> 3640 * <li><p>For each non-blank line (as defined by {@link String#isBlank()}), 3641 * the leading {@linkplain Character#isWhitespace(int) white space} 3642 * characters are counted.</p> 3643 * </li> 3644 * <li><p>The leading {@linkplain Character#isWhitespace(int) white space} 3645 * characters on the last line are also counted even if 3646 * {@linkplain String#isBlank() blank}.</p> 3647 * </li> 3648 * </ul> 3649 * <p>The <i>min</i> value is the smallest of these counts. 3650 * <p> 3651 * For each {@linkplain String#isBlank() non-blank} line, <i>min</i> leading 3652 * {@linkplain Character#isWhitespace(int) white space} characters are 3653 * removed, and any trailing {@linkplain Character#isWhitespace(int) white 3654 * space} characters are removed. {@linkplain String#isBlank() Blank} lines 3655 * are replaced with the empty string. 3656 * 3657 * <p> 3658 * Finally, the lines are joined into a new string, using the LF character 3659 * {@code "\n"} (U+000A) to separate lines. 3660 * 3661 * @apiNote 3662 * This method's primary purpose is to shift a block of lines as far as 3663 * possible to the left, while preserving relative indentation. Lines 3664 * that were indented the least will thus have no leading 3665 * {@linkplain Character#isWhitespace(int) white space}. 3666 * The result will have the same number of line terminators as this string. 3667 * If this string ends with a line terminator then the result will end 3668 * with a line terminator. 3669 * 3670 * @implSpec 3671 * This method treats all {@linkplain Character#isWhitespace(int) white space} 3672 * characters as having equal width. As long as the indentation on every 3673 * line is consistently composed of the same character sequences, then the 3674 * result will be as described above. 3675 * 3676 * @return string with incidental indentation removed and line 3677 * terminators normalized 3678 * 3679 * @see String#lines() 3680 * @see String#isBlank() 3681 * @see String#indent(int) 3682 * @see Character#isWhitespace(int) 3683 * 3684 * @since 15 3685 * 3686 */ stripIndent()3687 public String stripIndent() { 3688 int length = length(); 3689 if (length == 0) { 3690 return ""; 3691 } 3692 char lastChar = charAt(length - 1); 3693 boolean optOut = lastChar == '\n' || lastChar == '\r'; 3694 List<String> lines = lines().toList(); 3695 final int outdent = optOut ? 0 : outdent(lines); 3696 return lines.stream() 3697 .map(line -> { 3698 int firstNonWhitespace = line.indexOfNonWhitespace(); 3699 int lastNonWhitespace = line.lastIndexOfNonWhitespace(); 3700 int incidentalWhitespace = Math.min(outdent, firstNonWhitespace); 3701 return firstNonWhitespace > lastNonWhitespace 3702 ? "" : line.substring(incidentalWhitespace, lastNonWhitespace); 3703 }) 3704 .collect(Collectors.joining("\n", "", optOut ? "\n" : "")); 3705 } 3706 outdent(List<String> lines)3707 private static int outdent(List<String> lines) { 3708 // Note: outdent is guaranteed to be zero or positive number. 3709 // If there isn't a non-blank line then the last must be blank 3710 int outdent = Integer.MAX_VALUE; 3711 for (String line : lines) { 3712 int leadingWhitespace = line.indexOfNonWhitespace(); 3713 if (leadingWhitespace != line.length()) { 3714 outdent = Integer.min(outdent, leadingWhitespace); 3715 } 3716 } 3717 String lastLine = lines.get(lines.size() - 1); 3718 if (lastLine.isBlank()) { 3719 outdent = Integer.min(outdent, lastLine.length()); 3720 } 3721 return outdent; 3722 } 3723 3724 /** 3725 * Returns a string whose value is this string, with escape sequences 3726 * translated as if in a string literal. 3727 * <p> 3728 * Escape sequences are translated as follows; 3729 * <table class="striped"> 3730 * <caption style="display:none">Translation</caption> 3731 * <thead> 3732 * <tr> 3733 * <th scope="col">Escape</th> 3734 * <th scope="col">Name</th> 3735 * <th scope="col">Translation</th> 3736 * </tr> 3737 * </thead> 3738 * <tbody> 3739 * <tr> 3740 * <th scope="row">{@code \u005Cb}</th> 3741 * <td>backspace</td> 3742 * <td>{@code U+0008}</td> 3743 * </tr> 3744 * <tr> 3745 * <th scope="row">{@code \u005Ct}</th> 3746 * <td>horizontal tab</td> 3747 * <td>{@code U+0009}</td> 3748 * </tr> 3749 * <tr> 3750 * <th scope="row">{@code \u005Cn}</th> 3751 * <td>line feed</td> 3752 * <td>{@code U+000A}</td> 3753 * </tr> 3754 * <tr> 3755 * <th scope="row">{@code \u005Cf}</th> 3756 * <td>form feed</td> 3757 * <td>{@code U+000C}</td> 3758 * </tr> 3759 * <tr> 3760 * <th scope="row">{@code \u005Cr}</th> 3761 * <td>carriage return</td> 3762 * <td>{@code U+000D}</td> 3763 * </tr> 3764 * <tr> 3765 * <th scope="row">{@code \u005Cs}</th> 3766 * <td>space</td> 3767 * <td>{@code U+0020}</td> 3768 * </tr> 3769 * <tr> 3770 * <th scope="row">{@code \u005C"}</th> 3771 * <td>double quote</td> 3772 * <td>{@code U+0022}</td> 3773 * </tr> 3774 * <tr> 3775 * <th scope="row">{@code \u005C'}</th> 3776 * <td>single quote</td> 3777 * <td>{@code U+0027}</td> 3778 * </tr> 3779 * <tr> 3780 * <th scope="row">{@code \u005C\u005C}</th> 3781 * <td>backslash</td> 3782 * <td>{@code U+005C}</td> 3783 * </tr> 3784 * <tr> 3785 * <th scope="row">{@code \u005C0 - \u005C377}</th> 3786 * <td>octal escape</td> 3787 * <td>code point equivalents</td> 3788 * </tr> 3789 * <tr> 3790 * <th scope="row">{@code \u005C<line-terminator>}</th> 3791 * <td>continuation</td> 3792 * <td>discard</td> 3793 * </tr> 3794 * </tbody> 3795 * </table> 3796 * 3797 * @implNote 3798 * This method does <em>not</em> translate Unicode escapes such as "{@code \u005cu2022}". 3799 * Unicode escapes are translated by the Java compiler when reading input characters and 3800 * are not part of the string literal specification. 3801 * 3802 * @throws IllegalArgumentException when an escape sequence is malformed. 3803 * 3804 * @return String with escape sequences translated. 3805 * 3806 * @jls 3.10.7 Escape Sequences 3807 * 3808 * @since 15 3809 */ translateEscapes()3810 public String translateEscapes() { 3811 if (isEmpty()) { 3812 return ""; 3813 } 3814 char[] chars = toCharArray(); 3815 int length = chars.length; 3816 int from = 0; 3817 int to = 0; 3818 while (from < length) { 3819 char ch = chars[from++]; 3820 if (ch == '\\') { 3821 ch = from < length ? chars[from++] : '\0'; 3822 switch (ch) { 3823 case 'b': 3824 ch = '\b'; 3825 break; 3826 case 'f': 3827 ch = '\f'; 3828 break; 3829 case 'n': 3830 ch = '\n'; 3831 break; 3832 case 'r': 3833 ch = '\r'; 3834 break; 3835 case 's': 3836 ch = ' '; 3837 break; 3838 case 't': 3839 ch = '\t'; 3840 break; 3841 case '\'': 3842 case '\"': 3843 case '\\': 3844 // as is 3845 break; 3846 case '0': case '1': case '2': case '3': 3847 case '4': case '5': case '6': case '7': 3848 int limit = Integer.min(from + (ch <= '3' ? 2 : 1), length); 3849 int code = ch - '0'; 3850 while (from < limit) { 3851 ch = chars[from]; 3852 if (ch < '0' || '7' < ch) { 3853 break; 3854 } 3855 from++; 3856 code = (code << 3) | (ch - '0'); 3857 } 3858 ch = (char)code; 3859 break; 3860 case '\n': 3861 continue; 3862 case '\r': 3863 if (from < length && chars[from] == '\n') { 3864 from++; 3865 } 3866 continue; 3867 default: { 3868 String msg = String.format( 3869 "Invalid escape sequence: \\%c \\\\u%04X", 3870 ch, (int)ch); 3871 throw new IllegalArgumentException(msg); 3872 } 3873 } 3874 } 3875 3876 chars[to++] = ch; 3877 } 3878 3879 return new String(chars, 0, to); 3880 } 3881 3882 /** 3883 * This method allows the application of a function to {@code this} 3884 * string. The function should expect a single String argument 3885 * and produce an {@code R} result. 3886 * <p> 3887 * Any exception thrown by {@code f.apply()} will be propagated to the 3888 * caller. 3889 * 3890 * @param f a function to apply 3891 * 3892 * @param <R> the type of the result 3893 * 3894 * @return the result of applying the function to this string 3895 * 3896 * @see java.util.function.Function 3897 * 3898 * @since 12 3899 */ 3900 public <R> R transform(Function<? super String, ? extends R> f) { 3901 return f.apply(this); 3902 } 3903 3904 /** 3905 * This object (which is already a string!) is itself returned. 3906 * 3907 * @return the string itself. 3908 */ 3909 public String toString() { 3910 return this; 3911 } 3912 3913 /** 3914 * Returns a stream of {@code int} zero-extending the {@code char} values 3915 * from this sequence. Any char which maps to a <a 3916 * href="{@docRoot}/java.base/java/lang/Character.html#unicode">surrogate code 3917 * point</a> is passed through uninterpreted. 3918 * 3919 * @return an IntStream of char values from this sequence 3920 * @since 9 3921 */ 3922 @Override 3923 public IntStream chars() { 3924 return StreamSupport.intStream( 3925 // BEGIN Android-removed: Delegate to StringUTF16. 3926 /* 3927 isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE) 3928 : new StringUTF16.CharsSpliterator(value, Spliterator.IMMUTABLE), 3929 */ 3930 new StringUTF16.CharsSpliteratorForString(this, Spliterator.IMMUTABLE), 3931 // END Android-removed: Delegate to StringUTF16. 3932 false); 3933 } 3934 3935 3936 /** 3937 * Returns a stream of code point values from this sequence. Any surrogate 3938 * pairs encountered in the sequence are combined as if by {@linkplain 3939 * Character#toCodePoint Character.toCodePoint} and the result is passed 3940 * to the stream. Any other code units, including ordinary BMP characters, 3941 * unpaired surrogates, and undefined code units, are zero-extended to 3942 * {@code int} values which are then passed to the stream. 3943 * 3944 * @return an IntStream of Unicode code points from this sequence 3945 * @since 9 3946 */ 3947 @Override 3948 public IntStream codePoints() { 3949 return StreamSupport.intStream( 3950 // BEGIN Android-removed: Delegate to StringUTF16. 3951 /* 3952 isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE) 3953 : new StringUTF16.CodePointsSpliterator(value, Spliterator.IMMUTABLE), 3954 */ 3955 new StringUTF16.CodePointsSpliteratorForString(this, Spliterator.IMMUTABLE), 3956 // END Android-removed: Delegate to StringUTF16. 3957 false); 3958 } 3959 3960 /** 3961 * Converts this string to a new character array. 3962 * 3963 * @return a newly allocated character array whose length is the length 3964 * of this string and whose contents are initialized to contain 3965 * the character sequence represented by this string. 3966 */ 3967 // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above). 3968 /* 3969 public char[] toCharArray() { 3970 return isLatin1() ? StringLatin1.toChars(value) 3971 : StringUTF16.toChars(value); 3972 } 3973 */ 3974 @FastNative 3975 public native char[] toCharArray(); 3976 // END Android-changed: Replace with implementation in runtime to access chars (see above). 3977 3978 3979 /** 3980 * Returns a formatted string using the specified format string and 3981 * arguments. 3982 * 3983 * <p> The locale always used is the one returned by {@link 3984 * java.util.Locale#getDefault(java.util.Locale.Category) 3985 * Locale.getDefault(Locale.Category)} with 3986 * {@link java.util.Locale.Category#FORMAT FORMAT} category specified. 3987 * 3988 * @param format 3989 * A <a href="../util/Formatter.html#syntax">format string</a> 3990 * 3991 * @param args 3992 * Arguments referenced by the format specifiers in the format 3993 * string. If there are more arguments than format specifiers, the 3994 * extra arguments are ignored. The number of arguments is 3995 * variable and may be zero. The maximum number of arguments is 3996 * limited by the maximum dimension of a Java array as defined by 3997 * <cite>The Java™ Virtual Machine Specification</cite>. 3998 * The behaviour on a 3999 * {@code null} argument depends on the <a 4000 * href="../util/Formatter.html#syntax">conversion</a>. 4001 * 4002 * @throws java.util.IllegalFormatException 4003 * If a format string contains an illegal syntax, a format 4004 * specifier that is incompatible with the given arguments, 4005 * insufficient arguments given the format string, or other 4006 * illegal conditions. For specification of all possible 4007 * formatting errors, see the <a 4008 * href="../util/Formatter.html#detail">Details</a> section of the 4009 * formatter class specification. 4010 * 4011 * @return A formatted string 4012 * 4013 * @see java.util.Formatter 4014 * @since 1.5 4015 */ 4016 public static String format(String format, Object... args) { 4017 return new Formatter().format(format, args).toString(); 4018 } 4019 4020 /** 4021 * Returns a formatted string using the specified locale, format string, 4022 * and arguments. 4023 * 4024 * @param l 4025 * The {@linkplain java.util.Locale locale} to apply during 4026 * formatting. If {@code l} is {@code null} then no localization 4027 * is applied. 4028 * 4029 * @param format 4030 * A <a href="../util/Formatter.html#syntax">format string</a> 4031 * 4032 * @param args 4033 * Arguments referenced by the format specifiers in the format 4034 * string. If there are more arguments than format specifiers, the 4035 * extra arguments are ignored. The number of arguments is 4036 * variable and may be zero. The maximum number of arguments is 4037 * limited by the maximum dimension of a Java array as defined by 4038 * <cite>The Java™ Virtual Machine Specification</cite>. 4039 * The behaviour on a 4040 * {@code null} argument depends on the 4041 * <a href="../util/Formatter.html#syntax">conversion</a>. 4042 * 4043 * @throws java.util.IllegalFormatException 4044 * If a format string contains an illegal syntax, a format 4045 * specifier that is incompatible with the given arguments, 4046 * insufficient arguments given the format string, or other 4047 * illegal conditions. For specification of all possible 4048 * formatting errors, see the <a 4049 * href="../util/Formatter.html#detail">Details</a> section of the 4050 * formatter class specification 4051 * 4052 * @return A formatted string 4053 * 4054 * @see java.util.Formatter 4055 * @since 1.5 4056 */ 4057 public static String format(Locale l, String format, Object... args) { 4058 return new Formatter(l).format(format, args).toString(); 4059 } 4060 4061 /** 4062 * Formats using this string as the format string, and the supplied 4063 * arguments. 4064 * 4065 * @implSpec This method is equivalent to {@code String.format(this, args)}. 4066 * 4067 * @param args 4068 * Arguments referenced by the format specifiers in this string. 4069 * 4070 * @return A formatted string 4071 * 4072 * @see java.lang.String#format(String,Object...) 4073 * @see java.util.Formatter 4074 * 4075 * @since 15 4076 * 4077 */ 4078 public String formatted(Object... args) { 4079 return new Formatter().format(this, args).toString(); 4080 } 4081 4082 /** 4083 * Returns the string representation of the {@code Object} argument. 4084 * 4085 * @param obj an {@code Object}. 4086 * @return if the argument is {@code null}, then a string equal to 4087 * {@code "null"}; otherwise, the value of 4088 * {@code obj.toString()} is returned. 4089 * @see java.lang.Object#toString() 4090 */ 4091 public static String valueOf(Object obj) { 4092 return (obj == null) ? "null" : obj.toString(); 4093 } 4094 4095 /** 4096 * Returns the string representation of the {@code char} array 4097 * argument. The contents of the character array are copied; subsequent 4098 * modification of the character array does not affect the returned 4099 * string. 4100 * 4101 * @param data the character array. 4102 * @return a {@code String} that contains the characters of the 4103 * character array. 4104 */ 4105 public static String valueOf(char data[]) { 4106 return new String(data); 4107 } 4108 4109 /** 4110 * Returns the string representation of a specific subarray of the 4111 * {@code char} array argument. 4112 * <p> 4113 * The {@code offset} argument is the index of the first 4114 * character of the subarray. The {@code count} argument 4115 * specifies the length of the subarray. The contents of the subarray 4116 * are copied; subsequent modification of the character array does not 4117 * affect the returned string. 4118 * 4119 * @param data the character array. 4120 * @param offset initial offset of the subarray. 4121 * @param count length of the subarray. 4122 * @return a {@code String} that contains the characters of the 4123 * specified subarray of the character array. 4124 * @exception IndexOutOfBoundsException if {@code offset} is 4125 * negative, or {@code count} is negative, or 4126 * {@code offset+count} is larger than 4127 * {@code data.length}. 4128 */ 4129 public static String valueOf(char data[], int offset, int count) { 4130 return new String(data, offset, count); 4131 } 4132 4133 /** 4134 * Equivalent to {@link #valueOf(char[], int, int)}. 4135 * 4136 * @param data the character array. 4137 * @param offset initial offset of the subarray. 4138 * @param count length of the subarray. 4139 * @return a {@code String} that contains the characters of the 4140 * specified subarray of the character array. 4141 * @exception IndexOutOfBoundsException if {@code offset} is 4142 * negative, or {@code count} is negative, or 4143 * {@code offset+count} is larger than 4144 * {@code data.length}. 4145 */ 4146 public static String copyValueOf(char data[], int offset, int count) { 4147 return new String(data, offset, count); 4148 } 4149 4150 /** 4151 * Equivalent to {@link #valueOf(char[])}. 4152 * 4153 * @param data the character array. 4154 * @return a {@code String} that contains the characters of the 4155 * character array. 4156 */ 4157 public static String copyValueOf(char data[]) { 4158 return new String(data); 4159 } 4160 4161 /** 4162 * Returns the string representation of the {@code boolean} argument. 4163 * 4164 * @param b a {@code boolean}. 4165 * @return if the argument is {@code true}, a string equal to 4166 * {@code "true"} is returned; otherwise, a string equal to 4167 * {@code "false"} is returned. 4168 */ 4169 public static String valueOf(boolean b) { 4170 return b ? "true" : "false"; 4171 } 4172 4173 /** 4174 * Returns the string representation of the {@code char} 4175 * argument. 4176 * 4177 * @param c a {@code char}. 4178 * @return a string of length {@code 1} containing 4179 * as its single character the argument {@code c}. 4180 */ 4181 public static String valueOf(char c) { 4182 // BEGIN Android-changed: Replace constructor call with call to StringFactory class. 4183 // There is currently no String(char[], boolean) on Android to call. http://b/79902155 4184 /* 4185 if (COMPACT_STRINGS && StringLatin1.canEncode(c)) { 4186 return new String(StringLatin1.toBytes(c), LATIN1); 4187 } 4188 return new String(StringUTF16.toBytes(c), UTF16); 4189 */ 4190 return StringFactory.newStringFromChars(0, 1, new char[] { c }); 4191 // END Android-changed: Replace constructor call with call to StringFactory class. 4192 } 4193 4194 /** 4195 * Returns the string representation of the {@code int} argument. 4196 * <p> 4197 * The representation is exactly the one returned by the 4198 * {@code Integer.toString} method of one argument. 4199 * 4200 * @param i an {@code int}. 4201 * @return a string representation of the {@code int} argument. 4202 * @see java.lang.Integer#toString(int, int) 4203 */ 4204 public static String valueOf(int i) { 4205 return Integer.toString(i); 4206 } 4207 4208 /** 4209 * Returns the string representation of the {@code long} argument. 4210 * <p> 4211 * The representation is exactly the one returned by the 4212 * {@code Long.toString} method of one argument. 4213 * 4214 * @param l a {@code long}. 4215 * @return a string representation of the {@code long} argument. 4216 * @see java.lang.Long#toString(long) 4217 */ 4218 public static String valueOf(long l) { 4219 return Long.toString(l); 4220 } 4221 4222 /** 4223 * Returns the string representation of the {@code float} argument. 4224 * <p> 4225 * The representation is exactly the one returned by the 4226 * {@code Float.toString} method of one argument. 4227 * 4228 * @param f a {@code float}. 4229 * @return a string representation of the {@code float} argument. 4230 * @see java.lang.Float#toString(float) 4231 */ 4232 public static String valueOf(float f) { 4233 return Float.toString(f); 4234 } 4235 4236 /** 4237 * Returns the string representation of the {@code double} argument. 4238 * <p> 4239 * The representation is exactly the one returned by the 4240 * {@code Double.toString} method of one argument. 4241 * 4242 * @param d a {@code double}. 4243 * @return a string representation of the {@code double} argument. 4244 * @see java.lang.Double#toString(double) 4245 */ 4246 public static String valueOf(double d) { 4247 return Double.toString(d); 4248 } 4249 4250 /** 4251 * Returns a canonical representation for the string object. 4252 * <p> 4253 * A pool of strings, initially empty, is maintained privately by the 4254 * class {@code String}. 4255 * <p> 4256 * When the intern method is invoked, if the pool already contains a 4257 * string equal to this {@code String} object as determined by 4258 * the {@link #equals(Object)} method, then the string from the pool is 4259 * returned. Otherwise, this {@code String} object is added to the 4260 * pool and a reference to this {@code String} object is returned. 4261 * <p> 4262 * It follows that for any two strings {@code s} and {@code t}, 4263 * {@code s.intern() == t.intern()} is {@code true} 4264 * if and only if {@code s.equals(t)} is {@code true}. 4265 * <p> 4266 * All literal strings and string-valued constant expressions are 4267 * interned. String literals are defined in section 3.10.5 of the 4268 * <cite>The Java™ Language Specification</cite>. 4269 * 4270 * @return a string that has the same contents as this string, but is 4271 * guaranteed to be from a pool of unique strings. 4272 * @jls 3.10.5 String Literals 4273 */ 4274 // Android-added: Annotate native method as @FastNative. 4275 @FastNative 4276 public native String intern(); 4277 4278 /** 4279 * Returns a string whose value is the concatenation of this 4280 * string repeated {@code count} times. 4281 * <p> 4282 * If this string is empty or count is zero then the empty 4283 * string is returned. 4284 * 4285 * @param count number of times to repeat 4286 * 4287 * @return A string composed of this string repeated 4288 * {@code count} times or the empty string if this 4289 * string is empty or count is zero 4290 * 4291 * @throws IllegalArgumentException if the {@code count} is 4292 * negative. 4293 * 4294 * @since 11 4295 */ 4296 public String repeat(int count) { 4297 if (count < 0) { 4298 throw new IllegalArgumentException("count is negative: " + count); 4299 } 4300 if (count == 1) { 4301 return this; 4302 } 4303 // Android-changed: Replace with implementation in runtime. 4304 // final int len = value.length; 4305 final int len = length(); 4306 if (len == 0 || count == 0) { 4307 return ""; 4308 } 4309 // BEGIN Android-changed: Replace with implementation in runtime. 4310 /* 4311 if (len == 1) { 4312 final byte[] single = new byte[count]; 4313 Arrays.fill(single, value[0]); 4314 return new String(single, coder); 4315 } 4316 */ 4317 // END Android-changed: Replace with implementation in runtime. 4318 if (Integer.MAX_VALUE / count < len) { 4319 throw new OutOfMemoryError("Repeating " + len + " bytes String " + count + 4320 " times will produce a String exceeding maximum size."); 4321 } 4322 // BEGIN Android-changed: Replace with implementation in runtime. 4323 /* 4324 final int limit = len * count; 4325 final byte[] multiple = new byte[limit]; 4326 System.arraycopy(value, 0, multiple, 0, len); 4327 int copied = len; 4328 for (; copied < limit - copied; copied <<= 1) { 4329 System.arraycopy(multiple, 0, multiple, copied, copied); 4330 } 4331 System.arraycopy(multiple, 0, multiple, copied, limit - copied); 4332 return new String(multiple, coder); 4333 */ 4334 // END Android-changed: Replace with implementation in runtime. 4335 return doRepeat(count); 4336 } 4337 4338 @FastNative 4339 private native String doRepeat(int count); 4340 4341 //////////////////////////////////////////////////////////////// 4342 4343 /** 4344 * Copy character bytes from this string into dst starting at dstBegin. 4345 * This method doesn't perform any range checking. 4346 * 4347 * Invoker guarantees: dst is in UTF16 (inflate itself for asb), if two 4348 * coders are different, and dst is big enough (range check) 4349 * 4350 * @param dstBegin the char index, not offset of byte[] 4351 * @param coder the coder of dst[] 4352 */ 4353 void getBytes(byte dst[], int dstBegin, byte coder) { 4354 // Android-changed: libcore doesn't store String as Latin1 or UTF16 byte[] field. 4355 /* 4356 if (coder() == coder) { 4357 System.arraycopy(value, 0, dst, dstBegin << coder, value.length); 4358 } else { // this.coder == LATIN && coder == UTF16 4359 StringLatin1.inflate(value, 0, dst, dstBegin, value.length); 4360 } 4361 */ 4362 // We do bound check here before the native calls, because the upstream implementation does 4363 // the bound check in System.arraycopy and StringLatin1.inflate or throws an exception. 4364 if (coder == UTF16) { 4365 int fromIndex = dstBegin << 1; 4366 checkBoundsOffCount(fromIndex, length() << 1, dst.length); 4367 fillBytesUTF16(dst, fromIndex); 4368 } else { 4369 if (coder() != LATIN1) { 4370 // Do not concat String in the error message. 4371 throw new StringIndexOutOfBoundsException("Expect Latin-1 coder."); 4372 } 4373 checkBoundsOffCount(dstBegin, length(), dst.length); 4374 fillBytesLatin1(dst, dstBegin); 4375 } 4376 } 4377 4378 // BEGIN Android-added: Implement fillBytes*() method natively. 4379 4380 /** 4381 * Fill the underlying characters into the byte buffer. No range check. 4382 * The caller should guarantee that dst is big enough for this operation. 4383 */ 4384 @FastNative 4385 private native void fillBytesLatin1(byte[] dst, int byteIndex); 4386 4387 /** 4388 * Fill the underlying characters into the byte buffer. No range check. 4389 * The caller should guarantee that dst is big enough for this operation. 4390 */ 4391 @FastNative 4392 private native void fillBytesUTF16(byte[] dst, int byteIndex); 4393 // END Android-added: Implement fillBytes*() method natively. 4394 4395 /* 4396 * Package private constructor which shares value array for speed. 4397 */ 4398 String(byte[] value, byte coder) { 4399 // BEGIN Android-changed: Implemented as compiler and runtime intrinsics. 4400 // this.value = value; 4401 // this.coder = coder; 4402 throw new UnsupportedOperationException("Use StringFactory instead."); 4403 // END Android-changed: Implemented as compiler and runtime intrinsics. 4404 } 4405 4406 /** 4407 * Android note: It returns UTF16 if the string has any 0x00 char. 4408 * See the difference between {@link StringLatin1#canEncode(int)} and 4409 * art::mirror::String::IsASCII(uint16_t) in string.h. 4410 */ 4411 byte coder() { 4412 // Android-changed: ART stores the flag in the count field. 4413 // return COMPACT_STRINGS ? coder : UTF16; 4414 // We assume that STRING_COMPRESSION_ENABLED is enabled here. 4415 // The flag has been true for 6+ years. 4416 return COMPACT_STRINGS ? ((byte) (count & 1)) : UTF16; 4417 } 4418 4419 /* 4420 * StringIndexOutOfBoundsException if {@code index} is 4421 * negative or greater than or equal to {@code length}. 4422 */ 4423 static void checkIndex(int index, int length) { 4424 if (index < 0 || index >= length) { 4425 throw new StringIndexOutOfBoundsException("index " + index + 4426 ",length " + length); 4427 } 4428 } 4429 4430 /* 4431 * StringIndexOutOfBoundsException if {@code offset} 4432 * is negative or greater than {@code length}. 4433 */ 4434 static void checkOffset(int offset, int length) { 4435 if (offset < 0 || offset > length) { 4436 throw new StringIndexOutOfBoundsException("offset " + offset + 4437 ",length " + length); 4438 } 4439 } 4440 4441 /* 4442 * Check {@code offset}, {@code count} against {@code 0} and {@code length} 4443 * bounds. 4444 * 4445 * @throws StringIndexOutOfBoundsException 4446 * If {@code offset} is negative, {@code count} is negative, 4447 * or {@code offset} is greater than {@code length - count} 4448 */ 4449 static void checkBoundsOffCount(int offset, int count, int length) { 4450 if (offset < 0 || count < 0 || offset > length - count) { 4451 throw new StringIndexOutOfBoundsException( 4452 "offset " + offset + ", count " + count + ", length " + length); 4453 } 4454 } 4455 4456 /* 4457 * Check {@code begin}, {@code end} against {@code 0} and {@code length} 4458 * bounds. 4459 * 4460 * @throws StringIndexOutOfBoundsException 4461 * If {@code begin} is negative, {@code begin} is greater than 4462 * {@code end}, or {@code end} is greater than {@code length}. 4463 */ 4464 static void checkBoundsBeginEnd(int begin, int end, int length) { 4465 if (begin < 0 || begin > end || end > length) { 4466 throw new StringIndexOutOfBoundsException( 4467 "begin " + begin + ", end " + end + ", length " + length); 4468 } 4469 } 4470 } 4471