1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.lang;
19
20import java.io.Serializable;
21import java.io.UnsupportedEncodingException;
22import java.nio.ByteBuffer;
23import java.nio.CharBuffer;
24import java.nio.charset.Charset;
25import java.nio.charset.Charsets;
26import java.util.Arrays;
27import java.util.Comparator;
28import java.util.Formatter;
29import java.util.Locale;
30import java.util.regex.Pattern;
31import libcore.util.EmptyArray;
32
33/**
34 * An immutable sequence of characters/code units ({@code char}s). A
35 * {@code String} is represented by array of UTF-16 values, such that
36 * Unicode supplementary characters (code points) are stored/encoded as
37 * surrogate pairs via Unicode code units ({@code char}).
38 *
39 * <a name="backing_array"><h3>Backing Arrays</h3></a>
40 * This class is implemented using a char[]. The length of the array may exceed
41 * the length of the string. For example, the string "Hello" may be backed by
42 * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
43 * offset 0 and length 5.
44 *
45 * <p>Multiple strings can share the same char[] because strings are immutable.
46 * The {@link #substring} method <strong>always</strong> returns a string that
47 * shares the backing array of its source string. Generally this is an
48 * optimization: fewer character arrays need to be allocated, and less copying
49 * is necessary. But this can also lead to unwanted heap retention. Taking a
50 * short substring of long string means that the long shared char[] won't be
51 * garbage until both strings are garbage. This typically happens when parsing
52 * small substrings out of a large input. To avoid this where necessary, call
53 * {@code new String(longString.subString(...))}. The string copy constructor
54 * always ensures that the backing array is no larger than necessary.
55 *
56 * @see StringBuffer
57 * @see StringBuilder
58 * @see Charset
59 * @since 1.0
60 */
61public final class String implements Serializable, Comparable<String>, CharSequence {
62
63    private static final long serialVersionUID = -6849794470754667710L;
64
65    private static final char REPLACEMENT_CHAR = (char) 0xfffd;
66
67    /**
68     * CaseInsensitiveComparator compares Strings ignoring the case of the
69     * characters.
70     */
71    private static final class CaseInsensitiveComparator implements
72            Comparator<String>, Serializable {
73        private static final long serialVersionUID = 8575799808933029326L;
74
75        /**
76         * Compare the two objects to determine the relative ordering.
77         *
78         * @param o1
79         *            an Object to compare
80         * @param o2
81         *            an Object to compare
82         * @return an int < 0 if object1 is less than object2, 0 if they are
83         *         equal, and > 0 if object1 is greater
84         *
85         * @exception ClassCastException
86         *                if objects are not the correct type
87         */
88        public int compare(String o1, String o2) {
89            return o1.compareToIgnoreCase(o2);
90        }
91    }
92
93    /**
94     * A comparator ignoring the case of the characters.
95     */
96    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
97
98    private static final char[] ASCII;
99    static {
100        ASCII = new char[128];
101        for (int i = 0; i < ASCII.length; ++i) {
102            ASCII[i] = (char) i;
103        }
104    }
105
106    private final char[] value;
107
108    private final int offset;
109
110    private final int count;
111
112    private int hashCode;
113
114    /**
115     * Creates an empty string.
116     */
117    public String() {
118        value = EmptyArray.CHAR;
119        offset = 0;
120        count = 0;
121    }
122
123    /*
124     * Private constructor used for JIT optimization.
125     */
126    @SuppressWarnings("unused")
127    private String(String s, char c) {
128        offset = 0;
129        value = new char[s.count + 1];
130        count = s.count + 1;
131        System.arraycopy(s.value, s.offset, value, 0, s.count);
132        value[s.count] = c;
133    }
134
135    /**
136     * Converts the byte array to a string using the system's
137     * {@link java.nio.charset.Charset#defaultCharset default charset}.
138     */
139    @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING")
140    public String(byte[] data) {
141        this(data, 0, data.length);
142    }
143
144    /**
145     * Converts the byte array to a string, setting the high byte of every
146     * character to the specified value.
147     *
148     * @param data
149     *            the byte array to convert to a string.
150     * @param high
151     *            the high byte to use.
152     * @throws NullPointerException
153     *             if {@code data == null}.
154     * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead.
155     */
156    @Deprecated
157    public String(byte[] data, int high) {
158        this(data, high, 0, data.length);
159    }
160
161    /**
162     * Converts a subsequence of the byte array to a string using the system's
163     * {@link java.nio.charset.Charset#defaultCharset default charset}.
164     *
165     * @throws NullPointerException
166     *             if {@code data == null}.
167     * @throws IndexOutOfBoundsException
168     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
169     */
170    public String(byte[] data, int offset, int byteCount) {
171        this(data, offset, byteCount, Charset.defaultCharset());
172    }
173
174    /**
175     * Converts the byte array to a string, setting the high byte of every
176     * character to {@code high}.
177     *
178     * @throws NullPointerException
179     *             if {@code data == null}.
180     * @throws IndexOutOfBoundsException
181     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
182     *
183     * @deprecated Use {@link #String(byte[], int, int)} instead.
184     */
185    @Deprecated
186    public String(byte[] data, int high, int offset, int byteCount) {
187        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
188            throw failedBoundsCheck(data.length, offset, byteCount);
189        }
190        this.offset = 0;
191        this.value = new char[byteCount];
192        this.count = byteCount;
193        high <<= 8;
194        for (int i = 0; i < count; i++) {
195            value[i] = (char) (high + (data[offset++] & 0xff));
196        }
197    }
198
199    /**
200     * Converts the byte array to a string using the named charset.
201     *
202     * <p>The behavior when the bytes cannot be decoded by the named charset
203     * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
204     *
205     * @throws NullPointerException
206     *             if {@code data == null}.
207     * @throws IndexOutOfBoundsException
208     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
209     * @throws UnsupportedEncodingException
210     *             if the named charset is not supported.
211     */
212    public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
213        this(data, offset, byteCount, Charset.forNameUEE(charsetName));
214    }
215
216    /**
217     * Converts the byte array to a string using the named charset.
218     *
219     * <p>The behavior when the bytes cannot be decoded by the named charset
220     * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
221     *
222     * @throws NullPointerException
223     *             if {@code data == null}.
224     * @throws UnsupportedEncodingException
225     *             if {@code charsetName} is not supported.
226     */
227    public String(byte[] data, String charsetName) throws UnsupportedEncodingException {
228        this(data, 0, data.length, Charset.forNameUEE(charsetName));
229    }
230
231    /**
232     * Converts the byte array to a string using the given charset.
233     *
234     * <p>The behavior when the bytes cannot be decoded by the given charset
235     * is to replace malformed input and unmappable characters with the charset's default
236     * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
237     *
238     * @throws IndexOutOfBoundsException
239     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
240     * @throws NullPointerException
241     *             if {@code data == null}
242     *
243     * @since 1.6
244     */
245    public String(byte[] data, int offset, int byteCount, Charset charset) {
246        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
247            throw failedBoundsCheck(data.length, offset, byteCount);
248        }
249
250        // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and
251        // 'value' are final.
252        String canonicalCharsetName = charset.name();
253        if (canonicalCharsetName.equals("UTF-8")) {
254            byte[] d = data;
255            char[] v = new char[byteCount];
256
257            int idx = offset;
258            int last = offset + byteCount;
259            int s = 0;
260outer:
261            while (idx < last) {
262                byte b0 = d[idx++];
263                if ((b0 & 0x80) == 0) {
264                    // 0xxxxxxx
265                    // Range:  U-00000000 - U-0000007F
266                    int val = b0 & 0xff;
267                    v[s++] = (char) val;
268                } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) ||
269                        ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) {
270                    int utfCount = 1;
271                    if ((b0 & 0xf0) == 0xe0) utfCount = 2;
272                    else if ((b0 & 0xf8) == 0xf0) utfCount = 3;
273                    else if ((b0 & 0xfc) == 0xf8) utfCount = 4;
274                    else if ((b0 & 0xfe) == 0xfc) utfCount = 5;
275
276                    // 110xxxxx (10xxxxxx)+
277                    // Range:  U-00000080 - U-000007FF (count == 1)
278                    // Range:  U-00000800 - U-0000FFFF (count == 2)
279                    // Range:  U-00010000 - U-001FFFFF (count == 3)
280                    // Range:  U-00200000 - U-03FFFFFF (count == 4)
281                    // Range:  U-04000000 - U-7FFFFFFF (count == 5)
282
283                    if (idx + utfCount > last) {
284                        v[s++] = REPLACEMENT_CHAR;
285                        break;
286                    }
287
288                    // Extract usable bits from b0
289                    int val = b0 & (0x1f >> (utfCount - 1));
290                    for (int i = 0; i < utfCount; i++) {
291                        byte b = d[idx++];
292                        if ((b & 0xC0) != 0x80) {
293                            v[s++] = REPLACEMENT_CHAR;
294                            idx--; // Put the input char back
295                            continue outer;
296                        }
297                        // Push new bits in from the right side
298                        val <<= 6;
299                        val |= b & 0x3f;
300                    }
301
302                    // Note: Java allows overlong char
303                    // specifications To disallow, check that val
304                    // is greater than or equal to the minimum
305                    // value for each count:
306                    //
307                    // count    min value
308                    // -----   ----------
309                    //   1           0x80
310                    //   2          0x800
311                    //   3        0x10000
312                    //   4       0x200000
313                    //   5      0x4000000
314
315                    // Allow surrogate values (0xD800 - 0xDFFF) to
316                    // be specified using 3-byte UTF values only
317                    if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) {
318                        v[s++] = REPLACEMENT_CHAR;
319                        continue;
320                    }
321
322                    // Reject chars greater than the Unicode maximum of U+10FFFF.
323                    if (val > 0x10FFFF) {
324                        v[s++] = REPLACEMENT_CHAR;
325                        continue;
326                    }
327
328                    // Encode chars from U+10000 up as surrogate pairs
329                    if (val < 0x10000) {
330                        v[s++] = (char) val;
331                    } else {
332                        int x = val & 0xffff;
333                        int u = (val >> 16) & 0x1f;
334                        int w = (u - 1) & 0xffff;
335                        int hi = 0xd800 | (w << 6) | (x >> 10);
336                        int lo = 0xdc00 | (x & 0x3ff);
337                        v[s++] = (char) hi;
338                        v[s++] = (char) lo;
339                    }
340                } else {
341                    // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff
342                    v[s++] = REPLACEMENT_CHAR;
343                }
344            }
345
346            if (s == byteCount) {
347                // We guessed right, so we can use our temporary array as-is.
348                this.offset = 0;
349                this.value = v;
350                this.count = s;
351            } else {
352                // Our temporary array was too big, so reallocate and copy.
353                this.offset = 0;
354                this.value = new char[s];
355                this.count = s;
356                System.arraycopy(v, 0, value, 0, s);
357            }
358        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
359            this.offset = 0;
360            this.value = new char[byteCount];
361            this.count = byteCount;
362            Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
363        } else if (canonicalCharsetName.equals("US-ASCII")) {
364            this.offset = 0;
365            this.value = new char[byteCount];
366            this.count = byteCount;
367            Charsets.asciiBytesToChars(data, offset, byteCount, value);
368        } else {
369            CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
370            this.offset = 0;
371            this.count = cb.length();
372            if (count > 0) {
373                // We could use cb.array() directly, but that would mean we'd have to trust
374                // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
375                // which would break String's immutability guarantee. It would also tend to
376                // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
377                // array. So we copy.
378                this.value = new char[count];
379                System.arraycopy(cb.array(), 0, value, 0, count);
380            } else {
381                this.value = EmptyArray.CHAR;
382            }
383        }
384    }
385
386    /**
387     * Converts the byte array to a String using the given charset.
388     *
389     * @throws NullPointerException if {@code data == null}
390     * @since 1.6
391     */
392    public String(byte[] data, Charset charset) {
393        this(data, 0, data.length, charset);
394    }
395
396    /**
397     * Initializes this string to contain the characters in the specified
398     * character array. Modifying the character array after creating the string
399     * has no effect on the string.
400     *
401     * @throws NullPointerException if {@code data == null}
402     */
403    public String(char[] data) {
404        this(data, 0, data.length);
405    }
406
407    /**
408     * Initializes this string to contain the specified characters in the
409     * character array. Modifying the character array after creating the string
410     * has no effect on the string.
411     *
412     * @throws NullPointerException
413     *             if {@code data == null}.
414     * @throws IndexOutOfBoundsException
415     *             if {@code charCount < 0 || offset < 0 || offset + charCount > data.length}
416     */
417    public String(char[] data, int offset, int charCount) {
418        if ((offset | charCount) < 0 || charCount > data.length - offset) {
419            throw failedBoundsCheck(data.length, offset, charCount);
420        }
421        this.offset = 0;
422        this.value = new char[charCount];
423        this.count = charCount;
424        System.arraycopy(data, offset, value, 0, count);
425    }
426
427    /*
428     * Internal version of the String(char[], int, int) constructor.
429     * Does not range check, null check, or copy the character array.
430     */
431    String(int offset, int charCount, char[] chars) {
432        this.value = chars;
433        this.offset = offset;
434        this.count = charCount;
435    }
436
437    /**
438     * Constructs a new string with the same sequence of characters as {@code
439     * toCopy}. The returned string's <a href="#backing_array">backing array</a>
440     * is no larger than necessary.
441     */
442    public String(String toCopy) {
443        value = (toCopy.value.length == toCopy.count)
444                ? toCopy.value
445                : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length());
446        offset = 0;
447        count = value.length;
448    }
449
450    /*
451     * Private constructor useful for JIT optimization.
452     */
453    @SuppressWarnings( { "unused", "nls" })
454    private String(String s1, String s2) {
455        if (s1 == null) {
456            s1 = "null";
457        }
458        if (s2 == null) {
459            s2 = "null";
460        }
461        count = s1.count + s2.count;
462        value = new char[count];
463        offset = 0;
464        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
465        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
466    }
467
468    /*
469     * Private constructor useful for JIT optimization.
470     */
471    @SuppressWarnings( { "unused", "nls" })
472    private String(String s1, String s2, String s3) {
473        if (s1 == null) {
474            s1 = "null";
475        }
476        if (s2 == null) {
477            s2 = "null";
478        }
479        if (s3 == null) {
480            s3 = "null";
481        }
482        count = s1.count + s2.count + s3.count;
483        value = new char[count];
484        offset = 0;
485        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
486        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
487        System.arraycopy(s3.value, s3.offset, value, s1.count + s2.count, s3.count);
488    }
489
490    /**
491     * Creates a {@code String} from the contents of the specified
492     * {@code StringBuffer}.
493     */
494    public String(StringBuffer stringBuffer) {
495        offset = 0;
496        synchronized (stringBuffer) {
497            value = stringBuffer.shareValue();
498            count = stringBuffer.length();
499        }
500    }
501
502    /**
503     * Creates a {@code String} from the sub-array of Unicode code points.
504     *
505     * @throws NullPointerException
506     *             if {@code codePoints == null}.
507     * @throws IllegalArgumentException
508     *             if any of the elements of {@code codePoints} are not valid
509     *             Unicode code points.
510     * @throws IndexOutOfBoundsException
511     *             if {@code offset} or {@code count} are not within the bounds
512     *             of {@code codePoints}.
513     * @since 1.5
514     */
515    public String(int[] codePoints, int offset, int count) {
516        if (codePoints == null) {
517            throw new NullPointerException("codePoints == null");
518        }
519        if ((offset | count) < 0 || count > codePoints.length - offset) {
520            throw failedBoundsCheck(codePoints.length, offset, count);
521        }
522        this.offset = 0;
523        this.value = new char[count * 2];
524        int end = offset + count;
525        int c = 0;
526        for (int i = offset; i < end; i++) {
527            c += Character.toChars(codePoints[i], this.value, c);
528        }
529        this.count = c;
530    }
531
532    /**
533     * Creates a {@code String} from the contents of the specified {@code
534     * StringBuilder}.
535     *
536     * @throws NullPointerException
537     *             if {@code stringBuilder == null}.
538     * @since 1.5
539     */
540    public String(StringBuilder stringBuilder) {
541        if (stringBuilder == null) {
542            throw new NullPointerException("stringBuilder == null");
543        }
544        this.offset = 0;
545        this.count = stringBuilder.length();
546        this.value = new char[this.count];
547        stringBuilder.getChars(0, this.count, this.value, 0);
548    }
549
550    /*
551     * Creates a {@code String} that is s1 + v1. May be used by JIT code.
552     */
553    @SuppressWarnings("unused")
554    private String(String s1, int v1) {
555        if (s1 == null) {
556            s1 = "null";
557        }
558        String s2 = String.valueOf(v1);
559        int len = s1.count + s2.count;
560        value = new char[len];
561        offset = 0;
562        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
563        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
564        count = len;
565    }
566
567    /**
568     * Returns the character at the specified offset in this string.
569     *
570     * @param index
571     *            the zero-based index in this string.
572     * @return the character at the index.
573     * @throws IndexOutOfBoundsException
574     *             if {@code index < 0} or {@code index >= length()}.
575     */
576    public native char charAt(int index);
577
578    private StringIndexOutOfBoundsException indexAndLength(int index) {
579        throw new StringIndexOutOfBoundsException(this, index);
580    }
581
582    private StringIndexOutOfBoundsException startEndAndLength(int start, int end) {
583        throw new StringIndexOutOfBoundsException(this, start, end - start);
584    }
585
586    private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) {
587        throw new StringIndexOutOfBoundsException(arrayLength, offset, count);
588    }
589
590    /**
591     * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode
592     * case folds, but it's what the RI uses.
593     */
594    private char foldCase(char ch) {
595        if (ch < 128) {
596            if ('A' <= ch && ch <= 'Z') {
597                return (char) (ch + ('a' - 'A'));
598            }
599            return ch;
600        }
601        return Character.toLowerCase(Character.toUpperCase(ch));
602    }
603
604    /**
605     * Compares the specified string to this string using the Unicode values of
606     * the characters. Returns 0 if the strings contain the same characters in
607     * the same order. Returns a negative integer if the first non-equal
608     * character in this string has a Unicode value which is less than the
609     * Unicode value of the character at the same position in the specified
610     * string, or if this string is a prefix of the specified string. Returns a
611     * positive integer if the first non-equal character in this string has a
612     * Unicode value which is greater than the Unicode value of the character at
613     * the same position in the specified string, or if the specified string is
614     * a prefix of this string.
615     *
616     * @param string
617     *            the string to compare.
618     * @return 0 if the strings are equal, a negative integer if this string is
619     *         before the specified string, or a positive integer if this string
620     *         is after the specified string.
621     * @throws NullPointerException
622     *             if {@code string} is {@code null}.
623     */
624    public native int compareTo(String string);
625
626    /**
627     * Compares the specified string to this string using the Unicode values of
628     * the characters, ignoring case differences. Returns 0 if the strings
629     * contain the same characters in the same order. Returns a negative integer
630     * if the first non-equal character in this string has a Unicode value which
631     * is less than the Unicode value of the character at the same position in
632     * the specified string, or if this string is a prefix of the specified
633     * string. Returns a positive integer if the first non-equal character in
634     * this string has a Unicode value which is greater than the Unicode value
635     * of the character at the same position in the specified string, or if the
636     * specified string is a prefix of this string.
637     *
638     * @param string
639     *            the string to compare.
640     * @return 0 if the strings are equal, a negative integer if this string is
641     *         before the specified string, or a positive integer if this string
642     *         is after the specified string.
643     * @throws NullPointerException
644     *             if {@code string} is {@code null}.
645     */
646    public int compareToIgnoreCase(String string) {
647        int o1 = offset, o2 = string.offset, result;
648        int end = offset + (count < string.count ? count : string.count);
649        char c1, c2;
650        char[] target = string.value;
651        while (o1 < end) {
652            if ((c1 = value[o1++]) == (c2 = target[o2++])) {
653                continue;
654            }
655            c1 = foldCase(c1);
656            c2 = foldCase(c2);
657            if ((result = c1 - c2) != 0) {
658                return result;
659            }
660        }
661        return count - string.count;
662    }
663
664    /**
665     * Concatenates this string and the specified string.
666     *
667     * @param string
668     *            the string to concatenate
669     * @return a new string which is the concatenation of this string and the
670     *         specified string.
671     */
672    public String concat(String string) {
673        if (string.count > 0 && count > 0) {
674            char[] buffer = new char[count + string.count];
675            System.arraycopy(value, offset, buffer, 0, count);
676            System.arraycopy(string.value, string.offset, buffer, count, string.count);
677            return new String(0, buffer.length, buffer);
678        }
679        return count == 0 ? string : this;
680    }
681
682    /**
683     * Creates a new string containing the characters in the specified character
684     * array. Modifying the character array after creating the string has no
685     * effect on the string.
686     *
687     * @param data
688     *            the array of characters.
689     * @return the new string.
690     * @throws NullPointerException
691     *             if {@code data} is {@code null}.
692     */
693    public static String copyValueOf(char[] data) {
694        return new String(data, 0, data.length);
695    }
696
697    /**
698     * Creates a new string containing the specified characters in the character
699     * array. Modifying the character array after creating the string has no
700     * effect on the string.
701     *
702     * @param data
703     *            the array of characters.
704     * @param start
705     *            the starting offset in the character array.
706     * @param length
707     *            the number of characters to use.
708     * @return the new string.
709     * @throws NullPointerException
710     *             if {@code data} is {@code null}.
711     * @throws IndexOutOfBoundsException
712     *             if {@code length < 0, start < 0} or {@code start + length >
713     *             data.length}.
714     */
715    public static String copyValueOf(char[] data, int start, int length) {
716        return new String(data, start, length);
717    }
718
719    /**
720     * Compares the specified string to this string to determine if the
721     * specified string is a suffix.
722     *
723     * @param suffix
724     *            the suffix to look for.
725     * @return {@code true} if the specified string is a suffix of this string,
726     *         {@code false} otherwise.
727     * @throws NullPointerException
728     *             if {@code suffix} is {@code null}.
729     */
730    public boolean endsWith(String suffix) {
731        return regionMatches(count - suffix.count, suffix, 0, suffix.count);
732    }
733
734    /**
735     * Compares the specified object to this string and returns true if they are
736     * equal. The object must be an instance of string with the same characters
737     * in the same order.
738     *
739     * @param object
740     *            the object to compare.
741     * @return {@code true} if the specified object is equal to this string,
742     *         {@code false} otherwise.
743     * @see #hashCode
744     */
745    @Override public native boolean equals(Object object);
746
747    /**
748     * Compares the specified string to this string ignoring the case of the
749     * characters and returns true if they are equal.
750     *
751     * @param string
752     *            the string to compare.
753     * @return {@code true} if the specified string is equal to this string,
754     *         {@code false} otherwise.
755     */
756    @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
757    public boolean equalsIgnoreCase(String string) {
758        if (string == this) {
759            return true;
760        }
761        if (string == null || count != string.count) {
762            return false;
763        }
764        int o1 = offset, o2 = string.offset;
765        int end = offset + count;
766        char[] target = string.value;
767        while (o1 < end) {
768            char c1 = value[o1++];
769            char c2 = target[o2++];
770            if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
771                return false;
772            }
773        }
774        return true;
775    }
776
777    /**
778     * Mangles this string into a byte array by stripping the high order bits from
779     * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
780     *
781     * @param start
782     *            the starting offset of characters to copy.
783     * @param end
784     *            the ending offset of characters to copy.
785     * @param data
786     *            the destination byte array.
787     * @param index
788     *            the starting offset in the destination byte array.
789     * @throws NullPointerException
790     *             if {@code data} is {@code null}.
791     * @throws IndexOutOfBoundsException
792     *             if {@code start < 0}, {@code end > length()}, {@code index <
793     *             0} or {@code end - start > data.length - index}.
794     * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)}
795     */
796    @Deprecated
797    public void getBytes(int start, int end, byte[] data, int index) {
798        // Note: last character not copied!
799        if (start >= 0 && start <= end && end <= count) {
800            end += offset;
801            try {
802                for (int i = offset + start; i < end; i++) {
803                    data[index++] = (byte) value[i];
804                }
805            } catch (ArrayIndexOutOfBoundsException ignored) {
806                throw failedBoundsCheck(data.length, index, end - start);
807            }
808        } else {
809            throw startEndAndLength(start, end);
810        }
811    }
812
813    /**
814     * Returns a new byte array containing the characters of this string encoded using the
815     * system's {@link java.nio.charset.Charset#defaultCharset default charset}.
816     *
817     * <p>The behavior when this string cannot be represented in the system's default charset
818     * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android),
819     * all strings can be encoded.
820     */
821    public byte[] getBytes() {
822        return getBytes(Charset.defaultCharset());
823    }
824
825    /**
826     * Returns a new byte array containing the characters of this string encoded using the
827     * named charset.
828     *
829     * <p>The behavior when this string cannot be represented in the named charset
830     * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control.
831     *
832     * @throws UnsupportedEncodingException if the charset is not supported
833     */
834    public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
835        return getBytes(Charset.forNameUEE(charsetName));
836    }
837
838    /**
839     * Returns a new byte array containing the characters of this string encoded using the
840     * given charset.
841     *
842     * <p>The behavior when this string cannot be represented in the given charset
843     * is to replace malformed input and unmappable characters with the charset's default
844     * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
845     *
846     * @since 1.6
847     */
848    public byte[] getBytes(Charset charset) {
849        String canonicalCharsetName = charset.name();
850        if (canonicalCharsetName.equals("UTF-8")) {
851            return Charsets.toUtf8Bytes(value, offset, count);
852        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
853            return Charsets.toIsoLatin1Bytes(value, offset, count);
854        } else if (canonicalCharsetName.equals("US-ASCII")) {
855            return Charsets.toAsciiBytes(value, offset, count);
856        } else if (canonicalCharsetName.equals("UTF-16BE")) {
857            return Charsets.toBigEndianUtf16Bytes(value, offset, count);
858        } else {
859            CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
860            ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
861            byte[] bytes = new byte[buffer.limit()];
862            buffer.get(bytes);
863            return bytes;
864        }
865    }
866
867    /**
868     * Copies the specified characters in this string to the character array
869     * starting at the specified offset in the character array.
870     *
871     * @param start
872     *            the starting offset of characters to copy.
873     * @param end
874     *            the ending offset of characters to copy.
875     * @param buffer
876     *            the destination character array.
877     * @param index
878     *            the starting offset in the character array.
879     * @throws NullPointerException
880     *             if {@code buffer} is {@code null}.
881     * @throws IndexOutOfBoundsException
882     *             if {@code start < 0}, {@code end > length()}, {@code start >
883     *             end}, {@code index < 0}, {@code end - start > buffer.length -
884     *             index}
885     */
886    public void getChars(int start, int end, char[] buffer, int index) {
887        // Note: last character not copied!
888        if (start >= 0 && start <= end && end <= count) {
889            System.arraycopy(value, start + offset, buffer, index, end - start);
890        } else {
891            // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE.
892            throw startEndAndLength(start, end);
893        }
894    }
895
896    /**
897     * Version of getChars without bounds checks, for use by other classes
898     * within the java.lang package only.  The caller is responsible for
899     * ensuring that start >= 0 && start <= end && end <= count.
900     */
901    void _getChars(int start, int end, char[] buffer, int index) {
902        // NOTE last character not copied!
903        System.arraycopy(value, start + offset, buffer, index, end - start);
904    }
905
906    @Override public int hashCode() {
907        int hash = hashCode;
908        if (hash == 0) {
909            if (count == 0) {
910                return 0;
911            }
912            final int end = count + offset;
913            final char[] chars = value;
914            for (int i = offset; i < end; ++i) {
915                hash = 31*hash + chars[i];
916            }
917            hashCode = hash;
918        }
919        return hash;
920    }
921
922    /**
923     * Searches in this string for the first index of the specified character.
924     * The search for the character starts at the beginning and moves towards
925     * the end of this string.
926     *
927     * @param c
928     *            the character to find.
929     * @return the index in this string of the specified character, -1 if the
930     *         character isn't found.
931     */
932    public int indexOf(int c) {
933        // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
934        if (c > 0xffff) {
935            return indexOfSupplementary(c, 0);
936        }
937        return fastIndexOf(c, 0);
938    }
939
940    /**
941     * Searches in this string for the index of the specified character. The
942     * search for the character starts at the specified offset and moves towards
943     * the end of this string.
944     *
945     * @param c
946     *            the character to find.
947     * @param start
948     *            the starting offset.
949     * @return the index in this string of the specified character, -1 if the
950     *         character isn't found.
951     */
952    public int indexOf(int c, int start) {
953        if (c > 0xffff) {
954            return indexOfSupplementary(c, start);
955        }
956        return fastIndexOf(c, start);
957    }
958
959    private native int fastIndexOf(int c, int start);
960
961    private int indexOfSupplementary(int c, int start) {
962        if (!Character.isSupplementaryCodePoint(c)) {
963            return -1;
964        }
965        char[] chars = Character.toChars(c);
966        String needle = new String(0, chars.length, chars);
967        return indexOf(needle, start);
968    }
969
970    /**
971     * Searches in this string for the first index of the specified string. The
972     * search for the string starts at the beginning and moves towards the end
973     * of this string.
974     *
975     * @param string
976     *            the string to find.
977     * @return the index of the first character of the specified string in this
978     *         string, -1 if the specified string is not a substring.
979     * @throws NullPointerException
980     *             if {@code string} is {@code null}.
981     */
982    public int indexOf(String string) {
983        int start = 0;
984        int subCount = string.count;
985        int _count = count;
986        if (subCount > 0) {
987            if (subCount > _count) {
988                return -1;
989            }
990            char[] target = string.value;
991            int subOffset = string.offset;
992            char firstChar = target[subOffset];
993            int end = subOffset + subCount;
994            while (true) {
995                int i = indexOf(firstChar, start);
996                if (i == -1 || subCount + i > _count) {
997                    return -1; // handles subCount > count || start >= count
998                }
999                int o1 = offset + i, o2 = subOffset;
1000                char[] _value = value;
1001                while (++o2 < end && _value[++o1] == target[o2]) {
1002                    // Intentionally empty
1003                }
1004                if (o2 == end) {
1005                    return i;
1006                }
1007                start = i + 1;
1008            }
1009        }
1010        return start < _count ? start : _count;
1011    }
1012
1013    /**
1014     * Searches in this string for the index of the specified string. The search
1015     * for the string starts at the specified offset and moves towards the end
1016     * of this string.
1017     *
1018     * @param subString
1019     *            the string to find.
1020     * @param start
1021     *            the starting offset.
1022     * @return the index of the first character of the specified string in this
1023     *         string, -1 if the specified string is not a substring.
1024     * @throws NullPointerException
1025     *             if {@code subString} is {@code null}.
1026     */
1027    public int indexOf(String subString, int start) {
1028        if (start < 0) {
1029            start = 0;
1030        }
1031        int subCount = subString.count;
1032        int _count = count;
1033        if (subCount > 0) {
1034            if (subCount + start > _count) {
1035                return -1;
1036            }
1037            char[] target = subString.value;
1038            int subOffset = subString.offset;
1039            char firstChar = target[subOffset];
1040            int end = subOffset + subCount;
1041            while (true) {
1042                int i = indexOf(firstChar, start);
1043                if (i == -1 || subCount + i > _count) {
1044                    return -1; // handles subCount > count || start >= count
1045                }
1046                int o1 = offset + i, o2 = subOffset;
1047                char[] _value = value;
1048                while (++o2 < end && _value[++o1] == target[o2]) {
1049                    // Intentionally empty
1050                }
1051                if (o2 == end) {
1052                    return i;
1053                }
1054                start = i + 1;
1055            }
1056        }
1057        return start < _count ? start : _count;
1058    }
1059
1060    /**
1061     * Returns an interned string equal to this string. The VM maintains an internal set of
1062     * unique strings. All string literals found in loaded classes'
1063     * constant pools are automatically interned. Manually-interned strings are only weakly
1064     * referenced, so calling {@code intern} won't lead to unwanted retention.
1065     *
1066     * <p>Interning is typically used because it guarantees that for interned strings
1067     * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to
1068     * {@code a == b}. (This is not true of non-interned strings.)
1069     *
1070     * <p>Many applications find it simpler and more convenient to use an explicit
1071     * {@link java.util.HashMap} to implement their own pools.
1072     */
1073    public native String intern();
1074
1075    /**
1076     * Returns true if the length of this string is 0.
1077     *
1078     * @since 1.6
1079     */
1080    public native boolean isEmpty();
1081
1082    /**
1083     * Returns the last index of the code point {@code c}, or -1.
1084     * The search for the character starts at the end and moves towards the
1085     * beginning of this string.
1086     */
1087    public int lastIndexOf(int c) {
1088        if (c > 0xffff) {
1089            return lastIndexOfSupplementary(c, Integer.MAX_VALUE);
1090        }
1091        int _count = count;
1092        int _offset = offset;
1093        char[] _value = value;
1094        for (int i = _offset + _count - 1; i >= _offset; --i) {
1095            if (_value[i] == c) {
1096                return i - _offset;
1097            }
1098        }
1099        return -1;
1100    }
1101
1102    /**
1103     * Returns the last index of the code point {@code c}, or -1.
1104     * The search for the character starts at offset {@code start} and moves towards
1105     * the beginning of this string.
1106     */
1107    public int lastIndexOf(int c, int start) {
1108        if (c > 0xffff) {
1109            return lastIndexOfSupplementary(c, start);
1110        }
1111        int _count = count;
1112        int _offset = offset;
1113        char[] _value = value;
1114        if (start >= 0) {
1115            if (start >= _count) {
1116                start = _count - 1;
1117            }
1118            for (int i = _offset + start; i >= _offset; --i) {
1119                if (_value[i] == c) {
1120                    return i - _offset;
1121                }
1122            }
1123        }
1124        return -1;
1125    }
1126
1127    private int lastIndexOfSupplementary(int c, int start) {
1128        if (!Character.isSupplementaryCodePoint(c)) {
1129            return -1;
1130        }
1131        char[] chars = Character.toChars(c);
1132        String needle = new String(0, chars.length, chars);
1133        return lastIndexOf(needle, start);
1134    }
1135
1136    /**
1137     * Searches in this string for the last index of the specified string. The
1138     * search for the string starts at the end and moves towards the beginning
1139     * of this string.
1140     *
1141     * @param string
1142     *            the string to find.
1143     * @return the index of the first character of the specified string in this
1144     *         string, -1 if the specified string is not a substring.
1145     * @throws NullPointerException
1146     *             if {@code string} is {@code null}.
1147     */
1148    public int lastIndexOf(String string) {
1149        // Use count instead of count - 1 so lastIndexOf("") returns count
1150        return lastIndexOf(string, count);
1151    }
1152
1153    /**
1154     * Searches in this string for the index of the specified string. The search
1155     * for the string starts at the specified offset and moves towards the
1156     * beginning of this string.
1157     *
1158     * @param subString
1159     *            the string to find.
1160     * @param start
1161     *            the starting offset.
1162     * @return the index of the first character of the specified string in this
1163     *         string , -1 if the specified string is not a substring.
1164     * @throws NullPointerException
1165     *             if {@code subString} is {@code null}.
1166     */
1167    public int lastIndexOf(String subString, int start) {
1168        int subCount = subString.count;
1169        if (subCount <= count && start >= 0) {
1170            if (subCount > 0) {
1171                if (start > count - subCount) {
1172                    start = count - subCount;
1173                }
1174                // count and subCount are both >= 1
1175                char[] target = subString.value;
1176                int subOffset = subString.offset;
1177                char firstChar = target[subOffset];
1178                int end = subOffset + subCount;
1179                while (true) {
1180                    int i = lastIndexOf(firstChar, start);
1181                    if (i == -1) {
1182                        return -1;
1183                    }
1184                    int o1 = offset + i, o2 = subOffset;
1185                    while (++o2 < end && value[++o1] == target[o2]) {
1186                        // Intentionally empty
1187                    }
1188                    if (o2 == end) {
1189                        return i;
1190                    }
1191                    start = i - 1;
1192                }
1193            }
1194            return start < count ? start : count;
1195        }
1196        return -1;
1197    }
1198
1199    /**
1200     * Returns the size of this string.
1201     *
1202     * @return the number of characters in this string.
1203     */
1204    public native int length();
1205
1206    /**
1207     * Compares the specified string to this string and compares the specified
1208     * range of characters to determine if they are the same.
1209     *
1210     * @param thisStart
1211     *            the starting offset in this string.
1212     * @param string
1213     *            the string to compare.
1214     * @param start
1215     *            the starting offset in the specified string.
1216     * @param length
1217     *            the number of characters to compare.
1218     * @return {@code true} if the ranges of characters are equal, {@code false}
1219     *         otherwise
1220     * @throws NullPointerException
1221     *             if {@code string} is {@code null}.
1222     */
1223    public boolean regionMatches(int thisStart, String string, int start, int length) {
1224        if (string == null) {
1225            throw new NullPointerException("string == null");
1226        }
1227        if (start < 0 || string.count - start < length) {
1228            return false;
1229        }
1230        if (thisStart < 0 || count - thisStart < length) {
1231            return false;
1232        }
1233        if (length <= 0) {
1234            return true;
1235        }
1236        int o1 = offset + thisStart, o2 = string.offset + start;
1237        char[] value1 = value;
1238        char[] value2 = string.value;
1239        for (int i = 0; i < length; ++i) {
1240            if (value1[o1 + i] != value2[o2 + i]) {
1241                return false;
1242            }
1243        }
1244        return true;
1245    }
1246
1247    /**
1248     * Compares the specified string to this string and compares the specified
1249     * range of characters to determine if they are the same. When ignoreCase is
1250     * true, the case of the characters is ignored during the comparison.
1251     *
1252     * @param ignoreCase
1253     *            specifies if case should be ignored.
1254     * @param thisStart
1255     *            the starting offset in this string.
1256     * @param string
1257     *            the string to compare.
1258     * @param start
1259     *            the starting offset in the specified string.
1260     * @param length
1261     *            the number of characters to compare.
1262     * @return {@code true} if the ranges of characters are equal, {@code false}
1263     *         otherwise.
1264     * @throws NullPointerException
1265     *             if {@code string} is {@code null}.
1266     */
1267    public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) {
1268        if (!ignoreCase) {
1269            return regionMatches(thisStart, string, start, length);
1270        }
1271        if (string == null) {
1272            throw new NullPointerException("string == null");
1273        }
1274        if (thisStart < 0 || length > count - thisStart) {
1275            return false;
1276        }
1277        if (start < 0 || length > string.count - start) {
1278            return false;
1279        }
1280        thisStart += offset;
1281        start += string.offset;
1282        int end = thisStart + length;
1283        char[] target = string.value;
1284        while (thisStart < end) {
1285            char c1 = value[thisStart++];
1286            char c2 = target[start++];
1287            if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
1288                return false;
1289            }
1290        }
1291        return true;
1292    }
1293
1294    /**
1295     * Copies this string replacing occurrences of the specified character with
1296     * another character.
1297     *
1298     * @param oldChar
1299     *            the character to replace.
1300     * @param newChar
1301     *            the replacement character.
1302     * @return a new string with occurrences of oldChar replaced by newChar.
1303     */
1304    public String replace(char oldChar, char newChar) {
1305        char[] buffer = value;
1306        int _offset = offset;
1307        int _count = count;
1308
1309        int idx = _offset;
1310        int last = _offset + _count;
1311        boolean copied = false;
1312        while (idx < last) {
1313            if (buffer[idx] == oldChar) {
1314                if (!copied) {
1315                    char[] newBuffer = new char[_count];
1316                    System.arraycopy(buffer, _offset, newBuffer, 0, _count);
1317                    buffer = newBuffer;
1318                    idx -= _offset;
1319                    last -= _offset;
1320                    copied = true;
1321                }
1322                buffer[idx] = newChar;
1323            }
1324            idx++;
1325        }
1326
1327        return copied ? new String(0, count, buffer) : this;
1328    }
1329
1330    /**
1331     * Copies this string replacing occurrences of the specified target sequence
1332     * with another sequence. The string is processed from the beginning to the
1333     * end.
1334     *
1335     * @param target
1336     *            the sequence to replace.
1337     * @param replacement
1338     *            the replacement sequence.
1339     * @return the resulting string.
1340     * @throws NullPointerException
1341     *             if {@code target} or {@code replacement} is {@code null}.
1342     */
1343    public String replace(CharSequence target, CharSequence replacement) {
1344        if (target == null) {
1345            throw new NullPointerException("target == null");
1346        }
1347        if (replacement == null) {
1348            throw new NullPointerException("replacement == null");
1349        }
1350
1351        String targetString = target.toString();
1352        int matchStart = indexOf(targetString, 0);
1353        if (matchStart == -1) {
1354            // If there's nothing to replace, return the original string untouched.
1355            return this;
1356        }
1357
1358        String replacementString = replacement.toString();
1359
1360        // The empty target matches at the start and end and between each character.
1361        int targetLength = targetString.length();
1362        if (targetLength == 0) {
1363            int resultLength = (count + 2) * replacementString.length();
1364            StringBuilder result = new StringBuilder(resultLength);
1365            result.append(replacementString);
1366            for (int i = offset; i < count; ++i) {
1367                result.append(value[i]);
1368                result.append(replacementString);
1369            }
1370            return result.toString();
1371        }
1372
1373        StringBuilder result = new StringBuilder(count);
1374        int searchStart = 0;
1375        do {
1376            // Copy characters before the match...
1377            result.append(value, offset + searchStart, matchStart - searchStart);
1378            // Insert the replacement...
1379            result.append(replacementString);
1380            // And skip over the match...
1381            searchStart = matchStart + targetLength;
1382        } while ((matchStart = indexOf(targetString, searchStart)) != -1);
1383        // Copy any trailing chars...
1384        result.append(value, offset + searchStart, count - searchStart);
1385        return result.toString();
1386    }
1387
1388    /**
1389     * Compares the specified string to this string to determine if the
1390     * specified string is a prefix.
1391     *
1392     * @param prefix
1393     *            the string to look for.
1394     * @return {@code true} if the specified string is a prefix of this string,
1395     *         {@code false} otherwise
1396     * @throws NullPointerException
1397     *             if {@code prefix} is {@code null}.
1398     */
1399    public boolean startsWith(String prefix) {
1400        return startsWith(prefix, 0);
1401    }
1402
1403    /**
1404     * Compares the specified string to this string, starting at the specified
1405     * offset, to determine if the specified string is a prefix.
1406     *
1407     * @param prefix
1408     *            the string to look for.
1409     * @param start
1410     *            the starting offset.
1411     * @return {@code true} if the specified string occurs in this string at the
1412     *         specified offset, {@code false} otherwise.
1413     * @throws NullPointerException
1414     *             if {@code prefix} is {@code null}.
1415     */
1416    public boolean startsWith(String prefix, int start) {
1417        return regionMatches(start, prefix, 0, prefix.count);
1418    }
1419
1420    /**
1421     * Returns a string containing a suffix of this string. The returned string
1422     * shares this string's <a href="#backing_array">backing array</a>.
1423     *
1424     * @param start
1425     *            the offset of the first character.
1426     * @return a new string containing the characters from start to the end of
1427     *         the string.
1428     * @throws IndexOutOfBoundsException
1429     *             if {@code start < 0} or {@code start > length()}.
1430     */
1431    public String substring(int start) {
1432        if (start == 0) {
1433            return this;
1434        }
1435        if (start >= 0 && start <= count) {
1436            return new String(offset + start, count - start, value);
1437        }
1438        throw indexAndLength(start);
1439    }
1440
1441    /**
1442     * Returns a string containing a subsequence of characters from this string.
1443     * The returned string shares this string's <a href="#backing_array">backing
1444     * array</a>.
1445     *
1446     * @param start
1447     *            the offset of the first character.
1448     * @param end
1449     *            the offset one past the last character.
1450     * @return a new string containing the characters from start to end - 1
1451     * @throws IndexOutOfBoundsException
1452     *             if {@code start < 0}, {@code start > end} or {@code end >
1453     *             length()}.
1454     */
1455    public String substring(int start, int end) {
1456        if (start == 0 && end == count) {
1457            return this;
1458        }
1459        // NOTE last character not copied!
1460        // Fast range check.
1461        if (start >= 0 && start <= end && end <= count) {
1462            return new String(offset + start, end - start, value);
1463        }
1464        throw startEndAndLength(start, end);
1465    }
1466
1467    /**
1468     * Copies the characters in this string to a character array.
1469     *
1470     * @return a character array containing the characters of this string.
1471     */
1472    public char[] toCharArray() {
1473        char[] buffer = new char[count];
1474        System.arraycopy(value, offset, buffer, 0, count);
1475        return buffer;
1476    }
1477
1478    /**
1479     * Converts this string to lower case, using the rules of the user's default locale.
1480     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1481     *
1482     * @return a new lower case string, or {@code this} if it's already all lower case.
1483     */
1484    public String toLowerCase() {
1485        return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count);
1486    }
1487
1488    /**
1489     * Converts this string to lower case, using the rules of {@code locale}.
1490     *
1491     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
1492     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
1493     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
1494     * correct case mapping of Greek characters: any locale will do.
1495     *
1496     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
1497     * for full details of context- and language-specific special cases.
1498     *
1499     * @return a new lower case string, or {@code this} if it's already all lower case.
1500     */
1501    public String toLowerCase(Locale locale) {
1502        return CaseMapper.toLowerCase(locale, this, value, offset, count);
1503    }
1504
1505    /**
1506     * Returns this string.
1507     */
1508    @Override
1509    public String toString() {
1510        return this;
1511    }
1512
1513    /**
1514     * Converts this this string to upper case, using the rules of the user's default locale.
1515     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1516     *
1517     * @return a new upper case string, or {@code this} if it's already all upper case.
1518     */
1519    public String toUpperCase() {
1520        return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
1521    }
1522
1523    /**
1524     * Converts this this string to upper case, using the rules of {@code locale}.
1525     *
1526     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
1527     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
1528     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
1529     * correct case mapping of Greek characters: any locale will do.
1530     *
1531     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
1532     * for full details of context- and language-specific special cases.
1533     *
1534     * @return a new upper case string, or {@code this} if it's already all upper case.
1535     */
1536    public String toUpperCase(Locale locale) {
1537        return CaseMapper.toUpperCase(locale, this, value, offset, count);
1538    }
1539
1540    /**
1541     * Copies this string removing white space characters from the beginning and
1542     * end of the string.
1543     *
1544     * @return a new string with characters <code><= \\u0020</code> removed from
1545     *         the beginning and the end.
1546     */
1547    public String trim() {
1548        int start = offset, last = offset + count - 1;
1549        int end = last;
1550        while ((start <= end) && (value[start] <= ' ')) {
1551            start++;
1552        }
1553        while ((end >= start) && (value[end] <= ' ')) {
1554            end--;
1555        }
1556        if (start == offset && end == last) {
1557            return this;
1558        }
1559        return new String(start, end - start + 1, value);
1560    }
1561
1562    /**
1563     * Creates a new string containing the characters in the specified character
1564     * array. Modifying the character array after creating the string has no
1565     * effect on the string.
1566     *
1567     * @param data
1568     *            the array of characters.
1569     * @return the new string.
1570     * @throws NullPointerException
1571     *             if {@code data} is {@code null}.
1572     */
1573    public static String valueOf(char[] data) {
1574        return new String(data, 0, data.length);
1575    }
1576
1577    /**
1578     * Creates a new string containing the specified characters in the character
1579     * array. Modifying the character array after creating the string has no
1580     * effect on the string.
1581     *
1582     * @param data
1583     *            the array of characters.
1584     * @param start
1585     *            the starting offset in the character array.
1586     * @param length
1587     *            the number of characters to use.
1588     * @return the new string.
1589     * @throws IndexOutOfBoundsException
1590     *             if {@code length < 0}, {@code start < 0} or {@code start +
1591     *             length > data.length}
1592     * @throws NullPointerException
1593     *             if {@code data} is {@code null}.
1594     */
1595    public static String valueOf(char[] data, int start, int length) {
1596        return new String(data, start, length);
1597    }
1598
1599    /**
1600     * Converts the specified character to its string representation.
1601     *
1602     * @param value
1603     *            the character.
1604     * @return the character converted to a string.
1605     */
1606    public static String valueOf(char value) {
1607        String s;
1608        if (value < 128) {
1609            s = new String(value, 1, ASCII);
1610        } else {
1611            s = new String(0, 1, new char[] { value });
1612        }
1613        s.hashCode = value;
1614        return s;
1615    }
1616
1617    /**
1618     * Converts the specified double to its string representation.
1619     *
1620     * @param value
1621     *            the double.
1622     * @return the double converted to a string.
1623     */
1624    public static String valueOf(double value) {
1625        return Double.toString(value);
1626    }
1627
1628    /**
1629     * Converts the specified float to its string representation.
1630     *
1631     * @param value
1632     *            the float.
1633     * @return the float converted to a string.
1634     */
1635    public static String valueOf(float value) {
1636        return Float.toString(value);
1637    }
1638
1639    /**
1640     * Converts the specified integer to its string representation.
1641     *
1642     * @param value
1643     *            the integer.
1644     * @return the integer converted to a string.
1645     */
1646    public static String valueOf(int value) {
1647        return Integer.toString(value);
1648    }
1649
1650    /**
1651     * Converts the specified long to its string representation.
1652     *
1653     * @param value
1654     *            the long.
1655     * @return the long converted to a string.
1656     */
1657    public static String valueOf(long value) {
1658        return Long.toString(value);
1659    }
1660
1661    /**
1662     * Converts the specified object to its string representation. If the object
1663     * is null return the string {@code "null"}, otherwise use {@code
1664     * toString()} to get the string representation.
1665     *
1666     * @param value
1667     *            the object.
1668     * @return the object converted to a string, or the string {@code "null"}.
1669     */
1670    public static String valueOf(Object value) {
1671        return value != null ? value.toString() : "null";
1672    }
1673
1674    /**
1675     * Converts the specified boolean to its string representation. When the
1676     * boolean is {@code true} return {@code "true"}, otherwise return {@code
1677     * "false"}.
1678     *
1679     * @param value
1680     *            the boolean.
1681     * @return the boolean converted to a string.
1682     */
1683    public static String valueOf(boolean value) {
1684        return value ? "true" : "false";
1685    }
1686
1687    /**
1688     * Returns whether the characters in the StringBuffer {@code strbuf} are the
1689     * same as those in this string.
1690     *
1691     * @param strbuf
1692     *            the StringBuffer to compare this string to.
1693     * @return {@code true} if the characters in {@code strbuf} are identical to
1694     *         those in this string. If they are not, {@code false} will be
1695     *         returned.
1696     * @throws NullPointerException
1697     *             if {@code strbuf} is {@code null}.
1698     * @since 1.4
1699     */
1700    public boolean contentEquals(StringBuffer strbuf) {
1701        synchronized (strbuf) {
1702            int size = strbuf.length();
1703            if (count != size) {
1704                return false;
1705            }
1706            return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
1707                    size);
1708        }
1709    }
1710
1711    /**
1712     * Compares a {@code CharSequence} to this {@code String} to determine if
1713     * their contents are equal.
1714     *
1715     * @param cs
1716     *            the character sequence to compare to.
1717     * @return {@code true} if equal, otherwise {@code false}
1718     * @since 1.5
1719     */
1720    public boolean contentEquals(CharSequence cs) {
1721        if (cs == null) {
1722            throw new NullPointerException("cs == null");
1723        }
1724
1725        int len = cs.length();
1726
1727        if (len != count) {
1728            return false;
1729        }
1730
1731        if (len == 0 && count == 0) {
1732            return true; // since both are empty strings
1733        }
1734
1735        return regionMatches(0, cs.toString(), 0, len);
1736    }
1737
1738    /**
1739     * Tests whether this string matches the given {@code regularExpression}. This method returns
1740     * true only if the regular expression matches the <i>entire</i> input string. A common mistake is
1741     * to assume that this method behaves like {@link #contains}; if you want to match anywhere
1742     * within the input string, you need to add {@code .*} to the beginning and end of your
1743     * regular expression. See {@link Pattern#matches}.
1744     *
1745     * <p>If the same regular expression is to be used for multiple operations, it may be more
1746     * efficient to reuse a compiled {@code Pattern}.
1747     *
1748     * @throws PatternSyntaxException
1749     *             if the syntax of the supplied regular expression is not
1750     *             valid.
1751     * @throws NullPointerException if {@code regularExpression == null}
1752     * @since 1.4
1753     */
1754    public boolean matches(String regularExpression) {
1755        return Pattern.matches(regularExpression, this);
1756    }
1757
1758    /**
1759     * Replaces all matches for {@code regularExpression} within this string with the given
1760     * {@code replacement}.
1761     * See {@link Pattern} for regular expression syntax.
1762     *
1763     * <p>If the same regular expression is to be used for multiple operations, it may be more
1764     * efficient to reuse a compiled {@code Pattern}.
1765     *
1766     * @throws PatternSyntaxException
1767     *             if the syntax of the supplied regular expression is not
1768     *             valid.
1769     * @throws NullPointerException if {@code regularExpression == null}
1770     * @see Pattern
1771     * @since 1.4
1772     */
1773    public String replaceAll(String regularExpression, String replacement) {
1774        return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement);
1775    }
1776
1777    /**
1778     * Replaces the first match for {@code regularExpression} within this string with the given
1779     * {@code replacement}.
1780     * See {@link Pattern} for regular expression syntax.
1781     *
1782     * <p>If the same regular expression is to be used for multiple operations, it may be more
1783     * efficient to reuse a compiled {@code Pattern}.
1784     *
1785     * @throws PatternSyntaxException
1786     *             if the syntax of the supplied regular expression is not
1787     *             valid.
1788     * @throws NullPointerException if {@code regularExpression == null}
1789     * @see Pattern
1790     * @since 1.4
1791     */
1792    public String replaceFirst(String regularExpression, String replacement) {
1793        return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement);
1794    }
1795
1796    /**
1797     * Splits this string using the supplied {@code regularExpression}.
1798     * Equivalent to {@code split(regularExpression, 0)}.
1799     * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
1800     * See {@link Pattern} for regular expression syntax.
1801     *
1802     * <p>If the same regular expression is to be used for multiple operations, it may be more
1803     * efficient to reuse a compiled {@code Pattern}.
1804     *
1805     * @throws NullPointerException if {@code regularExpression ==  null}
1806     * @throws PatternSyntaxException
1807     *             if the syntax of the supplied regular expression is not
1808     *             valid.
1809     * @see Pattern
1810     * @since 1.4
1811     */
1812    public String[] split(String regularExpression) {
1813        return split(regularExpression, 0);
1814    }
1815
1816    /**
1817     * Splits this string using the supplied {@code regularExpression}.
1818     * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
1819     * See {@link Pattern} for regular expression syntax.
1820     *
1821     * <p>If the same regular expression is to be used for multiple operations, it may be more
1822     * efficient to reuse a compiled {@code Pattern}.
1823     *
1824     * @throws NullPointerException if {@code regularExpression ==  null}
1825     * @throws PatternSyntaxException
1826     *             if the syntax of the supplied regular expression is not
1827     *             valid.
1828     * @since 1.4
1829     */
1830    public String[] split(String regularExpression, int limit) {
1831        String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit);
1832        return result != null ? result : Pattern.compile(regularExpression).split(this, limit);
1833    }
1834
1835    /**
1836     * Has the same result as the substring function, but is present so that
1837     * string may implement the CharSequence interface.
1838     *
1839     * @param start
1840     *            the offset the first character.
1841     * @param end
1842     *            the offset of one past the last character to include.
1843     * @return the subsequence requested.
1844     * @throws IndexOutOfBoundsException
1845     *             if {@code start < 0}, {@code end < 0}, {@code start > end} or
1846     *             {@code end > length()}.
1847     * @see java.lang.CharSequence#subSequence(int, int)
1848     * @since 1.4
1849     */
1850    public CharSequence subSequence(int start, int end) {
1851        return substring(start, end);
1852    }
1853
1854    /**
1855     * Returns the Unicode code point at the given {@code index}.
1856     *
1857     * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()}
1858     * @see Character#codePointAt(char[], int, int)
1859     * @since 1.5
1860     */
1861    public int codePointAt(int index) {
1862        if (index < 0 || index >= count) {
1863            throw indexAndLength(index);
1864        }
1865        return Character.codePointAt(value, offset + index, offset + count);
1866    }
1867
1868    /**
1869     * Returns the Unicode code point that precedes the given {@code index}.
1870     *
1871     * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()}
1872     * @see Character#codePointBefore(char[], int, int)
1873     * @since 1.5
1874     */
1875    public int codePointBefore(int index) {
1876        if (index < 1 || index > count) {
1877            throw indexAndLength(index);
1878        }
1879        return Character.codePointBefore(value, offset + index, offset);
1880    }
1881
1882    /**
1883     * Calculates the number of Unicode code points between {@code start}
1884     * and {@code end}.
1885     *
1886     * @param start
1887     *            the inclusive beginning index of the subsequence.
1888     * @param end
1889     *            the exclusive end index of the subsequence.
1890     * @return the number of Unicode code points in the subsequence.
1891     * @throws IndexOutOfBoundsException
1892     *         if {@code start < 0 || end > length() || start > end}
1893     * @see Character#codePointCount(CharSequence, int, int)
1894     * @since 1.5
1895     */
1896    public int codePointCount(int start, int end) {
1897        if (start < 0 || end > count || start > end) {
1898            throw startEndAndLength(start, end);
1899        }
1900        return Character.codePointCount(value, offset + start, end - start);
1901    }
1902
1903    /**
1904     * Determines if this {@code String} contains the sequence of characters in
1905     * the {@code CharSequence} passed.
1906     *
1907     * @param cs
1908     *            the character sequence to search for.
1909     * @return {@code true} if the sequence of characters are contained in this
1910     *         string, otherwise {@code false}.
1911     * @since 1.5
1912     */
1913    public boolean contains(CharSequence cs) {
1914        if (cs == null) {
1915            throw new NullPointerException("cs == null");
1916        }
1917        return indexOf(cs.toString()) >= 0;
1918    }
1919
1920    /**
1921     * Returns the index within this object that is offset from {@code index} by
1922     * {@code codePointOffset} code points.
1923     *
1924     * @param index
1925     *            the index within this object to calculate the offset from.
1926     * @param codePointOffset
1927     *            the number of code points to count.
1928     * @return the index within this object that is the offset.
1929     * @throws IndexOutOfBoundsException
1930     *             if {@code index} is negative or greater than {@code length()}
1931     *             or if there aren't enough code points before or after {@code
1932     *             index} to match {@code codePointOffset}.
1933     * @since 1.5
1934     */
1935    public int offsetByCodePoints(int index, int codePointOffset) {
1936        int s = index + offset;
1937        int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset);
1938        return r - offset;
1939    }
1940
1941    /**
1942     * Returns a localized formatted string, using the supplied format and arguments,
1943     * using the user's default locale.
1944     *
1945     * <p>If you're formatting a string other than for human
1946     * consumption, you should use the {@code format(Locale, String, Object...)}
1947     * overload and supply {@code Locale.US}. See
1948     * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
1949     *
1950     * @param format the format string (see {@link java.util.Formatter#format})
1951     * @param args
1952     *            the list of arguments passed to the formatter. If there are
1953     *            more arguments than required by {@code format},
1954     *            additional arguments are ignored.
1955     * @return the formatted string.
1956     * @throws NullPointerException if {@code format == null}
1957     * @throws java.util.IllegalFormatException
1958     *             if the format is invalid.
1959     * @since 1.5
1960     */
1961    public static String format(String format, Object... args) {
1962        return format(Locale.getDefault(), format, args);
1963    }
1964
1965    /**
1966     * Returns a formatted string, using the supplied format and arguments,
1967     * localized to the given locale.
1968     *
1969     * @param locale
1970     *            the locale to apply; {@code null} value means no localization.
1971     * @param format the format string (see {@link java.util.Formatter#format})
1972     * @param args
1973     *            the list of arguments passed to the formatter. If there are
1974     *            more arguments than required by {@code format},
1975     *            additional arguments are ignored.
1976     * @return the formatted string.
1977     * @throws NullPointerException if {@code format == null}
1978     * @throws java.util.IllegalFormatException
1979     *             if the format is invalid.
1980     * @since 1.5
1981     */
1982    public static String format(Locale locale, String format, Object... args) {
1983        if (format == null) {
1984            throw new NullPointerException("format == null");
1985        }
1986        int bufferSize = format.length() + (args == null ? 0 : args.length * 10);
1987        Formatter f = new Formatter(new StringBuilder(bufferSize), locale);
1988        return f.format(format, args).toString();
1989    }
1990
1991    /*
1992     * An implementation of a String.indexOf that is supposed to perform
1993     * substantially better than the default algorithm if the "needle" (the
1994     * subString being searched for) is a constant string.
1995     *
1996     * For example, a JIT, upon encountering a call to String.indexOf(String),
1997     * where the needle is a constant string, may compute the values cache, md2
1998     * and lastChar, and change the call to the following method.
1999     */
2000    @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
2001    @SuppressWarnings("unused")
2002    private static int indexOf(String haystackString, String needleString,
2003            int cache, int md2, char lastChar) {
2004        char[] haystack = haystackString.value;
2005        int haystackOffset = haystackString.offset;
2006        int haystackLength = haystackString.count;
2007        char[] needle = needleString.value;
2008        int needleOffset = needleString.offset;
2009        int needleLength = needleString.count;
2010        int needleLengthMinus1 = needleLength - 1;
2011        int haystackEnd = haystackOffset + haystackLength;
2012        outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) {
2013            if (lastChar == haystack[i]) {
2014                for (int j = 0; j < needleLengthMinus1; ++j) {
2015                    if (needle[j + needleOffset] != haystack[i + j
2016                            - needleLengthMinus1]) {
2017                        int skip = 1;
2018                        if ((cache & (1 << haystack[i])) == 0) {
2019                            skip += j;
2020                        }
2021                        i += Math.max(md2, skip);
2022                        continue outer_loop;
2023                    }
2024                }
2025                return i - needleLengthMinus1 - haystackOffset;
2026            }
2027
2028            if ((cache & (1 << haystack[i])) == 0) {
2029                i += needleLengthMinus1;
2030            }
2031            i++;
2032        }
2033        return -1;
2034    }
2035}
2036