Source for java.lang.String

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