home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / String.java < prev    next >
Text File  |  1997-10-27  |  52KB  |  1,468 lines

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