1 /* String.java -- immutable character sequences; the object of string literals
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4 
5 This file is part of GNU Classpath.
6 
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11 
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21 
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26 
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38 
39 
40 package java.lang;
41 
42 import gnu.java.lang.CharData;
43 import gnu.java.lang.CPStringBuilder;
44 
45 import java.io.Serializable;
46 import java.io.UnsupportedEncodingException;
47 import java.nio.ByteBuffer;
48 import java.nio.CharBuffer;
49 import java.nio.charset.CharacterCodingException;
50 import java.nio.charset.Charset;
51 import java.nio.charset.CharsetDecoder;
52 import java.nio.charset.CharsetEncoder;
53 import java.nio.charset.CodingErrorAction;
54 import java.nio.charset.IllegalCharsetNameException;
55 import java.nio.charset.UnsupportedCharsetException;
56 import java.text.Collator;
57 import java.util.Comparator;
58 import java.util.Formatter;
59 import java.util.Locale;
60 import java.util.regex.Matcher;
61 import java.util.regex.Pattern;
62 import java.util.regex.PatternSyntaxException;
63 
64 /**
65  * Strings represent an immutable set of characters.  All String literals
66  * are instances of this class, and two string literals with the same contents
67  * refer to the same String object.
68  *
69  * <p>This class also includes a number of methods for manipulating the
70  * contents of strings (of course, creating a new object if there are any
71  * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
72  * standards, where some character sequences have a different number of
73  * characters in the uppercase version than the lower case.
74  *
75  * <p>Strings are special, in that they are the only object with an overloaded
76  * operator. When you use '+' with at least one String argument, both
77  * arguments have String conversion performed on them, and another String (not
78  * guaranteed to be unique) results.
79  *
80  * <p>String is special-cased when doing data serialization - rather than
81  * listing the fields of this class, a String object is converted to a string
82  * literal in the object stream.
83  *
84  * @author Paul N. Fisher
85  * @author Eric Blake (ebb9@email.byu.edu)
86  * @author Per Bothner (bothner@cygnus.com)
87  * @author Tom Tromey (tromey@redhat.com)
88  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
89  * @since 1.0
90  * @status updated to 1.4; but could use better data sharing via offset field
91  */
92 public final class String
93   implements Serializable, Comparable<String>, CharSequence
94 {
95   // WARNING: String is a CORE class in the bootstrap cycle. See the comments
96   // in vm/reference/java/lang/Runtime for implications of this fact.
97 
98   /**
99    * This is probably not necessary because this class is special cased already
100    * but it will avoid showing up as a discrepancy when comparing SUIDs.
101    */
102   private static final long serialVersionUID = -6849794470754667710L;
103 
104   /**
105    * Stores unicode multi-character uppercase expansion table.
106    * @see #toUpperCase(Locale)
107    * @see CharData#UPPER_EXPAND
108    */
109   private static final char[] upperExpand
110         = zeroBasedStringValue(CharData.UPPER_EXPAND);
111 
112   /**
113    * Stores unicode multi-character uppercase special casing table.
114    * @see #upperCaseExpansion(char)
115    * @see CharData#UPPER_SPECIAL
116    */
117   private static final char[] upperSpecial
118           = zeroBasedStringValue(CharData.UPPER_SPECIAL);
119 
120   /**
121    * Characters which make up the String.
122    * Package access is granted for use by StringBuffer.
123    */
124   final char[] value;
125 
126   /**
127    * Holds the number of characters in value.  This number is generally
128    * the same as value.length, but can be smaller because substrings and
129    * StringBuffers can share arrays. Package visible for use by trusted code.
130    */
131   final int count;
132 
133   /**
134    * Caches the result of hashCode().  If this value is zero, the hashcode
135    * is considered uncached (even if 0 is the correct hash value).
136    */
137   private int cachedHashCode;
138 
139   /**
140    * Holds the starting position for characters in value[].  Since
141    * substring()'s are common, the use of offset allows the operation
142    * to perform in O(1). Package access is granted for use by StringBuffer.
143    */
144   final int offset;
145 
146   /**
147    * An implementation for {@link #CASE_INSENSITIVE_ORDER}.
148    * This must be {@link Serializable}. The class name is dictated by
149    * compatibility with Sun's JDK.
150    */
151   private static final class CaseInsensitiveComparator
152     implements Comparator<String>, Serializable
153   {
154     /**
155      * Compatible with JDK 1.2.
156      */
157     private static final long serialVersionUID = 8575799808933029326L;
158 
159     /**
160      * The default private constructor generates unnecessary overhead.
161      */
CaseInsensitiveComparator()162     CaseInsensitiveComparator() {}
163 
164     /**
165      * Compares to Strings, using
166      * <code>String.compareToIgnoreCase(String)</code>.
167      *
168      * @param o1 the first string
169      * @param o2 the second string
170      * @return &lt; 0, 0, or &gt; 0 depending on the case-insensitive
171      *         comparison of the two strings.
172      * @throws NullPointerException if either argument is null
173      * @throws ClassCastException if either argument is not a String
174      * @see #compareToIgnoreCase(String)
175      */
compare(String o1, String o2)176     public int compare(String o1, String o2)
177     {
178       return o1.compareToIgnoreCase(o2);
179     }
180   } // class CaseInsensitiveComparator
181 
182   /**
183    * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
184    * This comparator is {@link Serializable}. Note that it ignores Locale,
185    * for that, you want a Collator.
186    *
187    * @see Collator#compare(String, String)
188    * @since 1.2
189    */
190   public static final Comparator<String> CASE_INSENSITIVE_ORDER
191     = new CaseInsensitiveComparator();
192 
193   /**
194    * Creates an empty String (length 0). Unless you really need a new object,
195    * consider using <code>""</code> instead.
196    */
String()197   public String()
198   {
199     value = "".value;
200     offset = 0;
201     count = 0;
202   }
203 
204   /**
205    * Copies the contents of a String to a new String. Since Strings are
206    * immutable, only a shallow copy is performed.
207    *
208    * @param str String to copy
209    * @throws NullPointerException if value is null
210    */
String(String str)211   public String(String str)
212   {
213     value = str.value;
214     offset = str.offset;
215     count = str.count;
216     cachedHashCode = str.cachedHashCode;
217   }
218 
219   /**
220    * Creates a new String using the character sequence of the char array.
221    * Subsequent changes to data do not affect the String.
222    *
223    * @param data char array to copy
224    * @throws NullPointerException if data is null
225    */
String(char[] data)226   public String(char[] data)
227   {
228     this(data, 0, data.length, false);
229   }
230 
231   /**
232    * Creates a new String using the character sequence of a subarray of
233    * characters. The string starts at offset, and copies count chars.
234    * Subsequent changes to data do not affect the String.
235    *
236    * @param data char array to copy
237    * @param offset position (base 0) to start copying out of data
238    * @param count the number of characters from data to copy
239    * @throws NullPointerException if data is null
240    * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
241    *         || offset + count &lt; 0 (overflow)
242    *         || offset + count &gt; data.length)
243    *         (while unspecified, this is a StringIndexOutOfBoundsException)
244    */
String(char[] data, int offset, int count)245   public String(char[] data, int offset, int count)
246   {
247     this(data, offset, count, false);
248   }
249 
250   /**
251    * Creates a new String using an 8-bit array of integer values, starting at
252    * an offset, and copying up to the count. Each character c, using
253    * corresponding byte b, is created in the new String as if by performing:
254    *
255    * <pre>
256    * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
257    * </pre>
258    *
259    * @param ascii array of integer values
260    * @param hibyte top byte of each Unicode character
261    * @param offset position (base 0) to start copying out of ascii
262    * @param count the number of characters from ascii to copy
263    * @throws NullPointerException if ascii is null
264    * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
265    *         || offset + count &lt; 0 (overflow)
266    *         || offset + count &gt; ascii.length)
267    *         (while unspecified, this is a StringIndexOutOfBoundsException)
268    * @see #String(byte[])
269    * @see #String(byte[], String)
270    * @see #String(byte[], int, int)
271    * @see #String(byte[], int, int, String)
272    * @deprecated use {@link #String(byte[], int, int, String)} to perform
273    *             correct encoding
274    */
String(byte[] ascii, int hibyte, int offset, int count)275   public String(byte[] ascii, int hibyte, int offset, int count)
276   {
277     if (offset < 0)
278       throw new StringIndexOutOfBoundsException("offset: " + offset);
279     if (count < 0)
280       throw new StringIndexOutOfBoundsException("count: " + count);
281     // equivalent to: offset + count < 0 || offset + count > ascii.length
282     if (ascii.length - offset < count)
283       throw new StringIndexOutOfBoundsException("offset + count: "
284                                                 + (offset + count));
285     value = new char[count];
286     this.offset = 0;
287     this.count = count;
288     hibyte <<= 8;
289     offset += count;
290     while (--count >= 0)
291       value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
292   }
293 
294   /**
295    * Creates a new String using an 8-bit array of integer values. Each
296    * character c, using corresponding byte b, is created in the new String
297    * as if by performing:
298    *
299    * <pre>
300    * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
301    * </pre>
302    *
303    * @param ascii array of integer values
304    * @param hibyte top byte of each Unicode character
305    * @throws NullPointerException if ascii is null
306    * @see #String(byte[])
307    * @see #String(byte[], String)
308    * @see #String(byte[], int, int)
309    * @see #String(byte[], int, int, String)
310    * @see #String(byte[], int, int, int)
311    * @deprecated use {@link #String(byte[], String)} to perform
312    *             correct encoding
313    */
String(byte[] ascii, int hibyte)314   public String(byte[] ascii, int hibyte)
315   {
316     this(ascii, hibyte, 0, ascii.length);
317   }
318 
319   /**
320    * Creates a new String using the portion of the byte array starting at the
321    * offset and ending at offset + count. Uses the specified encoding type
322    * to decode the byte array, so the resulting string may be longer or
323    * shorter than the byte array. For more decoding control, use
324    * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
325    * see {@link java.nio.charset.Charset}. The behavior is not specified if
326    * the decoder encounters invalid characters; this implementation throws
327    * an Error.
328    *
329    * @param data byte array to copy
330    * @param offset the offset to start at
331    * @param count the number of bytes in the array to use
332    * @param encoding the name of the encoding to use
333    * @throws NullPointerException if data or encoding is null
334    * @throws IndexOutOfBoundsException if offset or count is incorrect
335    *         (while unspecified, this is a StringIndexOutOfBoundsException)
336    * @throws UnsupportedEncodingException if encoding is not found
337    * @throws Error if the decoding fails
338    * @since 1.1
339    */
String(byte[] data, int offset, int count, final String encoding)340   public String(byte[] data, int offset, int count, final String encoding)
341     throws UnsupportedEncodingException
342   {
343     this(data, offset, count, stringToCharset(encoding));
344   }
345 
346   /**
347    * Wrapper method to convert exceptions resulting from
348    * the selection of a {@link java.nio.charset.Charset} based on
349    * a String.
350    *
351    * @throws UnsupportedEncodingException if encoding is not found
352    */
stringToCharset(final String encoding)353   private static final Charset stringToCharset(final String encoding)
354     throws UnsupportedEncodingException
355   {
356     try
357       {
358         return Charset.forName(encoding);
359       }
360     catch(IllegalCharsetNameException e)
361       {
362         throw new UnsupportedEncodingException("Encoding: "+encoding+
363                                                " not found.");
364       }
365     catch(UnsupportedCharsetException e)
366       {
367         throw new UnsupportedEncodingException("Encoding: "+encoding+
368                                                " not found.");
369       }
370   }
371 
372   /**
373    * Creates a new String using the portion of the byte array starting at the
374    * offset and ending at offset + count. Uses the specified encoding type
375    * to decode the byte array, so the resulting string may be longer or
376    * shorter than the byte array. For more decoding control, use
377    * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
378    * see {@link java.nio.charset.Charset}. Malformed input and unmappable
379    * character sequences are replaced with the default replacement string
380    * provided by the {@link java.nio.charset.Charset}.
381    *
382    * @param data byte array to copy
383    * @param offset the offset to start at
384    * @param count the number of bytes in the array to use
385    * @param encoding the encoding to use
386    * @throws NullPointerException if data or encoding is null
387    * @throws IndexOutOfBoundsException if offset or count is incorrect
388    *         (while unspecified, this is a StringIndexOutOfBoundsException)
389    * @since 1.6
390    */
String(byte[] data, int offset, int count, Charset encoding)391   public String(byte[] data, int offset, int count, Charset encoding)
392   {
393     if (offset < 0)
394       throw new StringIndexOutOfBoundsException("offset: " + offset);
395     if (count < 0)
396       throw new StringIndexOutOfBoundsException("count: " + count);
397     // equivalent to: offset + count < 0 || offset + count > data.length
398     if (data.length - offset < count)
399       throw new StringIndexOutOfBoundsException("offset + count: "
400                                                 + (offset + count));
401     try
402       {
403         CharsetDecoder csd = encoding.newDecoder();
404         csd.onMalformedInput(CodingErrorAction.REPLACE);
405         csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
406         CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
407         if(cbuf.hasArray())
408           {
409             value = cbuf.array();
410             this.offset = cbuf.position();
411             this.count = cbuf.remaining();
412           } else {
413             // Doubt this will happen. But just in case.
414             value = new char[cbuf.remaining()];
415             cbuf.get(value);
416             this.offset = 0;
417             this.count = value.length;
418           }
419       }
420     catch(CharacterCodingException e)
421       {
422         // This shouldn't ever happen.
423         throw (InternalError) new InternalError().initCause(e);
424       }
425   }
426 
427   /**
428    * Creates a new String using the byte array. Uses the specified encoding
429    * type to decode the byte array, so the resulting string may be longer or
430    * shorter than the byte array. For more decoding control, use
431    * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
432    * see {@link java.nio.charset.Charset}. The behavior is not specified if
433    * the decoder encounters invalid characters; this implementation throws
434    * an Error.
435    *
436    * @param data byte array to copy
437    * @param encoding the name of the encoding to use
438    * @throws NullPointerException if data or encoding is null
439    * @throws UnsupportedEncodingException if encoding is not found
440    * @throws Error if the decoding fails
441    * @see #String(byte[], int, int, String)
442    * @since 1.1
443    */
String(byte[] data, String encoding)444   public String(byte[] data, String encoding)
445     throws UnsupportedEncodingException
446   {
447     this(data, 0, data.length, encoding);
448   }
449 
450   /**
451    * Creates a new String using the byte array. Uses the specified encoding
452    * type to decode the byte array, so the resulting string may be longer or
453    * shorter than the byte array. For more decoding control, use
454    * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
455    * see {@link java.nio.charset.Charset}. Malformed input and unmappable
456    * character sequences are replaced with the default replacement string
457    * provided by the {@link java.nio.charset.Charset}.
458    *
459    * @param data byte array to copy
460    * @param encoding the name of the encoding to use
461    * @throws NullPointerException if data or encoding is null
462    * @see #String(byte[], int, int, java.nio.Charset)
463    * @since 1.6
464    */
String(byte[] data, Charset encoding)465   public String(byte[] data, Charset encoding)
466   {
467     this(data, 0, data.length, encoding);
468   }
469 
470   /**
471    * Creates a new String using the portion of the byte array starting at the
472    * offset and ending at offset + count. Uses the encoding of the platform's
473    * default charset, so the resulting string may be longer or shorter than
474    * the byte array. For more decoding control, use
475    * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
476    * if the decoder encounters invalid characters; this implementation throws
477    * an Error.
478    *
479    * @param data byte array to copy
480    * @param offset the offset to start at
481    * @param count the number of bytes in the array to use
482    * @throws NullPointerException if data is null
483    * @throws IndexOutOfBoundsException if offset or count is incorrect
484    * @throws Error if the decoding fails
485    * @see #String(byte[], int, int, String)
486    * @since 1.1
487    */
String(byte[] data, int offset, int count)488   public String(byte[] data, int offset, int count)
489   {
490     if (offset < 0)
491       throw new StringIndexOutOfBoundsException("offset: " + offset);
492     if (count < 0)
493       throw new StringIndexOutOfBoundsException("count: " + count);
494     // equivalent to: offset + count < 0 || offset + count > data.length
495     if (data.length - offset < count)
496       throw new StringIndexOutOfBoundsException("offset + count: "
497                                                 + (offset + count));
498     int o, c;
499     char[] v;
500     String encoding;
501     try
502         {
503           encoding = System.getProperty("file.encoding");
504           CharsetDecoder csd = Charset.forName(encoding).newDecoder();
505           csd.onMalformedInput(CodingErrorAction.REPLACE);
506           csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
507           CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
508           if(cbuf.hasArray())
509             {
510               v = cbuf.array();
511               o = cbuf.position();
512               c = cbuf.remaining();
513             } else {
514               // Doubt this will happen. But just in case.
515               v = new char[cbuf.remaining()];
516               cbuf.get(v);
517               o = 0;
518               c = v.length;
519             }
520         } catch(Exception ex){
521             // If anything goes wrong (System property not set,
522             // NIO provider not available, etc)
523             // Default to the 'safe' encoding ISO8859_1
524             v = new char[count];
525             o = 0;
526             c = count;
527             for (int i=0;i<count;i++)
528               v[i] = (char)data[offset+i];
529         }
530     this.value = v;
531     this.offset = o;
532     this.count = c;
533   }
534 
535   /**
536    * Creates a new String using the byte array. Uses the encoding of the
537    * platform's default charset, so the resulting string may be longer or
538    * shorter than the byte array. For more decoding control, use
539    * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
540    * if the decoder encounters invalid characters; this implementation throws
541    * an Error.
542    *
543    * @param data byte array to copy
544    * @throws NullPointerException if data is null
545    * @throws Error if the decoding fails
546    * @see #String(byte[], int, int)
547    * @see #String(byte[], int, int, String)
548    * @since 1.1
549    */
String(byte[] data)550   public String(byte[] data)
551   {
552     this(data, 0, data.length);
553   }
554 
555   /**
556    * Creates a new String using the character sequence represented by
557    * the StringBuffer. Subsequent changes to buf do not affect the String.
558    *
559    * @param buffer StringBuffer to copy
560    * @throws NullPointerException if buffer is null
561    */
String(StringBuffer buffer)562   public String(StringBuffer buffer)
563   {
564     synchronized (buffer)
565       {
566         offset = 0;
567         count = buffer.count;
568         // Share unless buffer is 3/4 empty.
569         if ((count << 2) < buffer.value.length)
570           {
571             value = new char[count];
572             VMSystem.arraycopy(buffer.value, 0, value, 0, count);
573           }
574         else
575           {
576             buffer.shared = true;
577             value = buffer.value;
578           }
579       }
580   }
581 
582   /**
583    * Creates a new String using the character sequence represented by
584    * the StringBuilder. Subsequent changes to buf do not affect the String.
585    *
586    * @param buffer StringBuilder to copy
587    * @throws NullPointerException if buffer is null
588    */
String(StringBuilder buffer)589   public String(StringBuilder buffer)
590   {
591     this(buffer.value, 0, buffer.count);
592   }
593 
594   /**
595    * Special constructor which can share an array when safe to do so.
596    *
597    * @param data the characters to copy
598    * @param offset the location to start from
599    * @param count the number of characters to use
600    * @param dont_copy true if the array is trusted, and need not be copied
601    * @throws NullPointerException if chars is null
602    * @throws StringIndexOutOfBoundsException if bounds check fails
603    */
String(char[] data, int offset, int count, boolean dont_copy)604   String(char[] data, int offset, int count, boolean dont_copy)
605   {
606     if (offset < 0)
607       throw new StringIndexOutOfBoundsException("offset: " + offset);
608     if (count < 0)
609       throw new StringIndexOutOfBoundsException("count: " + count);
610     // equivalent to: offset + count < 0 || offset + count > data.length
611     if (data.length - offset < count)
612       throw new StringIndexOutOfBoundsException("offset + count: "
613                                                 + (offset + count));
614     if (dont_copy)
615       {
616         value = data;
617         this.offset = offset;
618       }
619     else
620       {
621         value = new char[count];
622         VMSystem.arraycopy(data, offset, value, 0, count);
623         this.offset = 0;
624       }
625     this.count = count;
626   }
627 
628   /**
629    * Creates a new String containing the characters represented in the
630    * given subarray of Unicode code points.
631    * @param codePoints the entire array of code points
632    * @param offset the start of the subarray
633    * @param count the length of the subarray
634    *
635    * @throws IllegalArgumentException if an invalid code point is found
636    * in the codePoints array
637    * @throws IndexOutOfBoundsException if offset is negative or offset + count
638    * is greater than the length of the array.
639    */
String(int[] codePoints, int offset, int count)640   public String(int[] codePoints, int offset, int count)
641   {
642     // FIXME: This implementation appears to give correct internal
643     // representation of the String because:
644     //   - length() is correct
645     //   - getting a char[] from toCharArray() and testing
646     //     Character.codePointAt() on all the characters in that array gives
647     //     the appropriate results
648     // however printing the String gives incorrect results.  This may be
649     // due to printing method errors (such as incorrectly looping through
650     // the String one char at a time rather than one "character" at a time.
651 
652     if (offset < 0)
653       throw new IndexOutOfBoundsException();
654     int end = offset + count;
655     int pos = 0;
656     // This creates a char array that is long enough for all of the code
657     // points to represent supplementary characters.  This is more than likely
658     // a waste of storage, so we use it only temporarily and then copy the
659     // used portion into the value array.
660     char[] temp = new char[2 * codePoints.length];
661     for (int i = offset; i < end; i++)
662       {
663         pos += Character.toChars(codePoints[i], temp, pos);
664       }
665     this.count = pos;
666     this.value = new char[pos];
667     System.arraycopy(temp, 0, value, 0, pos);
668     this.offset = 0;
669   }
670 
671   /**
672    * Returns the number of characters contained in this String.
673    *
674    * @return the length of this String
675    */
length()676   public int length()
677   {
678     return count;
679   }
680 
681   /**
682    * Returns the character located at the specified index within this String.
683    *
684    * @param index position of character to return (base 0)
685    * @return character located at position index
686    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= length()
687    *         (while unspecified, this is a StringIndexOutOfBoundsException)
688    */
charAt(int index)689   public char charAt(int index)
690   {
691     if (index < 0 || index >= count)
692       throw new StringIndexOutOfBoundsException(index);
693     return value[offset + index];
694   }
695 
696   /**
697    * Get the code point at the specified index.  This is like #charAt(int),
698    * but if the character is the start of a surrogate pair, and the
699    * following character completes the pair, then the corresponding
700    * supplementary code point is returned.
701    * @param index the index of the codepoint to get, starting at 0
702    * @return the codepoint at the specified index
703    * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
704    * @since 1.5
705    */
codePointAt(int index)706   public synchronized int codePointAt(int index)
707   {
708     if (index < 0 || index >= count)
709       throw new StringIndexOutOfBoundsException(index);
710     // Use the CharSequence overload as we get better range checking
711     // this way.
712     return Character.codePointAt(this, index);
713   }
714 
715   /**
716    * Get the code point before the specified index.  This is like
717    * #codePointAt(int), but checks the characters at <code>index-1</code> and
718    * <code>index-2</code> to see if they form a supplementary code point.
719    * @param index the index just past the codepoint to get, starting at 0
720    * @return the codepoint at the specified index
721    * @throws IndexOutOfBoundsException if index is less than 1 or &gt; length()
722    *         (while unspecified, this is a StringIndexOutOfBoundsException)
723    * @since 1.5
724    */
codePointBefore(int index)725   public synchronized int codePointBefore(int index)
726   {
727     if (index < 1 || index > count)
728       throw new StringIndexOutOfBoundsException(index);
729     // Use the CharSequence overload as we get better range checking
730     // this way.
731     return Character.codePointBefore(this, index);
732   }
733 
734   /**
735    * Copies characters from this String starting at a specified start index,
736    * ending at a specified stop index, to a character array starting at
737    * a specified destination begin index.
738    *
739    * @param srcBegin index to begin copying characters from this String
740    * @param srcEnd index after the last character to be copied from this String
741    * @param dst character array which this String is copied into
742    * @param dstBegin index to start writing characters into dst
743    * @throws NullPointerException if dst is null
744    * @throws IndexOutOfBoundsException if any indices are out of bounds
745    *         (while unspecified, source problems cause a
746    *         StringIndexOutOfBoundsException, and dst problems cause an
747    *         ArrayIndexOutOfBoundsException)
748    */
getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)749   public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
750   {
751     if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
752       throw new StringIndexOutOfBoundsException();
753     VMSystem.arraycopy(value, srcBegin + offset,
754                      dst, dstBegin, srcEnd - srcBegin);
755   }
756 
757   /**
758    * Copies the low byte of each character from this String starting at a
759    * specified start index, ending at a specified stop index, to a byte array
760    * starting at a specified destination begin index.
761    *
762    * @param srcBegin index to being copying characters from this String
763    * @param srcEnd index after the last character to be copied from this String
764    * @param dst byte array which each low byte of this String is copied into
765    * @param dstBegin index to start writing characters into dst
766    * @throws NullPointerException if dst is null and copy length is non-zero
767    * @throws IndexOutOfBoundsException if any indices are out of bounds
768    *         (while unspecified, source problems cause a
769    *         StringIndexOutOfBoundsException, and dst problems cause an
770    *         ArrayIndexOutOfBoundsException)
771    * @see #getBytes()
772    * @see #getBytes(String)
773    * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
774    */
getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)775   public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)
776   {
777     if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
778       throw new StringIndexOutOfBoundsException();
779     int i = srcEnd - srcBegin;
780     srcBegin += offset;
781     while (--i >= 0)
782       dst[dstBegin++] = (byte) value[srcBegin++];
783   }
784 
785   /**
786    * Converts the Unicode characters in this String to a byte array. Uses the
787    * specified encoding method, so the result may be longer or shorter than
788    * the String. For more encoding control, use
789    * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
790    * see {@link java.nio.charset.Charset}. Unsupported characters get
791    * replaced by an encoding specific byte.
792    *
793    * @param enc encoding name
794    * @return the resulting byte array
795    * @throws NullPointerException if enc is null
796    * @throws UnsupportedEncodingException if encoding is not supported
797    * @since 1.1
798    */
getBytes(final String enc)799   public byte[] getBytes(final String enc)
800     throws UnsupportedEncodingException
801   {
802     return getBytes(stringToCharset(enc));
803   }
804 
805   /**
806    * Converts the Unicode characters in this String to a byte array. Uses the
807    * specified encoding method, so the result may be longer or shorter than
808    * the String. For more encoding control, use
809    * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
810    * see {@link java.nio.charset.Charset}. Unsupported characters get
811    * replaced by the {@link java.nio.charset.Charset}'s default replacement.
812    *
813    * @param enc encoding name
814    * @return the resulting byte array
815    * @throws NullPointerException if enc is null
816    * @since 1.6
817    */
getBytes(Charset enc)818   public byte[] getBytes(Charset enc)
819   {
820     try
821       {
822         CharsetEncoder cse = enc.newEncoder();
823         cse.onMalformedInput(CodingErrorAction.REPLACE);
824         cse.onUnmappableCharacter(CodingErrorAction.REPLACE);
825         ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count));
826         if(bbuf.hasArray())
827           return bbuf.array();
828 
829         // Doubt this will happen. But just in case.
830         byte[] bytes = new byte[bbuf.remaining()];
831         bbuf.get(bytes);
832         return bytes;
833       }
834     catch(CharacterCodingException e)
835       {
836         // This shouldn't ever happen.
837         throw (InternalError) new InternalError().initCause(e);
838       }
839   }
840 
841   /**
842    * Converts the Unicode characters in this String to a byte array. Uses the
843    * encoding of the platform's default charset, so the result may be longer
844    * or shorter than the String. For more encoding control, use
845    * {@link java.nio.charset.CharsetEncoder}. Unsupported characters get
846    * replaced by an encoding specific byte.
847    *
848    * @return the resulting byte array, or null on a problem
849    * @since 1.1
850    */
getBytes()851   public byte[] getBytes()
852   {
853       try
854           {
855               return getBytes(System.getProperty("file.encoding"));
856           } catch(Exception e) {
857               // XXX - Throw an error here?
858               // For now, default to the 'safe' encoding.
859               byte[] bytes = new byte[count];
860               for(int i=0;i<count;i++)
861                   bytes[i] = (byte)((value[offset+i] <= 0xFF)?
862                                     value[offset+i]:'?');
863               return bytes;
864       }
865   }
866 
867   /**
868    * Predicate which compares anObject to this. This is true only for Strings
869    * with the same character sequence.
870    *
871    * @param anObject the object to compare
872    * @return true if anObject is semantically equal to this
873    * @see #compareTo(String)
874    * @see #equalsIgnoreCase(String)
875    */
equals(Object anObject)876   public boolean equals(Object anObject)
877   {
878     if (! (anObject instanceof String))
879       return false;
880     String str2 = (String) anObject;
881     if (count != str2.count)
882       return false;
883     if (value == str2.value && offset == str2.offset)
884       return true;
885     int i = count;
886     int x = offset;
887     int y = str2.offset;
888     while (--i >= 0)
889       if (value[x++] != str2.value[y++])
890         return false;
891     return true;
892   }
893 
894   /**
895    * Compares the given StringBuffer to this String. This is true if the
896    * StringBuffer has the same content as this String at this moment.
897    *
898    * @param buffer the StringBuffer to compare to
899    * @return true if StringBuffer has the same character sequence
900    * @throws NullPointerException if the given StringBuffer is null
901    * @since 1.4
902    */
contentEquals(StringBuffer buffer)903   public boolean contentEquals(StringBuffer buffer)
904   {
905     synchronized (buffer)
906       {
907         if (count != buffer.count)
908           return false;
909         if (value == buffer.value)
910           return true; // Possible if shared.
911         int i = count;
912         int x = offset + count;
913         while (--i >= 0)
914           if (value[--x] != buffer.value[i])
915             return false;
916         return true;
917       }
918   }
919 
920   /**
921    * Compares the given CharSequence to this String. This is true if
922    * the CharSequence has the same content as this String at this
923    * moment.
924    *
925    * @param seq the CharSequence to compare to
926    * @return true if CharSequence has the same character sequence
927    * @throws NullPointerException if the given CharSequence is null
928    * @since 1.5
929    */
contentEquals(CharSequence seq)930   public boolean contentEquals(CharSequence seq)
931   {
932     if (seq.length() != count)
933       return false;
934     for (int i = 0; i < count; ++i)
935       if (value[offset + i] != seq.charAt(i))
936         return false;
937     return true;
938   }
939 
940   /**
941    * Compares a String to this String, ignoring case. This does not handle
942    * multi-character capitalization exceptions; instead the comparison is
943    * made on a character-by-character basis, and is true if:<br><ul>
944    * <li><code>c1 == c2</code></li>
945    * <li><code>Character.toUpperCase(c1)
946    *     == Character.toUpperCase(c2)</code></li>
947    * <li><code>Character.toLowerCase(c1)
948    *     == Character.toLowerCase(c2)</code></li>
949    * </ul>
950    *
951    * @param anotherString String to compare to this String
952    * @return true if anotherString is equal, ignoring case
953    * @see #equals(Object)
954    * @see Character#toUpperCase(char)
955    * @see Character#toLowerCase(char)
956    */
equalsIgnoreCase(String anotherString)957   public boolean equalsIgnoreCase(String anotherString)
958   {
959     if (anotherString == null || count != anotherString.count)
960       return false;
961     int i = count;
962     int x = offset;
963     int y = anotherString.offset;
964     while (--i >= 0)
965       {
966         char c1 = value[x++];
967         char c2 = anotherString.value[y++];
968         // Note that checking c1 != c2 is redundant, but avoids method calls.
969         if (c1 != c2
970             && Character.toUpperCase(c1) != Character.toUpperCase(c2)
971             && Character.toLowerCase(c1) != Character.toLowerCase(c2))
972           return false;
973       }
974     return true;
975   }
976 
977   /**
978    * Compares this String and another String (case sensitive,
979    * lexicographically). The result is less than 0 if this string sorts
980    * before the other, 0 if they are equal, and greater than 0 otherwise.
981    * After any common starting sequence is skipped, the result is
982    * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
983    * have characters remaining, or
984    * <code>this.length() - anotherString.length()</code> if one string is
985    * a subsequence of the other.
986    *
987    * @param anotherString the String to compare against
988    * @return the comparison
989    * @throws NullPointerException if anotherString is null
990    */
compareTo(String anotherString)991   public int compareTo(String anotherString)
992   {
993     int i = Math.min(count, anotherString.count);
994     int x = offset;
995     int y = anotherString.offset;
996     while (--i >= 0)
997       {
998         int result = value[x++] - anotherString.value[y++];
999         if (result != 0)
1000           return result;
1001       }
1002     return count - anotherString.count;
1003   }
1004 
1005   /**
1006    * Compares this String and another String (case insensitive). This
1007    * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
1008    * locale and multi-characater capitalization, and compares characters
1009    * after performing
1010    * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
1011    * character of the string. This is unsatisfactory for locale-based
1012    * comparison, in which case you should use {@link java.text.Collator}.
1013    *
1014    * @param str the string to compare against
1015    * @return the comparison
1016    * @see Collator#compare(String, String)
1017    * @since 1.2
1018    */
compareToIgnoreCase(String str)1019   public int compareToIgnoreCase(String str)
1020   {
1021     int i = Math.min(count, str.count);
1022     int x = offset;
1023     int y = str.offset;
1024     while (--i >= 0)
1025       {
1026         int result = Character.toLowerCase(Character.toUpperCase(value[x++]))
1027           - Character.toLowerCase(Character.toUpperCase(str.value[y++]));
1028         if (result != 0)
1029           return result;
1030       }
1031     return count - str.count;
1032   }
1033 
1034   /**
1035    * Predicate which determines if this String matches another String
1036    * starting at a specified offset for each String and continuing
1037    * for a specified length. Indices out of bounds are harmless, and give
1038    * a false result.
1039    *
1040    * @param toffset index to start comparison at for this String
1041    * @param other String to compare region to this String
1042    * @param ooffset index to start comparison at for other
1043    * @param len number of characters to compare
1044    * @return true if regions match (case sensitive)
1045    * @throws NullPointerException if other is null
1046    */
regionMatches(int toffset, String other, int ooffset, int len)1047   public boolean regionMatches(int toffset, String other, int ooffset, int len)
1048   {
1049     return regionMatches(false, toffset, other, ooffset, len);
1050   }
1051 
1052   /**
1053    * Predicate which determines if this String matches another String
1054    * starting at a specified offset for each String and continuing
1055    * for a specified length, optionally ignoring case. Indices out of bounds
1056    * are harmless, and give a false result. Case comparisons are based on
1057    * <code>Character.toLowerCase()</code> and
1058    * <code>Character.toUpperCase()</code>, not on multi-character
1059    * capitalization expansions.
1060    *
1061    * @param ignoreCase true if case should be ignored in comparision
1062    * @param toffset index to start comparison at for this String
1063    * @param other String to compare region to this String
1064    * @param ooffset index to start comparison at for other
1065    * @param len number of characters to compare
1066    * @return true if regions match, false otherwise
1067    * @throws NullPointerException if other is null
1068    */
regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)1069   public boolean regionMatches(boolean ignoreCase, int toffset,
1070                                String other, int ooffset, int len)
1071   {
1072     if (toffset < 0 || ooffset < 0 || toffset + len > count
1073         || ooffset + len > other.count)
1074       return false;
1075     toffset += offset;
1076     ooffset += other.offset;
1077     while (--len >= 0)
1078       {
1079         char c1 = value[toffset++];
1080         char c2 = other.value[ooffset++];
1081         // Note that checking c1 != c2 is redundant when ignoreCase is true,
1082         // but it avoids method calls.
1083         if (c1 != c2
1084             && (! ignoreCase
1085                 || (Character.toLowerCase(c1) != Character.toLowerCase(c2)
1086                     && (Character.toUpperCase(c1)
1087                         != Character.toUpperCase(c2)))))
1088           return false;
1089       }
1090     return true;
1091   }
1092 
1093   /**
1094    * Predicate which determines if this String contains the given prefix,
1095    * beginning comparison at toffset. The result is false if toffset is
1096    * negative or greater than this.length(), otherwise it is the same as
1097    * <code>this.substring(toffset).startsWith(prefix)</code>.
1098    *
1099    * @param prefix String to compare
1100    * @param toffset offset for this String where comparison starts
1101    * @return true if this String starts with prefix
1102    * @throws NullPointerException if prefix is null
1103    * @see #regionMatches(boolean, int, String, int, int)
1104    */
startsWith(String prefix, int toffset)1105   public boolean startsWith(String prefix, int toffset)
1106   {
1107     return regionMatches(false, toffset, prefix, 0, prefix.count);
1108   }
1109 
1110   /**
1111    * Predicate which determines if this String starts with a given prefix.
1112    * If the prefix is an empty String, true is returned.
1113    *
1114    * @param prefix String to compare
1115    * @return true if this String starts with the prefix
1116    * @throws NullPointerException if prefix is null
1117    * @see #startsWith(String, int)
1118    */
startsWith(String prefix)1119   public boolean startsWith(String prefix)
1120   {
1121     return regionMatches(false, 0, prefix, 0, prefix.count);
1122   }
1123 
1124   /**
1125    * Predicate which determines if this String ends with a given suffix.
1126    * If the suffix is an empty String, true is returned.
1127    *
1128    * @param suffix String to compare
1129    * @return true if this String ends with the suffix
1130    * @throws NullPointerException if suffix is null
1131    * @see #regionMatches(boolean, int, String, int, int)
1132    */
endsWith(String suffix)1133   public boolean endsWith(String suffix)
1134   {
1135     return regionMatches(false, count - suffix.count, suffix, 0, suffix.count);
1136   }
1137 
1138   /**
1139    * Computes the hashcode for this String. This is done with int arithmetic,
1140    * where ** represents exponentiation, by this formula:<br>
1141    * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
1142    *
1143    * @return hashcode value of this String
1144    */
hashCode()1145   public int hashCode()
1146   {
1147     if (cachedHashCode != 0)
1148       return cachedHashCode;
1149 
1150     // Compute the hash code using a local variable to be reentrant.
1151     int hashCode = 0;
1152     int limit = count + offset;
1153     for (int i = offset; i < limit; i++)
1154       hashCode = hashCode * 31 + value[i];
1155     return cachedHashCode = hashCode;
1156   }
1157 
1158   /**
1159    * Finds the first instance of a character in this String.
1160    *
1161    * @param ch character to find
1162    * @return location (base 0) of the character, or -1 if not found
1163    */
indexOf(int ch)1164   public int indexOf(int ch)
1165   {
1166     return indexOf(ch, 0);
1167   }
1168 
1169   /**
1170    * Finds the first instance of a character in this String, starting at
1171    * a given index.  If starting index is less than 0, the search
1172    * starts at the beginning of this String.  If the starting index
1173    * is greater than the length of this String, -1 is returned.
1174    *
1175    * @param ch character to find
1176    * @param fromIndex index to start the search
1177    * @return location (base 0) of the character, or -1 if not found
1178    */
indexOf(int ch, int fromIndex)1179   public int indexOf(int ch, int fromIndex)
1180   {
1181     if ((char) ch != ch)
1182       return -1;
1183     if (fromIndex < 0)
1184       fromIndex = 0;
1185     int i = fromIndex + offset;
1186     for ( ; fromIndex < count; fromIndex++)
1187       if (value[i++] == ch)
1188         return fromIndex;
1189     return -1;
1190   }
1191 
1192   /**
1193    * Finds the last instance of a character in this String.
1194    *
1195    * @param ch character to find
1196    * @return location (base 0) of the character, or -1 if not found
1197    */
lastIndexOf(int ch)1198   public int lastIndexOf(int ch)
1199   {
1200     return lastIndexOf(ch, count - 1);
1201   }
1202 
1203   /**
1204    * Finds the last instance of a character in this String, starting at
1205    * a given index.  If starting index is greater than the maximum valid
1206    * index, then the search begins at the end of this String.  If the
1207    * starting index is less than zero, -1 is returned.
1208    *
1209    * @param ch character to find
1210    * @param fromIndex index to start the search
1211    * @return location (base 0) of the character, or -1 if not found
1212    */
lastIndexOf(int ch, int fromIndex)1213   public int lastIndexOf(int ch, int fromIndex)
1214   {
1215     if ((char) ch != ch)
1216       return -1;
1217     if (fromIndex >= count)
1218       fromIndex = count - 1;
1219     int i = fromIndex + offset;
1220     for ( ; fromIndex >= 0; fromIndex--)
1221       if (value[i--] == ch)
1222         return fromIndex;
1223     return -1;
1224   }
1225 
1226   /**
1227    * Finds the first instance of a String in this String.
1228    *
1229    * @param str String to find
1230    * @return location (base 0) of the String, or -1 if not found
1231    * @throws NullPointerException if str is null
1232    */
indexOf(String str)1233   public int indexOf(String str)
1234   {
1235     return indexOf(str, 0);
1236   }
1237 
1238   /**
1239    * Finds the first instance of a String in this String, starting at
1240    * a given index.  If starting index is less than 0, the search
1241    * starts at the beginning of this String.  If the starting index
1242    * is greater than the length of this String, -1 is returned.
1243    *
1244    * @param str String to find
1245    * @param fromIndex index to start the search
1246    * @return location (base 0) of the String, or -1 if not found
1247    * @throws NullPointerException if str is null
1248    */
indexOf(String str, int fromIndex)1249   public int indexOf(String str, int fromIndex)
1250   {
1251     if (fromIndex < 0)
1252       fromIndex = 0;
1253     int limit = count - str.count;
1254     for ( ; fromIndex <= limit; fromIndex++)
1255       if (regionMatches(fromIndex, str, 0, str.count))
1256         return fromIndex;
1257     return -1;
1258   }
1259 
1260   /**
1261    * Finds the last instance of a String in this String.
1262    *
1263    * @param str String to find
1264    * @return location (base 0) of the String, or -1 if not found
1265    * @throws NullPointerException if str is null
1266    */
lastIndexOf(String str)1267   public int lastIndexOf(String str)
1268   {
1269     return lastIndexOf(str, count - str.count);
1270   }
1271 
1272   /**
1273    * Finds the last instance of a String in this String, starting at
1274    * a given index.  If starting index is greater than the maximum valid
1275    * index, then the search begins at the end of this String.  If the
1276    * starting index is less than zero, -1 is returned.
1277    *
1278    * @param str String to find
1279    * @param fromIndex index to start the search
1280    * @return location (base 0) of the String, or -1 if not found
1281    * @throws NullPointerException if str is null
1282    */
lastIndexOf(String str, int fromIndex)1283   public int lastIndexOf(String str, int fromIndex)
1284   {
1285     fromIndex = Math.min(fromIndex, count - str.count);
1286     for ( ; fromIndex >= 0; fromIndex--)
1287       if (regionMatches(fromIndex, str, 0, str.count))
1288         return fromIndex;
1289     return -1;
1290   }
1291 
1292   /**
1293    * Creates a substring of this String, starting at a specified index
1294    * and ending at the end of this String.
1295    *
1296    * @param begin index to start substring (base 0)
1297    * @return new String which is a substring of this String
1298    * @throws IndexOutOfBoundsException if begin &lt; 0 || begin &gt; length()
1299    *         (while unspecified, this is a StringIndexOutOfBoundsException)
1300    */
substring(int begin)1301   public String substring(int begin)
1302   {
1303     return substring(begin, count);
1304   }
1305 
1306   /**
1307    * Creates a substring of this String, starting at a specified index
1308    * and ending at one character before a specified index.
1309    *
1310    * @param beginIndex index to start substring (inclusive, base 0)
1311    * @param endIndex index to end at (exclusive)
1312    * @return new String which is a substring of this String
1313    * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
1314    *         || begin &gt; end (while unspecified, this is a
1315    *         StringIndexOutOfBoundsException)
1316    */
substring(int beginIndex, int endIndex)1317   public String substring(int beginIndex, int endIndex)
1318   {
1319     if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
1320       throw new StringIndexOutOfBoundsException();
1321     if (beginIndex == 0 && endIndex == count)
1322       return this;
1323     int len = endIndex - beginIndex;
1324     // Package constructor avoids an array copy.
1325     return new String(value, beginIndex + offset, len,
1326                       (len << 2) >= value.length);
1327   }
1328 
1329   /**
1330    * Creates a substring of this String, starting at a specified index
1331    * and ending at one character before a specified index. This behaves like
1332    * <code>substring(begin, end)</code>.
1333    *
1334    * @param begin index to start substring (inclusive, base 0)
1335    * @param end index to end at (exclusive)
1336    * @return new String which is a substring of this String
1337    * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
1338    *         || begin &gt; end
1339    * @since 1.4
1340    */
subSequence(int begin, int end)1341   public CharSequence subSequence(int begin, int end)
1342   {
1343     return substring(begin, end);
1344   }
1345 
1346   /**
1347    * Concatenates a String to this String. This results in a new string unless
1348    * one of the two originals is "".
1349    *
1350    * @param str String to append to this String
1351    * @return newly concatenated String
1352    * @throws NullPointerException if str is null
1353    */
concat(String str)1354   public String concat(String str)
1355   {
1356     if (str.count == 0)
1357       return this;
1358     if (count == 0)
1359       return str;
1360     char[] newStr = new char[count + str.count];
1361     VMSystem.arraycopy(value, offset, newStr, 0, count);
1362     VMSystem.arraycopy(str.value, str.offset, newStr, count, str.count);
1363     // Package constructor avoids an array copy.
1364     return new String(newStr, 0, newStr.length, true);
1365   }
1366 
1367   /**
1368    * Replaces every instance of a character in this String with a new
1369    * character. If no replacements occur, this is returned.
1370    *
1371    * @param oldChar the old character to replace
1372    * @param newChar the new character
1373    * @return new String with all instances of oldChar replaced with newChar
1374    */
replace(char oldChar, char newChar)1375   public String replace(char oldChar, char newChar)
1376   {
1377     if (oldChar == newChar)
1378       return this;
1379     int i = count;
1380     int x = offset - 1;
1381     while (--i >= 0)
1382       if (value[++x] == oldChar)
1383         break;
1384     if (i < 0)
1385       return this;
1386     char[] newStr = toCharArray();
1387     newStr[x - offset] = newChar;
1388     while (--i >= 0)
1389       if (value[++x] == oldChar)
1390         newStr[x - offset] = newChar;
1391     // Package constructor avoids an array copy.
1392     return new String(newStr, 0, count, true);
1393   }
1394 
1395   /**
1396    * Test if this String matches a regular expression. This is shorthand for
1397    * <code>{@link Pattern}.matches(regex, this)</code>.
1398    *
1399    * @param regex the pattern to match
1400    * @return true if the pattern matches
1401    * @throws NullPointerException if regex is null
1402    * @throws PatternSyntaxException if regex is invalid
1403    * @see Pattern#matches(String, CharSequence)
1404    * @since 1.4
1405    */
matches(String regex)1406   public boolean matches(String regex)
1407   {
1408     return Pattern.matches(regex, this);
1409   }
1410 
1411   /**
1412    * Replaces the first substring match of the regular expression with a
1413    * given replacement. This is shorthand for <code>{@link Pattern}
1414    *   .compile(regex).matcher(this).replaceFirst(replacement)</code>.
1415    *
1416    * @param regex the pattern to match
1417    * @param replacement the replacement string
1418    * @return the modified string
1419    * @throws NullPointerException if regex or replacement is null
1420    * @throws PatternSyntaxException if regex is invalid
1421    * @see #replaceAll(String, String)
1422    * @see Pattern#compile(String)
1423    * @see Pattern#matcher(CharSequence)
1424    * @see Matcher#replaceFirst(String)
1425    * @since 1.4
1426    */
replaceFirst(String regex, String replacement)1427   public String replaceFirst(String regex, String replacement)
1428   {
1429     return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
1430   }
1431 
1432   /**
1433    * Replaces all matching substrings of the regular expression with a
1434    * given replacement. This is shorthand for <code>{@link Pattern}
1435    *   .compile(regex).matcher(this).replaceAll(replacement)</code>.
1436    *
1437    * @param regex the pattern to match
1438    * @param replacement the replacement string
1439    * @return the modified string
1440    * @throws NullPointerException if regex or replacement is null
1441    * @throws PatternSyntaxException if regex is invalid
1442    * @see #replaceFirst(String, String)
1443    * @see Pattern#compile(String)
1444    * @see Pattern#matcher(CharSequence)
1445    * @see Matcher#replaceAll(String)
1446    * @since 1.4
1447    */
replaceAll(String regex, String replacement)1448   public String replaceAll(String regex, String replacement)
1449   {
1450     return Pattern.compile(regex).matcher(this).replaceAll(replacement);
1451   }
1452 
1453   /**
1454    * Split this string around the matches of a regular expression. Each
1455    * element of the returned array is the largest block of characters not
1456    * terminated by the regular expression, in the order the matches are found.
1457    *
1458    * <p>The limit affects the length of the array. If it is positive, the
1459    * array will contain at most n elements (n - 1 pattern matches). If
1460    * negative, the array length is unlimited, but there can be trailing empty
1461    * entries. if 0, the array length is unlimited, and trailing empty entries
1462    * are discarded.
1463    *
1464    * <p>For example, splitting "boo:and:foo" yields:<br>
1465    * <table border=0>
1466    * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
1467    * <tr><td>":"</td>   <td>2</td>  <td>{ "boo", "and:foo" }</td></tr>
1468    * <tr><td>":"</td>   <td>t</td>  <td>{ "boo", "and", "foo" }</td></tr>
1469    * <tr><td>":"</td>   <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
1470    * <tr><td>"o"</td>   <td>5</td>  <td>{ "b", "", ":and:f", "", "" }</td></tr>
1471    * <tr><td>"o"</td>   <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
1472    * <tr><td>"o"</td>   <td>0</td>  <td>{ "b", "", ":and:f" }</td></tr>
1473    * </table>
1474    *
1475    * <p>This is shorthand for
1476    * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
1477    *
1478    * @param regex the pattern to match
1479    * @param limit the limit threshold
1480    * @return the array of split strings
1481    * @throws NullPointerException if regex or replacement is null
1482    * @throws PatternSyntaxException if regex is invalid
1483    * @see Pattern#compile(String)
1484    * @see Pattern#split(CharSequence, int)
1485    * @since 1.4
1486    */
split(String regex, int limit)1487   public String[] split(String regex, int limit)
1488   {
1489     return Pattern.compile(regex).split(this, limit);
1490   }
1491 
1492   /**
1493    * Split this string around the matches of a regular expression. Each
1494    * element of the returned array is the largest block of characters not
1495    * terminated by the regular expression, in the order the matches are found.
1496    * The array length is unlimited, and trailing empty entries are discarded,
1497    * as though calling <code>split(regex, 0)</code>.
1498    *
1499    * @param regex the pattern to match
1500    * @return the array of split strings
1501    * @throws NullPointerException if regex or replacement is null
1502    * @throws PatternSyntaxException if regex is invalid
1503    * @see #split(String, int)
1504    * @see Pattern#compile(String)
1505    * @see Pattern#split(CharSequence, int)
1506    * @since 1.4
1507    */
split(String regex)1508   public String[] split(String regex)
1509   {
1510     return Pattern.compile(regex).split(this, 0);
1511   }
1512 
1513   /**
1514    * Convert string to lower case for a Turkish locale that requires special
1515    * handling of '\u0049'
1516    */
toLowerCaseTurkish()1517   private String toLowerCaseTurkish()
1518   {
1519     // First, see if the current string is already lower case.
1520     int i = count;
1521     int x = offset - 1;
1522     while (--i >= 0)
1523       {
1524         char ch = value[++x];
1525         if ((ch == '\u0049') || ch != Character.toLowerCase(ch))
1526           break;
1527       }
1528     if (i < 0)
1529       return this;
1530 
1531     // Now we perform the conversion. Fortunately, there are no multi-character
1532     // lowercase expansions in Unicode 3.0.0.
1533     char[] newStr = new char[count];
1534     VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
1535     do
1536       {
1537         char ch = value[x];
1538         // Hardcoded special case.
1539         if (ch != '\u0049')
1540           {
1541             newStr[x - offset] = Character.toLowerCase(ch);
1542           }
1543         else
1544           {
1545             newStr[x - offset] = '\u0131';
1546           }
1547         x++;
1548       }
1549     while (--i >= 0);
1550     // Package constructor avoids an array copy.
1551     return new String(newStr, 0, count, true);
1552   }
1553 
1554   /**
1555    * Lowercases this String according to a particular locale. This uses
1556    * Unicode's special case mappings, as applied to the given Locale, so the
1557    * resulting string may be a different length.
1558    *
1559    * @param loc locale to use
1560    * @return new lowercased String, or this if no characters were lowercased
1561    * @throws NullPointerException if loc is null
1562    * @see #toUpperCase(Locale)
1563    * @since 1.1
1564    */
toLowerCase(Locale loc)1565   public String toLowerCase(Locale loc)
1566   {
1567     // First, see if the current string is already lower case.
1568 
1569     // Is loc turkish? String equality test is ok as Locale.language is interned
1570     if ("tr" == loc.getLanguage())
1571       {
1572         return toLowerCaseTurkish();
1573       }
1574     else
1575       {
1576         int i = count;
1577         int x = offset - 1;
1578         while (--i >= 0)
1579           {
1580             char ch = value[++x];
1581             if (ch != Character.toLowerCase(ch))
1582               break;
1583           }
1584         if (i < 0)
1585           return this;
1586 
1587         // Now we perform the conversion. Fortunately, there are no
1588         // multi-character lowercase expansions in Unicode 3.0.0.
1589         char[] newStr = new char[count];
1590         VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
1591         do
1592           {
1593             char ch = value[x];
1594             // Hardcoded special case.
1595             newStr[x - offset] = Character.toLowerCase(ch);
1596             x++;
1597           }
1598         while (--i >= 0);
1599         // Package constructor avoids an array copy.
1600         return new String(newStr, 0, count, true);
1601      }
1602   }
1603 
1604   /**
1605    * Lowercases this String. This uses Unicode's special case mappings, as
1606    * applied to the platform's default Locale, so the resulting string may
1607    * be a different length.
1608    *
1609    * @return new lowercased String, or this if no characters were lowercased
1610    * @see #toLowerCase(Locale)
1611    * @see #toUpperCase()
1612    */
toLowerCase()1613   public String toLowerCase()
1614   {
1615     return toLowerCase(Locale.getDefault());
1616   }
1617 
1618   /**
1619    * Uppercase this string for a Turkish locale
1620    */
toUpperCaseTurkish()1621   private String toUpperCaseTurkish()
1622   {
1623     // First, see how many characters we have to grow by, as well as if the
1624     // current string is already upper case.
1625     int expand = 0;
1626     boolean unchanged = true;
1627     int i = count;
1628     int x = i + offset;
1629     while (--i >= 0)
1630       {
1631         char ch = value[--x];
1632         expand += upperCaseExpansion(ch);
1633         unchanged = (unchanged && expand == 0
1634                      && ch != '\u0069'
1635                      && ch == Character.toUpperCase(ch));
1636       }
1637     if (unchanged)
1638       return this;
1639 
1640     // Now we perform the conversion.
1641     i = count;
1642     if (expand == 0)
1643       {
1644         char[] newStr = new char[count];
1645         VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
1646         while (--i >= 0)
1647           {
1648             char ch = value[x];
1649             // Hardcoded special case.
1650             if (ch != '\u0069')
1651               {
1652                 newStr[x - offset] = Character.toUpperCase(ch);
1653               }
1654             else
1655               {
1656                 newStr[x - offset] = '\u0130';
1657               }
1658             x++;
1659           }
1660         // Package constructor avoids an array copy.
1661         return new String(newStr, 0, count, true);
1662       }
1663 
1664     // Expansion is necessary.
1665     char[] newStr = new char[count + expand];
1666     int j = 0;
1667     while (--i >= 0)
1668       {
1669         char ch = value[x++];
1670         // Hardcoded special case.
1671         if (ch == '\u0069')
1672           {
1673             newStr[j++] = '\u0130';
1674             continue;
1675           }
1676         expand = upperCaseExpansion(ch);
1677         if (expand > 0)
1678           {
1679             int index = upperCaseIndex(ch);
1680             while (expand-- >= 0)
1681               newStr[j++] = upperExpand[index++];
1682           }
1683         else
1684           newStr[j++] = Character.toUpperCase(ch);
1685       }
1686     // Package constructor avoids an array copy.
1687     return new String(newStr, 0, newStr.length, true);
1688   }
1689 
1690   /**
1691    * Uppercases this String according to a particular locale. This uses
1692    * Unicode's special case mappings, as applied to the given Locale, so the
1693    * resulting string may be a different length.
1694    *
1695    * @param loc locale to use
1696    * @return new uppercased String, or this if no characters were uppercased
1697    * @throws NullPointerException if loc is null
1698    * @see #toLowerCase(Locale)
1699    * @since 1.1
1700    */
toUpperCase(Locale loc)1701   public String toUpperCase(Locale loc)
1702   {
1703     // First, see how many characters we have to grow by, as well as if the
1704     // current string is already upper case.
1705 
1706     // Is loc turkish? String equality test is ok as Locale.language is interned
1707     if ("tr" == loc.getLanguage())
1708       {
1709         return toUpperCaseTurkish();
1710       }
1711     else
1712       {
1713         int expand = 0;
1714         boolean unchanged = true;
1715         int i = count;
1716         int x = i + offset;
1717         while (--i >= 0)
1718           {
1719             char ch = value[--x];
1720             expand += upperCaseExpansion(ch);
1721             unchanged = (unchanged && expand == 0
1722                          && ch == Character.toUpperCase(ch));
1723           }
1724         if (unchanged)
1725           return this;
1726 
1727         // Now we perform the conversion.
1728         i = count;
1729         if (expand == 0)
1730           {
1731             char[] newStr = new char[count];
1732             VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
1733             while (--i >= 0)
1734               {
1735                 char ch = value[x];
1736                 newStr[x - offset] = Character.toUpperCase(ch);
1737                 x++;
1738               }
1739             // Package constructor avoids an array copy.
1740             return new String(newStr, 0, count, true);
1741           }
1742 
1743         // Expansion is necessary.
1744         char[] newStr = new char[count + expand];
1745         int j = 0;
1746         while (--i >= 0)
1747           {
1748             char ch = value[x++];
1749             expand = upperCaseExpansion(ch);
1750             if (expand > 0)
1751               {
1752                 int index = upperCaseIndex(ch);
1753                 while (expand-- >= 0)
1754                   newStr[j++] = upperExpand[index++];
1755               }
1756             else
1757               newStr[j++] = Character.toUpperCase(ch);
1758           }
1759         // Package constructor avoids an array copy.
1760         return new String(newStr, 0, newStr.length, true);
1761       }
1762   }
1763   /**
1764    * Uppercases this String. This uses Unicode's special case mappings, as
1765    * applied to the platform's default Locale, so the resulting string may
1766    * be a different length.
1767    *
1768    * @return new uppercased String, or this if no characters were uppercased
1769    * @see #toUpperCase(Locale)
1770    * @see #toLowerCase()
1771    */
toUpperCase()1772   public String toUpperCase()
1773   {
1774     return toUpperCase(Locale.getDefault());
1775   }
1776 
1777   /**
1778    * Trims all characters less than or equal to <code>'\u0020'</code>
1779    * (<code>' '</code>) from the beginning and end of this String. This
1780    * includes many, but not all, ASCII control characters, and all
1781    * {@link Character#isWhitespace(char)}.
1782    *
1783    * @return new trimmed String, or this if nothing trimmed
1784    */
trim()1785   public String trim()
1786   {
1787     int limit = count + offset;
1788     if (count == 0 || (value[offset] > '\u0020'
1789                        && value[limit - 1] > '\u0020'))
1790       return this;
1791     int begin = offset;
1792     do
1793       if (begin == limit)
1794         return "";
1795     while (value[begin++] <= '\u0020');
1796 
1797     int end = limit;
1798     while (value[--end] <= '\u0020')
1799       ;
1800     return substring(begin - offset - 1, end - offset + 1);
1801   }
1802 
1803   /**
1804    * Returns this, as it is already a String!
1805    *
1806    * @return this
1807    */
toString()1808   public String toString()
1809   {
1810     return this;
1811   }
1812 
1813   /**
1814    * Copies the contents of this String into a character array. Subsequent
1815    * changes to the array do not affect the String.
1816    *
1817    * @return character array copying the String
1818    */
toCharArray()1819   public char[] toCharArray()
1820   {
1821     char[] copy = new char[count];
1822     VMSystem.arraycopy(value, offset, copy, 0, count);
1823     return copy;
1824   }
1825 
1826   /**
1827    * Returns a String representation of an Object. This is "null" if the
1828    * object is null, otherwise it is <code>obj.toString()</code> (which
1829    * can be null).
1830    *
1831    * @param obj the Object
1832    * @return the string conversion of obj
1833    */
valueOf(Object obj)1834   public static String valueOf(Object obj)
1835   {
1836     return obj == null ? "null" : obj.toString();
1837   }
1838 
1839   /**
1840    * Returns a String representation of a character array. Subsequent
1841    * changes to the array do not affect the String.
1842    *
1843    * @param data the character array
1844    * @return a String containing the same character sequence as data
1845    * @throws NullPointerException if data is null
1846    * @see #valueOf(char[], int, int)
1847    * @see #String(char[])
1848    */
valueOf(char[] data)1849   public static String valueOf(char[] data)
1850   {
1851     return valueOf (data, 0, data.length);
1852   }
1853 
1854   /**
1855    * Returns a String representing the character sequence of the char array,
1856    * starting at the specified offset, and copying chars up to the specified
1857    * count. Subsequent changes to the array do not affect the String.
1858    *
1859    * @param data character array
1860    * @param offset position (base 0) to start copying out of data
1861    * @param count the number of characters from data to copy
1862    * @return String containing the chars from data[offset..offset+count]
1863    * @throws NullPointerException if data is null
1864    * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
1865    *         || offset + count &gt; data.length)
1866    *         (while unspecified, this is a StringIndexOutOfBoundsException)
1867    * @see #String(char[], int, int)
1868    */
valueOf(char[] data, int offset, int count)1869   public static String valueOf(char[] data, int offset, int count)
1870   {
1871     return new String(data, offset, count, false);
1872   }
1873 
1874   /**
1875    * Returns a String representing the character sequence of the char array,
1876    * starting at the specified offset, and copying chars up to the specified
1877    * count. Subsequent changes to the array do not affect the String.
1878    *
1879    * @param data character array
1880    * @param offset position (base 0) to start copying out of data
1881    * @param count the number of characters from data to copy
1882    * @return String containing the chars from data[offset..offset+count]
1883    * @throws NullPointerException if data is null
1884    * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
1885    *         || offset + count &lt; 0 (overflow)
1886    *         || offset + count &lt; 0 (overflow)
1887    *         || offset + count &gt; data.length)
1888    *         (while unspecified, this is a StringIndexOutOfBoundsException)
1889    * @see #String(char[], int, int)
1890    */
copyValueOf(char[] data, int offset, int count)1891   public static String copyValueOf(char[] data, int offset, int count)
1892   {
1893     return new String(data, offset, count, false);
1894   }
1895 
1896   /**
1897    * Returns a String representation of a character array. Subsequent
1898    * changes to the array do not affect the String.
1899    *
1900    * @param data the character array
1901    * @return a String containing the same character sequence as data
1902    * @throws NullPointerException if data is null
1903    * @see #copyValueOf(char[], int, int)
1904    * @see #String(char[])
1905    */
copyValueOf(char[] data)1906   public static String copyValueOf(char[] data)
1907   {
1908     return copyValueOf (data, 0, data.length);
1909   }
1910 
1911   /**
1912    * Returns a String representing a boolean.
1913    *
1914    * @param b the boolean
1915    * @return "true" if b is true, else "false"
1916    */
valueOf(boolean b)1917   public static String valueOf(boolean b)
1918   {
1919     return b ? "true" : "false";
1920   }
1921 
1922   /**
1923    * Returns a String representing a character.
1924    *
1925    * @param c the character
1926    * @return String containing the single character c
1927    */
valueOf(char c)1928   public static String valueOf(char c)
1929   {
1930     // Package constructor avoids an array copy.
1931     return new String(new char[] { c }, 0, 1, true);
1932   }
1933 
1934   /**
1935    * Returns a String representing an integer.
1936    *
1937    * @param i the integer
1938    * @return String containing the integer in base 10
1939    * @see Integer#toString(int)
1940    */
valueOf(int i)1941   public static String valueOf(int i)
1942   {
1943     // See Integer to understand why we call the two-arg variant.
1944     return Integer.toString(i, 10);
1945   }
1946 
1947   /**
1948    * Returns a String representing a long.
1949    *
1950    * @param l the long
1951    * @return String containing the long in base 10
1952    * @see Long#toString(long)
1953    */
valueOf(long l)1954   public static String valueOf(long l)
1955   {
1956     return Long.toString(l);
1957   }
1958 
1959   /**
1960    * Returns a String representing a float.
1961    *
1962    * @param f the float
1963    * @return String containing the float
1964    * @see Float#toString(float)
1965    */
valueOf(float f)1966   public static String valueOf(float f)
1967   {
1968     return Float.toString(f);
1969   }
1970 
1971   /**
1972    * Returns a String representing a double.
1973    *
1974    * @param d the double
1975    * @return String containing the double
1976    * @see Double#toString(double)
1977    */
valueOf(double d)1978   public static String valueOf(double d)
1979   {
1980     return Double.toString(d);
1981   }
1982 
1983 
1984   /** @since 1.5 */
format(Locale locale, String format, Object... args)1985   public static String format(Locale locale, String format, Object... args)
1986   {
1987     Formatter f = new Formatter(locale);
1988     return f.format(format, args).toString();
1989   }
1990 
1991   /** @since 1.5 */
format(String format, Object... args)1992   public static String format(String format, Object... args)
1993   {
1994     return format(Locale.getDefault(), format, args);
1995   }
1996 
1997   /**
1998    * If two Strings are considered equal, by the equals() method,
1999    * then intern() will return the same String instance. ie.
2000    * if (s1.equals(s2)) then (s1.intern() == s2.intern()).
2001    * All string literals and string-valued constant expressions
2002    * are already interned.
2003    *
2004    * @return the interned String
2005    */
intern()2006   public String intern()
2007   {
2008     return VMString.intern(this);
2009   }
2010 
2011   /**
2012    * Return the number of code points between two indices in the
2013    * <code>String</code>.  An unpaired surrogate counts as a
2014    * code point for this purpose.  Characters outside the indicated
2015    * range are not examined, even if the range ends in the middle of a
2016    * surrogate pair.
2017    *
2018    * @param start the starting index
2019    * @param end one past the ending index
2020    * @return the number of code points
2021    * @since 1.5
2022    */
codePointCount(int start, int end)2023   public synchronized int codePointCount(int start, int end)
2024   {
2025     if (start < 0 || end > count || start > end)
2026       throw new StringIndexOutOfBoundsException();
2027 
2028     start += offset;
2029     end += offset;
2030     int count = 0;
2031     while (start < end)
2032       {
2033         char base = value[start];
2034         if (base < Character.MIN_HIGH_SURROGATE
2035             || base > Character.MAX_HIGH_SURROGATE
2036             || start == end
2037             || start == count
2038             || value[start + 1] < Character.MIN_LOW_SURROGATE
2039             || value[start + 1] > Character.MAX_LOW_SURROGATE)
2040           {
2041             // Nothing.
2042           }
2043         else
2044           {
2045             // Surrogate pair.
2046             ++start;
2047           }
2048         ++start;
2049         ++count;
2050       }
2051     return count;
2052   }
2053 
2054   /**
2055    * Helper function used to detect which characters have a multi-character
2056    * uppercase expansion. Note that this is only used in locations which
2057    * track one-to-many capitalization (java.lang.Character does not do this).
2058    * As of Unicode 3.0.0, the result is limited in the range 0 to 2, as the
2059    * longest uppercase expansion is three characters (a growth of 2 from the
2060    * lowercase character).
2061    *
2062    * @param ch the char to check
2063    * @return the number of characters to add when converting to uppercase
2064    * @see CharData#DIRECTION
2065    * @see CharData#UPPER_SPECIAL
2066    * @see #toUpperCase(Locale)
2067    */
upperCaseExpansion(char ch)2068   private static int upperCaseExpansion(char ch)
2069   {
2070     return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3;
2071   }
2072 
2073   /**
2074    * Helper function used to locate the offset in upperExpand given a
2075    * character with a multi-character expansion. The binary search is
2076    * optimized under the assumption that this method will only be called on
2077    * characters which exist in upperSpecial.
2078    *
2079    * @param ch the char to check
2080    * @return the index where its expansion begins
2081    * @see CharData#UPPER_SPECIAL
2082    * @see CharData#UPPER_EXPAND
2083    * @see #toUpperCase(Locale)
2084    */
upperCaseIndex(char ch)2085   private static int upperCaseIndex(char ch)
2086   {
2087     // Simple binary search for the correct character.
2088     int low = 0;
2089     int hi = upperSpecial.length - 2;
2090     int mid = ((low + hi) >> 2) << 1;
2091     char c = upperSpecial[mid];
2092     while (ch != c)
2093       {
2094         if (ch < c)
2095           hi = mid - 2;
2096         else
2097           low = mid + 2;
2098         mid = ((low + hi) >> 2) << 1;
2099         c = upperSpecial[mid];
2100       }
2101     return upperSpecial[mid + 1];
2102   }
2103 
2104   /**
2105    * Returns the value array of the given string if it is zero based or a
2106    * copy of it that is zero based (stripping offset and making length equal
2107    * to count). Used for accessing the char[]s of gnu.java.lang.CharData.
2108    * Package private for use in Character.
2109    */
zeroBasedStringValue(String s)2110   static char[] zeroBasedStringValue(String s)
2111   {
2112     char[] value;
2113 
2114     if (s.offset == 0 && s.count == s.value.length)
2115       value = s.value;
2116     else
2117       {
2118         int count = s.count;
2119         value = new char[count];
2120         VMSystem.arraycopy(s.value, s.offset, value, 0, count);
2121       }
2122 
2123     return value;
2124   }
2125 
2126   /**
2127    * Returns true iff this String contains the sequence of Characters
2128    * described in s.
2129    * @param s the CharSequence
2130    * @return true iff this String contains s
2131    *
2132    * @since 1.5
2133    */
contains(CharSequence s)2134   public boolean contains (CharSequence s)
2135   {
2136     return this.indexOf(s.toString()) != -1;
2137   }
2138 
2139   /**
2140    * Returns a string that is this string with all instances of the sequence
2141    * represented by <code>target</code> replaced by the sequence in
2142    * <code>replacement</code>.
2143    * @param target the sequence to be replaced
2144    * @param replacement the sequence used as the replacement
2145    * @return the string constructed as above
2146    */
replace(CharSequence target, CharSequence replacement)2147   public String replace (CharSequence target, CharSequence replacement)
2148   {
2149     String targetString = target.toString();
2150     String replaceString = replacement.toString();
2151     int targetLength = target.length();
2152     int replaceLength = replacement.length();
2153 
2154     int startPos = this.indexOf(targetString);
2155     CPStringBuilder result = new CPStringBuilder(this);
2156     while (startPos != -1)
2157       {
2158         // Replace the target with the replacement
2159         result.replace(startPos, startPos + targetLength, replaceString);
2160 
2161         // Search for a new occurrence of the target
2162         startPos = result.indexOf(targetString, startPos + replaceLength);
2163       }
2164     return result.toString();
2165   }
2166 
2167   /**
2168    * Return the index into this String that is offset from the given index by
2169    * <code>codePointOffset</code> code points.
2170    * @param index the index at which to start
2171    * @param codePointOffset the number of code points to offset
2172    * @return the index into this String that is <code>codePointOffset</code>
2173    * code points offset from <code>index</code>.
2174    *
2175    * @throws IndexOutOfBoundsException if index is negative or larger than the
2176    * length of this string.
2177    * @throws IndexOutOfBoundsException if codePointOffset is positive and the
2178    * substring starting with index has fewer than codePointOffset code points.
2179    * @throws IndexOutOfBoundsException if codePointOffset is negative and the
2180    * substring ending with index has fewer than (-codePointOffset) code points.
2181    * @since 1.5
2182    */
offsetByCodePoints(int index, int codePointOffset)2183   public int offsetByCodePoints(int index, int codePointOffset)
2184   {
2185     if (index < 0 || index > count)
2186       throw new IndexOutOfBoundsException();
2187 
2188     return Character.offsetByCodePoints(value, offset, count, offset + index,
2189                                         codePointOffset);
2190   }
2191 
2192   /**
2193    * Returns true if, and only if, {@link #length()}
2194    * is <code>0</code>.
2195    *
2196    * @return true if the length of the string is zero.
2197    * @since 1.6
2198    */
isEmpty()2199   public boolean isEmpty()
2200   {
2201     return count == 0;
2202   }
2203 
2204 }
2205