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