001/* String.java -- immutable character sequences; the object of string literals
002   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
003   Free Software Foundation, Inc.
004
005This file is part of GNU Classpath.
006
007GNU Classpath is free software; you can redistribute it and/or modify
008it under the terms of the GNU General Public License as published by
009the Free Software Foundation; either version 2, or (at your option)
010any later version.
011
012GNU Classpath is distributed in the hope that it will be useful, but
013WITHOUT ANY WARRANTY; without even the implied warranty of
014MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015General Public License for more details.
016
017You should have received a copy of the GNU General Public License
018along with GNU Classpath; see the file COPYING.  If not, write to the
019Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02002110-1301 USA.
021
022Linking this library statically or dynamically with other modules is
023making a combined work based on this library.  Thus, the terms and
024conditions of the GNU General Public License cover the whole
025combination.
026
027As a special exception, the copyright holders of this library give you
028permission to link this library with independent modules to produce an
029executable, regardless of the license terms of these independent
030modules, and to copy and distribute the resulting executable under
031terms of your choice, provided that you also meet, for each linked
032independent module, the terms and conditions of the license of that
033module.  An independent module is a module which is not derived from
034or based on this library.  If you modify this library, you may extend
035this exception to your version of the library, but you are not
036obligated to do so.  If you do not wish to do so, delete this
037exception statement from your version. */
038
039
040package java.lang;
041
042import gnu.java.lang.CharData;
043import gnu.java.lang.CPStringBuilder;
044
045import java.io.Serializable;
046import java.io.UnsupportedEncodingException;
047import java.nio.ByteBuffer;
048import java.nio.CharBuffer;
049import java.nio.charset.CharacterCodingException;
050import java.nio.charset.Charset;
051import java.nio.charset.CharsetDecoder;
052import java.nio.charset.CharsetEncoder;
053import java.nio.charset.CodingErrorAction;
054import java.nio.charset.IllegalCharsetNameException;
055import java.nio.charset.UnsupportedCharsetException;
056import java.text.Collator;
057import java.util.Comparator;
058import java.util.Formatter;
059import java.util.Locale;
060import java.util.regex.Matcher;
061import java.util.regex.Pattern;
062import java.util.regex.PatternSyntaxException;
063
064/**
065 * Strings represent an immutable set of characters.  All String literals
066 * are instances of this class, and two string literals with the same contents
067 * refer to the same String object.
068 *
069 * <p>This class also includes a number of methods for manipulating the
070 * contents of strings (of course, creating a new object if there are any
071 * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
072 * standards, where some character sequences have a different number of
073 * characters in the uppercase version than the lower case.
074 *
075 * <p>Strings are special, in that they are the only object with an overloaded
076 * operator. When you use '+' with at least one String argument, both
077 * arguments have String conversion performed on them, and another String (not
078 * guaranteed to be unique) results.
079 *
080 * <p>String is special-cased when doing data serialization - rather than
081 * listing the fields of this class, a String object is converted to a string
082 * literal in the object stream.
083 *
084 * @author Paul N. Fisher
085 * @author Eric Blake (ebb9@email.byu.edu)
086 * @author Per Bothner (bothner@cygnus.com)
087 * @author Tom Tromey (tromey@redhat.com)
088 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
089 * @since 1.0
090 * @status updated to 1.4; but could use better data sharing via offset field
091 */
092public final class String
093  implements Serializable, Comparable<String>, CharSequence
094{
095  // WARNING: String is a CORE class in the bootstrap cycle. See the comments
096  // in vm/reference/java/lang/Runtime for implications of this fact.
097
098  /**
099   * 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     */
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     */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
1613  public String toLowerCase()
1614  {
1615    return toLowerCase(Locale.getDefault());
1616  }
1617
1618  /**
1619   * Uppercase this string for a Turkish locale
1620   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
1978  public static String valueOf(double d)
1979  {
1980    return Double.toString(d);
1981  }
1982
1983
1984  /** @since 1.5 */
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 */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
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   */
2199  public boolean isEmpty()
2200  {
2201    return count == 0;
2202  }
2203
2204}