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