1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.lang; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.UnsupportedEncodingException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.CharBuffer; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.charset.Charset; 255cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughesimport java.nio.charset.Charsets; 26ab73941feb7f8677174cc97722201437edcb1299Jesse Wilsonimport java.util.Arrays; 270510f0d8ce7c20b8f6022545a70e8b868805dc60Elliott Hughesimport java.util.Comparator; 280510f0d8ce7c20b8f6022545a70e8b868805dc60Elliott Hughesimport java.util.Formatter; 290510f0d8ce7c20b8f6022545a70e8b868805dc60Elliott Hughesimport java.util.Locale; 300510f0d8ce7c20b8f6022545a70e8b868805dc60Elliott Hughesimport java.util.regex.Pattern; 316186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 3418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * An immutable sequence of UTF-16 {@code char}s. 3518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * See {@link Character} for details about the relationship between {@code char} and 3618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Unicode code points. 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 38ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * <a name="backing_array"><h3>Backing Arrays</h3></a> 3918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * This class is implemented using a {@code char[]}. The length of the array may exceed 40ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * the length of the string. For example, the string "Hello" may be backed by 41ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with 42ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * offset 0 and length 5. 43ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * 4418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>Multiple strings can share the same {@code char[]} because strings are immutable. 45ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * The {@link #substring} method <strong>always</strong> returns a string that 46ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * shares the backing array of its source string. Generally this is an 4718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * optimization: fewer {@code char[]}s need to be allocated, and less copying 48ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * is necessary. But this can also lead to unwanted heap retention. Taking a 4918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * short substring of long string means that the long shared {@code char[]} won't be 50ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * garbage until both strings are garbage. This typically happens when parsing 51ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * small substrings out of a large input. To avoid this where necessary, call 52ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * {@code new String(longString.subString(...))}. The string copy constructor 53ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * always ensures that the backing array is no larger than necessary. 54ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see StringBuffer 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see StringBuilder 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Charset 58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.0 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 609de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughespublic final class String implements Serializable, Comparable<String>, CharSequence { 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -6849794470754667710L; 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final char REPLACEMENT_CHAR = (char) 0xfffd; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final class CaseInsensitiveComparator implements 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Comparator<String>, Serializable { 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 8575799808933029326L; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 7118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * See {@link java.lang.String#compareToIgnoreCase}. 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @exception ClassCastException 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if objects are not the correct type 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compare(String o1, String o2) { 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return o1.compareToIgnoreCase(o2); 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 8218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Compares strings using {@link #compareToIgnoreCase}. 8318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * This is not suitable for case-insensitive string comparison for all locales. 8418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Use a {@link java.text.Collator} instead. 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes private static final char[] ASCII; 89c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes static { 90c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes ASCII = new char[128]; 91c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes for (int i = 0; i < ASCII.length; ++i) { 92c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes ASCII[i] = (char) i; 93c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 94c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final char[] value; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final int offset; 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final int count; 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int hashCode; 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an empty string. 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String() { 108693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes value = EmptyArray.CHAR; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = 0; 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = 0; 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 114c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * Converts the byte array to a string using the system's 115c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * {@link java.nio.charset.Charset#defaultCharset default charset}. 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1170d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING") 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String(byte[] data) { 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(data, 0, data.length); 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Converts the byte array to a string, setting the high byte of every 12418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * {@code char} to the specified value. 125f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param data 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the byte array to convert to a string. 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param high 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the high byte to use. 130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 13144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null}. 13244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String(byte[] data, int high) { 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(data, high, 0, data.length); 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 140c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * Converts a subsequence of the byte array to a string using the system's 141c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * {@link java.nio.charset.Charset#defaultCharset default charset}. 142f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 143f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 14444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null}. 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 14644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}. 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 14844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(byte[] data, int offset, int byteCount) { 149bbe3e7f1f8c312fcfbd7af2ecbfa98c48f502c61Elliott Hughes this(data, offset, byteCount, Charset.defaultCharset()); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Converts the byte array to a string, setting the high byte of every 15418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * {@code char} to {@code high}. 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 15744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null}. 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 15944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length} 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @deprecated Use {@link #String(byte[], int, int)} instead. 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 16444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(byte[] data, int high, int offset, int byteCount) { 16544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if ((offset | byteCount) < 0 || byteCount > data.length - offset) { 16644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw failedBoundsCheck(data.length, offset, byteCount); 16744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes } 16844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.offset = 0; 16944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.value = new char[byteCount]; 17044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.count = byteCount; 17144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes high <<= 8; 17244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes for (int i = 0; i < count; i++) { 17344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes value[i] = (char) (high + (data[offset++] & 0xff)); 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 178c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * Converts the byte array to a string using the named charset. 179c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * 180c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * <p>The behavior when the bytes cannot be decoded by the named charset 181c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control. 182f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 18444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null}. 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 18644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}. 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnsupportedEncodingException 188c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * if the named charset is not supported. 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 19044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException { 19144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this(data, offset, byteCount, Charset.forNameUEE(charsetName)); 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 195c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * Converts the byte array to a string using the named charset. 196c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * 197c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * <p>The behavior when the bytes cannot be decoded by the named charset 198c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control. 199f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 200f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 20144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null}. 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnsupportedEncodingException 203c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * if {@code charsetName} is not supported. 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 205c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes public String(byte[] data, String charsetName) throws UnsupportedEncodingException { 2065cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes this(data, 0, data.length, Charset.forNameUEE(charsetName)); 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 210c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * Converts the byte array to a string using the given charset. 211c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * 212c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * <p>The behavior when the bytes cannot be decoded by the given charset 21318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * is to replace malformed input and unmappable code points with the charset's default 214c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control. 215f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 216b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes * @throws IndexOutOfBoundsException 21744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length} 218b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes * @throws NullPointerException 21944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null} 22044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * 221b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes * @since 1.6 222b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes */ 22344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(byte[] data, int offset, int byteCount, Charset charset) { 22444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if ((offset | byteCount) < 0 || byteCount > data.length - offset) { 22544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw failedBoundsCheck(data.length, offset, byteCount); 226b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes } 227c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 228c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and 229c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 'value' are final. 230c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes String canonicalCharsetName = charset.name(); 231c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if (canonicalCharsetName.equals("UTF-8")) { 232c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes byte[] d = data; 23344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes char[] v = new char[byteCount]; 234c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 23544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes int idx = offset; 23644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes int last = offset + byteCount; 23744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes int s = 0; 238c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughesouter: 239c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes while (idx < last) { 240c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes byte b0 = d[idx++]; 241c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if ((b0 & 0x80) == 0) { 242c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 0xxxxxxx 243c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Range: U-00000000 - U-0000007F 244c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int val = b0 & 0xff; 245c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = (char) val; 246c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) || 247c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) { 248c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int utfCount = 1; 249c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if ((b0 & 0xf0) == 0xe0) utfCount = 2; 250c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes else if ((b0 & 0xf8) == 0xf0) utfCount = 3; 251c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes else if ((b0 & 0xfc) == 0xf8) utfCount = 4; 252c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes else if ((b0 & 0xfe) == 0xfc) utfCount = 5; 253c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 254c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 110xxxxx (10xxxxxx)+ 255c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Range: U-00000080 - U-000007FF (count == 1) 256c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Range: U-00000800 - U-0000FFFF (count == 2) 257c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Range: U-00010000 - U-001FFFFF (count == 3) 258c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Range: U-00200000 - U-03FFFFFF (count == 4) 259c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Range: U-04000000 - U-7FFFFFFF (count == 5) 260c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 261c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if (idx + utfCount > last) { 262c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = REPLACEMENT_CHAR; 263a47599f6fc631436407e01ae94cc6dc3fc99e16eElliott Hughes continue; 264c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 265c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 266c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Extract usable bits from b0 267c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int val = b0 & (0x1f >> (utfCount - 1)); 268a47599f6fc631436407e01ae94cc6dc3fc99e16eElliott Hughes for (int i = 0; i < utfCount; ++i) { 269c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes byte b = d[idx++]; 270a47599f6fc631436407e01ae94cc6dc3fc99e16eElliott Hughes if ((b & 0xc0) != 0x80) { 271c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = REPLACEMENT_CHAR; 272c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes idx--; // Put the input char back 273c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes continue outer; 274c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 275c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Push new bits in from the right side 276c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes val <<= 6; 277c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes val |= b & 0x3f; 278c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 279c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 280c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Note: Java allows overlong char 281c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // specifications To disallow, check that val 282c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // is greater than or equal to the minimum 283c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // value for each count: 284c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 285c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // count min value 286c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // ----- ---------- 287c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 1 0x80 288c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 2 0x800 289c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 3 0x10000 290c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 4 0x200000 291c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // 5 0x4000000 292c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 293c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Allow surrogate values (0xD800 - 0xDFFF) to 294c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // be specified using 3-byte UTF values only 295c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) { 296c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = REPLACEMENT_CHAR; 297c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes continue; 298c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 299c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 300c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Reject chars greater than the Unicode maximum of U+10FFFF. 301c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if (val > 0x10FFFF) { 302c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = REPLACEMENT_CHAR; 303c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes continue; 304c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 305c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 306c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Encode chars from U+10000 up as surrogate pairs 307c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if (val < 0x10000) { 308c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = (char) val; 309c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else { 310c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int x = val & 0xffff; 311c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int u = (val >> 16) & 0x1f; 312c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int w = (u - 1) & 0xffff; 313c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int hi = 0xd800 | (w << 6) | (x >> 10); 314c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes int lo = 0xdc00 | (x & 0x3ff); 315c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = (char) hi; 316c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = (char) lo; 317c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 318c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else { 319c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff 320c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes v[s++] = REPLACEMENT_CHAR; 321c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 322c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 323c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes 32444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if (s == byteCount) { 325e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes // We guessed right, so we can use our temporary array as-is. 326e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes this.offset = 0; 327e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes this.value = v; 328e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes this.count = s; 329e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes } else { 330e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes // Our temporary array was too big, so reallocate and copy. 331e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes this.offset = 0; 332e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes this.value = new char[s]; 333e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes this.count = s; 334e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes System.arraycopy(v, 0, value, 0, s); 335e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes } 336c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else if (canonicalCharsetName.equals("ISO-8859-1")) { 337c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes this.offset = 0; 33844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.value = new char[byteCount]; 33944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.count = byteCount; 34044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes Charsets.isoLatin1BytesToChars(data, offset, byteCount, value); 341c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else if (canonicalCharsetName.equals("US-ASCII")) { 342c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes this.offset = 0; 34344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.value = new char[byteCount]; 34444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.count = byteCount; 34544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes Charsets.asciiBytesToChars(data, offset, byteCount, value); 346c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else { 34744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount)); 348c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes this.offset = 0; 349c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes this.count = cb.length(); 350c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes if (count > 0) { 351c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // We could use cb.array() directly, but that would mean we'd have to trust 352c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later, 353c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // which would break String's immutability guarantee. It would also tend to 354c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // mean that we'd be wasting memory because CharsetDecoder doesn't trim the 355c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes // array. So we copy. 356c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes this.value = new char[count]; 357c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes System.arraycopy(cb.array(), 0, value, 0, count); 358c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } else { 35944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.value = EmptyArray.CHAR; 360c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 361c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes } 362b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes } 363b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes 364b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes /** 365c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * Converts the byte array to a String using the given charset. 366f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 367c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * @throws NullPointerException if {@code data == null} 368b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes * @since 1.6 369b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes */ 370c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes public String(byte[] data, Charset charset) { 371c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes this(data, 0, data.length, charset); 372b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes } 373f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 374b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes /** 37518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Initializes this string to contain the given {@code char}s. 37618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Modifying the array after creating the string 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has no effect on the string. 378f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 37944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * @throws NullPointerException if {@code data == null} 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String(char[] data) { 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(data, 0, data.length); 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 38618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Initializes this string to contain the given {@code char}s. 38718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Modifying the array after creating the string 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has no effect on the string. 389f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 390f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 39144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code data == null}. 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 39344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code charCount < 0 || offset < 0 || offset + charCount > data.length} 39444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes */ 39544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(char[] data, int offset, int charCount) { 39644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if ((offset | charCount) < 0 || charCount > data.length - offset) { 39744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw failedBoundsCheck(data.length, offset, charCount); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 39944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.offset = 0; 40044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.value = new char[charCount]; 40144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.count = charCount; 40244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes System.arraycopy(data, offset, value, 0, count); 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 40644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * Internal version of the String(char[], int, int) constructor. 40718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Does not range check, null check, or copy the array. 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 40944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes String(int offset, int charCount, char[] chars) { 41044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.value = chars; 41144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.offset = offset; 41244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.count = charCount; 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 41618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Constructs a copy of the given string. 41718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The returned string's <a href="#backing_array">backing array</a> 418ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * is no larger than necessary. 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 420ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson public String(String toCopy) { 421ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson value = (toCopy.value.length == toCopy.count) 422ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson ? toCopy.value 423ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length()); 424ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson offset = 0; 425ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson count = value.length; 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a {@code String} from the contents of the specified 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code StringBuffer}. 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 43244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(StringBuffer stringBuffer) { 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = 0; 43444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes synchronized (stringBuffer) { 43544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes value = stringBuffer.shareValue(); 43644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes count = stringBuffer.length(); 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a {@code String} from the sub-array of Unicode code points. 442f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 443f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 44444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code codePoints == null}. 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any of the elements of {@code codePoints} are not valid 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unicode code points. 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset} or {@code count} are not within the bounds 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of {@code codePoints}. 451f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String(int[] codePoints, int offset, int count) { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (codePoints == null) { 45586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("codePoints == null"); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 45744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if ((offset | count) < 0 || count > codePoints.length - offset) { 45844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw failedBoundsCheck(codePoints.length, offset, count); 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.offset = 0; 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.value = new char[count * 2]; 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = offset + count; 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = 0; 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = offset; i < end; i++) { 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project c += Character.toChars(codePoints[i], this.value, c); 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.count = c; 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a {@code String} from the contents of the specified {@code 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * StringBuilder}. 473f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 474f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 47544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code stringBuilder == null}. 476f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 47844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public String(StringBuilder stringBuilder) { 47944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if (stringBuilder == null) { 48044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw new NullPointerException("stringBuilder == null"); 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.offset = 0; 48344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes this.count = stringBuilder.length(); 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.value = new char[this.count]; 48544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes stringBuilder.getChars(0, this.count, this.value, 0); 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 48918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the {@code char} at {@code index}. 49031891252fb2fd6ef2319341a25d1ae7fa1ed45ccElliott Hughes * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}. 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 49283bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom public char charAt(int index) { 49383bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom if (index < 0 || index >= count) { 49483bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom throw indexAndLength(index); 49583bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 49683bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return value[offset + index]; 49783bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 49844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes 49944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes private StringIndexOutOfBoundsException indexAndLength(int index) { 500363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein throw new StringIndexOutOfBoundsException(this, index); 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes private StringIndexOutOfBoundsException startEndAndLength(int start, int end) { 504363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein throw new StringIndexOutOfBoundsException(this, start, end - start); 50544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes } 50644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes 50744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) { 508363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein throw new StringIndexOutOfBoundsException(arrayLength, offset, count); 50944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes } 51044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes 51151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes /** 51251cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode 51351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes * case folds, but it's what the RI uses. 51451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes */ 51551cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes private char foldCase(char ch) { 516f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (ch < 128) { 517f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if ('A' <= ch && ch <= 'Z') { 518f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (char) (ch + ('a' - 'A')); 519f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 520f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return ch; 521f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 522f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return Character.toLowerCase(Character.toUpperCase(ch)); 523f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 524f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 52618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Compares this string to the given string. 52718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * 52818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>The strings are compared one {@code char} at a time. 52918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * In the discussion of the return value below, note that {@code char} does not 53018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * mean code point, though this should only be visible for surrogate pairs. 53118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * 53218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>If there is an index at which the two strings differ, the result is 53318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the difference between the two {@code char}s at the lowest such index. 53418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * If not, but the lengths of the strings differ, the result is the difference 53518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * between the two strings' lengths. 53618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * If the strings are the same length and every {@code char} is the same, the result is 0. 537f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 538f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 539f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code string} is {@code null}. 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 54108343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes public native int compareTo(String string); 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 54418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Compares this string to the given string, ignoring case differences. 54518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * 54618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>The strings are compared one {@code char} at a time. This is not suitable 54718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * for case-insensitive string comparison for all locales. 54818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Use a {@link java.text.Collator} instead. 54918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * 55018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>If there is an index at which the two strings differ, the result is 55118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the difference between the two {@code char}s at the lowest such index. 55218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * If not, but the lengths of the strings differ, the result is the difference 55318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * between the two strings' lengths. 55418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * If the strings are the same length and every {@code char} is the same, the result is 0. 555f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 556f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 557f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code string} is {@code null}. 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compareToIgnoreCase(String string) { 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int o1 = offset, o2 = string.offset, result; 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = offset + (count < string.count ? count : string.count); 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char c1, c2; 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] target = string.value; 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (o1 < end) { 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((c1 = value[o1++]) == (c2 = target[o2++])) { 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 56851cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes c1 = foldCase(c1); 56951cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes c2 = foldCase(c2); 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((result = c1 - c2) != 0) { 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return count - string.count; 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Concatenates this string and the specified string. 579f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param string 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the string to concatenate 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new string which is the concatenation of this string and the 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified string. 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String concat(String string) { 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (string.count > 0 && count > 0) { 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] buffer = new char[count + string.count]; 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(value, offset, buffer, 0, count); 589c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes System.arraycopy(string.value, string.offset, buffer, count, string.count); 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(0, buffer.length, buffer); 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return count == 0 ? string : this; 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 59618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Creates a new string by copying the given {@code char[]}. 59718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Modifying the array after creating the string has no 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * effect on the string. 599f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 600f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 601f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code data} is {@code null}. 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String copyValueOf(char[] data) { 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(data, 0, data.length); 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 60818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Creates a new string by copying the given subsequence of the given {@code char[]}. 60918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Modifying the array after creating the string has no 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * effect on the string. 61118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes 612f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 613f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code data} is {@code null}. 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code length < 0, start < 0} or {@code start + length > 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * data.length}. 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String copyValueOf(char[] data, int start, int length) { 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(data, start, length); 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares the specified string to this string to determine if the 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified string is a suffix. 625f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 626f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 627f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code suffix} is {@code null}. 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean endsWith(String suffix) { 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return regionMatches(count - suffix.count, suffix, 0, suffix.count); 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 63418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Compares the given object to this string and returns true if they are 63518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * equal. The object must be an instance of {@code String} with the same length, 63618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * where for every index, {@code charAt} on each string returns the same value. 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 63883bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom @Override public boolean equals(Object other) { 63983bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom if (other == this) { 64083bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return true; 64183bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 64283bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom if (other instanceof String) { 64383bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom String s = (String)other; 64483bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom int count = this.count; 64583bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom if (s.count != count) { 64683bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return false; 64783bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 64883bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom // TODO: we want to avoid many boundchecks in the loop below 64983bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom // for long Strings until we have array equality intrinsic. 65083bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom // Bad benchmarks just push .equals without first getting a 65183bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom // hashCode hit (unlike real world use in a Hashtable). Filter 65283bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom // out these long strings here. When we get the array equality 65383bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom // intrinsic then remove this use of hashCode. 65483bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom if (hashCode() != s.hashCode()) { 65583bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return false; 65683bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 65783bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom char[] value1 = value; 65883bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom int offset1 = offset; 65983bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom char[] value2 = s.value; 66083bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom int offset2 = s.offset; 66183bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom for (int end = offset1 + count; offset1 < end; ) { 66283bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom if (value1[offset1] != value2[offset2]) { 66383bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return false; 66483bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 66583bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom offset1++; 66683bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom offset2++; 66783bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 66883bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return true; 66983bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } else { 67083bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return false; 67183bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 67283bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 67518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Compares the given string to this string ignoring case. 676f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 67718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>The strings are compared one {@code char} at a time. This is not suitable 67818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * for case-insensitive string comparison for all locales. 67918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Use a {@link java.text.Collator} instead. 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6810d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ") 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equalsIgnoreCase(String string) { 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (string == this) { 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (string == null || count != string.count) { 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int o1 = offset, o2 = string.offset; 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = offset + count; 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] target = string.value; 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (o1 < end) { 69351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes char c1 = value[o1++]; 69451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes char c2 = target[o2++]; 69551cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes if (c1 != c2 && foldCase(c1) != foldCase(c2)) { 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 70318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Mangles a subsequence of this string into a byte array by stripping the high order bits from 70418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * each {@code char}. Use {@link #getBytes()} or {@link #getBytes(String)} instead. 705f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 70718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the start offset in this string. 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 70918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the end+1 offset in this string. 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param data 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the destination byte array. 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param index 71318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the start offset in the destination byte array. 714f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 715f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code data} is {@code null}. 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code start < 0}, {@code end > length()}, {@code index < 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 0} or {@code end - start > data.length - index}. 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)} 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void getBytes(int start, int end, byte[] data, int index) { 723b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (start >= 0 && start <= end && end <= count) { 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end += offset; 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = offset + start; i < end; i++) { 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project data[index++] = (byte) value[i]; 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 729f3b4a80f2ecd6dd1a0df51bb74a01042b11fad97Jesse Wilson } catch (ArrayIndexOutOfBoundsException ignored) { 730363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein throw failedBoundsCheck(data.length, index, end - start); 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7328bc9296d071a77994b6418df2edb120d6a9f70acElliott Hughes } else { 7338bc9296d071a77994b6418df2edb120d6a9f70acElliott Hughes throw startEndAndLength(start, end); 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 73818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new byte array containing the code points in this string encoded using the 739c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * system's {@link java.nio.charset.Charset#defaultCharset default charset}. 740f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 741c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * <p>The behavior when this string cannot be represented in the system's default charset 742c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android), 743c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * all strings can be encoded. 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 745c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes public byte[] getBytes() { 746d0628c5cb80e3c1270634c56a784329a4836b9aaElliott Hughes return getBytes(Charset.defaultCharset()); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 749c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes /** 75018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new byte array containing the code points of this string encoded using the 751c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * named charset. 752c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * 753c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * <p>The behavior when this string cannot be represented in the named charset 754c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control. 755c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * 756c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * @throws UnsupportedEncodingException if the charset is not supported 757c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes */ 758c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes public byte[] getBytes(String charsetName) throws UnsupportedEncodingException { 7595cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes return getBytes(Charset.forNameUEE(charsetName)); 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 76318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new byte array containing the code points of this string encoded using the 764b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes * given charset. 765f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 766c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * <p>The behavior when this string cannot be represented in the given charset 76718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * is to replace malformed input and unmappable code points with the charset's default 768c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control. 769f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 770b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes * @since 1.6 771b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes */ 772c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes public byte[] getBytes(Charset charset) { 773c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes String canonicalCharsetName = charset.name(); 774c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes if (canonicalCharsetName.equals("UTF-8")) { 7755cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes return Charsets.toUtf8Bytes(value, offset, count); 776c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes } else if (canonicalCharsetName.equals("ISO-8859-1")) { 7775cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes return Charsets.toIsoLatin1Bytes(value, offset, count); 778c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes } else if (canonicalCharsetName.equals("US-ASCII")) { 7795cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes return Charsets.toAsciiBytes(value, offset, count); 7809559e748729ef1deb6400f31d0407543cbff3566Elliott Hughes } else if (canonicalCharsetName.equals("UTF-16BE")) { 7819559e748729ef1deb6400f31d0407543cbff3566Elliott Hughes return Charsets.toBigEndianUtf16Bytes(value, offset, count); 782c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes } else { 783c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count); 784c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer()); 785c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes byte[] bytes = new byte[buffer.limit()]; 786c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes buffer.get(bytes); 787c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes return bytes; 788c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes } 789c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes } 790c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes 791b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes /** 79218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Copies the given subsequence of this string to the given array 79318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * starting at the given offset. 794f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 79618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the start offset in this string. 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param end 79818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the end+1 offset in this string. 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 80018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the destination array. 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param index 80218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the start offset in the destination array. 803f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 804f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code buffer} is {@code null}. 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code start < 0}, {@code end > length()}, {@code start > 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * end}, {@code index < 0}, {@code end - start > buffer.length - 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * index} 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void getChars(int start, int end, char[] buffer, int index) { 811b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (start >= 0 && start <= end && end <= count) { 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(value, start + offset, buffer, index, end - start); 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 81444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE. 815363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein throw startEndAndLength(start, end); 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 82018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * getChars without bounds checks, for use by other classes 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * within the java.lang package only. The caller is responsible for 822b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes * ensuring that start >= 0 && start <= end && end <= count. 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void _getChars(int start, int end, char[] buffer, int index) { 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(value, start + offset, buffer, index, end - start); 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82836f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes @Override public int hashCode() { 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hashCode; 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (hash == 0) { 83136f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes if (count == 0) { 83236f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes return 0; 83336f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes } 83436f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes final int end = count + offset; 83536f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes final char[] chars = value; 83636f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes for (int i = offset; i < end; ++i) { 83736f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes hash = 31*hash + chars[i]; 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project hashCode = hash; 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return hash; 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 84518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the first index of the given code point, or -1. 84618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The search starts at the beginning and moves towards 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end of this string. 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int indexOf(int c) { 8504a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep. 8514a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes if (c > 0xffff) { 8524a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return indexOfSupplementary(c, 0); 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 8544a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return fastIndexOf(c, 0); 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 85818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the next index of the given code point, or -1. The 85918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * search starts at the given offset and moves towards 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end of this string. 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int indexOf(int c, int start) { 8634a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes if (c > 0xffff) { 8644a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return indexOfSupplementary(c, start); 8654a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 8664a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return fastIndexOf(c, start); 8674a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 8684a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes 86908343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes private native int fastIndexOf(int c, int start); 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8714a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes private int indexOfSupplementary(int c, int start) { 8724a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes if (!Character.isSupplementaryCodePoint(c)) { 8734a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return -1; 8744a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 8754a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes char[] chars = Character.toChars(c); 8764a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes String needle = new String(0, chars.length, chars); 8774a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return indexOf(needle, start); 8784a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 8794a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 88118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the first index of the given string, or -1. The 88218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * search starts at the beginning and moves towards the end 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this string. 884f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 885f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 886f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code string} is {@code null}. 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int indexOf(String string) { 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int start = 0; 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int subCount = string.count; 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _count = count; 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subCount > 0) { 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subCount > _count) { 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] target = string.value; 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int subOffset = string.offset; 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char firstChar = target[subOffset]; 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = subOffset + subCount; 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i = indexOf(firstChar, start); 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == -1 || subCount + i > _count) { 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; // handles subCount > count || start >= count 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int o1 = offset + i, o2 = subOffset; 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] _value = value; 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (++o2 < end && _value[++o1] == target[o2]) { 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Intentionally empty 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o2 == end) { 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i; 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = i + 1; 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return start < _count ? start : _count; 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 92018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the next index of the given string in this string, or -1. The search 92118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * for the string starts at the given offset and moves towards the end 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this string. 923f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 924f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 925f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code subString} is {@code null}. 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int indexOf(String subString, int start) { 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start < 0) { 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = 0; 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int subCount = subString.count; 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _count = count; 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subCount > 0) { 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subCount + start > _count) { 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] target = subString.value; 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int subOffset = subString.offset; 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char firstChar = target[subOffset]; 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = subOffset + subCount; 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i = indexOf(firstChar, start); 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == -1 || subCount + i > _count) { 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; // handles subCount > count || start >= count 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int o1 = offset + i, o2 = subOffset; 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] _value = value; 948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (++o2 < end && _value[++o1] == target[o2]) { 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Intentionally empty 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o2 == end) { 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i; 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = i + 1; 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return start < _count ? start : _count; 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 96173ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * Returns an interned string equal to this string. The VM maintains an internal set of 96273ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * unique strings. All string literals found in loaded classes' 96373ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * constant pools are automatically interned. Manually-interned strings are only weakly 96473ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * referenced, so calling {@code intern} won't lead to unwanted retention. 965f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 96673ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * <p>Interning is typically used because it guarantees that for interned strings 96773ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to 96873ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * {@code a == b}. (This is not true of non-interned strings.) 96973ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * 97073ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * <p>Many applications find it simpler and more convenient to use an explicit 97173ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * {@link java.util.HashMap} to implement their own pools. 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 97373ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes public native String intern(); 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 97631df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes * Returns true if the length of this string is 0. 977f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 97831df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes * @since 1.6 97931df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes */ 98083bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom public boolean isEmpty() { 98183bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return count == 0; 98283bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 98331df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes 98431df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes /** 98573ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * Returns the last index of the code point {@code c}, or -1. 98618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The search starts at the end and moves towards the 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * beginning of this string. 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int lastIndexOf(int c) { 9904a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes if (c > 0xffff) { 9914a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return lastIndexOfSupplementary(c, Integer.MAX_VALUE); 9924a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _count = count; 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _offset = offset; 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] _value = value; 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = _offset + _count - 1; i >= _offset; --i) { 997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (_value[i] == c) { 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i - _offset; 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100573ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes * Returns the last index of the code point {@code c}, or -1. 100618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The search starts at offset {@code start} and moves towards 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the beginning of this string. 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int lastIndexOf(int c, int start) { 10104a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes if (c > 0xffff) { 10114a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return lastIndexOfSupplementary(c, start); 10124a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _count = count; 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _offset = offset; 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] _value = value; 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start >= 0) { 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start >= _count) { 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = _count - 1; 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = _offset + start; i >= _offset; --i) { 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (_value[i] == c) { 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i - _offset; 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10294a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes private int lastIndexOfSupplementary(int c, int start) { 10304a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes if (!Character.isSupplementaryCodePoint(c)) { 10314a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return -1; 10324a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 10334a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes char[] chars = Character.toChars(c); 10344a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes String needle = new String(0, chars.length, chars); 10354a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return lastIndexOf(needle, start); 10364a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes } 10374a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 103918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the index of the start of the last match for the given string in this string, or -1. 104018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The search for the string starts at the end and moves towards the beginning 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this string. 1042f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1043f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1044f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code string} is {@code null}. 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int lastIndexOf(String string) { 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Use count instead of count - 1 so lastIndexOf("") returns count 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return lastIndexOf(string, count); 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 105218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the index of the start of the previous match for the given string in this string, 105318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * or -1. 105418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The search for the string starts at the given index and moves towards the beginning 105518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * of this string. 1056f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1057f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1058f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code subString} is {@code null}. 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int lastIndexOf(String subString, int start) { 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int subCount = subString.count; 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subCount <= count && start >= 0) { 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subCount > 0) { 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start > count - subCount) { 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = count - subCount; 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // count and subCount are both >= 1 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] target = subString.value; 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int subOffset = subString.offset; 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char firstChar = target[subOffset]; 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = subOffset + subCount; 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i = lastIndexOf(firstChar, start); 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == -1) { 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int o1 = offset + i, o2 = subOffset; 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (++o2 < end && value[++o1] == target[o2]) { 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Intentionally empty 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o2 == end) { 1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i; 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start = i - 1; 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return start < count ? start : count; 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 109318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the number of {@code char}s in this string. If this string contains surrogate pairs, 109418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * this is not the same as the number of code points. 1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 109683bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom public int length() { 109783bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom return count; 109883bae0b56e9a6e21dee51f95406ee55ff5abc64dBrian Carlstrom } 1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 110118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns true if the given subsequence of the given string matches this string starting 110218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * at the given offset. 1103f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 110418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param thisStart the start offset in this string. 110518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param string the other string. 110618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param start the start offset in {@code string}. 110718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param length the number of {@code char}s to compare. 1108f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1109f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code string} is {@code null}. 1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 111151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes public boolean regionMatches(int thisStart, String string, int start, int length) { 1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (string == null) { 111386acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("string == null"); 1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start < 0 || string.count - start < length) { 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (thisStart < 0 || count - thisStart < length) { 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (length <= 0) { 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int o1 = offset + thisStart, o2 = string.offset + start; 1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] value1 = value; 1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] value2 = string.value; 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < length; ++i) { 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value1[o1 + i] != value2[o2 + i]) { 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 113618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns true if the given subsequence of the given string matches this string starting 113718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * at the given offset. 113818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * 113918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * <p>If ignoreCase is true, case is ignored during the comparison. 114018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The strings are compared one {@code char} at a time. This is not suitable 114118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * for case-insensitive string comparison for all locales. 114218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Use a {@link java.text.Collator} instead. 1143f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ignoreCase 114518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * specifies if case should be ignored (use {@link java.text.Collator} instead for 114618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * non-ASCII case insensitivity). 114718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param thisStart the start offset in this string. 114818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param string the other string. 114918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param start the start offset in {@code string}. 115018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param length the number of {@code char}s to compare. 1151f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1152f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code string} is {@code null}. 1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 115451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) { 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!ignoreCase) { 1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return regionMatches(thisStart, string, start, length); 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115851cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes if (string == null) { 115951cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes throw new NullPointerException("string == null"); 116051cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes } 116151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes if (thisStart < 0 || length > count - thisStart) { 116251cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes return false; 116351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes } 116451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes if (start < 0 || length > string.count - start) { 116551cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes return false; 116651cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes } 116751cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes thisStart += offset; 116851cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes start += string.offset; 116951cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes int end = thisStart + length; 117051cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes char[] target = string.value; 117151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes while (thisStart < end) { 117251cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes char c1 = value[thisStart++]; 117351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes char c2 = target[start++]; 117451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes if (c1 != c2 && foldCase(c1) != foldCase(c2)) { 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117851cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes return true; 1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1182c40cfbbe48b79682392aa861211764f316f05587Elliott Hughes * Returns a copy of this string after replacing occurrences of the given {@code char} with another. 1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String replace(char oldChar, char newChar) { 1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] buffer = value; 1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _offset = offset; 1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _count = count; 1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int idx = _offset; 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int last = _offset + _count; 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean copied = false; 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (idx < last) { 1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buffer[idx] == oldChar) { 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!copied) { 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] newBuffer = new char[_count]; 1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(buffer, _offset, newBuffer, 0, _count); 1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer = newBuffer; 1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project idx -= _offset; 1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project last -= _offset; 1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project copied = true; 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer[idx] = newChar; 1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project idx++; 1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return copied ? new String(0, count, buffer) : this; 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1209f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 121118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a copy of this string after replacing occurrences of {@code target} replaced 121218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * with {@code replacement}. The string is processed from the beginning to the 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * end. 1214f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1215f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1216f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code target} or {@code replacement} is {@code null}. 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String replace(CharSequence target, CharSequence replacement) { 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (target == null) { 1220870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes throw new NullPointerException("target == null"); 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (replacement == null) { 1223870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes throw new NullPointerException("replacement == null"); 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1226870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes String targetString = target.toString(); 1227870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes int matchStart = indexOf(targetString, 0); 1228870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes if (matchStart == -1) { 1229870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes // If there's nothing to replace, return the original string untouched. 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 1231870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes } 1232870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes 1233870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes String replacementString = replacement.toString(); 1234870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes 123518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes // The empty target matches at the start and end and between each char. 1236870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes int targetLength = targetString.length(); 1237870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes if (targetLength == 0) { 123818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes // The result contains the original 'count' chars, a copy of the 123918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes // replacement string before every one of those chars, and a final 12405fb22c375c55a9575cfb2e0b651c744e98fb6aa6Elliott Hughes // copy of the replacement string at the end. 12415fb22c375c55a9575cfb2e0b651c744e98fb6aa6Elliott Hughes int resultLength = count + (count + 1) * replacementString.length(); 1242870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes StringBuilder result = new StringBuilder(resultLength); 1243870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes result.append(replacementString); 12445fb22c375c55a9575cfb2e0b651c744e98fb6aa6Elliott Hughes int end = offset + count; 12455fb22c375c55a9575cfb2e0b651c744e98fb6aa6Elliott Hughes for (int i = offset; i != end; ++i) { 1246870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes result.append(value[i]); 1247870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes result.append(replacementString); 1248870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes } 1249870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes return result.toString(); 1250870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes } 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1252870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes StringBuilder result = new StringBuilder(count); 1253870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes int searchStart = 0; 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 125518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes // Copy chars before the match... 1256870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes result.append(value, offset + searchStart, matchStart - searchStart); 1257870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes // Insert the replacement... 1258870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes result.append(replacementString); 1259870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes // And skip over the match... 1260870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes searchStart = matchStart + targetLength; 1261870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes } while ((matchStart = indexOf(targetString, searchStart)) != -1); 1262870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes // Copy any trailing chars... 1263870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes result.append(value, offset + searchStart, count - searchStart); 1264870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes return result.toString(); 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares the specified string to this string to determine if the 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified string is a prefix. 1270f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param prefix 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the string to look for. 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the specified string is a prefix of this string, 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise 1275f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1276f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code prefix} is {@code null}. 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean startsWith(String prefix) { 1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return startsWith(prefix, 0); 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares the specified string to this string, starting at the specified 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * offset, to determine if the specified string is a prefix. 1285f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param prefix 1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the string to look for. 1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param start 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the starting offset. 1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the specified string occurs in this string at the 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified offset, {@code false} otherwise. 1292f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1293f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code prefix} is {@code null}. 1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean startsWith(String prefix, int start) { 1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return regionMatches(start, prefix, 0, prefix.count); 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 130018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a string containing a suffix of this string starting at {@code start}. 130118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The returned string shares this string's <a href="#backing_array">backing array</a>. 1302f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code start < 0} or {@code start > length()}. 1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String substring(int start) { 1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start == 0) { 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1310b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (start >= 0 && start <= count) { 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(offset + start, count - start, value); 1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1313363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein throw indexAndLength(start); 1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 131718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a string containing the given subsequence of this string. 131818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * The returned string shares this string's <a href="#backing_array">backing array</a>. 1319f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 132018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param start the start offset. 132118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * @param end the end+1 offset. 1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 132318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * if {@code start < 0}, {@code start > end} or {@code end > length()}. 1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String substring(int start, int end) { 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start == 0 && end == count) { 1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Fast range check. 1330b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (start >= 0 && start <= end && end <= count) { 1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(offset + start, end - start, value); 1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw startEndAndLength(start, end); 1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 133718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new {@code char} array containing a copy of the {@code char}s in this string. 133818faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * This is expensive and rarely useful. If you just want to iterate over the {@code char}s in 1339cc9d315b9aefbbe677b34b017eeae032521f5447Elliott Hughes * the string, use {@link #charAt} instead. 1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public char[] toCharArray() { 1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] buffer = new char[count]; 1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(value, offset, buffer, 0, count); 1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buffer; 1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1348a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * Converts this string to lower case, using the rules of the user's default locale. 13493106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 13503106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * 1351a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * @return a new lower case string, or {@code this} if it's already all lower case. 1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toLowerCase() { 135496b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count); 1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1358a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * Converts this string to lower case, using the rules of {@code locale}. 13599de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * 13609de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include 136196b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in 13629de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get 136396b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes * correct case mapping of Greek characters: any locale will do. 13649de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * 13659de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a> 136696b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes * for full details of context- and language-specific special cases. 13679de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * 1368a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * @return a new lower case string, or {@code this} if it's already all lower case. 1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toLowerCase(Locale locale) { 137196b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes return CaseMapper.toLowerCase(locale, this, value, offset, count); 1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this string. 1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1383a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * Converts this this string to upper case, using the rules of the user's default locale. 13843106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 13853106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * 1386a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * @return a new upper case string, or {@code this} if it's already all upper case. 1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toUpperCase() { 13899de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count); 1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1393a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * Converts this this string to upper case, using the rules of {@code locale}. 1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 13959de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include 13969de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in 13979de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get 13989de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * correct case mapping of Greek characters: any locale will do. 1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 14009de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a> 14019de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * for full details of context- and language-specific special cases. 14029de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes * 1403a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * @return a new upper case string, or {@code this} if it's already all upper case. 1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toUpperCase(Locale locale) { 14069de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes return CaseMapper.toUpperCase(locale, this, value, offset, count); 1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 141018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a string with no code points <code><= \\u0020</code> at 141118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * the beginning or end. 1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String trim() { 1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int start = offset, last = offset + count - 1; 1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = last; 1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while ((start <= end) && (value[start] <= ' ')) { 1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project start++; 1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while ((end >= start) && (value[end] <= ' ')) { 1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end--; 1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (start == offset && end == last) { 1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(start, end - start + 1, value); 1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 142918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new string containing the same {@code char}s as the given 143018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * array. Modifying the array after creating the string has no 1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * effect on the string. 1432f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1433f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1434f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code data} is {@code null}. 1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(char[] data) { 1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(data, 0, data.length); 1438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 144118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new string containing the same {@code char}s as the given 144218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * subset of the given array. Modifying the array after creating the string has no 1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * effect on the string. 1444f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 144618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * if {@code length < 0}, {@code start < 0} or {@code start + length > data.length} 1447f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 1448f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code data} is {@code null}. 1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(char[] data, int start, int length) { 1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new String(data, start, length); 1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 145518faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns a new string of just the given {@code char}. 1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(char value) { 1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String s; 1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value < 128) { 1460c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes s = new String(value, 1, ASCII); 1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = new String(0, 1, new char[] { value }); 1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.hashCode = value; 1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return s; 1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 146918faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the string representation of the given double. 1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(double value) { 1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Double.toString(value); 1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 147618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the string representation of the given float. 1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(float value) { 1479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Float.toString(value); 1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 148318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the string representation of the given int. 1484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(int value) { 1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.toString(value); 1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 149018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns the string representation of the given long. 1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(long value) { 1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Long.toString(value); 1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Converts the specified object to its string representation. If the object 1498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is null return the string {@code "null"}, otherwise use {@code 1499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * toString()} to get the string representation. 1500f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 1502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object. 1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the object converted to a string, or the string {@code "null"}. 1504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(Object value) { 15069de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes return value != null ? value.toString() : "null"; 1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Converts the specified boolean to its string representation. When the 1511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * boolean is {@code true} return {@code "true"}, otherwise return {@code 1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "false"}. 1513f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 1515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the boolean. 1516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the boolean converted to a string. 1517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String valueOf(boolean value) { 15199de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes return value ? "true" : "false"; 1520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 152318faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns true if the {@code char}s in the given {@code StringBuffer} are the same 152418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * as those in this string. 1525f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1526f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws NullPointerException 152718faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * if {@code sb} is {@code null}. 1528f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 153018faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes public boolean contentEquals(StringBuffer sb) { 153118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes synchronized (sb) { 153218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes int size = sb.length(); 1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (count != size) { 1534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153618faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes return regionMatches(0, new String(0, size, sb.getValue()), 0, size); 1537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 154118faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns true if the {@code char}s in the given {@code CharSequence} are the same 154218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * as those in this string. 1543f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1544f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contentEquals(CharSequence cs) { 1547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cs == null) { 154886acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("cs == null"); 1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int len = cs.length(); 1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (len != count) { 1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (len == 0 && count == 0) { 1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; // since both are empty strings 1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return regionMatches(0, cs.toString(), 0, len); 1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 15655f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * Tests whether this string matches the given {@code regularExpression}. This method returns 15665f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * true only if the regular expression matches the <i>entire</i> input string. A common mistake is 15675f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * to assume that this method behaves like {@link #contains}; if you want to match anywhere 15685f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * within the input string, you need to add {@code .*} to the beginning and end of your 15695f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * regular expression. See {@link Pattern#matches}. 1570f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 15715f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * <p>If the same regular expression is to be used for multiple operations, it may be more 15725f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * efficient to reuse a compiled {@code Pattern}. 1573f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PatternSyntaxException 1575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the syntax of the supplied regular expression is not 1576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid. 15775f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * @throws NullPointerException if {@code regularExpression == null} 1578f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 15805f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes public boolean matches(String regularExpression) { 15815f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes return Pattern.matches(regularExpression, this); 1582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 15855f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * Replaces all matches for {@code regularExpression} within this string with the given 15865f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * {@code replacement}. 15875f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * See {@link Pattern} for regular expression syntax. 1588f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 15895f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * <p>If the same regular expression is to be used for multiple operations, it may be more 15905f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * efficient to reuse a compiled {@code Pattern}. 1591f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PatternSyntaxException 1593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the syntax of the supplied regular expression is not 1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid. 15955f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * @throws NullPointerException if {@code regularExpression == null} 1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Pattern 1597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 15995f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes public String replaceAll(String regularExpression, String replacement) { 16005f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement); 1601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 16045f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * Replaces the first match for {@code regularExpression} within this string with the given 16055f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * {@code replacement}. 16065f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * See {@link Pattern} for regular expression syntax. 1607f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16085f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * <p>If the same regular expression is to be used for multiple operations, it may be more 16095f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * efficient to reuse a compiled {@code Pattern}. 1610f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PatternSyntaxException 1612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the syntax of the supplied regular expression is not 1613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid. 16145f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * @throws NullPointerException if {@code regularExpression == null} 1615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Pattern 1616f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16185f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes public String replaceFirst(String regularExpression, String replacement) { 16195f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement); 1620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 16235f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * Splits this string using the supplied {@code regularExpression}. 16245f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * Equivalent to {@code split(regularExpression, 0)}. 16255f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}. 16265f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * See {@link Pattern} for regular expression syntax. 1627f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16285f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * <p>If the same regular expression is to be used for multiple operations, it may be more 16295f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * efficient to reuse a compiled {@code Pattern}. 1630f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16315f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * @throws NullPointerException if {@code regularExpression == null} 1632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PatternSyntaxException 1633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the syntax of the supplied regular expression is not 1634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid. 1635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Pattern 1636f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16385f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes public String[] split(String regularExpression) { 16395f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes return split(regularExpression, 0); 1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 16435f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * Splits this string using the supplied {@code regularExpression}. 16445f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}. 16455f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * See {@link Pattern} for regular expression syntax. 1646f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16475f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * <p>If the same regular expression is to be used for multiple operations, it may be more 16485f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * efficient to reuse a compiled {@code Pattern}. 1649f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16505f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes * @throws NullPointerException if {@code regularExpression == null} 1651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PatternSyntaxException 1652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the syntax of the supplied regular expression is not 1653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid. 1654f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16565f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes public String[] split(String regularExpression, int limit) { 16575f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit); 16585f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes return result != null ? result : Pattern.compile(regularExpression).split(this, limit); 1659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 166218faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Equivalent to {@link #substring(int, int)} but needed to implement {@code CharSequence}. 1663f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 1665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code start < 0}, {@code end < 0}, {@code start > end} or 1666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code end > length()}. 1667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.CharSequence#subSequence(int, int) 1668f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.4 1669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public CharSequence subSequence(int start, int end) { 1671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return substring(start, end); 1672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 16754a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes * Returns the Unicode code point at the given {@code index}. 1676f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16774a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()} 1678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Character#codePointAt(char[], int, int) 1679f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int codePointAt(int index) { 1682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index < 0 || index >= count) { 168344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw indexAndLength(index); 1684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 16854a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return Character.codePointAt(value, offset + index, offset + count); 1686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 16894a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes * Returns the Unicode code point that precedes the given {@code index}. 1690f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 16914a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()} 1692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Character#codePointBefore(char[], int, int) 1693f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int codePointBefore(int index) { 1696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index < 1 || index > count) { 169744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw indexAndLength(index); 1698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 16994a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes return Character.codePointBefore(value, offset + index, offset); 1700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 170344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * Calculates the number of Unicode code points between {@code start} 170444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * and {@code end}. 1705f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 170644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * @param start 1707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the inclusive beginning index of the subsequence. 170844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * @param end 1709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the exclusive end index of the subsequence. 1710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of Unicode code points in the subsequence. 1711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 171244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes * if {@code start < 0 || end > length() || start > end} 1713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Character#codePointCount(CharSequence, int, int) 1714f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 171644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes public int codePointCount(int start, int end) { 171744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes if (start < 0 || end > count || start > end) { 171844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes throw startEndAndLength(start, end); 1719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 172044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes return Character.codePointCount(value, offset + start, end - start); 1721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 172418faff22684ebf763de4f49abc19fb8af7ef83daElliott Hughes * Returns true if this string contains the {@code chars}s from the given {@code CharSequence}. 1725f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1726f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contains(CharSequence cs) { 1729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cs == null) { 173086acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("cs == null"); 1731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return indexOf(cs.toString()) >= 0; 1733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the index within this object that is offset from {@code index} by 1737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code codePointOffset} code points. 1738f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param index 1740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the index within this object to calculate the offset from. 1741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param codePointOffset 1742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of code points to count. 1743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the index within this object that is the offset. 1744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 1745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code index} is negative or greater than {@code length()} 1746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * or if there aren't enough code points before or after {@code 1747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * index} to match {@code codePointOffset}. 1748f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int offsetByCodePoints(int index, int codePointOffset) { 1751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int s = index + offset; 17524a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset); 1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return r - offset; 1754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1757438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes * Returns a localized formatted string, using the supplied format and arguments, 1758438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes * using the user's default locale. 1759f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 17603106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * <p>If you're formatting a string other than for human 17613dd153c6795866734d66e6b5f69c40edae698f6dElliott Hughes * consumption, you should use the {@code format(Locale, String, Object...)} 17623106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * overload and supply {@code Locale.US}. See 17633106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 1764f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 17653106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * @param format the format string (see {@link java.util.Formatter#format}) 1766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param args 17673106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * the list of arguments passed to the formatter. If there are 17683106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * more arguments than required by {@code format}, 17693106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * additional arguments are ignored. 1770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the formatted string. 17713106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * @throws NullPointerException if {@code format == null} 1772f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws java.util.IllegalFormatException 1773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the format is invalid. 1774f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String format(String format, Object... args) { 1777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return format(Locale.getDefault(), format, args); 1778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a formatted string, using the supplied format and arguments, 17823dd153c6795866734d66e6b5f69c40edae698f6dElliott Hughes * localized to the given locale. 1783f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 17843106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * @param locale 1785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the locale to apply; {@code null} value means no localization. 17863106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * @param format the format string (see {@link java.util.Formatter#format}) 1787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param args 17883106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * the list of arguments passed to the formatter. If there are 17893106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * more arguments than required by {@code format}, 17903106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * additional arguments are ignored. 1791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the formatted string. 17923106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * @throws NullPointerException if {@code format == null} 1793f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @throws java.util.IllegalFormatException 1794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the format is invalid. 1795f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.5 1796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17973106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes public static String format(Locale locale, String format, Object... args) { 1798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (format == null) { 179986acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("format == null"); 1800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 18013106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes int bufferSize = format.length() + (args == null ? 0 : args.length * 10); 18023106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes Formatter f = new Formatter(new StringBuilder(bufferSize), locale); 1803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return f.format(format, args).toString(); 1804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An implementation of a String.indexOf that is supposed to perform 1808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * substantially better than the default algorithm if the "needle" (the 1809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * subString being searched for) is a constant string. 1810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 181196b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes * For example, a JIT, upon encountering a call to String.indexOf(String), 1812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * where the needle is a constant string, may compute the values cache, md2 1813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and lastChar, and change the call to the following method. 1814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 18150d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD") 1816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unused") 1817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static int indexOf(String haystackString, String needleString, 1818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int cache, int md2, char lastChar) { 1819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] haystack = haystackString.value; 1820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int haystackOffset = haystackString.offset; 1821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int haystackLength = haystackString.count; 1822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] needle = needleString.value; 1823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int needleOffset = needleString.offset; 1824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int needleLength = needleString.count; 1825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int needleLengthMinus1 = needleLength - 1; 1826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int haystackEnd = haystackOffset + haystackLength; 1827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) { 1828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastChar == haystack[i]) { 1829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = 0; j < needleLengthMinus1; ++j) { 1830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (needle[j + needleOffset] != haystack[i + j 1831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project - needleLengthMinus1]) { 1832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int skip = 1; 1833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((cache & (1 << haystack[i])) == 0) { 1834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project skip += j; 1835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project i += Math.max(md2, skip); 1837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue outer_loop; 1838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return i - needleLengthMinus1 - haystackOffset; 1841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((cache & (1 << haystack[i])) == 0) { 1844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project i += needleLengthMinus1; 1845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project i++; 1847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 1849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1851