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/**
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An immutable sequence of characters/code units ({@code char}s). A
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code String} is represented by array of UTF-16 values, such that
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unicode supplementary characters (code points) are stored/encoded as
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * surrogate pairs via Unicode code units ({@code char}).
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
39ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * <a name="backing_array"><h3>Backing Arrays</h3></a>
40ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * This class is implemented using a char[]. The length of the array may exceed
41ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * the length of the string. For example, the string "Hello" may be backed by
42ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
43ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * offset 0 and length 5.
44ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson *
45ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * <p>Multiple strings can share the same char[] because strings are immutable.
46ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * The {@link #substring} method <strong>always</strong> returns a string that
47ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * shares the backing array of its source string. Generally this is an
48ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * optimization: fewer character arrays need to be allocated, and less copying
49ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * is necessary. But this can also lead to unwanted heap retention. Taking a
50ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * short substring of long string means that the long shared char[] won't be
51ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * garbage until both strings are garbage. This typically happens when parsing
52ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * small substrings out of a large input. To avoid this where necessary, call
53ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * {@code new String(longString.subString(...))}. The string copy constructor
54ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson * always ensures that the backing array is no larger than necessary.
55ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson *
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see StringBuffer
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see StringBuilder
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Charset
59f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.0
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
619de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughespublic final class String implements Serializable, Comparable<String>, CharSequence {
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -6849794470754667710L;
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final char REPLACEMENT_CHAR = (char) 0xfffd;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * CaseInsensitiveComparator compares Strings ignoring the case of the
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * characters.
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final class CaseInsensitiveComparator implements
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Comparator<String>, Serializable {
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private static final long serialVersionUID = 8575799808933029326L;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Compare the two objects to determine the relative ordering.
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param o1
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            an Object to compare
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param o2
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            an Object to compare
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return an int < 0 if object1 is less than object2, 0 if they are
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         equal, and > 0 if object1 is greater
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @exception ClassCastException
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *                if objects are not the correct type
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int compare(String o1, String o2) {
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return o1.compareToIgnoreCase(o2);
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A comparator ignoring the case of the characters.
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
98c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    private static final char[] ASCII;
99c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    static {
100c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        ASCII = new char[128];
101c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        for (int i = 0; i < ASCII.length; ++i) {
102c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            ASCII[i] = (char) i;
103c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        }
104c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    }
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final char[] value;
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final int offset;
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final int count;
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int hashCode;
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates an empty string.
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String() {
118693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes        value = EmptyArray.CHAR;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        offset = 0;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        count = 0;
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
123a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    /*
124a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson     * Private constructor used for JIT optimization.
125a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson     */
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unused")
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String(String s, char c) {
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        offset = 0;
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value = new char[s.count + 1];
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        count = s.count + 1;
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(s.value, s.offset, value, 0, s.count);
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value[s.count] = c;
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
136c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Converts the byte array to a string using the system's
137c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * {@link java.nio.charset.Charset#defaultCharset default charset}.
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1390d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes    @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING")
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String(byte[] data) {
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(data, 0, data.length);
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the byte array to a string, setting the high byte of every
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * character to the specified value.
147f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param data
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte array to convert to a string.
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param high
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the high byte to use.
152f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
15344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}.
15444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead.
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String(byte[] data, int high) {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(data, high, 0, data.length);
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
162c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Converts a subsequence of the byte array to a string using the system's
163c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * {@link java.nio.charset.Charset#defaultCharset default charset}.
164f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
165f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
16644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}.
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
16844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
17044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(byte[] data, int offset, int byteCount) {
171bbe3e7f1f8c312fcfbd7af2ecbfa98c48f502c61Elliott Hughes        this(data, offset, byteCount, Charset.defaultCharset());
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the byte array to a string, setting the high byte of every
17644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * character to {@code high}.
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
178f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
17944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}.
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
18144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@link #String(byte[], int, int)} instead.
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
18644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(byte[] data, int high, int offset, int byteCount) {
18744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
18844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw failedBoundsCheck(data.length, offset, byteCount);
18944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        }
19044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.offset = 0;
19144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.value = new char[byteCount];
19244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.count = byteCount;
19344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        high <<= 8;
19444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        for (int i = 0; i < count; i++) {
19544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            value[i] = (char) (high + (data[offset++] & 0xff));
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
200c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Converts the byte array to a string using the named charset.
201c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *
202c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * <p>The behavior when the bytes cannot be decoded by the named charset
203c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
204f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
205f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
20644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}.
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
20844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnsupportedEncodingException
210c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *             if the named charset is not supported.
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
21244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
21344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this(data, offset, byteCount, Charset.forNameUEE(charsetName));
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
217c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Converts the byte array to a string using the named charset.
218c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *
219c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * <p>The behavior when the bytes cannot be decoded by the named charset
220c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
221f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
222f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
22344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}.
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnsupportedEncodingException
225c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *             if {@code charsetName} is not supported.
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
227c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    public String(byte[] data, String charsetName) throws UnsupportedEncodingException {
2285cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes        this(data, 0, data.length, Charset.forNameUEE(charsetName));
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
232c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Converts the byte array to a string using the given charset.
233c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *
234c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * <p>The behavior when the bytes cannot be decoded by the given charset
235c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * is to replace malformed input and unmappable characters with the charset's default
236c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
237f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
238b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     * @throws IndexOutOfBoundsException
23944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
240b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     * @throws NullPointerException
24144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}
24244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *
243b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     * @since 1.6
244b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     */
24544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(byte[] data, int offset, int byteCount, Charset charset) {
24644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
24744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw failedBoundsCheck(data.length, offset, byteCount);
248b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes        }
249c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
250c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and
251c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        // 'value' are final.
252c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        String canonicalCharsetName = charset.name();
253c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        if (canonicalCharsetName.equals("UTF-8")) {
254c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            byte[] d = data;
25544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            char[] v = new char[byteCount];
256c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
25744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            int idx = offset;
25844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            int last = offset + byteCount;
25944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            int s = 0;
260c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughesouter:
261c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            while (idx < last) {
262c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                byte b0 = d[idx++];
263c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                if ((b0 & 0x80) == 0) {
264c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // 0xxxxxxx
265c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Range:  U-00000000 - U-0000007F
266c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    int val = b0 & 0xff;
267c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    v[s++] = (char) val;
268c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) ||
269c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) {
270c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    int utfCount = 1;
271c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    if ((b0 & 0xf0) == 0xe0) utfCount = 2;
272c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    else if ((b0 & 0xf8) == 0xf0) utfCount = 3;
273c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    else if ((b0 & 0xfc) == 0xf8) utfCount = 4;
274c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    else if ((b0 & 0xfe) == 0xfc) utfCount = 5;
275c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
276c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // 110xxxxx (10xxxxxx)+
277c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Range:  U-00000080 - U-000007FF (count == 1)
278c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Range:  U-00000800 - U-0000FFFF (count == 2)
279c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Range:  U-00010000 - U-001FFFFF (count == 3)
280c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Range:  U-00200000 - U-03FFFFFF (count == 4)
281c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Range:  U-04000000 - U-7FFFFFFF (count == 5)
282c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
283c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    if (idx + utfCount > last) {
284c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        v[s++] = REPLACEMENT_CHAR;
285c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        break;
286c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    }
287c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
288c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Extract usable bits from b0
289c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    int val = b0 & (0x1f >> (utfCount - 1));
290c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    for (int i = 0; i < utfCount; i++) {
291c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        byte b = d[idx++];
292c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        if ((b & 0xC0) != 0x80) {
293c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                            v[s++] = REPLACEMENT_CHAR;
294c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                            idx--; // Put the input char back
295c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                            continue outer;
296c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        }
297c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        // Push new bits in from the right side
298c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        val <<= 6;
299c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        val |= b & 0x3f;
300c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    }
301c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
302c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Note: Java allows overlong char
303c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // specifications To disallow, check that val
304c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // is greater than or equal to the minimum
305c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // value for each count:
306c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    //
307c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // count    min value
308c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // -----   ----------
309c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    //   1           0x80
310c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    //   2          0x800
311c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    //   3        0x10000
312c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    //   4       0x200000
313c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    //   5      0x4000000
314c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
315c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Allow surrogate values (0xD800 - 0xDFFF) to
316c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // be specified using 3-byte UTF values only
317c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) {
318c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        v[s++] = REPLACEMENT_CHAR;
319c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        continue;
320c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    }
321c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
322c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Reject chars greater than the Unicode maximum of U+10FFFF.
323c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    if (val > 0x10FFFF) {
324c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        v[s++] = REPLACEMENT_CHAR;
325c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        continue;
326c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    }
327c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
328c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Encode chars from U+10000 up as surrogate pairs
329c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    if (val < 0x10000) {
330c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        v[s++] = (char) val;
331c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    } else {
332c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        int x = val & 0xffff;
333c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        int u = (val >> 16) & 0x1f;
334c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        int w = (u - 1) & 0xffff;
335c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        int hi = 0xd800 | (w << 6) | (x >> 10);
336c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        int lo = 0xdc00 | (x & 0x3ff);
337c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        v[s++] = (char) hi;
338c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                        v[s++] = (char) lo;
339c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    }
340c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                } else {
341c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff
342c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                    v[s++] = REPLACEMENT_CHAR;
343c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                }
344c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            }
345c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes
34644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            if (s == byteCount) {
347e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                // We guessed right, so we can use our temporary array as-is.
348e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                this.offset = 0;
349e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                this.value = v;
350e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                this.count = s;
351e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes            } else {
352e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                // Our temporary array was too big, so reallocate and copy.
353e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                this.offset = 0;
354e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                this.value = new char[s];
355e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                this.count = s;
356e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes                System.arraycopy(v, 0, value, 0, s);
357e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes            }
358c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
359c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            this.offset = 0;
36044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            this.value = new char[byteCount];
36144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            this.count = byteCount;
36244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
363c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        } else if (canonicalCharsetName.equals("US-ASCII")) {
364c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            this.offset = 0;
36544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            this.value = new char[byteCount];
36644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            this.count = byteCount;
36744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            Charsets.asciiBytesToChars(data, offset, byteCount, value);
368c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        } else {
36944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
370c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            this.offset = 0;
371c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            this.count = cb.length();
372c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            if (count > 0) {
373c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                // We could use cb.array() directly, but that would mean we'd have to trust
374c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
375c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                // which would break String's immutability guarantee. It would also tend to
376c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
377c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                // array. So we copy.
378c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                this.value = new char[count];
379c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes                System.arraycopy(cb.array(), 0, value, 0, count);
380c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            } else {
38144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes                this.value = EmptyArray.CHAR;
382c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            }
383c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        }
384b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes    }
385b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes
386b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes    /**
387c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Converts the byte array to a String using the given charset.
388f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
389c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * @throws NullPointerException if {@code data == null}
390b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     * @since 1.6
391b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     */
392c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    public String(byte[] data, Charset charset) {
393c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes        this(data, 0, data.length, charset);
394b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes    }
395f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
396b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes    /**
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes this string to contain the characters in the specified
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * character array. Modifying the character array after creating the string
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * has no effect on the string.
400f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
40144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * @throws NullPointerException if {@code data == null}
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String(char[] data) {
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(data, 0, data.length);
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes this string to contain the specified characters in the
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * character array. Modifying the character array after creating the string
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * has no effect on the string.
411f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
412f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
41344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code data == null}.
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
41544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code charCount < 0 || offset < 0 || offset + charCount > data.length}
41644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     */
41744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(char[] data, int offset, int charCount) {
41844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        if ((offset | charCount) < 0 || charCount > data.length - offset) {
41944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw failedBoundsCheck(data.length, offset, charCount);
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
42144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.offset = 0;
42244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.value = new char[charCount];
42344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.count = charCount;
42444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        System.arraycopy(data, offset, value, 0, count);
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
42844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * Internal version of the String(char[], int, int) constructor.
42944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * Does not range check, null check, or copy the character array.
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
43144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    String(int offset, int charCount, char[] chars) {
43244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.value = chars;
43344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.offset = offset;
43444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.count = charCount;
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
438ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * Constructs a new string with the same sequence of characters as {@code
439ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * toCopy}. The returned string's <a href="#backing_array">backing array</a>
440ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * is no larger than necessary.
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
442ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson    public String(String toCopy) {
443ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson        value = (toCopy.value.length == toCopy.count)
444ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson                ? toCopy.value
445ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson                : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length());
446ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson        offset = 0;
447ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson        count = value.length;
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
450a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    /*
451a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson     * Private constructor useful for JIT optimization.
452a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson     */
453a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    @SuppressWarnings( { "unused", "nls" })
454a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    private String(String s1, String s2) {
455a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        if (s1 == null) {
456a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson            s1 = "null";
457a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        }
458a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        if (s2 == null) {
459a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson            s2 = "null";
460a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        }
461a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        count = s1.count + s2.count;
462a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        value = new char[count];
463a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        offset = 0;
464a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
465a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
466a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    }
467a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson
468a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    /*
469a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson     * Private constructor useful for JIT optimization.
470a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson     */
471a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    @SuppressWarnings( { "unused", "nls" })
472a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    private String(String s1, String s2, String s3) {
473a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        if (s1 == null) {
474a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson            s1 = "null";
475a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        }
476a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        if (s2 == null) {
477a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson            s2 = "null";
478a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        }
479a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        if (s3 == null) {
480a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson            s3 = "null";
481a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        }
482a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        count = s1.count + s2.count + s3.count;
483a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        value = new char[count];
484a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        offset = 0;
485a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
486a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
48744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        System.arraycopy(s3.value, s3.offset, value, s1.count + s2.count, s3.count);
488a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson    }
489a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a {@code String} from the contents of the specified
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code StringBuffer}.
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
49444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(StringBuffer stringBuffer) {
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        offset = 0;
49644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        synchronized (stringBuffer) {
49744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            value = stringBuffer.shareValue();
49844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            count = stringBuffer.length();
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a {@code String} from the sub-array of Unicode code points.
504f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
505f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
50644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code codePoints == null}.
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if any of the elements of {@code codePoints} are not valid
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             Unicode code points.
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code count} are not within the bounds
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             of {@code codePoints}.
513f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String(int[] codePoints, int offset, int count) {
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (codePoints == null) {
51786acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("codePoints == null");
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
51944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        if ((offset | count) < 0 || count > codePoints.length - offset) {
52044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw failedBoundsCheck(codePoints.length, offset, count);
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.offset = 0;
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.value = new char[count * 2];
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = offset + count;
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int c = 0;
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = offset; i < end; i++) {
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            c += Character.toChars(codePoints[i], this.value, c);
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.count = c;
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a {@code String} from the contents of the specified {@code
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * StringBuilder}.
535f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
536f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
53744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *             if {@code stringBuilder == null}.
538f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
54044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public String(StringBuilder stringBuilder) {
54144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        if (stringBuilder == null) {
54244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw new NullPointerException("stringBuilder == null");
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.offset = 0;
54544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        this.count = stringBuilder.length();
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.value = new char[this.count];
54744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        stringBuilder.getChars(0, this.count, this.value, 0);
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a {@code String} that is s1 + v1. May be used by JIT code.
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unused")
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String(String s1, int v1) {
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s1 == null) {
5569de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes            s1 = "null";
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String s2 = String.valueOf(v1);
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int len = s1.count + s2.count;
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value = new char[len];
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        offset = 0;
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        count = len;
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the character at the specified offset in this string.
569f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param index
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the zero-based index in this string.
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the character at the index.
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code index < 0} or {@code index >= length()}.
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
57608343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes    public native char charAt(int index);
57744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes
57844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    private StringIndexOutOfBoundsException indexAndLength(int index) {
579363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein        throw new StringIndexOutOfBoundsException(this, index);
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    private StringIndexOutOfBoundsException startEndAndLength(int start, int end) {
583363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein        throw new StringIndexOutOfBoundsException(this, start, end - start);
58444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    }
58544a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes
58644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) {
587363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein        throw new StringIndexOutOfBoundsException(arrayLength, offset, count);
58844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    }
58944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes
59051cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes    /**
59151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes     * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode
59251cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes     * case folds, but it's what the RI uses.
59351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes     */
59451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes    private char foldCase(char ch) {
595f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (ch < 128) {
596f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            if ('A' <= ch && ch <= 'Z') {
597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                return (char) (ch + ('a' - 'A'));
598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            }
599f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            return ch;
600f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
601f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        return Character.toLowerCase(Character.toUpperCase(ch));
602f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
603f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string using the Unicode values of
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the characters. Returns 0 if the strings contain the same characters in
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the same order. Returns a negative integer if the first non-equal
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * character in this string has a Unicode value which is less than the
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Unicode value of the character at the same position in the specified
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * string, or if this string is a prefix of the specified string. Returns a
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * positive integer if the first non-equal character in this string has a
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Unicode value which is greater than the Unicode value of the character at
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the same position in the specified string, or if the specified string is
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * a prefix of this string.
615f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to compare.
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return 0 if the strings are equal, a negative integer if this string is
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         before the specified string, or a positive integer if this string
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         is after the specified string.
621f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
622f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code string} is {@code null}.
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
62408343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes    public native int compareTo(String string);
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string using the Unicode values of
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the characters, ignoring case differences. Returns 0 if the strings
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * contain the same characters in the same order. Returns a negative integer
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * if the first non-equal character in this string has a Unicode value which
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is less than the Unicode value of the character at the same position in
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the specified string, or if this string is a prefix of the specified
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * string. Returns a positive integer if the first non-equal character in
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this string has a Unicode value which is greater than the Unicode value
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of the character at the same position in the specified string, or if the
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified string is a prefix of this string.
637f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to compare.
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return 0 if the strings are equal, a negative integer if this string is
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         before the specified string, or a positive integer if this string
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         is after the specified string.
643f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
644f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code string} is {@code null}.
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int compareToIgnoreCase(String string) {
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int o1 = offset, o2 = string.offset, result;
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = offset + (count < string.count ? count : string.count);
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char c1, c2;
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] target = string.value;
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (o1 < end) {
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((c1 = value[o1++]) == (c2 = target[o2++])) {
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
65551cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            c1 = foldCase(c1);
65651cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            c2 = foldCase(c2);
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((result = c1 - c2) != 0) {
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return result;
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return count - string.count;
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Concatenates this string and the specified string.
666f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to concatenate
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new string which is the concatenation of this string and the
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified string.
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String concat(String string) {
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (string.count > 0 && count > 0) {
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char[] buffer = new char[count + string.count];
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(value, offset, buffer, 0, count);
676c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            System.arraycopy(string.value, string.offset, buffer, count, string.count);
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new String(0, buffer.length, buffer);
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return count == 0 ? string : this;
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new string containing the characters in the specified character
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array. Modifying the character array after creating the string has no
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * effect on the string.
686f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param data
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array of characters.
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new string.
690f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
691f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code data} is {@code null}.
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String copyValueOf(char[] data) {
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new String(data, 0, data.length);
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new string containing the specified characters in the character
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array. Modifying the character array after creating the string has no
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * effect on the string.
701f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param data
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array of characters.
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in the character array.
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of characters to use.
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new string.
709f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
710f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code data} is {@code null}.
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code length < 0, start < 0} or {@code start + length >
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             data.length}.
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String copyValueOf(char[] data, int start, int length) {
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new String(data, start, length);
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string to determine if the
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified string is a suffix.
722f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param suffix
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the suffix to look for.
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified string is a suffix of this string,
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
727f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
728f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code suffix} is {@code null}.
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean endsWith(String suffix) {
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return regionMatches(count - suffix.count, suffix, 0, suffix.count);
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified object to this string and returns true if they are
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * equal. The object must be an instance of string with the same characters
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the same order.
738f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param object
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to compare.
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified object is equal to this string,
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #hashCode
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
74508343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes    @Override public native boolean equals(Object object);
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string ignoring the case of the
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * characters and returns true if they are equal.
750f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to compare.
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified string is equal to this string,
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
7560d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes    @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equalsIgnoreCase(String string) {
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (string == this) {
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (string == null || count != string.count) {
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int o1 = offset, o2 = string.offset;
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = offset + count;
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] target = string.value;
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (o1 < end) {
76851cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            char c1 = value[o1++];
76951cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            char c2 = target[o2++];
77051cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
77844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * Mangles this string into a byte array by stripping the high order bits from
77944a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
780f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset of characters to copy.
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param end
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the ending offset of characters to copy.
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param data
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination byte array.
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param index
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in the destination byte array.
789f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
790f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code data} is {@code null}.
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code start < 0}, {@code end > length()}, {@code index <
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             0} or {@code end - start > data.length - index}.
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)}
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void getBytes(int start, int end, byte[] data, int index) {
7988bc9296d071a77994b6418df2edb120d6a9f70acElliott Hughes        // Note: last character not copied!
799b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (start >= 0 && start <= end && end <= count) {
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            end += offset;
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = offset + start; i < end; i++) {
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    data[index++] = (byte) value[i];
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
805f3b4a80f2ecd6dd1a0df51bb74a01042b11fad97Jesse Wilson            } catch (ArrayIndexOutOfBoundsException ignored) {
806363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein                throw failedBoundsCheck(data.length, index, end - start);
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
8088bc9296d071a77994b6418df2edb120d6a9f70acElliott Hughes        } else {
8098bc9296d071a77994b6418df2edb120d6a9f70acElliott Hughes            throw startEndAndLength(start, end);
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
814c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Returns a new byte array containing the characters of this string encoded using the
815c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * system's {@link java.nio.charset.Charset#defaultCharset default charset}.
816f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
817c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * <p>The behavior when this string cannot be represented in the system's default charset
818c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android),
819c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * all strings can be encoded.
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
821c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    public byte[] getBytes() {
822d0628c5cb80e3c1270634c56a784329a4836b9aaElliott Hughes        return getBytes(Charset.defaultCharset());
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
825c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    /**
826c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Returns a new byte array containing the characters of this string encoded using the
827c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * named charset.
828c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *
829c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * <p>The behavior when this string cannot be represented in the named charset
830c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control.
831c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     *
832c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * @throws UnsupportedEncodingException if the charset is not supported
833c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     */
834c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
8355cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes        return getBytes(Charset.forNameUEE(charsetName));
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
839c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * Returns a new byte array containing the characters of this string encoded using the
840b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     * given charset.
841f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
842c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * <p>The behavior when this string cannot be represented in the given charset
843c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * is to replace malformed input and unmappable characters with the charset's default
844c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes     * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
845f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
846b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     * @since 1.6
847b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes     */
848c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes    public byte[] getBytes(Charset charset) {
849c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes        String canonicalCharsetName = charset.name();
850c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes        if (canonicalCharsetName.equals("UTF-8")) {
8515cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes            return Charsets.toUtf8Bytes(value, offset, count);
852c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
8535cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes            return Charsets.toIsoLatin1Bytes(value, offset, count);
854c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes        } else if (canonicalCharsetName.equals("US-ASCII")) {
8555cd6df2f627e06f9b7f714181d70d3148a3d6c60Elliott Hughes            return Charsets.toAsciiBytes(value, offset, count);
8569559e748729ef1deb6400f31d0407543cbff3566Elliott Hughes        } else if (canonicalCharsetName.equals("UTF-16BE")) {
8579559e748729ef1deb6400f31d0407543cbff3566Elliott Hughes            return Charsets.toBigEndianUtf16Bytes(value, offset, count);
858c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes        } else {
859c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes            CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
860c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes            ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
861c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes            byte[] bytes = new byte[buffer.limit()];
862c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes            buffer.get(bytes);
863c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes            return bytes;
864c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes        }
865c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes    }
866c61e057ac9af32c1987d70d19cb2ead75ed8f612Elliott Hughes
867b43c9fb9c581d94304e9a54ec96cf4d752e8d917Elliott Hughes    /**
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies the specified characters in this string to the character array
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * starting at the specified offset in the character array.
870f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset of characters to copy.
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param end
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the ending offset of characters to copy.
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination character array.
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param index
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in the character array.
879f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
880f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code buffer} is {@code null}.
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code start < 0}, {@code end > length()}, {@code start >
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             end}, {@code index < 0}, {@code end - start > buffer.length -
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             index}
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void getChars(int start, int end, char[] buffer, int index) {
8878bc9296d071a77994b6418df2edb120d6a9f70acElliott Hughes        // Note: last character not copied!
888b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (start >= 0 && start <= end && end <= count) {
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(value, start + offset, buffer, index, end - start);
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
89144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE.
892363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein            throw startEndAndLength(start, end);
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Version of getChars without bounds checks, for use by other classes
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * within the java.lang package only.  The caller is responsible for
899b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes     * ensuring that start >= 0 && start <= end && end <= count.
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void _getChars(int start, int end, char[] buffer, int index) {
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // NOTE last character not copied!
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(value, start + offset, buffer, index, end - start);
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
90636f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes    @Override public int hashCode() {
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int hash = hashCode;
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hash == 0) {
90936f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes            if (count == 0) {
91036f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes                return 0;
91136f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes            }
91236f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes            final int end = count + offset;
91336f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes            final char[] chars = value;
91436f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes            for (int i = offset; i < end; ++i) {
91536f1fe647ee886d8d8a0d703ac2fbbcc8194c716Elliott Hughes                hash = 31*hash + chars[i];
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hashCode = hash;
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return hash;
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches in this string for the first index of the specified character.
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The search for the character starts at the beginning and moves towards
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the end of this string.
926f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param c
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character to find.
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index in this string of the specified character, -1 if the
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         character isn't found.
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int indexOf(int c) {
9334a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
9344a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        if (c > 0xffff) {
9354a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes            return indexOfSupplementary(c, 0);
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
9374a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        return fastIndexOf(c, 0);
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches in this string for the index of the specified character. The
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * search for the character starts at the specified offset and moves towards
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the end of this string.
944f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param c
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character to find.
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset.
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index in this string of the specified character, -1 if the
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         character isn't found.
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int indexOf(int c, int start) {
9534a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        if (c > 0xffff) {
9544a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes            return indexOfSupplementary(c, start);
9554a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        }
9564a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        return fastIndexOf(c, start);
9574a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes    }
9584a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes
95908343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes    private native int fastIndexOf(int c, int start);
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9614a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes    private int indexOfSupplementary(int c, int start) {
9624a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        if (!Character.isSupplementaryCodePoint(c)) {
9634a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes            return -1;
9644a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        }
9654a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        char[] chars = Character.toChars(c);
9664a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        String needle = new String(0, chars.length, chars);
9674a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        return indexOf(needle, start);
9684a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes    }
9694a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches in this string for the first index of the specified string. The
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * search for the string starts at the beginning and moves towards the end
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of this string.
974f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to find.
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index of the first character of the specified string in this
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         string, -1 if the specified string is not a substring.
979f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
980f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code string} is {@code null}.
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int indexOf(String string) {
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int start = 0;
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int subCount = string.count;
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _count = count;
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subCount > 0) {
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (subCount > _count) {
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return -1;
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char[] target = string.value;
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int subOffset = string.offset;
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char firstChar = target[subOffset];
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int end = subOffset + subCount;
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (true) {
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int i = indexOf(firstChar, start);
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i == -1 || subCount + i > _count) {
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1; // handles subCount > count || start >= count
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int o1 = offset + i, o2 = subOffset;
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char[] _value = value;
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (++o2 < end && _value[++o1] == target[o2]) {
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Intentionally empty
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (o2 == end) {
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return i;
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                start = i + 1;
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return start < _count ? start : _count;
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches in this string for the index of the specified string. The search
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for the string starts at the specified offset and moves towards the end
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of this string.
1017f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subString
1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to find.
1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset.
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index of the first character of the specified string in this
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         string, -1 if the specified string is not a substring.
1024f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1025f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code subString} is {@code null}.
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int indexOf(String subString, int start) {
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (start < 0) {
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            start = 0;
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int subCount = subString.count;
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _count = count;
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subCount > 0) {
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (subCount + start > _count) {
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return -1;
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char[] target = subString.value;
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int subOffset = subString.offset;
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            char firstChar = target[subOffset];
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int end = subOffset + subCount;
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (true) {
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int i = indexOf(firstChar, start);
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i == -1 || subCount + i > _count) {
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1; // handles subCount > count || start >= count
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int o1 = offset + i, o2 = subOffset;
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char[] _value = value;
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (++o2 < end && _value[++o1] == target[o2]) {
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Intentionally empty
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (o2 == end) {
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return i;
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                start = i + 1;
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return start < _count ? start : _count;
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
106173ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * Returns an interned string equal to this string. The VM maintains an internal set of
106273ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * unique strings. All string literals found in loaded classes'
106373ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * constant pools are automatically interned. Manually-interned strings are only weakly
106473ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * referenced, so calling {@code intern} won't lead to unwanted retention.
1065f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
106673ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * <p>Interning is typically used because it guarantees that for interned strings
106773ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to
106873ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * {@code a == b}. (This is not true of non-interned strings.)
106973ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     *
107073ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * <p>Many applications find it simpler and more convenient to use an explicit
107173ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * {@link java.util.HashMap} to implement their own pools.
1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
107373ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes    public native String intern();
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
107631df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes     * Returns true if the length of this string is 0.
1077f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
107831df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes     * @since 1.6
107931df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes     */
108008343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes    public native boolean isEmpty();
108131df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes
108231df07d33bf4730c76d5f11b802e8e2bd40baba9Elliott Hughes    /**
108373ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * Returns the last index of the code point {@code c}, or -1.
1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The search for the character starts at the end and moves towards the
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * beginning of this string.
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int lastIndexOf(int c) {
10884a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        if (c > 0xffff) {
10894a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes            return lastIndexOfSupplementary(c, Integer.MAX_VALUE);
10904a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        }
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _count = count;
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _offset = offset;
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] _value = value;
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = _offset + _count - 1; i >= _offset; --i) {
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (_value[i] == c) {
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return i - _offset;
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return -1;
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
110373ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * Returns the last index of the code point {@code c}, or -1.
110473ab73fc55e57f4936ce2f35ced41642630f6c6eElliott Hughes     * The search for the character starts at offset {@code start} and moves towards
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the beginning of this string.
1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int lastIndexOf(int c, int start) {
11084a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        if (c > 0xffff) {
11094a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes            return lastIndexOfSupplementary(c, start);
11104a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        }
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _count = count;
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _offset = offset;
1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] _value = value;
1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (start >= 0) {
1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (start >= _count) {
1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                start = _count - 1;
1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = _offset + start; i >= _offset; --i) {
1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (_value[i] == c) {
1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return i - _offset;
1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return -1;
1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
11274a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes    private int lastIndexOfSupplementary(int c, int start) {
11284a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        if (!Character.isSupplementaryCodePoint(c)) {
11294a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes            return -1;
11304a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        }
11314a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        char[] chars = Character.toChars(c);
11324a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        String needle = new String(0, chars.length, chars);
11334a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        return lastIndexOf(needle, start);
11344a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes    }
11354a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches in this string for the last index of the specified string. The
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * search for the string starts at the end and moves towards the beginning
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of this string.
1140f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to find.
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index of the first character of the specified string in this
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         string, -1 if the specified string is not a substring.
1145f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1146f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code string} is {@code null}.
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int lastIndexOf(String string) {
1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Use count instead of count - 1 so lastIndexOf("") returns count
1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return lastIndexOf(string, count);
1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Searches in this string for the index of the specified string. The search
1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for the string starts at the specified offset and moves towards the
1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * beginning of this string.
1157f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subString
1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to find.
1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset.
1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index of the first character of the specified string in this
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         string , -1 if the specified string is not a substring.
1164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1165f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code subString} is {@code null}.
1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int lastIndexOf(String subString, int start) {
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int subCount = subString.count;
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subCount <= count && start >= 0) {
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (subCount > 0) {
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (start > count - subCount) {
1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    start = count - subCount;
1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // count and subCount are both >= 1
1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char[] target = subString.value;
1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int subOffset = subString.offset;
1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char firstChar = target[subOffset];
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int end = subOffset + subCount;
1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (true) {
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    int i = lastIndexOf(firstChar, start);
1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (i == -1) {
1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return -1;
1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    int o1 = offset + i, o2 = subOffset;
1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    while (++o2 < end && value[++o1] == target[o2]) {
1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // Intentionally empty
1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (o2 == end) {
1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return i;
1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    start = i - 1;
1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return start < count ? start : count;
1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return -1;
1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the size of this string.
1201f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of characters in this string.
1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
120408343a4ef77616fc420e51d1095c0d6a266041baElliott Hughes    public native int length();
1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string and compares the specified
1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * range of characters to determine if they are the same.
1209f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param thisStart
1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in this string.
1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to compare.
1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in the specified string.
1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of characters to compare.
1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the ranges of characters are equal, {@code false}
1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise
1220f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1221f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code string} is {@code null}.
1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
122351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes    public boolean regionMatches(int thisStart, String string, int start, int length) {
1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (string == null) {
122586acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("string == null");
1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (start < 0 || string.count - start < length) {
1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (thisStart < 0 || count - thisStart < length) {
1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length <= 0) {
1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int o1 = offset + thisStart, o2 = string.offset + start;
1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] value1 = value;
1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] value2 = string.value;
1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < length; ++i) {
1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (value1[o1 + i] != value2[o2 + i]) {
1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string and compares the specified
1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * range of characters to determine if they are the same. When ignoreCase is
1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * true, the case of the characters is ignored during the comparison.
1251f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ignoreCase
1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            specifies if case should be ignored.
1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param thisStart
1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in this string.
1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param string
1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to compare.
1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in the specified string.
1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of characters to compare.
1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the ranges of characters are equal, {@code false}
1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
1264f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1265f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code string} is {@code null}.
1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
126751cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes    public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) {
1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!ignoreCase) {
1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return regionMatches(thisStart, string, start, length);
1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
127151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        if (string == null) {
127251cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            throw new NullPointerException("string == null");
127351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        }
127451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        if (thisStart < 0 || length > count - thisStart) {
127551cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            return false;
127651cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        }
127751cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        if (start < 0 || length > string.count - start) {
127851cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            return false;
127951cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        }
128051cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        thisStart += offset;
128151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        start += string.offset;
128251cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        int end = thisStart + length;
128351cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        char[] target = string.value;
128451cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        while (thisStart < end) {
128551cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            char c1 = value[thisStart++];
128651cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            char c2 = target[start++];
128751cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes            if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
129151cb5459b4515f6c0c164a26c6244d8305bd89bbElliott Hughes        return true;
1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies this string replacing occurrences of the specified character with
1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * another character.
1297f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oldChar
1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character to replace.
1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newChar
1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the replacement character.
1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new string with occurrences of oldChar replaced by newChar.
1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String replace(char oldChar, char newChar) {
1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] buffer = value;
1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _offset = offset;
1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int _count = count;
1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int idx = _offset;
1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int last = _offset + _count;
1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean copied = false;
1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (idx < last) {
1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (buffer[idx] == oldChar) {
1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!copied) {
1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    char[] newBuffer = new char[_count];
1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    System.arraycopy(buffer, _offset, newBuffer, 0, _count);
1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    buffer = newBuffer;
1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    idx -= _offset;
1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    last -= _offset;
1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    copied = true;
1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                buffer[idx] = newChar;
1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            idx++;
1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return copied ? new String(0, count, buffer) : this;
1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1329f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies this string replacing occurrences of the specified target sequence
1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * with another sequence. The string is processed from the beginning to the
1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * end.
1334f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param target
1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the sequence to replace.
1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param replacement
1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the replacement sequence.
1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the resulting string.
1340f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1341f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code target} or {@code replacement} is {@code null}.
1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String replace(CharSequence target, CharSequence replacement) {
1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (target == null) {
1345870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            throw new NullPointerException("target == null");
1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (replacement == null) {
1348870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            throw new NullPointerException("replacement == null");
1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1351870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        String targetString = target.toString();
1352870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        int matchStart = indexOf(targetString, 0);
1353870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        if (matchStart == -1) {
1354870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            // If there's nothing to replace, return the original string untouched.
1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this;
1356870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        }
1357870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes
1358870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        String replacementString = replacement.toString();
1359870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes
1360870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        // The empty target matches at the start and end and between each character.
1361870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        int targetLength = targetString.length();
1362870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        if (targetLength == 0) {
1363870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            int resultLength = (count + 2) * replacementString.length();
1364870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            StringBuilder result = new StringBuilder(resultLength);
1365870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            result.append(replacementString);
1366870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            for (int i = offset; i < count; ++i) {
1367870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes                result.append(value[i]);
1368870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes                result.append(replacementString);
1369870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            }
1370870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            return result.toString();
1371870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        }
1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1373870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        StringBuilder result = new StringBuilder(count);
1374870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        int searchStart = 0;
1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        do {
1376870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            // Copy characters before the match...
1377870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            result.append(value, offset + searchStart, matchStart - searchStart);
1378870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            // Insert the replacement...
1379870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            result.append(replacementString);
1380870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            // And skip over the match...
1381870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes            searchStart = matchStart + targetLength;
1382870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        } while ((matchStart = indexOf(targetString, searchStart)) != -1);
1383870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        // Copy any trailing chars...
1384870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        result.append(value, offset + searchStart, count - searchStart);
1385870b23b3febc851c9cd2321f82a9971a34093e77Elliott Hughes        return result.toString();
1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string to determine if the
1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified string is a prefix.
1391f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param prefix
1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to look for.
1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified string is a prefix of this string,
1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise
1396f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1397f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code prefix} is {@code null}.
1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean startsWith(String prefix) {
1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return startsWith(prefix, 0);
1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified string to this string, starting at the specified
1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * offset, to determine if the specified string is a prefix.
1406f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param prefix
1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string to look for.
1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset.
1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified string occurs in this string at the
1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified offset, {@code false} otherwise.
1413f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1414f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code prefix} is {@code null}.
1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean startsWith(String prefix, int start) {
1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return regionMatches(start, prefix, 0, prefix.count);
1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1421ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * Returns a string containing a suffix of this string. The returned string
1422ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * shares this string's <a href="#backing_array">backing array</a>.
1423f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset of the first character.
1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new string containing the characters from start to the end of
1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         the string.
1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code start < 0} or {@code start > length()}.
1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String substring(int start) {
1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (start == 0) {
1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this;
1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1435b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (start >= 0 && start <= count) {
1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new String(offset + start, count - start, value);
1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1438363291564f107e500e0b584baa0377757cc2ae09Dan Bornstein        throw indexAndLength(start);
1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1442ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * Returns a string containing a subsequence of characters from this string.
1443ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * The returned string shares this string's <a href="#backing_array">backing
1444ab73941feb7f8677174cc97722201437edcb1299Jesse Wilson     * array</a>.
1445f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset of the first character.
1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param end
1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset one past the last character.
1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new string containing the characters from start to end - 1
1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code start < 0}, {@code start > end} or {@code end >
1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             length()}.
1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String substring(int start, int end) {
1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (start == 0 && end == count) {
1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this;
1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // NOTE last character not copied!
1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Fast range check.
1461b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (start >= 0 && start <= end && end <= count) {
1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new String(offset + start, end - start, value);
1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
146444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        throw startEndAndLength(start, end);
1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies the characters in this string to a character array.
1469f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a character array containing the characters of this string.
1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public char[] toCharArray() {
1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] buffer = new char[count];
1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(value, offset, buffer, 0, count);
1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return buffer;
1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1479a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * Converts this string to lower case, using the rules of the user's default locale.
14803106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
14813106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *
1482a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * @return a new lower case string, or {@code this} if it's already all lower case.
1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toLowerCase() {
148596b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes        return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count);
1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1489a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * Converts this string to lower case, using the rules of {@code locale}.
14909de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     *
14919de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
149296b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
14939de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
149496b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes     * correct case mapping of Greek characters: any locale will do.
14959de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     *
14969de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
149796b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes     * for full details of context- and language-specific special cases.
14989de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     *
1499a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * @return a new lower case string, or {@code this} if it's already all lower case.
1500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toLowerCase(Locale locale) {
150296b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes        return CaseMapper.toLowerCase(locale, this, value, offset, count);
1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this string.
1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
1511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1514a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * Converts this this string to upper case, using the rules of the user's default locale.
15153106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
15163106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *
1517a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * @return a new upper case string, or {@code this} if it's already all upper case.
1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toUpperCase() {
15209de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes        return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1524a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * Converts this this string to upper case, using the rules of {@code locale}.
1525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
15269de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
15279de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
15289de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
15299de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * correct case mapping of Greek characters: any locale will do.
1530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
15319de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
15329de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     * for full details of context- and language-specific special cases.
15339de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes     *
1534a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * @return a new upper case string, or {@code this} if it's already all upper case.
1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toUpperCase(Locale locale) {
15379de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes        return CaseMapper.toUpperCase(locale, this, value, offset, count);
1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies this string removing white space characters from the beginning and
1542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * end of the string.
1543f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new string with characters <code><= \\u0020</code> removed from
1545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         the beginning and the end.
1546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String trim() {
1548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int start = offset, last = offset + count - 1;
1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = last;
1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while ((start <= end) && (value[start] <= ' ')) {
1551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            start++;
1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while ((end >= start) && (value[end] <= ' ')) {
1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            end--;
1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (start == offset && end == last) {
1557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this;
1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new String(start, end - start + 1, value);
1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new string containing the characters in the specified character
1564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array. Modifying the character array after creating the string has no
1565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * effect on the string.
1566f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param data
1568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array of characters.
1569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new string.
1570f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1571f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code data} is {@code null}.
1572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(char[] data) {
1574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new String(data, 0, data.length);
1575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new string containing the specified characters in the character
1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array. Modifying the character array after creating the string has no
1580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * effect on the string.
1581f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param data
1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array of characters.
1584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the starting offset in the character array.
1586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param length
1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of characters to use.
1588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new string.
1589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code length < 0}, {@code start < 0} or {@code start +
1591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             length > data.length}
1592f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code data} is {@code null}.
1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(char[] data, int start, int length) {
1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new String(data, start, length);
1597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified character to its string representation.
1601f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character.
1604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the character converted to a string.
1605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(char value) {
1607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String s;
1608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (value < 128) {
1609c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes            s = new String(value, 1, ASCII);
1610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            s = new String(0, 1, new char[] { value });
1612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        s.hashCode = value;
1614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return s;
1615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified double to its string representation.
1619f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the double.
1622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the double converted to a string.
1623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(double value) {
1625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Double.toString(value);
1626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified float to its string representation.
1630f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the float.
1633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the float converted to a string.
1634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(float value) {
1636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Float.toString(value);
1637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified integer to its string representation.
1641f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the integer.
1644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the integer converted to a string.
1645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(int value) {
1647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Integer.toString(value);
1648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified long to its string representation.
1652f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the long.
1655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the long converted to a string.
1656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(long value) {
1658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Long.toString(value);
1659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified object to its string representation. If the object
1663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is null return the string {@code "null"}, otherwise use {@code
1664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * toString()} to get the string representation.
1665f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object.
1668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object converted to a string, or the string {@code "null"}.
1669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(Object value) {
16719de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes        return value != null ? value.toString() : "null";
1672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts the specified boolean to its string representation. When the
1676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * boolean is {@code true} return {@code "true"}, otherwise return {@code
1677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * "false"}.
1678f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the boolean.
1681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the boolean converted to a string.
1682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String valueOf(boolean value) {
16849de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes        return value ? "true" : "false";
1685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the characters in the StringBuffer {@code strbuf} are the
1689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * same as those in this string.
1690f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param strbuf
1692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the StringBuffer to compare this string to.
1693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the characters in {@code strbuf} are identical to
1694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         those in this string. If they are not, {@code false} will be
1695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         returned.
1696f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws NullPointerException
1697f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if {@code strbuf} is {@code null}.
1698f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean contentEquals(StringBuffer strbuf) {
1701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (strbuf) {
1702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int size = strbuf.length();
1703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (count != size) {
1704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
1707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    size);
1708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares a {@code CharSequence} to this {@code String} to determine if
1713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * their contents are equal.
1714f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param cs
1716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character sequence to compare to.
1717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if equal, otherwise {@code false}
1718f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean contentEquals(CharSequence cs) {
1721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (cs == null) {
172286acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("cs == null");
1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int len = cs.length();
1726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (len != count) {
1728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (len == 0 && count == 0) {
1732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true; // since both are empty strings
1733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return regionMatches(0, cs.toString(), 0, len);
1736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
17395f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * Tests whether this string matches the given {@code regularExpression}. This method returns
17405f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * true only if the regular expression matches the <i>entire</i> input string. A common mistake is
17415f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * to assume that this method behaves like {@link #contains}; if you want to match anywhere
17425f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * within the input string, you need to add {@code .*} to the beginning and end of your
17435f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * regular expression. See {@link Pattern#matches}.
1744f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
17455f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * <p>If the same regular expression is to be used for multiple operations, it may be more
17465f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * efficient to reuse a compiled {@code Pattern}.
1747f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws PatternSyntaxException
1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the syntax of the supplied regular expression is not
1750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             valid.
17515f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * @throws NullPointerException if {@code regularExpression == null}
1752f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
17545f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes    public boolean matches(String regularExpression) {
17555f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes        return Pattern.matches(regularExpression, this);
1756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
17595f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * Replaces all matches for {@code regularExpression} within this string with the given
17605f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * {@code replacement}.
17615f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * See {@link Pattern} for regular expression syntax.
1762f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
17635f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * <p>If the same regular expression is to be used for multiple operations, it may be more
17645f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * efficient to reuse a compiled {@code Pattern}.
1765f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws PatternSyntaxException
1767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the syntax of the supplied regular expression is not
1768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             valid.
17695f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * @throws NullPointerException if {@code regularExpression == null}
1770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Pattern
1771f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
17735f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes    public String replaceAll(String regularExpression, String replacement) {
17745f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes        return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement);
1775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
17785f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * Replaces the first match for {@code regularExpression} within this string with the given
17795f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * {@code replacement}.
17805f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * See {@link Pattern} for regular expression syntax.
1781f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
17825f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * <p>If the same regular expression is to be used for multiple operations, it may be more
17835f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * efficient to reuse a compiled {@code Pattern}.
1784f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws PatternSyntaxException
1786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the syntax of the supplied regular expression is not
1787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             valid.
17885f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * @throws NullPointerException if {@code regularExpression == null}
1789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Pattern
1790f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
17925f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes    public String replaceFirst(String regularExpression, String replacement) {
17935f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes        return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement);
1794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
17975f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * Splits this string using the supplied {@code regularExpression}.
17985f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * Equivalent to {@code split(regularExpression, 0)}.
17995f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
18005f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * See {@link Pattern} for regular expression syntax.
1801f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
18025f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * <p>If the same regular expression is to be used for multiple operations, it may be more
18035f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * efficient to reuse a compiled {@code Pattern}.
1804f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
18055f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * @throws NullPointerException if {@code regularExpression ==  null}
1806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws PatternSyntaxException
1807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the syntax of the supplied regular expression is not
1808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             valid.
1809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Pattern
1810f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
18125f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes    public String[] split(String regularExpression) {
18135f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes        return split(regularExpression, 0);
1814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
18175f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * Splits this string using the supplied {@code regularExpression}.
18185f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
18195f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * See {@link Pattern} for regular expression syntax.
1820f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
18215f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * <p>If the same regular expression is to be used for multiple operations, it may be more
18225f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * efficient to reuse a compiled {@code Pattern}.
1823f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
18245f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes     * @throws NullPointerException if {@code regularExpression ==  null}
1825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws PatternSyntaxException
1826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the syntax of the supplied regular expression is not
1827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             valid.
1828f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
18305f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes    public String[] split(String regularExpression, int limit) {
18315f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes        String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit);
18325f37da05bb48298568f8abd7c97c3d11552e1867Elliott Hughes        return result != null ? result : Pattern.compile(regularExpression).split(this, limit);
1833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Has the same result as the substring function, but is present so that
1837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * string may implement the CharSequence interface.
1838f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
1839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param start
1840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset the first character.
1841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param end
1842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset of one past the last character to include.
1843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the subsequence requested.
1844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
1845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code start < 0}, {@code end < 0}, {@code start > end} or
1846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code end > length()}.
1847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.lang.CharSequence#subSequence(int, int)
1848f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.4
1849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public CharSequence subSequence(int start, int end) {
1851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return substring(start, end);
1852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
18554a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes     * Returns the Unicode code point at the given {@code index}.
1856f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
18574a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes     * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()}
1858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Character#codePointAt(char[], int, int)
1859f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int codePointAt(int index) {
1862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (index < 0 || index >= count) {
186344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw indexAndLength(index);
1864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
18654a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        return Character.codePointAt(value, offset + index, offset + count);
1866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
18694a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes     * Returns the Unicode code point that precedes the given {@code index}.
1870f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
18714a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes     * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()}
1872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Character#codePointBefore(char[], int, int)
1873f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int codePointBefore(int index) {
1876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (index < 1 || index > count) {
187744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw indexAndLength(index);
1878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
18794a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        return Character.codePointBefore(value, offset + index, offset);
1880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
188344a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * Calculates the number of Unicode code points between {@code start}
188444a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * and {@code end}.
1885f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
188644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * @param start
1887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the inclusive beginning index of the subsequence.
188844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     * @param end
1889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the exclusive end index of the subsequence.
1890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of Unicode code points in the subsequence.
1891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
189244a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes     *         if {@code start < 0 || end > length() || start > end}
1893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Character#codePointCount(CharSequence, int, int)
1894f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
189644a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes    public int codePointCount(int start, int end) {
189744a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        if (start < 0 || end > count || start > end) {
189844a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            throw startEndAndLength(start, end);
1899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
190044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes        return Character.codePointCount(value, offset + start, end - start);
1901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Determines if this {@code String} contains the sequence of characters in
1905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the {@code CharSequence} passed.
1906f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param cs
1908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character sequence to search for.
1909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the sequence of characters are contained in this
1910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         string, otherwise {@code false}.
1911f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean contains(CharSequence cs) {
1914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (cs == null) {
191586acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("cs == null");
1916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return indexOf(cs.toString()) >= 0;
1918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the index within this object that is offset from {@code index} by
1922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code codePointOffset} code points.
1923f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param index
1925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index within this object to calculate the offset from.
1926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param codePointOffset
1927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of code points to count.
1928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the index within this object that is the offset.
1929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
1930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code index} is negative or greater than {@code length()}
1931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             or if there aren't enough code points before or after {@code
1932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             index} to match {@code codePointOffset}.
1933f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int offsetByCodePoints(int index, int codePointOffset) {
1936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int s = index + offset;
19374a6cd08d55ec407dea29586cc917f8a423f5645fElliott Hughes        int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset);
1938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return r - offset;
1939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1942438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes     * Returns a localized formatted string, using the supplied format and arguments,
1943438d9883775e6ee31c097e2103a25571d2426cd9Elliott Hughes     * using the user's default locale.
1944f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
19453106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * <p>If you're formatting a string other than for human
19463dd153c6795866734d66e6b5f69c40edae698f6dElliott Hughes     * consumption, you should use the {@code format(Locale, String, Object...)}
19473106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * overload and supply {@code Locale.US}. See
19483106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1949f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
19503106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * @param format the format string (see {@link java.util.Formatter#format})
1951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param args
19523106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *            the list of arguments passed to the formatter. If there are
19533106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *            more arguments than required by {@code format},
19543106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *            additional arguments are ignored.
1955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the formatted string.
19563106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * @throws NullPointerException if {@code format == null}
1957f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws java.util.IllegalFormatException
1958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the format is invalid.
1959f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String format(String format, Object... args) {
1962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return format(Locale.getDefault(), format, args);
1963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a formatted string, using the supplied format and arguments,
19673dd153c6795866734d66e6b5f69c40edae698f6dElliott Hughes     * localized to the given locale.
1968f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
19693106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * @param locale
1970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the locale to apply; {@code null} value means no localization.
19713106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * @param format the format string (see {@link java.util.Formatter#format})
1972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param args
19733106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *            the list of arguments passed to the formatter. If there are
19743106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *            more arguments than required by {@code format},
19753106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     *            additional arguments are ignored.
1976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the formatted string.
19773106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes     * @throws NullPointerException if {@code format == null}
1978f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @throws java.util.IllegalFormatException
1979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the format is invalid.
1980f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @since 1.5
1981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
19823106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes    public static String format(Locale locale, String format, Object... args) {
1983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (format == null) {
198486acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("format == null");
1985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
19863106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes        int bufferSize = format.length() + (args == null ? 0 : args.length * 10);
19873106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes        Formatter f = new Formatter(new StringBuilder(bufferSize), locale);
1988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return f.format(format, args).toString();
1989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
1992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * An implementation of a String.indexOf that is supposed to perform
1993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * substantially better than the default algorithm if the "needle" (the
1994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * subString being searched for) is a constant string.
1995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
199696b251cd6e3aa354b86330da0c598d538151be0aElliott Hughes     * For example, a JIT, upon encountering a call to String.indexOf(String),
1997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * where the needle is a constant string, may compute the values cache, md2
1998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and lastChar, and change the call to the following method.
1999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
20000d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes    @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
2001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unused")
2002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static int indexOf(String haystackString, String needleString,
2003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int cache, int md2, char lastChar) {
2004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] haystack = haystackString.value;
2005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int haystackOffset = haystackString.offset;
2006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int haystackLength = haystackString.count;
2007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        char[] needle = needleString.value;
2008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int needleOffset = needleString.offset;
2009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int needleLength = needleString.count;
2010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int needleLengthMinus1 = needleLength - 1;
2011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int haystackEnd = haystackOffset + haystackLength;
2012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) {
2013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (lastChar == haystack[i]) {
2014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int j = 0; j < needleLengthMinus1; ++j) {
2015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (needle[j + needleOffset] != haystack[i + j
2016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            - needleLengthMinus1]) {
2017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        int skip = 1;
2018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if ((cache & (1 << haystack[i])) == 0) {
2019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            skip += j;
2020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
2021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        i += Math.max(md2, skip);
2022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        continue outer_loop;
2023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
2024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return i - needleLengthMinus1 - haystackOffset;
2026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((cache & (1 << haystack[i])) == 0) {
2029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i += needleLengthMinus1;
2030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            i++;
2032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return -1;
2034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
2036