mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			412 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			412 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation
 | |
| 
 | |
|    This file is part of libgcj.
 | |
| 
 | |
| This software is copyrighted work licensed under the terms of the
 | |
| Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | |
| details.  */
 | |
| 
 | |
| package java.lang;
 | |
| import java.io.UnsupportedEncodingException;
 | |
| import java.io.Serializable;
 | |
| import java.lang.Comparable;
 | |
| import java.util.Comparator;
 | |
| import java.util.Locale;
 | |
| 
 | |
| /**
 | |
|  * @author Per Bothner <bothner@cygnus.com>
 | |
|  * @date September 4, 1998.  
 | |
|  */
 | |
| /* Written using "Java Class Libraries", 2nd edition, plus online
 | |
|  * API docs for JDK 1.2 beta from http://www.javasoft.com.
 | |
|  * Status:  Complete to 1.3.
 | |
|  */
 | |
| 
 | |
| public final class String implements Serializable, Comparable, CharSequence
 | |
| {
 | |
|   private Object data;
 | |
|   private int boffset; // Note this is a byte offset - don't use in Java code!
 | |
|   private int count;
 | |
| 
 | |
|   // This is probably not necessary because this class is special cased already
 | |
|   // but it will avoid showing up as a discrepancy when comparing SUIDs.
 | |
|   private static final long serialVersionUID = -6849794470754667710L;
 | |
| 
 | |
|   /**
 | |
|    * An implementation for {@link CASE_INSENSITIVE_ORDER}.
 | |
|    * This must be {@link Serializable}.
 | |
|    */
 | |
|   private static final class CaseInsensitiveComparator
 | |
|     implements Comparator, Serializable
 | |
|   {
 | |
|     /**
 | |
|      * The default private constructor generates unnecessary overhead
 | |
|      */
 | |
|     CaseInsensitiveComparator() {}
 | |
| 
 | |
|     /**
 | |
|      * Compares two Strings, using
 | |
|      * <code>String.compareToIgnoreCase(String)</code>.
 | |
|      * 
 | |
|      * @param o1 the first string
 | |
|      * @param o2 the second string
 | |
|      * @return < 0, 0, or > 0 depending on the case-insensitive
 | |
|      *         comparison of the two strings.
 | |
|      * @throws NullPointerException if either argument is null
 | |
|      * @throws ClassCastException if either argument is not a String
 | |
|      * @see #compareToIgnoreCase(String)
 | |
|      */
 | |
|     public int compare(Object o1, Object o2)
 | |
|     {
 | |
|       return ((String) o1).compareToIgnoreCase((String) o2);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
 | |
|    * This comparator is {@link Serializable}.
 | |
|    *
 | |
|    * @since 1.2
 | |
|    */
 | |
|   public static final Comparator CASE_INSENSITIVE_ORDER
 | |
|     = new CaseInsensitiveComparator();
 | |
| 
 | |
|   public String ()
 | |
|   {
 | |
|     init();
 | |
|   }
 | |
| 
 | |
|   public String (String value)
 | |
|   {
 | |
|     data = value.data;
 | |
|     boffset = value.boffset;
 | |
|     count = value.count;
 | |
|   }
 | |
| 
 | |
|   public String (StringBuffer buffer)
 | |
|   {
 | |
|     synchronized (buffer)
 | |
|       {
 | |
| 	buffer.shared = true;
 | |
| 	init (buffer.value, 0, buffer.count, true);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   // This is used by gnu.gcj.runtime.StringBuffer, so it must have
 | |
|   // package-private protection.  It is accessed via CNI and so avoids
 | |
|   // ordinary protection mechanisms.
 | |
|   String (gnu.gcj.runtime.StringBuffer buffer)
 | |
|   {
 | |
|     // No need to synchronize or mark the buffer, since we know it is
 | |
|     // only used once.
 | |
|     init (buffer.value, 0, buffer.count, true);
 | |
|   }
 | |
| 
 | |
|   public String (char[] data)
 | |
|   {
 | |
|     init(data, 0, data.length, false);
 | |
|   }
 | |
| 
 | |
|   public String (char[] data, int offset, int count)
 | |
|   {
 | |
|     init(data, offset, count, false);
 | |
|   }
 | |
| 
 | |
|   public String (byte[] byteArray)
 | |
|   {
 | |
|     this (byteArray, 0, byteArray.length);
 | |
|   }
 | |
| 
 | |
|   public String (byte[] byteArray, int offset, int count)
 | |
|   {
 | |
|     try
 | |
|       {
 | |
| 	init (byteArray, offset, count,
 | |
| 	      System.getProperty("file.encoding", "8859_1"));
 | |
|       }
 | |
|     catch (UnsupportedEncodingException x1)
 | |
|       {
 | |
| 	// Maybe the default encoding is bad.
 | |
| 	try
 | |
| 	  {
 | |
| 	    init (byteArray, offset, count, "8859_1");
 | |
| 	  }
 | |
| 	catch (UnsupportedEncodingException x2)
 | |
| 	  {
 | |
| 	    // We know this can't happen.
 | |
| 	  }
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public String (byte[] byteArray, String enc)
 | |
|     throws UnsupportedEncodingException
 | |
|   {
 | |
|     this (byteArray, 0, byteArray.length, enc);
 | |
|   }
 | |
| 
 | |
|   public String (byte[] byteArray, int offset, int count, String enc)
 | |
|     throws UnsupportedEncodingException
 | |
|   {
 | |
|     init (byteArray, offset, count, enc);
 | |
|   }
 | |
| 
 | |
|   public static String copyValueOf(char[] data)
 | |
|   {
 | |
|     return copyValueOf (data, 0, data.length);
 | |
|   }
 | |
| 
 | |
|   public static String copyValueOf(char[] data, int offset, int count)
 | |
|   {
 | |
|     String r = new String ();
 | |
|     r.init(data, offset, count, false);
 | |
|     return r;
 | |
|   }
 | |
| 
 | |
|   /** @deprecated */
 | |
|   public String (byte[] ascii, int hibyte)
 | |
|   {
 | |
|     init(ascii, hibyte, 0, ascii.length);
 | |
|   }
 | |
| 
 | |
|   /** @deprecated */
 | |
|   public String (byte[] ascii, int hibyte, int offset, int count)
 | |
|   {
 | |
|     init(ascii, hibyte, offset, count);
 | |
|   }
 | |
| 
 | |
|   public String toString ()
 | |
|   {
 | |
|     return this;
 | |
|   }
 | |
| 
 | |
|   public native boolean equals (Object anObject);
 | |
| 
 | |
|   public native int hashCode ();
 | |
| 
 | |
|   public int length ()
 | |
|   {
 | |
|     return count;
 | |
|   }
 | |
| 
 | |
|   public native char charAt (int index);
 | |
| 
 | |
|   public native void getChars (int srcBegin, int srcEnd,
 | |
| 			       char[] dst, int dstBegin);
 | |
| 
 | |
|   public byte[] getBytes ()
 | |
|   {
 | |
|     try
 | |
|       {
 | |
| 	return getBytes (System.getProperty("file.encoding", "8859_1"));
 | |
|       }
 | |
|     catch (UnsupportedEncodingException x)
 | |
|       {
 | |
| 	// This probably shouldn't happen, but could if file.encoding
 | |
| 	// is somehow changed to a value we don't understand.
 | |
| 	try
 | |
| 	  {
 | |
| 	    return getBytes ("8859_1");
 | |
| 	  }
 | |
| 	catch (UnsupportedEncodingException x2)
 | |
| 	  {
 | |
| 	    // This really shouldn't happen, because the 8859_1
 | |
| 	    // encoding should always be available.
 | |
| 	    throw new InternalError ("couldn't find 8859_1 encoder");
 | |
| 	  }
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public native byte[] getBytes (String enc)
 | |
|     throws UnsupportedEncodingException;
 | |
| 
 | |
|   /** @deprecated */
 | |
|   public native void getBytes (int srcBegin, int srcEnd,
 | |
| 				byte[] dst, int dstBegin);
 | |
| 
 | |
|   public native char[] toCharArray ();
 | |
| 
 | |
|   public native boolean equalsIgnoreCase (String anotherString);
 | |
| 
 | |
|   public native int compareTo (String anotherString);
 | |
| 
 | |
|   public int compareTo (Object obj)
 | |
|   {
 | |
|     return compareTo ((String)obj);
 | |
|   }
 | |
|   
 | |
|   public int compareToIgnoreCase (String str)
 | |
|   {
 | |
|     return this.toUpperCase().toLowerCase().compareTo(
 | |
|      str.toUpperCase().toLowerCase());
 | |
|   }  
 | |
| 
 | |
|   public native boolean regionMatches (int toffset,
 | |
| 				       String other, int ooffset, int len);
 | |
| 
 | |
|   public native boolean regionMatches (boolean ignoreCase, int toffset,
 | |
| 				       String other, int ooffset, int len);
 | |
| 
 | |
|   public boolean startsWith (String prefix)
 | |
|   {
 | |
|     return startsWith (prefix, 0);
 | |
|   }
 | |
| 
 | |
|   public native boolean startsWith (String prefix, int toffset);
 | |
| 
 | |
|   public boolean endsWith (String suffix)
 | |
|   {
 | |
|     return regionMatches (this.count - suffix.count, suffix, 0, suffix.count);
 | |
|   }
 | |
| 
 | |
|   // No such method specified in the doc, including JDK 1.2.
 | |
|   // public boolean endsWith (String suffix, int toffset)
 | |
|   // {
 | |
|   //   return regionMatches (toffset, suffix, 0, suffix.count);
 | |
|   // }
 | |
| 
 | |
|   // The Language Specification, and the JDK 1.2 API docs say that
 | |
|   // index and lastIndex take an int, while the Class Libraries
 | |
|   // say they take a char.  The former wins ...
 | |
| 
 | |
|   public int indexOf (int ch)
 | |
|   {
 | |
|     return indexOf (ch, 0);
 | |
|   }
 | |
| 
 | |
|   public native int indexOf (int ch, int fromIndex);
 | |
| 
 | |
|   public int indexOf (String str)
 | |
|   {
 | |
|     return indexOf (str, 0);
 | |
|   }
 | |
| 
 | |
|   public native int indexOf (String str, int fromIndex);
 | |
| 
 | |
|   public int lastIndexOf (int ch)
 | |
|   {
 | |
|     return lastIndexOf (ch, count - 1);
 | |
|   }
 | |
| 
 | |
|   public native int lastIndexOf (int ch, int fromIndex);
 | |
| 
 | |
|   public int lastIndexOf (String str)
 | |
|   {
 | |
|     return lastIndexOf (str, count - str.count);
 | |
|   }
 | |
| 
 | |
|   public int lastIndexOf (String str, int fromIndex)
 | |
|   {
 | |
|     if (fromIndex >= count)
 | |
|       fromIndex = count - str.count;
 | |
|     for (;; --fromIndex)
 | |
|       {
 | |
| 	if (fromIndex < 0)
 | |
| 	  return -1;
 | |
| 	if (startsWith(str, fromIndex))
 | |
| 	  return fromIndex;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates a substring of this String, starting at a specified index
 | |
|    * and ending at one character before a specified index.
 | |
|    * <p>
 | |
|    * To implement <code>CharSequence</code>.
 | |
|    * Calls <code>substring(beginIndex, endIndex)</code>.
 | |
|    *
 | |
|    * @param beginIndex index to start substring (base 0)
 | |
|    * @param endIndex index after the last character to be 
 | |
|    *   copied into the substring
 | |
|    * 
 | |
|    * @return new String which is a substring of this String
 | |
|    *
 | |
|    * @exception StringIndexOutOfBoundsException 
 | |
|    *   if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex)
 | |
|    */
 | |
|   public CharSequence subSequence(int beginIndex, int endIndex)
 | |
|     throws IndexOutOfBoundsException
 | |
|   {
 | |
|     return substring(beginIndex, endIndex);
 | |
|   }
 | |
| 
 | |
|   public String substring (int beginIndex)
 | |
|   {
 | |
|     return substring (beginIndex, count);
 | |
|   }
 | |
| 
 | |
|   public native String substring (int beginIndex, int endIndex);
 | |
| 
 | |
|   public native String concat (String str);
 | |
| 
 | |
|   public native String replace (char oldChar, char newChar);
 | |
| 
 | |
|   public native String toLowerCase (Locale locale);
 | |
|   public native String toUpperCase (Locale locale);
 | |
| 
 | |
|   public String toLowerCase ()
 | |
|   {
 | |
|     // The JDK is a bit confused about what to do here.  If we pass in
 | |
|     // the default Locale then special Locale handling might be
 | |
|     // invoked.  However, the docs also say that Character.toLowerCase
 | |
|     // rules here.  We go with the latter.
 | |
|     return toLowerCase (null);
 | |
|   }
 | |
| 
 | |
|   public String toUpperCase ()
 | |
|   {
 | |
|     // The JDK is a bit confused about what to do here.  If we pass in
 | |
|     // the default Locale then special Locale handling might be
 | |
|     // invoked.  However, the docs also say that Character.toLowerCase
 | |
|     // rules here.  We go with the latter.
 | |
|     return toUpperCase (null);
 | |
|   }
 | |
| 
 | |
|   public native String trim ();
 | |
| 
 | |
|   public static String valueOf (Object obj)
 | |
|   {
 | |
|     return obj == null ? "null" : obj.toString();
 | |
|   }
 | |
| 
 | |
|   public static String valueOf (char[] data)
 | |
|   {
 | |
|     return valueOf (data, 0, data.length);
 | |
|   }
 | |
| 
 | |
|   public static native String valueOf (char[] data, int offset, int count);
 | |
| 
 | |
|   public static String valueOf (boolean b)
 | |
|   {
 | |
|     return b ? "true" : "false";
 | |
|   }
 | |
| 
 | |
|   public static native String valueOf (char c);
 | |
| 
 | |
|   public static native String valueOf (int i);
 | |
| 
 | |
|   public static String valueOf (long l)
 | |
|   {
 | |
|     return Long.toString(l);
 | |
|   }
 | |
| 
 | |
|   public static String valueOf (float f)
 | |
|   {
 | |
|     return Float.toString(f);
 | |
|   }
 | |
| 
 | |
|   public static String valueOf (double d)
 | |
|   {
 | |
|     return Double.toString(d);
 | |
|   }
 | |
| 
 | |
|   public native String intern ();
 | |
| 
 | |
|   private native void init ();
 | |
|   private native void init (char[] chars, int offset, int count,
 | |
| 			    boolean dont_copy);
 | |
|   private native void init (byte[] chars, int hibyte, int offset, int count);
 | |
|   private native void init (byte[] chars, int offset, int count, String enc)
 | |
|     throws UnsupportedEncodingException;
 | |
|   private static native void rehash ();
 | |
| }
 |