home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / lang / String.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  53.4 KB  |  1,549 lines

  1. /*
  2.  * @(#)String.java    1.92 98/03/18
  3.  *
  4.  * Copyright 1994-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang;
  16.  
  17. import java.util.Hashtable;
  18. import java.util.Locale;
  19. import sun.io.ByteToCharConverter;
  20. import sun.io.CharToByteConverter;
  21. import java.io.CharConversionException;
  22. import java.io.UnsupportedEncodingException;
  23.  
  24. /**
  25.  * The <code>String</code> class represents character strings. All 
  26.  * string literals in Java programs, such as <code>"abc"</code>, are 
  27.  * implemented as instances of this class. 
  28.  * <p>
  29.  * Strings are constant; their values cannot be changed after they 
  30.  * are created. String buffers support mutable strings.
  31.  * Because String objects are immutable they can be shared. For example:
  32.  * <p><blockquote><pre>
  33.  *     String str = "abc";
  34.  * </pre></blockquote><p>
  35.  * is equivalent to:
  36.  * <p><blockquote><pre>
  37.  *     char data[] = {'a', 'b', 'c'};
  38.  *     String str = new String(data);
  39.  * </pre></blockquote><p>
  40.  * Here are some more examples of how strings can be used:
  41.  * <p><blockquote><pre>
  42.  *     System.out.println("abc");
  43.  *     String cde = "cde";
  44.  *     System.out.println("abc" + cde);
  45.  *     String c = "abc".substring(2,3);
  46.  *     String d = cde.substring(1, 2);
  47.  * </pre></blockquote>
  48.  * <p>
  49.  * The class <code>String</code> includes methods for examining 
  50.  * individual characters of the sequence, for comparing strings, for 
  51.  * searching strings, for extracting substrings, and for creating a 
  52.  * copy of a string with all characters translated to uppercase or to 
  53.  * lowercase. 
  54.  * <p>
  55.  * The Java language provides special support for the string 
  56.  * concatentation operator ( + ), and for conversion of 
  57.  * other objects to strings. String concatenation is implemented 
  58.  * through the <code>StringBuffer</code> class and its 
  59.  * <code>append</code> method.
  60.  * String conversions are implemented through the method 
  61.  * <code>toString</code>, defined by <code>Object</code> and 
  62.  * inherited by all classes in Java. For additional information on 
  63.  * string concatenation and conversion, see Gosling, Joy, and Steele, 
  64.  * <i>The Java Language Specification</i>. 
  65.  *
  66.  * @author  Lee Boynton
  67.  * @author  Arthur van Hoff
  68.  * @version 1.92, 03/18/98
  69.  * @see     java.lang.Object#toString()
  70.  * @see     java.lang.StringBuffer
  71.  * @see     java.lang.StringBuffer#append(boolean)
  72.  * @see     java.lang.StringBuffer#append(char)
  73.  * @see     java.lang.StringBuffer#append(char[])
  74.  * @see     java.lang.StringBuffer#append(char[], int, int)
  75.  * @see     java.lang.StringBuffer#append(double)
  76.  * @see     java.lang.StringBuffer#append(float)
  77.  * @see     java.lang.StringBuffer#append(int)
  78.  * @see     java.lang.StringBuffer#append(long)
  79.  * @see     java.lang.StringBuffer#append(java.lang.Object)
  80.  * @see     java.lang.StringBuffer#append(java.lang.String)
  81.  * @since   JDK1.0
  82.  */
  83. public final
  84. class String implements java.io.Serializable, Comparable {
  85.     /** The value is used for character storage. */
  86.     private char value[];
  87.  
  88.     /** The offset is the first index of the storage that is used. */
  89.     private int offset;
  90.  
  91.     /** The count is the number of characters in the String. */
  92.     private int count;
  93.  
  94.     /** use serialVersionUID from JDK 1.0.2 for interoperability */
  95.     private static final long serialVersionUID = -6849794470754667710L;
  96.  
  97.     /**
  98.      * Allocates a new <code>String</code> containing no characters. 
  99.      */
  100.     public String() {
  101.     value = new char[0];
  102.     }
  103.  
  104.     /**
  105.      * Allocates a new string that contains the same sequence of 
  106.      * characters as the string argument. 
  107.      *
  108.      * @param   value   a <code>String</code>.
  109.      */
  110.     public String(String value) {
  111.     count = value.length();
  112.     this.value = new char[count];
  113.     value.getChars(0, count, this.value, 0);
  114.     }
  115.  
  116.     /**
  117.      * Allocates a new <code>String</code> so that it represents the 
  118.      * sequence of characters currently contained in the character array 
  119.      * argument. 
  120.      *
  121.      * @param  value   the initial value of the string.
  122.      */
  123.     public String(char value[]) {
  124.     this.count = value.length;
  125.     this.value = new char[count];
  126.     System.arraycopy(value, 0, this.value, 0, count);
  127.     }
  128.  
  129.     /**
  130.      * Allocates a new <code>String</code> that contains characters from 
  131.      * a subarray of the character array argument. The <code>offset</code> 
  132.      * argument is the index of the first character of the subarray and 
  133.      * the <code>count</code> argument specifies the length of the 
  134.      * subarray. 
  135.      *
  136.      * @param      value    array that is the source of characters.
  137.      * @param      offset   the initial offset.
  138.      * @param      count    the length.
  139.      * @exception  StringIndexOutOfBoundsException  if the <code>offset</code>
  140.      *               and <code>count</code> arguments index characters outside
  141.      *               the bounds of the <code>value</code> array.
  142.      */
  143.     public String(char value[], int offset, int count) {
  144.     if (offset < 0) {
  145.         throw new StringIndexOutOfBoundsException(offset);
  146.     }
  147.     if (count < 0) {
  148.         throw new StringIndexOutOfBoundsException(count);
  149.     }
  150.     // Note: offset or count might be near -1>>>1.
  151.     if (offset > value.length - count) {
  152.         throw new StringIndexOutOfBoundsException(offset + count);
  153.     }
  154.  
  155.     this.value = new char[count];
  156.     this.count = count;
  157.     System.arraycopy(value, offset, this.value, 0, count);
  158.     }
  159.  
  160.     /**
  161.      * Allocates a new <code>String</code> constructed from a subarray 
  162.      * of an array of 8-bit integer values. 
  163.      * <p>
  164.      * The <code>offset</code> argument is the index of the first byte 
  165.      * of the subarray, and the <code>count</code> argument specifies the 
  166.      * length of the subarray. 
  167.      * <p>
  168.      * Each <code>byte</code> in the subarray is converted to a 
  169.      * <code>char</code> as specified in the method above. 
  170.      *
  171.      * @deprecated This method does not properly convert bytes into characters.
  172.      * As of JDK 1.1, the preferred way to do this is via the
  173.      * <code>String</code> constructors that take a character-encoding name or
  174.      * that use the platform's default encoding.
  175.      *
  176.      * @param      ascii     the bytes to be converted to characters.
  177.      * @param      hibyte    the top 8 bits of each 16-bit Unicode character.
  178.      * @param      offset    the initial offset.
  179.      * @param      count     the length.
  180.      * @exception  StringIndexOutOfBoundsException  if the <code>offset</code>
  181.      *               or <code>count</code> argument is invalid.
  182.      * @see        java.lang.String#String(byte[], int)
  183.      * @see        java.lang.String#String(byte[], int, int, java.lang.String)
  184.      * @see        java.lang.String#String(byte[], int, int)
  185.      * @see        java.lang.String#String(byte[], java.lang.String)
  186.      * @see        java.lang.String#String(byte[])
  187.      */
  188.     public String(byte ascii[], int hibyte, int offset, int count) {
  189.     if (offset < 0) {
  190.         throw new StringIndexOutOfBoundsException(offset);
  191.     }
  192.     if (count < 0) {
  193.         throw new StringIndexOutOfBoundsException(count);
  194.     }
  195.     // Note: offset or count might be near -1>>>1.
  196.     if (offset > ascii.length - count) {
  197.         throw new StringIndexOutOfBoundsException(offset + count);
  198.     }
  199.  
  200.     char value[] = new char[count];
  201.     this.count = count;
  202.     this.value = value;
  203.  
  204.     if (hibyte == 0) {
  205.         for (int i = count ; i-- > 0 ;) {
  206.         value[i] = (char) (ascii[i + offset] & 0xff);
  207.         }
  208.     } else {
  209.         hibyte <<= 8;
  210.         for (int i = count ; i-- > 0 ;) {
  211.         value[i] = (char) (hibyte | (ascii[i + offset] & 0xff));
  212.         }
  213.     }
  214.     }
  215.  
  216.     /**
  217.      * Allocates a new <code>String</code> containing characters 
  218.      * constructed from an array of 8-bit integer values. Each character 
  219.      * <i>c</i>in the resulting string is constructed from the 
  220.      * corresponding component <i>b</i> in the byte array such that:
  221.      * <p><blockquote><pre>
  222.      *     <b><i>c</i></b> == (char)(((hibyte & 0xff) << 8)
  223.      *                         | (<b><i>b</i></b> & 0xff))
  224.      * </pre></blockquote>
  225.      *
  226.      * @deprecated This method does not properly convert bytes into characters.
  227.      * As of JDK 1.1, the preferred way to do this is via the
  228.      * <code>String</code> constructors that take a character-encoding name or
  229.      * that use the platform's default encoding.
  230.      *
  231.      * @param      ascii    the bytes to be converted to characters.
  232.      * @param      hibyte   the top 8 bits of each 16-bit Unicode character.
  233.      * @see        java.lang.String#String(byte[], int, int, java.lang.String)
  234.      * @see        java.lang.String#String(byte[], int, int)
  235.      * @see        java.lang.String#String(byte[], java.lang.String)
  236.      * @see        java.lang.String#String(byte[])
  237.      */
  238.     public String(byte ascii[], int hibyte) {
  239.     this(ascii, hibyte, 0, ascii.length);
  240.     }
  241.  
  242.     /**
  243.      * Construct a new <code>String</code> by converting the specified
  244.      * subarray of bytes using the specified character-encoding converter.  The
  245.      * length of the new <code>String</code> is a function of the encoding, and
  246.      * hence may not be equal to the length of the subarray.
  247.      *
  248.      * @param  bytes   The bytes to be converted into characters
  249.      * @param  offset  Index of the first byte to convert
  250.      * @param  length  Number of bytes to convert
  251.      * @param  btc     A ByteToCharConverter
  252.      */
  253.     private String(byte bytes[], int offset, int length,
  254.            ByteToCharConverter btc)
  255.     {
  256.     int estCount = btc.getMaxCharsPerByte() * length;
  257.     value = new char[estCount];
  258.  
  259.         try {
  260.         count = btc.convert(bytes, offset, offset+length,
  261.                 value, 0, estCount);
  262.         count += btc.flush(value, btc.nextCharIndex(), estCount);
  263.     }
  264.     catch (CharConversionException x) {
  265.         count = btc.nextCharIndex();
  266.     }
  267.  
  268.     if (count < estCount) {
  269.         // A multi-byte format was used:  Trim the char array.
  270.         char[] trimValue = new char[count];
  271.         System.arraycopy(value, 0, trimValue, 0, count);
  272.         value = trimValue;
  273.     }
  274.     }
  275.  
  276.     /**
  277.      * Construct a new <code>String</code> by converting the specified
  278.      * subarray of bytes using the specified character encoding.  The length of
  279.      * the new <code>String</code> is a function of the encoding, and hence may
  280.      * not be equal to the length of the subarray.
  281.      *
  282.      * @param  bytes   The bytes to be converted into characters
  283.      * @param  offset  Index of the first byte to convert
  284.      * @param  length  Number of bytes to convert
  285.      * @param  enc     The name of a character encoding
  286.      *
  287.      * @exception  UnsupportedEncodingException
  288.      *             If the named encoding is not supported
  289.      * @since      JDK1.1
  290.      */
  291.     public String(byte bytes[], int offset, int length, String enc)
  292.     throws UnsupportedEncodingException
  293.     {
  294.     this(bytes, offset, length, ByteToCharConverter.getConverter(enc));
  295.     }
  296.  
  297.     /**
  298.      * Construct a new <code>String</code> by converting the specified array
  299.      * of bytes using the specified character encoding.  The length of the new
  300.      * <code>String</code> is a function of the encoding, and hence may not be
  301.      * equal to the length of the byte array.
  302.      *
  303.      * @param  bytes   The bytes to be converted into characters
  304.      * @param  enc     A character-encoding name
  305.      *
  306.      * @exception  UnsupportedEncodingException
  307.      *             If the named encoding is not supported
  308.      * @since      JDK1.1
  309.      */
  310.     public String(byte bytes[], String enc)
  311.     throws UnsupportedEncodingException
  312.     {
  313.     this(bytes, 0, bytes.length, enc);
  314.     }
  315.  
  316.     /**
  317.      * Construct a new <code>String</code> by converting the specified
  318.      * subarray of bytes using the platform's default character encoding.  The
  319.      * length of the new <code>String</code> is a function of the encoding, and
  320.      * hence may not be equal to the length of the subarray.
  321.      *
  322.      * @param  bytes   The bytes to be converted into characters
  323.      * @param  offset  Index of the first byte to convert
  324.      * @param  length  Number of bytes to convert
  325.      * @since  JDK1.1
  326.      */
  327.     public String(byte bytes[], int offset, int length) {
  328.     this(bytes, offset, length, ByteToCharConverter.getDefault());
  329.     }
  330.  
  331.     /**
  332.      * Construct a new <code>String</code> by converting the specified array
  333.      * of bytes using the platform's default character encoding.  The length of
  334.      * the new <code>String</code> is a function of the encoding, and hence may
  335.      * not be equal to the length of the byte array.
  336.      *
  337.      * @param  bytes   The bytes to be converted into characters
  338.      * @since  JDK1.1
  339.      */
  340.     public String(byte bytes[]) {
  341.     this(bytes, 0, bytes.length, ByteToCharConverter.getDefault());
  342.     }
  343.  
  344.     /**
  345.      * Allocates a new string that contains the sequence of characters 
  346.      * currently contained in the string buffer argument. 
  347.      *
  348.      * @param   buffer   a <code>StringBuffer</code>.
  349.      */
  350.     public String (StringBuffer buffer) { 
  351.     synchronized(buffer) { 
  352.         buffer.setShared();
  353.         this.value = buffer.getValue();
  354.         this.offset = 0;
  355.         this.count = buffer.length();
  356.     }
  357.     }
  358.     
  359.     // Private constructor which shares value array for speed.
  360.     private String(int offset, int count, char value[]) {
  361.     this.value = value;
  362.     this.offset = offset;
  363.     this.count = count;
  364.     }
  365.  
  366.     /**
  367.      * Returns the length of this string.
  368.      * The length is equal to the number of 16-bit
  369.      * Unicode characters in the string.
  370.      *
  371.      * @return  the length of the sequence of characters represented by this
  372.      *          object.
  373.      */
  374.     public int length() {
  375.     return count;
  376.     }
  377.  
  378.     /**
  379.      * Returns the character at the specified index. An index ranges
  380.      * from <code>0</code> to <code>length() - 1</code>.
  381.      *
  382.      * @param      index   the index of the character.
  383.      * @return     the character at the specified index of this string.
  384.      *             The first character is at index <code>0</code>.
  385.      * @exception  StringIndexOutOfBoundsException  if the index is out of
  386.      *               range.
  387.      */
  388.     public char charAt(int index) {
  389.     if ((index < 0) || (index >= count)) {
  390.         throw new StringIndexOutOfBoundsException(index);
  391.     }
  392.     return value[index + offset];
  393.     }
  394.  
  395.     /**
  396.      * Copies characters from this string into the destination character array. 
  397.      * <p>
  398.      * The first character to be copied is at index <code>srcBegin</code>; 
  399.      * the last character to be copied is at index <code>srcEnd-1</code> 
  400.      * (thus the total number of characters to be copied is 
  401.      * <code>srcEnd-srcBegin</code>). The characters are copied into the 
  402.      * subarray of <code>dst</code> starting at index <code>dstBegin</code> 
  403.      * and ending at index: 
  404.      * <p><blockquote><pre>
  405.      *     dstbegin + (srcEnd-srcBegin) - 1
  406.      * </pre></blockquote>
  407.      *
  408.      * @param      srcBegin   index of the first character in the string
  409.      *                        to copy.
  410.      * @param      srcEnd     index after the last character in the string
  411.      *                        to copy.
  412.      * @param      dst        the destination array.
  413.      * @param      dstBegin   the start offset in the destination array.
  414.      * @exception StringIndexOutOfBoundsException If srcBegin or srcEnd is out 
  415.      *              of range, or if srcBegin is greater than the srcEnd.
  416.      */
  417.     public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
  418.     if (srcBegin < 0) {
  419.         throw new StringIndexOutOfBoundsException(srcBegin);
  420.     } 
  421.     if (srcEnd > count) {
  422.         throw new StringIndexOutOfBoundsException(srcEnd);
  423.     } 
  424.     if (srcBegin > srcEnd) {
  425.         throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
  426.     }
  427.     System.arraycopy(value, offset + srcBegin, dst, dstBegin, srcEnd - srcBegin);
  428.     }
  429.  
  430.     /**
  431.      * Copies characters from this string into the destination byte 
  432.      * array. Each byte receives the 8 low-order bits of the 
  433.      * corresponding character. 
  434.      * <p>
  435.      * The first character to be copied is at index <code>srcBegin</code>; 
  436.      * the last character to be copied is at index <code>srcEnd-1</code>. 
  437.      * The total number of characters to be copied is 
  438.      * <code>srcEnd-srcBegin</code>. The characters, converted to bytes, 
  439.      * are copied into the subarray of <code>dst</code> starting at index 
  440.      * <code>dstBegin</code> and ending at index: 
  441.      * <p><blockquote><pre>
  442.      *     dstbegin + (srcEnd-srcBegin) - 1
  443.      * </pre></blockquote>
  444.      *
  445.      * @deprecated This method does not properly convert characters into bytes.
  446.      * As of JDK 1.1, the preferred way to do this is via the
  447.      * <code>getBytes(String enc)</code> method, which takes a
  448.      * character-encoding name, or the <code>getBytes()</code> method, which
  449.      * uses the platform's default encoding.
  450.      *
  451.      * @param      srcBegin   index of the first character in the string
  452.      *                        to copy.
  453.      * @param      srcEnd     index after the last character in the string
  454.      *                        to copy.
  455.      * @param      dst        the destination array.
  456.      * @param      dstBegin   the start offset in the destination array.
  457.      * @exception StringIndexOutOfBoundsException  if srcBegin or srcEnd is out 
  458.      *              of range, or if srcBegin is greater than srcEnd.
  459.      */
  460.     public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
  461.     if (srcBegin < 0) {
  462.         throw new StringIndexOutOfBoundsException(srcBegin);
  463.     } 
  464.     if (srcEnd > count) {
  465.         throw new StringIndexOutOfBoundsException(srcEnd);
  466.     } 
  467.     if (srcBegin > srcEnd) {
  468.         throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
  469.     }
  470.      int j = dstBegin;
  471.      int n = offset + srcEnd;
  472.      int i = offset + srcBegin;
  473.     char[] val = value;   /* avoid getfield opcode */
  474.  
  475.      while (i < n) {
  476.          dst[j++] = (byte)val[i++];
  477.      }
  478.     }
  479.  
  480.     /**
  481.      * Apply the specified character-encoding converter to this String,
  482.      * storing the resulting bytes into a new byte array.
  483.      *
  484.      * @param  ctb  A CharToByteConverter
  485.      * @return      The resultant byte array
  486.      */
  487.     private byte[] getBytes(CharToByteConverter ctb) {
  488.     ctb.reset();
  489.     int estLength = ctb.getMaxBytesPerChar() * count;
  490.     byte[] result = new byte[estLength];
  491.     int length;
  492.  
  493.     try {
  494.         length = ctb.convert(value, offset, offset + count,
  495.                  result, 0, estLength);
  496.         length += ctb.flush(result, ctb.nextByteIndex(), estLength);
  497.     } catch (CharConversionException e) {
  498.         length = ctb.nextByteIndex();
  499.     }
  500.  
  501.     if (length < estLength) {
  502.         // A short format was used:  Trim the byte array.
  503.         byte[] trimResult = new byte[length];
  504.         System.arraycopy(result, 0, trimResult, 0, length);
  505.         return trimResult;
  506.     }
  507.     else {
  508.         return result;
  509.     }
  510.     }
  511.  
  512.     /**
  513.      * Convert this <code>String</code> into bytes according to the specified
  514.      * character encoding, storing the result into a new byte array.
  515.      *
  516.      * @param  enc  A character-encoding name
  517.      * @return      The resultant byte array
  518.      *
  519.      * @exception  UnsupportedEncodingException
  520.      *             If the named encoding is not supported
  521.      * @since      JDK1.1
  522.      */
  523.     public byte[] getBytes(String enc)
  524.     throws UnsupportedEncodingException
  525.     {
  526.     return getBytes(CharToByteConverter.getConverter(enc));
  527.     }
  528.  
  529.     /**
  530.      * Convert this <code>String</code> into bytes according to the platform's
  531.      * default character encoding, storing the result into a new byte array.
  532.      *
  533.      * @return  the resultant byte array.
  534.      * @since   JDK1.1
  535.      */
  536.     public byte[] getBytes() {
  537.     return getBytes(CharToByteConverter.getDefault());
  538.     }
  539.  
  540.     /**
  541.      * Compares this string to the specified object.
  542.      * The result is <code>true</code> if and only if the argument is not 
  543.      * <code>null</code> and is a <code>String</code> object that represents 
  544.      * the same sequence of characters as this object. 
  545.      *
  546.      * @param   anObject   the object to compare this <code>String</code>
  547.      *                     against.
  548.      * @return  <code>true</code> if the <code>String </code>are equal;
  549.      *          <code>false</code> otherwise.
  550.      * @see     java.lang.String#compareTo(java.lang.String)
  551.      * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
  552.      */
  553.     public boolean equals(Object anObject) {
  554.     if (this == anObject) {
  555.         return true;
  556.     }
  557.     if ((anObject != null) && (anObject instanceof String)) {
  558.         String anotherString = (String)anObject;
  559.         int n = count;
  560.         if (n == anotherString.count) {
  561.         char v1[] = value;
  562.         char v2[] = anotherString.value;
  563.         int i = offset;
  564.         int j = anotherString.offset;
  565.         while (n-- != 0) {
  566.             if (v1[i++] != v2[j++]) {
  567.             return false;
  568.             }
  569.         }
  570.         return true;
  571.         }
  572.     }
  573.     return false;
  574.     }
  575.  
  576.     /**
  577.      * Compares this String to another object.
  578.      * The result is <code>true</code> if and only if the argument is not 
  579.      * <code>null</code> and is a <code>String</code> object that represents 
  580.      * the same sequence of characters as this object, where case is ignored. 
  581.      * <p>
  582.      * Two characters are considered the same, ignoring case, if at 
  583.      * least one of the following is true: 
  584.      * <ul>
  585.      * <li>The two characters are the same (as compared by the <code>==</code> 
  586.      *     operator). 
  587.      * <li>Applying the method <code>Character.toUppercase</code> to each 
  588.      *     character produces the same result. 
  589.      * <li>Applying the method <code>Character.toLowercase</code> to each 
  590.      *     character produces the same result. 
  591.      * </ul>
  592.      * <p>
  593.      * Two sequences of characters are the same, ignoring case, if the 
  594.      * sequences have the same length and corresponding characters are 
  595.      * the same, ignoring case. 
  596.      *
  597.      * @param   anotherString   the <code>String</code> to compare this
  598.      *                          <code>String</code> against.
  599.      * @return  <code>true</code> if the <code>String</code>s are equal,
  600.      *          ignoring case; <code>false</code> otherwise.
  601.      * @see     java.lang.Character#toLowerCase(char)
  602.      * @see     java.lang.Character#toUpperCase(char)
  603.      */
  604.     public boolean equalsIgnoreCase(String anotherString) {
  605.     return (anotherString != null) && (anotherString.count == count) &&
  606.         regionMatches(true, 0, anotherString, 0, count);
  607.     }
  608.  
  609.     /**
  610.      * Compares two strings lexicographically. 
  611.      * The comparison is based on the Unicode value of each character in
  612.      * the strings. 
  613.      *
  614.      * @param   anotherString   the <code>String</code> to be compared.
  615.      * @return  the value <code>0</code> if the argument string is equal to
  616.      *          this string; a value less than <code>0</code> if this string
  617.      *          is lexicographically less than the string argument; and a
  618.      *          value greater than <code>0</code> if this string is
  619.      *          lexicographically greater than the string argument.
  620.      */
  621.     public int compareTo(String anotherString) {
  622.     int len1 = count;
  623.     int len2 = anotherString.count;
  624.     int n = Math.min(len1, len2);
  625.     char v1[] = value;
  626.     char v2[] = anotherString.value;
  627.     int i = offset;
  628.     int j = anotherString.offset;
  629.  
  630.     while (n-- != 0) {
  631.         char c1 = v1[i++];
  632.         char c2 = v2[j++];
  633.         if (c1 != c2) {
  634.         return c1 - c2;
  635.         }
  636.     }
  637.     return len1 - len2;
  638.     }
  639.  
  640.     /**
  641.      * Compares this String to another Object.  If the Object is a String,
  642.      * this function behaves like <code>compareTo(String)</code>.  Otherwise,
  643.      * it throws a <code>ClassCastException</code> (as Strings are comparable
  644.      * only to other Strings).
  645.      *
  646.      * @param   o the <code>Object</code> to be compared.
  647.      * @return  the value <code>0</code> if the argument is a string
  648.      *        lexicographically equal to this string; a value less than
  649.      *        <code>0</code> if the argument is a string lexicographically 
  650.      *        greater than this string; and a value greater than
  651.      *        <code>0</code> if the argument is a string lexicographically
  652.      *        less than this string.
  653.      * @exception <code>ClassCastException</code> if the argument is not a
  654.      *          <code>String</code>. 
  655.      * @see     java.lang.Comparable
  656.      * @since   JDK1.2
  657.      */
  658.     public int compareTo(Object o) {
  659.     return compareTo((String)o);
  660.     }
  661.  
  662.     /**
  663.      * Tests if two string regions are equal. 
  664.      * <p>
  665.      * If <code>toffset</code> or <code>ooffset</code> is negative, or 
  666.      * if <code>toffset</code>+<code>length</code> is greater than the 
  667.      * length of this string, or if 
  668.      * <code>ooffset</code>+<code>length</code> is greater than the 
  669.      * length of the string argument, then this method returns 
  670.      * <code>false</code>. 
  671.      *
  672.      * @param   toffset   the starting offset of the subregion in this string.
  673.      * @param   other     the string argument.
  674.      * @param   ooffset   the starting offset of the subregion in the string
  675.      *                    argument.
  676.      * @param   len       the number of characters to compare.
  677.      * @return  <code>true</code> if the specified subregion of this string
  678.      *          exactly matches the specified subregion of the string argument;
  679.      *          <code>false</code> otherwise.
  680.      */
  681.     public boolean regionMatches(int toffset, String other, int ooffset, int len) {
  682.     char ta[] = value;
  683.     int to = offset + toffset;
  684.     int tlim = offset + count;
  685.     char pa[] = other.value;
  686.     int po = other.offset + ooffset;
  687.     // Note: toffset, ooffset, or len might be near -1>>>1.
  688.     if ((ooffset < 0) || (toffset < 0) || (toffset > count - len) || (ooffset > other.count - len)) {
  689.         return false;
  690.     }
  691.     while (len-- > 0) {
  692.         if (ta[to++] != pa[po++]) {
  693.             return false;
  694.         }
  695.     }
  696.     return true;
  697.     }
  698.  
  699.     /**
  700.      * Tests if two string regions are equal. 
  701.      * <p>
  702.      * If <code>toffset</code> or <code>ooffset</code> is negative, or 
  703.      * if <code>toffset</code>+<code>length</code> is greater than the 
  704.      * length of this string, or if 
  705.      * <code>ooffset</code>+<code>length</code> is greater than the 
  706.      * length of the string argument, then this method returns 
  707.      * <code>false</code>. 
  708.      *
  709.      * @param   ignoreCase   if <code>true</code>, ignore case when comparing
  710.      *                       characters.
  711.      * @param   toffset      the starting offset of the subregion in this
  712.      *                       string.
  713.      * @param   other        the string argument.
  714.      * @param   ooffset      the starting offset of the subregion in the string
  715.      *                       argument.
  716.      * @param   len          the number of characters to compare.
  717.      * @return  <code>true</code> if the specified subregion of this string
  718.      *          matches the specified subregion of the string argument;
  719.      *          <code>false</code> otherwise. Whether the matching is exact
  720.      *          or case insensitive depends on the <code>ignoreCase</code>
  721.      *          argument.
  722.      */
  723.     public boolean regionMatches(boolean ignoreCase,
  724.                          int toffset,
  725.                            String other, int ooffset, int len) {
  726.     char ta[] = value;
  727.     int to = offset + toffset;
  728.     int tlim = offset + count;
  729.     char pa[] = other.value;
  730.     int po = other.offset + ooffset;
  731.     // Note: toffset, ooffset, or len might be near -1>>>1.
  732.     if ((ooffset < 0) || (toffset < 0) || (toffset > count - len) || (ooffset > other.count - len)) {
  733.         return false;
  734.     }
  735.     while (len-- > 0) {
  736.         char c1 = ta[to++];
  737.         char c2 = pa[po++];
  738.         if (c1 == c2)
  739.         continue;
  740.         if (ignoreCase) {
  741.         // If characters don't match but case may be ignored,
  742.         // try converting both characters to uppercase.
  743.         // If the results match, then the comparison scan should
  744.         // continue. 
  745.         char u1 = Character.toUpperCase(c1);
  746.         char u2 = Character.toUpperCase(c2);
  747.         if (u1 == u2)
  748.             continue;
  749.         // Unfortunately, conversion to uppercase does not work properly
  750.         // for the Georgian alphabet, which has strange rules about case
  751.         // conversion.  So we need to make one last check before 
  752.         // exiting.
  753.         if (Character.toLowerCase(u1) == Character.toLowerCase(u2))
  754.             continue;
  755.         }
  756.         return false;
  757.     }
  758.     return true;
  759.     }
  760.  
  761.     /**
  762.      * Tests if this string starts with the specified prefix.
  763.      *
  764.      * @param   prefix    the prefix.
  765.      * @param   toffset   where to begin looking in the string.
  766.      * @return  <code>true</code> if the character sequence represented by the
  767.      *          argument is a prefix of the substring of this object starting
  768.      *          at index <code>toffset</code>; <code>false</code> otherwise.
  769.      */
  770.     public boolean startsWith(String prefix, int toffset) {
  771.     char ta[] = value;
  772.     int to = offset + toffset;
  773.     int tlim = offset + count;
  774.     char pa[] = prefix.value;
  775.     int po = prefix.offset;
  776.     int pc = prefix.count;
  777.     // Note: toffset might be near -1>>>1.
  778.     if ((toffset < 0) || (toffset > count - pc)) {
  779.         return false;
  780.     }
  781.     while (--pc >= 0) {
  782.         if (ta[to++] != pa[po++]) {
  783.             return false;
  784.         }
  785.     }
  786.     return true;
  787.     }
  788.  
  789.     /**
  790.      * Tests if this string starts with the specified prefix.
  791.      *
  792.      * @param   prefix   the prefix.
  793.      * @return  <code>true</code> if the character sequence represented by the
  794.      *          argument is a prefix of the character sequence represented by
  795.      *          this string; <code>false</code> otherwise.
  796.      * @since   JDK1. 0
  797.      */
  798.     public boolean startsWith(String prefix) {
  799.     return startsWith(prefix, 0);
  800.     }
  801.  
  802.     /**
  803.      * Tests if this string ends with the specified suffix.
  804.      *
  805.      * @param   suffix   the suffix.
  806.      * @return  <code>true</code> if the character sequence represented by the
  807.      *          argument is a suffix of the character sequence represented by
  808.      *          this object; <code>false</code> otherwise.
  809.      */
  810.     public boolean endsWith(String suffix) {
  811.     return startsWith(suffix, count - suffix.count);
  812.     }
  813.  
  814.     /**
  815.      * Returns a hashcode for this string.
  816.      *
  817.      * @return  a hash code value for this object. 
  818.      */
  819.     public int hashCode() {
  820.     int h = 0;
  821.     int off = offset;
  822.     char val[] = value;
  823.     int len = count;
  824.  
  825.     for (int i = 0; i < len; i++)
  826.         h = 31*h + val[off++];
  827.  
  828.     return h;
  829.     }
  830.  
  831.     /**
  832.      * Returns the index within this string of the first occurrence of the
  833.      * specified character.
  834.      *
  835.      * @param   ch   a character.
  836.      * @return  the index of the first occurrence of the character in the
  837.      *          character sequence represented by this object, or
  838.      *          <code>-1</code> if the character does not occur.
  839.      */
  840.     public int indexOf(int ch) {
  841.     return indexOf(ch, 0);
  842.     }
  843.  
  844.     /**
  845.      * Returns the index within this string of the first occurrence of the
  846.      * specified character, starting the search at the specified index.
  847.      *
  848.      * @param   ch          a character.
  849.      * @param   fromIndex   the index to start the search from.
  850.      * @return  the index of the first occurrence of the character in the
  851.      *          character sequence represented by this object that is greater
  852.      *          than or equal to <code>fromIndex</code>, or <code>-1</code>
  853.      *          if the character does not occur.
  854.      */
  855.     public int indexOf(int ch, int fromIndex) {
  856.     int max = offset + count;
  857.     char v[] = value;
  858.  
  859.     if (fromIndex < 0) {
  860.         fromIndex = 0;
  861.     } else if (fromIndex >= count) {
  862.         // Note: fromIndex might be near -1>>>1.
  863.         return -1;
  864.     }
  865.     for (int i = offset + fromIndex ; i < max ; i++) {
  866.         if (v[i] == ch) {
  867.         return i - offset;
  868.         }
  869.     }
  870.     return -1;
  871.     }
  872.  
  873.     /**
  874.      * Returns the index within this string of the last occurrence of the
  875.      * specified character.
  876.      * The String is searched backwards starting at the last character.
  877.      *
  878.      * @param   ch   a character.
  879.      * @return  the index of the last occurrence of the character in the
  880.      *          character sequence represented by this object, or
  881.      *          <code>-1</code> if the character does not occur.
  882.      */
  883.     public int lastIndexOf(int ch) {
  884.     return lastIndexOf(ch, count - 1);
  885.     }
  886.  
  887.     /**
  888.      * Returns the index within this string of the last occurrence of the
  889.      * specified character, searching backward starting at the specified index.
  890.      *
  891.      * @param   ch          a character.
  892.      * @param   fromIndex   the index to start the search from.
  893.      * @return  the index of the last occurrence of the character in the
  894.      *          character sequence represented by this object that is less
  895.      *          than or equal to <code>fromIndex</code>, or <code>-1</code>
  896.      *          if the character does not occur before that point.
  897.      */
  898.     public int lastIndexOf(int ch, int fromIndex) {
  899.     int min = offset;
  900.     char v[] = value;
  901.     
  902.     for (int i = offset + ((fromIndex >= count) ? count - 1 : fromIndex) ; i >= min ; i--) {
  903.         if (v[i] == ch) {
  904.         return i - offset;
  905.         }
  906.     }
  907.     return -1;
  908.     }
  909.  
  910.     /**
  911.      * Returns the index within this string of the first occurrence of the
  912.      * specified substring.
  913.      *
  914.      * @param   str   any string.
  915.      * @return  if the string argument occurs as a substring within this
  916.      *          object, then the index of the first character of the first
  917.      *          such substring is returned; if it does not occur as a
  918.      *          substring, <code>-1</code> is returned.
  919.      */
  920.     public int indexOf(String str) {
  921.     return indexOf(str, 0);
  922.     }
  923.  
  924.     /**
  925.      * Returns the index within this string of the first occurrence of the
  926.      * specified substring, starting at the specified index.
  927.      *
  928.      * @param   str         the substring to search for.
  929.      * @param   fromIndex   the index to start the search from.
  930.      * @return  If the string argument occurs as a substring within this
  931.      *          object at a starting index no smaller than
  932.      *          <code>fromIndex</code>, then the index of the first character
  933.      *          of the first such substring is returned. If it does not occur
  934.      *          as a substring starting at <code>fromIndex</code> or beyond,
  935.      *          <code>-1</code> is returned.
  936.      */
  937.     public int indexOf(String str, int fromIndex) {
  938.         char v1[] = value;
  939.         char v2[] = str.value;
  940.         int max = offset + (count - str.count);
  941.     if (fromIndex >= count) {
  942.         if (count == 0 && fromIndex == 0 && str.count == 0) {
  943.         /* There is an empty string at index 0 in an empty string. */
  944.         return 0;
  945.         }
  946.         /* Note: fromIndex might be near -1>>>1 */
  947.         return -1;
  948.     }
  949.         if (fromIndex < 0) {
  950.             fromIndex = 0;
  951.         }
  952.     if (str.count == 0) {
  953.         return fromIndex;
  954.     }
  955.  
  956.         int strOffset = str.offset;
  957.         char first  = v2[strOffset];
  958.         int i = offset + fromIndex;
  959.  
  960.     startSearchForFirstChar:
  961.         while (true) {
  962.  
  963.         /* Look for first character. */
  964.         while (i <= max && v1[i] != first) {
  965.         i++;
  966.         }
  967.         if (i > max) {
  968.         return -1;
  969.         }
  970.  
  971.         /* Found first character, now look at the rest of v2 */
  972.         int j = i + 1;
  973.         int end = j + str.count - 1;
  974.         int k = strOffset + 1;
  975.         while (j < end) {
  976.         if (v1[j++] != v2[k++]) {
  977.             i++;
  978.             /* Look for str's first char again. */
  979.             continue startSearchForFirstChar;
  980.         }
  981.         }
  982.         return i - offset;    /* Found whole string. */
  983.         }
  984.     }
  985.  
  986.     /**
  987.      * Returns the index within this string of the rightmost occurrence
  988.      * of the specified substring.  The rightmost empty string "" is
  989.      * considered to occur at the index value <code>this.length()</code>.
  990.      *
  991.      * @param   str   the substring to search for.
  992.      * @return  if the string argument occurs one or more times as a substring
  993.      *          within this object, then the index of the first character of
  994.      *          the last such substring is returned. If it does not occur as
  995.      *          a substring, <code>-1</code> is returned.
  996.      */
  997.     public int lastIndexOf(String str) {
  998.     return lastIndexOf(str, count);
  999.     }
  1000.  
  1001.     /**
  1002.      * Returns the index within this string of the last occurrence of
  1003.      * the specified substring.
  1004.      * The returned index indicates the start of the substring, and it
  1005.      * must be equal to or less than <code>fromIndex</code>.
  1006.      *
  1007.      * @param   str         the substring to search for.
  1008.      * @param   fromIndex   the index to start the search from.
  1009.      * @return  If the string argument occurs one or more times as a substring
  1010.      *          within this object at a starting index no greater than
  1011.      *          <code>fromIndex</code>, then the index of the first character of
  1012.      *          the last such substring is returned. If it does not occur as a
  1013.      *          substring starting at <code>fromIndex</code> or earlier,
  1014.      *          <code>-1</code> is returned.
  1015.      */
  1016.     public int lastIndexOf(String str, int fromIndex) {
  1017.         /* 
  1018.      * Check arguments; return immediately where possible. For
  1019.      * consistency, don't check for null str.
  1020.      */
  1021.         int rightIndex = count - str.count;
  1022.     if (fromIndex < 0) {
  1023.         return -1;
  1024.     }
  1025.     if (fromIndex > rightIndex) {
  1026.         fromIndex = rightIndex;
  1027.     }
  1028.     /* Empty string always matches. */
  1029.     if (str.count == 0) {
  1030.         return fromIndex;
  1031.     }
  1032.  
  1033.     char v1[] = value;
  1034.     char v2[] = str.value;
  1035.     int strLastIndex = str.offset + str.count - 1;
  1036.     char strLastChar = v2[strLastIndex];
  1037.     int min = offset + str.count - 1;
  1038.     int i = min + fromIndex;
  1039.  
  1040.     startSearchForLastChar:
  1041.     while (true) {
  1042.  
  1043.         /* Look for the last character */
  1044.         while (i >= min && v1[i] != strLastChar) {
  1045.         i--;
  1046.         }
  1047.         if (i < min) {
  1048.         return -1;
  1049.         }
  1050.  
  1051.         /* Found last character, now look at the rest of v2. */
  1052.         int j = i - 1;
  1053.         int start = j - (str.count - 1);
  1054.         int k = strLastIndex - 1;
  1055.  
  1056.         while (j > start) {
  1057.             if (v1[j--] != v2[k--]) {
  1058.             i--;
  1059.             /* Look for str's last char again. */
  1060.             continue startSearchForLastChar;
  1061.         }
  1062.         }
  1063.  
  1064.         return start - offset + 1;    /* Found whole string. */
  1065.     }
  1066.     }
  1067.  
  1068.     /**
  1069.      * Returns a new string that is a substring of this string. The 
  1070.      * substring begins at the specified index and extends to the end of 
  1071.      * this string. 
  1072.      *
  1073.      * @param      beginIndex   the beginning index, inclusive.
  1074.      * @return     the specified substring.
  1075.      * @exception  StringIndexOutOfBoundsException  if the
  1076.      *             <code>beginIndex</code> is out of range.
  1077.      */
  1078.     public String substring(int beginIndex) {
  1079.     return substring(beginIndex, length());
  1080.     }
  1081.  
  1082.     /**
  1083.      * Returns a new string that is a substring of this string. The 
  1084.      * substring begins at the specified <code>beginIndex</code> and 
  1085.      * extends to the character at index <code>endIndex - 1</code>. 
  1086.      *
  1087.      * @param      beginIndex   the beginning index, inclusive.
  1088.      * @param      endIndex     the ending index, exclusive.
  1089.      * @return     the specified substring.
  1090.      * @exception  StringIndexOutOfBoundsException  if the
  1091.      *             <code>beginIndex</code> or the <code>endIndex</code> is
  1092.      *             out of range.
  1093.      */
  1094.     public String substring(int beginIndex, int endIndex) {
  1095.     if (beginIndex < 0) {
  1096.         throw new StringIndexOutOfBoundsException(beginIndex);
  1097.     } 
  1098.     if (endIndex > count) {
  1099.         throw new StringIndexOutOfBoundsException(endIndex);
  1100.     }
  1101.     if (beginIndex > endIndex) {
  1102.         throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
  1103.     }
  1104.     return ((beginIndex == 0) && (endIndex == count)) ? this :
  1105.         new String(offset + beginIndex, endIndex - beginIndex, value);
  1106.     }
  1107.  
  1108.     /**
  1109.      * Concatenates the specified string to the end of this string. 
  1110.      * <p>
  1111.      * If the length of the argument string is <code>0</code>, then this 
  1112.      * object is returned. 
  1113.      *
  1114.      * @param   str   the <code>String</code> that is concatenated to the end
  1115.      *                of this <code>String</code>.
  1116.      * @return  a string that represents the concatenation of this object's
  1117.      *          characters followed by the string argument's characters.
  1118.      */
  1119.     public String concat(String str) {
  1120.     int otherLen = str.length();
  1121.     if (otherLen == 0) {
  1122.         return this;
  1123.     }
  1124.     char buf[] = new char[count + otherLen];
  1125.     getChars(0, count, buf, 0);
  1126.     str.getChars(0, otherLen, buf, count);
  1127.     return new String(0, count + otherLen, buf);
  1128.     }
  1129.  
  1130.     /**
  1131.      * Returns a new string resulting from replacing all occurrences of 
  1132.      * <code>oldChar</code> in this string with <code>newChar</code>. 
  1133.      * <p>
  1134.      * If the character <code>oldChar</code> does not occur in the 
  1135.      * character sequence represented by this object, then this string is 
  1136.      * returned. 
  1137.      *
  1138.      * @param   oldChar   the old character.
  1139.      * @param   newChar   the new character.
  1140.      * @return  a string derived from this string by replacing every
  1141.      *          occurrence of <code>oldChar</code> with <code>newChar</code>.
  1142.      */
  1143.     public String replace(char oldChar, char newChar) {
  1144.     if (oldChar != newChar) {
  1145.         int len = count;
  1146.         int i = -1;
  1147.         char[] val = value; /* avoid getfield opcode */
  1148.         int off = offset;   /* avoid getfield opcode */
  1149.  
  1150.         while (++i < len) {
  1151.         if (val[off + i] == oldChar) {
  1152.             break;
  1153.         }
  1154.         }
  1155.         if (i < len) {
  1156.         char buf[] = new char[len];
  1157.         for (int j = 0 ; j < i ; j++) {
  1158.             buf[j] = val[off+j];
  1159.         }
  1160.         while (i < len) {
  1161.             char c = val[off + i];
  1162.             buf[i] = (c == oldChar) ? newChar : c;
  1163.             i++;
  1164.         }
  1165.         return new String(0, len, buf);
  1166.         }
  1167.     }
  1168.     return this;
  1169.     }
  1170.  
  1171.     /**
  1172.      * Converts all of the characters in this <code>String</code> to lower
  1173.      * case using the rules of the given locale.
  1174.      * @param locale use the case transformation rules for this locale
  1175.      * @return the String, converted to lowercase.
  1176.      * @see     java.lang.Character#toLowerCase(char)
  1177.      * @see     java.lang.String#toUpperCase()
  1178.      * @since   JDK1.1
  1179.      */
  1180.     public String toLowerCase(Locale locale) {
  1181.         char[] result = new char[count];
  1182.         int i;
  1183.         int len = count;
  1184.     int off = offset;       /* avoid getfield opcode */
  1185.     char[] val = value;        /* avoid getfield opcode */
  1186.       
  1187.         if (locale.getLanguage().equals("tr")) {
  1188.             // special loop for Turkey
  1189.         for (i = 0; i < len; ++i) {
  1190.                 char ch = val[off+i];
  1191.                 if (ch == 'I') {
  1192.                     result[i] = '\u0131'; // dotless small i
  1193.                     continue;
  1194.                 }
  1195.                 if (ch == '\u0130') {       // dotted I
  1196.                     result[i] = 'i';      // dotted i
  1197.                     continue;
  1198.                 }
  1199.                 result[i] = Character.toLowerCase(ch);
  1200.             }
  1201.         } else {
  1202.             // normal, fast loop
  1203.             for (i = 0; i < len; ++i) {
  1204.                 result[i] = Character.toLowerCase(val[off+i]);
  1205.             }
  1206.         }
  1207.         return new String(result);
  1208.     }
  1209.  
  1210.     /**
  1211.      * Converts this <code>String</code> to lowercase. 
  1212.      * <p>
  1213.      * If no character in the string has a different lowercase version, 
  1214.      * based on calling the <code>toLowerCase</code> method defined by 
  1215.      * <code>Character</code>, then the original string is returned. 
  1216.      * <p>
  1217.      * Otherwise, a new string is allocated, whose length is identical 
  1218.      * to this string, and such that each character that has a different 
  1219.      * lowercase version is mapped to this lowercase equivalent. 
  1220.      *
  1221.      * @return  the string, converted to lowercase.
  1222.      * @see     java.lang.Character#toLowerCase(char)
  1223.      * @see     java.lang.String#toUpperCase()
  1224.      */
  1225.     public String toLowerCase() {
  1226.         return toLowerCase( Locale.getDefault() );
  1227.     }
  1228.  
  1229.     /**
  1230.      * Converts all of the characters in this <code>String</code> to upper
  1231.      * case using the rules of the given locale.
  1232.      * @param locale use the case transformation rules for this locale
  1233.      * @return the String, converted to uppercase.
  1234.      * @see     java.lang.Character#toUpperCase(char)
  1235.      * @see     java.lang.String#toLowerCase(char)
  1236.      * @since   JDK1.1
  1237.      */
  1238.     public String toUpperCase(Locale locale) {
  1239.         char[] result = new char[count]; /* warning: might grow! */
  1240.         int i;
  1241.     int resultOffset = 0;  /* result might grow, so i+resultOffset
  1242.                 * gives correct write location in result
  1243.                 */
  1244.     int len = count;
  1245.         int off = offset;       /* avoid getfield opcode */
  1246.     char[] val = value;        /* avoid getfield opcode */
  1247.         if (locale.getLanguage().equals("tr")) {
  1248.             // special loop for Turkey
  1249.         for (i = 0; i < len; ++i) {
  1250.                 char ch = val[off+i];
  1251.                 if (ch == 'i') {
  1252.             result[i+resultOffset] = '\u0130';  // dotted cap i
  1253.                     continue;
  1254.                 }
  1255.                 if (ch == '\u0131') {                   // dotless i
  1256.                     result[i+resultOffset] = 'I';       // cap I
  1257.                     continue;
  1258.                 }
  1259.                 if (ch == '\u00DF') {                   // sharp s
  1260.             /* Grow result. */
  1261.             char[] result2 = new char[result.length + 1];
  1262.             System.arraycopy(result, 0, result2, 0,
  1263.                      i + 1 + resultOffset);
  1264.                     result2[i+resultOffset] = 'S';
  1265.             resultOffset++;
  1266.             result2[i+resultOffset] = 'S';
  1267.             result = result2;
  1268.                     continue;
  1269.                 }
  1270.                 result[i+resultOffset] = Character.toUpperCase(ch);
  1271.             }
  1272.         } else {
  1273.             // normal, fast loop
  1274.             for (i = 0; i < len; ++i) {
  1275.                 char ch = val[off+i];
  1276.                 if (ch == '\u00DF') { // sharp s
  1277.             /* Grow result. */
  1278.             char[] result2 = new char[result.length + 1];
  1279.             System.arraycopy(result, 0, result2, 0,
  1280.                      i + 1 + resultOffset);
  1281.                     result2[i+resultOffset] = 'S';
  1282.             resultOffset++;
  1283.             result2[i+resultOffset] = 'S';
  1284.             result = result2;
  1285.                     continue;
  1286.                 }
  1287.                 result[i+resultOffset] = Character.toUpperCase(ch);
  1288.             }
  1289.         }
  1290.         return new String(result);
  1291.     }
  1292.     
  1293.     /**
  1294.      * Converts this string to uppercase. 
  1295.      * <p>
  1296.      * If no character in this string has a different uppercase version, 
  1297.      * based on calling the <code>toUpperCase</code> method defined by 
  1298.      * <code>Character</code>, then the original string is returned. 
  1299.      * <p>
  1300.      * Otherwise, a new string is allocated, whose length is identical 
  1301.      * to this string, and such that each character that has a different 
  1302.      * uppercase version is mapped to this uppercase equivalent. 
  1303.      *
  1304.      * @return  the string, converted to uppercase.
  1305.      * @see     java.lang.Character#toUpperCase(char)
  1306.      * @see     java.lang.String#toLowerCase()
  1307.      */
  1308.     public String toUpperCase() {
  1309.         return toUpperCase( Locale.getDefault() );
  1310.     }
  1311.  
  1312.     /**
  1313.      * Removes white space from both ends of this string. 
  1314.      * <p>
  1315.      * All characters that have codes less than or equal to 
  1316.      * <code>'\u0020'</code> (the space character) are considered to be 
  1317.      * white space. 
  1318.      *
  1319.      * @return  this string, with white space removed from the front and end.
  1320.      */
  1321.     public String trim() {
  1322.     int len = count;
  1323.     int st = 0;
  1324.     int off = offset;      /* avoid getfield opcode */
  1325.     char[] val = value;    /* avoid getfield opcode */
  1326.  
  1327.     while ((st < len) && (val[off + st] <= ' ')) {
  1328.         st++;
  1329.     }
  1330.     while ((st < len) && (val[off + len - 1] <= ' ')) {
  1331.         len--;
  1332.     }
  1333.     return ((st > 0) || (len < count)) ? substring(st, len) : this;
  1334.     }
  1335.  
  1336.     /**
  1337.      * This object (which is already a string!) is itself returned. 
  1338.      *
  1339.      * @return  the string itself.
  1340.      */
  1341.     public String toString() {
  1342.     return this;
  1343.     }
  1344.  
  1345.     /**
  1346.      * Converts this string to a new character array.
  1347.      *
  1348.      * @return  a newly allocated character array whose length is the length
  1349.      *          of this string and whose contents are initialized to contain
  1350.      *          the character sequence represented by this string.
  1351.      */
  1352.     public char[] toCharArray() {
  1353.     int max = length();
  1354.     char result[] = new char[max];
  1355.     getChars(0, max, result, 0);
  1356.     return result;
  1357.     }
  1358.  
  1359.     /**
  1360.      * Returns the string representation of the <code>Object</code> argument. 
  1361.      *
  1362.      * @param   obj   an <code>Object</code>.
  1363.      * @return  if the argument is <code>null</code>, then a string equal to
  1364.      *          <code>"null"</code>; otherwise, the value of
  1365.      *          <code>obj.toString()</code> is returned.
  1366.      * @see     java.lang.Object#toString()  
  1367.      */
  1368.     public static String valueOf(Object obj) {
  1369.     return (obj == null) ? "null" : obj.toString();
  1370.     }
  1371.  
  1372.     /**
  1373.      * Returns the string representation of the <code>char</code> array
  1374.      * argument. 
  1375.      *
  1376.      * @param   data   a <code>char</code> array.
  1377.      * @return  a newly allocated string representing the same sequence of
  1378.      *          characters contained in the character array argument.
  1379.      */
  1380.     public static String valueOf(char data[]) {
  1381.     return new String(data);
  1382.     }
  1383.  
  1384.     /**
  1385.      * Returns the string representation of a specific subarray of the 
  1386.      * <code>char</code> array argument. 
  1387.      * <p>
  1388.      * The <code>offset</code> argument is the index of the first 
  1389.      * character of the subarray. The <code>count</code> argument 
  1390.      * specifies the length of the subarray. 
  1391.      *
  1392.      * @param   data     the character array.
  1393.      * @param   offset   the initial offset into the value of the
  1394.      *                  <code>String</code>.
  1395.      * @param   count    the length of the value of the <code>String</code>.
  1396.      * @return  a newly allocated string representing the sequence of
  1397.      *          characters contained in the subarray of the character array
  1398.      *          argument.
  1399.      */
  1400.     public static String valueOf(char data[], int offset, int count) {
  1401.     return new String(data, offset, count);
  1402.     }
  1403.     
  1404.     /**
  1405.      * Returns a String that is equivalent to the specified character array.
  1406.      * It creates a new array and copies the characters into it.
  1407.      *
  1408.      * @param   data     the character array.
  1409.      * @param   offset   initial offset of the subarray.
  1410.      * @param   count    length of the subarray.
  1411.      * @return  a <code>String</code> that contains the characters of the
  1412.      *          specified subarray of the character array.
  1413.      */
  1414.     public static String copyValueOf(char data[], int offset, int count) {
  1415.     // All public String constructors now copy the data.
  1416.     return new String(data, offset, count);
  1417.     }
  1418.  
  1419.     /**
  1420.      * Returns a String that is equivalent to the specified character array.
  1421.      * It creates a new array and copies the characters into it.
  1422.      *
  1423.      * @param   data   the character array.
  1424.      * @return  a <code>String</code> that contains the characters of the
  1425.      *          character array.
  1426.      */
  1427.     public static String copyValueOf(char data[]) {
  1428.     return copyValueOf(data, 0, data.length);
  1429.     }
  1430.  
  1431.     /**
  1432.      * Returns the string representation of the <code>boolean</code> argument. 
  1433.      *
  1434.      * @param   b   a <code>boolean</code>.
  1435.      * @return  if the argument is <code>true</code>, a string equal to
  1436.      *          <code>"true"</code> is returned; otherwise, a string equal to
  1437.      *          <code>"false"</code> is returned.
  1438.      */
  1439.     public static String valueOf(boolean b) {
  1440.     return b ? "true" : "false";
  1441.     }
  1442.  
  1443.     /**
  1444.      * Returns the string representation of the <code>char</code> * argument. 
  1445.      *
  1446.      * @param   c   a <code>char</code>.
  1447.      * @return  a newly allocated string of length <code>1</code> containing
  1448.      *          as its single character the argument <code>c</code>.
  1449.      */
  1450.     public static String valueOf(char c) {
  1451.     char data[] = {c};
  1452.     return new String(0, 1, data);
  1453.     }
  1454.  
  1455.     /**
  1456.      * Returns the string representation of the <code>int</code> argument. 
  1457.      * <p>
  1458.      * The representation is exactly the one returned by the 
  1459.      * <code>Integer.toString</code> method of one argument. 
  1460.      *
  1461.      * @param   i   an <code>int</code>.
  1462.      * @return  a newly allocated string containing a string representation of
  1463.      *          the <code>int</code> argument.
  1464.      * @see     java.lang.Integer#toString(int, int)
  1465.      */
  1466.     public static String valueOf(int i) {
  1467.         return Integer.toString(i, 10);
  1468.     }
  1469.  
  1470.     /**
  1471.      * Returns the string representation of the <code>long</code> argument. 
  1472.      * <p>
  1473.      * The representation is exactly the one returned by the 
  1474.      * <code>Long.toString</code> method of one argument. 
  1475.      *
  1476.      * @param   l   a <code>long</code>.
  1477.      * @return  a newly allocated string containing a string representation of
  1478.      *          the <code>long</code> argument.
  1479.      * @see     java.lang.Long#toString(long)
  1480.      */
  1481.     public static String valueOf(long l) {
  1482.         return Long.toString(l, 10);
  1483.     }
  1484.  
  1485.     /**
  1486.      * Returns the string representation of the <code>float</code> argument. 
  1487.      * <p>
  1488.      * The representation is exactly the one returned by the 
  1489.      * <code>Float.toString</code> method of one argument. 
  1490.      *
  1491.      * @param   f   a <code>float</code>.
  1492.      * @return  a newly allocated string containing a string representation of
  1493.      *          the <code>float</code> argument.
  1494.      * @see     java.lang.Float#toString(float)
  1495.      */
  1496.     public static String valueOf(float f) {
  1497.     return Float.toString(f);
  1498.     }
  1499.  
  1500.     /**
  1501.      * Returns the string representation of the <code>double</code> argument. 
  1502.      * <p>
  1503.      * The representation is exactly the one returned by the 
  1504.      * <code>Double.toString</code> method of one argument. 
  1505.      *
  1506.      * @param   d   a <code>double</code>.
  1507.      * @return  a newly allocated string containing a string representation of
  1508.      *          the <code>double</code> argument.
  1509.      * @see     java.lang.Double#toString(double)
  1510.      */
  1511.     public static String valueOf(double d) {
  1512.     return Double.toString(d);
  1513.     }
  1514.  
  1515.     /**
  1516.      * Returns a canonical representation for the string object. 
  1517.      * <p>
  1518.      * If <code>s</code> and <code>t</code> are strings such that 
  1519.      * <code>s.equals(t)</code>, it is guaranteed that<br>
  1520.      * <code>s.intern() == t.intern(). </code> 
  1521.      *
  1522.      * @return  a string that has the same contents as this string, but is
  1523.      *          guaranteed to be from a pool of unique strings.
  1524.      */
  1525.     public native String intern();
  1526.  
  1527.     /**
  1528.      * Returns the length of this string's UTF encoded form.
  1529.      */
  1530.     int utfLength() {
  1531.     int limit = offset + count;
  1532.     int utflen = 0;
  1533.     char[] val = value;
  1534.  
  1535.     for (int i = offset; i < limit; i++) {
  1536.         int c = val[i];
  1537.         if ((c >= 0x0001) && (c <= 0x007F)) {
  1538.         utflen++;
  1539.         } else if (c > 0x07FF) {
  1540.         utflen += 3;
  1541.         } else {
  1542.         utflen += 2;
  1543.         }
  1544.     }
  1545.     return utflen;
  1546.     }
  1547.  
  1548. }
  1549.