From harmony-commits-return-314-apmail-incubator-harmony-commits-archive=incubator.apache.org@incubator.apache.org Thu Dec 01 06:20:55 2005 Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 50820 invoked from network); 1 Dec 2005 06:20:50 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 1 Dec 2005 06:20:50 -0000 Received: (qmail 2934 invoked by uid 500); 1 Dec 2005 06:16:56 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 817 invoked by uid 500); 1 Dec 2005 06:15:54 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 98815 invoked by uid 99); 1 Dec 2005 06:13:55 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 30 Nov 2005 22:11:25 -0800 Received: (qmail 43699 invoked by uid 65534); 1 Dec 2005 06:11:05 -0000 Message-ID: <20051201061105.43698.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r350181 [55/198] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/ depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/ depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/ depends/oss/win.I... Date: Thu, 01 Dec 2005 06:04:00 -0000 To: harmony-commits@incubator.apache.org From: geirm@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/String.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/String.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/String.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/String.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,1744 @@ +/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.lang; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Comparator; +import java.util.Locale; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * The implementation of this class is provided, but the documented native must + * be provided by the vm vendor. + * + * Strings are objects which represent immutable arrays of characters. + * + * @see StringBuffer + */ +public final class String implements Serializable, Comparable, CharSequence { + static final long serialVersionUID = -6849794470754667710L; + + /** + * An PrintStream used for System.out which performs the + * correct character conversion for the console, since the + * console may use a different conversion than the default + * file.encoding. + */ + static class ConsolePrintStream extends java.io.PrintStream { + + static { + /** + * The encoding used for console conversions. + */ + String consoleEncoding = System.getProperty("console.encoding"); + if (consoleEncoding == null) + consoleEncoding = "ISO8859_1"; + } + + /** + * Create a ConsolePrintStream on the specified OutputStream, + * usually System.out. + * + * @param out the console OutputStream + */ + public ConsolePrintStream(java.io.OutputStream out) { + super(out, true); + + } + + /** + * Override the print(String) method from PrintStream to perform + * the character conversion using the console character converter. + * + * @param str the String to convert + */ + public void print(String str) { + if (str == null) + str = "null"; + + } + } + + /** + * CaseInsensitiveComparator compares Strings ignoring the case of the + * characters. + */ + private static final class CaseInsensitiveComparator implements Comparator, + Serializable { + static final long serialVersionUID = 8575799808933029326L; + + /** + * Compare the two objects to determine + * the relative ordering. + * + * @param o1 an Object to compare + * @param o2 an Object to compare + * @return an int < 0 if object1 is less than object2, + * 0 if they are equal, and > 0 if object1 is greater + * + * @exception ClassCastException when objects are not the correct type + */ + public int compare(Object o1, Object o2) { + return ((String) o1).compareToIgnoreCase((String) o2); + } + } + + /* + * A Comparator which compares Strings ignoring the case of the characters. + */ + public static final Comparator CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); + + private static final char[] ascii; + + private final char[] value; + + private final int offset; + + private final int count; + + private int hashCode; + + static { + ascii = new char[128]; + for (int i = 0; i < ascii.length; i++) + ascii[i] = (char) i; + } + + /** + * Answers an empty string. + */ + public String() { + value = new char[0]; + offset = 0; + count = 0; + } + + private String(String s, char c) { + offset = 0; + value = new char[s.count + 1]; + count = s.count + 1; + System.arraycopy(s.value, s.offset, value, 0, s.count); + value[s.count] = c; + } + + /** + * Converts the byte array to a String using the default encoding as + * specified by the file.encoding system property. If the system property is + * not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1 + * is not available, an ASCII encoding is used. + * + * @param data + * the byte array to convert to a String + * + * @throws NullPointerException + * when data is null + * + * @see #getBytes() + * @see #getBytes(int, int, byte[], int) + * @see #getBytes(String) + * @see #valueOf(boolean) + * @see #valueOf(char) + * @see #valueOf(char[]) + * @see #valueOf(char[], int, int) + * @see #valueOf(double) + * @see #valueOf(float) + * @see #valueOf(int) + * @see #valueOf(long) + * @see #valueOf(Object) + * + */ + public String(byte[] data) { + this(data, 0, data.length); + } + + /** + * Converts the byte array to a String, setting the high byte of every + * character to the specified value. + * + * @param data + * the byte array to convert to a String + * @param high + * the high byte to use + * + * @throws NullPointerException + * when data is null + * + * @deprecated Use String(byte[]) or String(byte[], String) instead + */ + public String(byte[] data, int high) { + this(data, high, 0, data.length); + } + + /** + * Converts the byte array to a String using the default encoding as + * specified by the file.encoding system property. If the system property is + * not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1 + * is not available, an ASCII encoding is used. + * + * @param data + * the byte array to convert to a String + * @param start + * the starting offset in the byte array + * @param length + * the number of bytes to convert + * + * @throws IndexOutOfBoundsException + * when length < 0, start < 0 or + * start + length > data.length + * @throws NullPointerException + * when data is null + * + * @see #getBytes() + * @see #getBytes(int, int, byte[], int) + * @see #getBytes(String) + * @see #valueOf(boolean) + * @see #valueOf(char) + * @see #valueOf(char[]) + * @see #valueOf(char[], int, int) + * @see #valueOf(double) + * @see #valueOf(float) + * @see #valueOf(int) + * @see #valueOf(long) + * @see #valueOf(Object) + * + */ + public String(byte[] data, int start, int length) { + value = new char[0]; + offset = 0; + count = 0; + } + + /** + * Converts the byte array to a String, setting the high byte of every + * character to the specified value. + * + * @param data + * the byte array to convert to a String + * @param high + * the high byte to use + * @param start + * the starting offset in the byte array + * @param length + * the number of bytes to convert + * + * @throws IndexOutOfBoundsException + * when length < 0, start < 0 or + * start + length > data.length + * @throws NullPointerException + * when data is null + * + * @deprecated Use String(byte[], int, int) instead + */ + public String(byte[] data, int high, int start, int length) { + if (data != null) { + // start + length could overflow, start/length maybe MaxInt + if (start >= 0 && 0 <= length && length <= data.length - start) { + offset = 0; + value = new char[length]; + count = length; + high <<= 8; + for (int i = 0; i < count; i++) + value[i] = (char) (high + (data[start++] & 0xff)); + } else + throw new StringIndexOutOfBoundsException(); + } else + throw new NullPointerException(); + } + + /** + * Converts the byte array to a String using the specified encoding. + * + * @param data + * the byte array to convert to a String + * @param start + * the starting offset in the byte array + * @param length + * the number of bytes to convert + * @param encoding + * the encoding + * + * @throws IndexOutOfBoundsException + * when length < 0, start < 0 or + * start + length > data.length + * @throws UnsupportedEncodingException + * when encoding is not supported + * @throws NullPointerException + * when data is null + * + * @see #getBytes() + * @see #getBytes(int, int, byte[], int) + * @see #getBytes(String) + * @see #valueOf(boolean) + * @see #valueOf(char) + * @see #valueOf(char[]) + * @see #valueOf(char[], int, int) + * @see #valueOf(double) + * @see #valueOf(float) + * @see #valueOf(int) + * @see #valueOf(long) + * @see #valueOf(Object) + * @see UnsupportedEncodingException + */ + public String(byte[] data, int start, int length, final String encoding) + throws UnsupportedEncodingException { + throw new UnsupportedEncodingException(); + } + + /** + * Converts the byte array to a String using the specified encoding. + * + * @param data + * the byte array to convert to a String + * @param encoding + * the encoding + * + * @throws UnsupportedEncodingException + * when encoding is not supported + * @throws NullPointerException + * when data is null + * + * @see #getBytes() + * @see #getBytes(int, int, byte[], int) + * @see #getBytes(String) + * @see #valueOf(boolean) + * @see #valueOf(char) + * @see #valueOf(char[]) + * @see #valueOf(char[], int, int) + * @see #valueOf(double) + * @see #valueOf(float) + * @see #valueOf(int) + * @see #valueOf(long) + * @see #valueOf(Object) + * @see UnsupportedEncodingException + */ + public String(byte[] data, String encoding) + throws UnsupportedEncodingException { + this(data, 0, data.length, encoding); + } + + /** + * Initializes this String to contain the characters in the specified + * character array. Modifying the character array after creating the String + * has no effect on the String. + * + * @param data + * the array of characters + * + * @throws NullPointerException + * when data is null + */ + public String(char[] data) { + this(data, 0, data.length); + } + + /** + * Initializes this String to contain the specified characters in the + * character array. Modifying the character array after creating the String + * has no effect on the String. + * + * @param data + * the array of characters + * @param start + * the starting offset in the character array + * @param length + * the number of characters to use + * + * @throws IndexOutOfBoundsException + * when length < 0, start < 0 or + * start + length > data.length + * @throws NullPointerException + * when data is null + */ + public String(char[] data, int start, int length) { + // range check everything so a new char[] is not created + // start + length could overflow, start/length maybe MaxInt + if (start >= 0 && 0 <= length && length <= data.length - start) { + offset = 0; + value = new char[length]; + count = length; + try { + System.arraycopy(data, start, value, 0, count); + } catch (IndexOutOfBoundsException e) { + throw new StringIndexOutOfBoundsException(); + } + } else + throw new StringIndexOutOfBoundsException(); + } + + /* + * Internal version of string constructor. Does not range check, null check, + * or copy the character array. + */ + String(int start, int length, char[] data) { + value = data; + offset = start; + count = length; + } + + /** + * Creates a string that is a copy of another string + * + * @param string + * the String to copy + */ + public String(String string) { + value = string.value; + offset = string.offset; + count = string.count; + } + + /** + * Creates a string from the contents of a StringBuffer. + * + * @param stringbuffer + * the StringBuffer + */ + public String(StringBuffer stringbuffer) { + value = new char[0]; + offset = 0; + count = 0; + synchronized (stringbuffer) { + } + } + + /* + * Creates a string that is s1 + v1. + */ + private String(String s1, int v1) { + if (s1 == null) + s1 = "null"; + String s2 = String.valueOf(v1); + int len = s1.count + s2.count; + value = new char[len]; + offset = 0; + System.arraycopy(s1.value, s1.offset, value, 0, s1.count); + System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count); + count = len; + } + + /** + * Answers the character at the specified offset in this String. + * + * @param index + * the zero-based index in this string + * @return the character at the index + * + * @throws IndexOutOfBoundsException + * when index < 0 or + * index >= length() + */ + public char charAt(int index) { + if (0 <= index && index < count) + return value[offset + index]; + throw new StringIndexOutOfBoundsException(); + } + + /** + * Compare the receiver to the specified Object to determine the relative + * ordering. + * + * @param object + * an Object + * @return an int < 0 if this String is less than the specified String, 0 if + * they are equal, and > 0 if this String is greater + * + * @throws ClassCastException + * when object is not a String + */ + public int compareTo(Object object) { + return compareTo((String) object); + } + + /** + * Compares the specified String to this String using the Unicode values of + * the characters. Answer 0 if the strings contain the same characters in + * the same order. Answer a negative integer if the first non-equal + * character in this String has a Unicode value which is less than the + * Unicode value of the character at the same position in the specified + * string, or if this String is a prefix of the specified string. Answer a + * positive integer if the first non-equal character in this String has a + * Unicode value which is greater than the Unicode value of the character at + * the same position in the specified string, or if the specified String is + * a prefix of the this String. + * + * @param string + * the string to compare + * @return 0 if the strings are equal, a negative integer if this String is + * before the specified String, or a positive integer if this String + * is after the specified String + * + * @throws NullPointerException + * when string is null + */ + public int compareTo(String string) { + // Code adapted from K&R, pg 101 + int o1 = offset, o2 = string.offset, result; + int end = offset + (count < string.count ? count : string.count); + char[] target = string.value; + while (o1 < end) + if ((result = value[o1++] - target[o2++]) != 0) + return result; + return count - string.count; + } + + /** + * Compare the receiver to the specified String to determine the relative + * ordering when the case of the characters is ignored. + * + * @param string + * a String + * @return an int < 0 if this String is less than the specified String, 0 if + * they are equal, and > 0 if this String is greater + */ + public int compareToIgnoreCase(String string) { + int o1 = offset, o2 = string.offset, result; + int end = offset + (count < string.count ? count : string.count); + char c1, c2; + char[] target = string.value; + while (o1 < end) { + if ((c1 = value[o1++]) == (c2 = target[o2++])) + continue; + c1 = Character.toLowerCase(Character.toUpperCase(c1)); + c2 = Character.toLowerCase(Character.toUpperCase(c2)); + if ((result = c1 - c2) != 0) + return result; + } + return count - string.count; + } + + /** + * Concatenates this String and the specified string. + * + * @param string + * the string to concatenate + * @return a new String which is the concatenation of this String and the + * specified String + * + * @throws NullPointerException + * if string is null + */ + public String concat(String string) { + if (string.count > 0 && count > 0) { + char[] buffer = new char[count + string.count]; + System.arraycopy(value, offset, buffer, 0, count); + System.arraycopy(string.value, string.offset, buffer, count, + string.count); + return new String(0, buffer.length, buffer); + } + return count == 0 ? string : this; + } + + /** + * Creates a new String containing the characters in the specified character + * array. Modifying the character array after creating the String has no + * effect on the String. + * + * @param data + * the array of characters + * @return the new String + * + * @throws NullPointerException + * if data is null + */ + public static String copyValueOf(char[] data) { + return new String(data, 0, data.length); + } + + /** + * Creates a new String containing the specified characters in the character + * array. Modifying the character array after creating the String has no + * effect on the String. + * + * @param data + * the array of characters + * @param start + * the starting offset in the character array + * @param length + * the number of characters to use + * @return the new String + * + * @throws IndexOutOfBoundsException + * if length < 0, start < 0 or + * start + length > data.length + * @throws NullPointerException + * if data is null + */ + public static String copyValueOf(char[] data, int start, int length) { + return new String(data, start, length); + } + + /** + * Compares the specified string to this String to determine if the + * specified string is a suffix. + * + * @param suffix + * the string to look for + * @return true when the specified string is a suffix of this String, false + * otherwise + * + * @throws NullPointerException + * if suffix is null + */ + public boolean endsWith(String suffix) { + return regionMatches(count - suffix.count, suffix, 0, suffix.count); + } + + /** + * Compares the specified object to this String and answer if they are + * equal. The object must be an instance of String with the same characters + * in the same order. + * + * @param object + * the object to compare + * @return true if the specified object is equal to this String, false + * otherwise + * + * @see #hashCode + */ + public boolean equals(Object object) { + if (object == this) + return true; + if (object instanceof String) { + String s = (String) object; + if (count != s.count + || (hashCode != s.hashCode && hashCode != 0 && s.hashCode != 0)) + return false; + return regionMatches(0, s, 0, count); + } + return false; + } + + /** + * Compares the specified String to this String ignoring the case of the + * characters and answer if they are equal. + * + * @param string + * the string to compare + * @return true if the specified string is equal to this String, false + * otherwise + */ + public boolean equalsIgnoreCase(String string) { + if (string == this) + return true; + if (string == null || count != string.count) + return false; + + int o1 = offset, o2 = string.offset; + int end = offset + count; + char c1, c2; + char[] target = string.value; + while (o1 < end) { + if ((c1 = value[o1++]) != (c2 = target[o2++]) + && Character.toUpperCase(c1) != Character.toUpperCase(c2) + // Required for unicode that we test both cases + && Character.toLowerCase(c1) != Character.toLowerCase(c2)) + return false; + } + return true; + } + + /** + * Converts this String to a byte encoding using the default encoding as + * specified by the file.encoding sytem property. If the system property is + * not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1 + * is not available, an ASCII encoding is used. + * + * @return the byte array encoding of this String + * + * @see String + */ + public byte[] getBytes() { + return null; + } + + /** + * Converts this String to a byte array, ignoring the high order bits of + * each character. + * + * @param start + * the starting offset of characters to copy + * @param end + * the ending offset of characters to copy + * @param data + * the destination byte array + * @param index + * the starting offset in the byte array + * + * @throws NullPointerException + * when data is null + * @throws IndexOutOfBoundsException + * when + * start < 0, end > length(), index < 0, end - start > data.length - index + * + * @deprecated Use getBytes() or getBytes(String) + */ + public void getBytes(int start, int end, byte[] data, int index) { + if (data != null) { + // index < 0, and end - start > data.length - index are caught by + // the catch below + // end > count not caught below when start == end + if (0 <= start && start <= end && end <= count) { + end += offset; + try { + for (int i = offset + start; i < end; i++) + data[index++] = (byte) value[i]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new StringIndexOutOfBoundsException(); + } + } else + throw new StringIndexOutOfBoundsException(); + } else + throw new NullPointerException(); + } + + /** + * Converts this String to a byte encoding using the specified encoding. + * + * @param encoding + * the encoding + * @return the byte array encoding of this String + * + * @throws UnsupportedEncodingException + * when the encoding is not supported + * + * @see String + * @see UnsupportedEncodingException + */ + public byte[] getBytes(String encoding) throws UnsupportedEncodingException { + return null; + } + + /** + * Copies the specified characters in this String to the character array + * starting at the specified offset in the character array. + * + * @param start + * the starting offset of characters to copy + * @param end + * the ending offset of characters to copy + * @param buffer + * the destination character array + * @param index + * the starting offset in the character array + * + * @throws IndexOutOfBoundsException + * when start < 0, end > length(), + * start > end, index < 0, end - start > buffer.length - index + * @throws NullPointerException + * when buffer is null + */ + public void getChars(int start, int end, char[] buffer, int index) { + // NOTE last character not copied! + // Fast range check. + if (0 <= start && start <= end && end <= count) + System.arraycopy(value, start + offset, buffer, index, end - start); + else + throw new StringIndexOutOfBoundsException(); + } + + /** + * Answers an integer hash code for the receiver. Objects which are equal + * answer the same value for this method. + * + * @return the receiver's hash + * + * @see #equals + */ + public int hashCode() { + if (hashCode == 0) { + int hash = 0, multiplier = 1; + for (int i = offset + count - 1; i >= offset; i--) { + hash += value[i] * multiplier; + int shifted = multiplier << 5; + multiplier = shifted - multiplier; + } + hashCode = hash; + } + return hashCode; + } + + /** + * Searches in this String for the first index of the specified character. + * The search for the character starts at the beginning and moves towards + * the end of this String. + * + * @param c + * the character to find + * @return the index in this String of the specified character, -1 if the + * character isn't found + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int indexOf(int c) { + return indexOf(c, 0); + } + + /** + * Searches in this String for the index of the specified character. The + * search for the character starts at the specified offset and moves towards + * the end of this String. + * + * @param c + * the character to find + * @param start + * the starting offset + * @return the index in this String of the specified character, -1 if the + * character isn't found + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int indexOf(int c, int start) { + if (start < count) { + if (start < 0) + start = 0; + for (int i = offset + start; i < offset + count; i++) { + if (value[i] == c) + return i - offset; + } + } + return -1; + } + + /** + * Searches in this String for the first index of the specified string. The + * search for the string starts at the beginning and moves towards the end + * of this String. + * + * @param string + * the string to find + * @return the index in this String of the specified string, -1 if the + * string isn't found + * + * @throws NullPointerException + * when string is null + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + * + */ + public int indexOf(String string) { + return indexOf(string, 0); + } + + /** + * Searches in this String for the index of the specified string. The search + * for the string starts at the specified offset and moves towards the end + * of this String. + * + * @param subString + * the string to find + * @param start + * the starting offset + * @return the index in this String of the specified string, -1 if the + * string isn't found + * + * @throws NullPointerException + * when string is null + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int indexOf(String subString, int start) { + if (start < 0) + start = 0; + int subCount = subString.count; + if (subCount > 0) { + if (subCount + start > count) + return -1; + char[] target = subString.value; + int subOffset = subString.offset; + char firstChar = target[subOffset]; + int end = subOffset + subCount; + while (true) { + int i = indexOf(firstChar, start); + if (i == -1 || subCount + i > count) + return -1; // handles subCount > count || start >= count + int o1 = offset + i, o2 = subOffset; + while (++o2 < end && value[++o1] == target[o2]) { + // Intentionally empty + } + if (o2 == end) { + return i; + } + start = i + 1; + } + } + return start < count ? start : count; + } + + /** + * Only this native must be implemented, the implementation for the rest of + * this class is provided. + * + * Searches an internal table of strings for a string equal to this String. + * If the string is not in the table, it is added. Answers the string + * contained in the table which is equal to this String. The same string + * object is always answered for strings which are equal. + * + * @return the interned string equal to this String + */ + public native String intern(); + + /** + * Searches in this String for the last index of the specified character. + * The search for the character starts at the end and moves towards the + * beginning of this String. + * + * @param c + * the character to find + * @return the index in this String of the specified character, -1 if the + * character isn't found + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int lastIndexOf(int c) { + return lastIndexOf(c, count - 1); + } + + /** + * Searches in this String for the index of the specified character. The + * search for the character starts at the specified offset and moves towards + * the beginning of this String. + * + * @param c + * the character to find + * @param start + * the starting offset + * @return the index in this String of the specified character, -1 if the + * character isn't found + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int lastIndexOf(int c, int start) { + if (start >= 0) { + if (start >= count) + start = count - 1; + for (int i = offset + start; i >= offset; --i) { + if (value[i] == c) + return i - offset; + } + } + return -1; + } + + /** + * Searches in this String for the last index of the specified string. The + * search for the string starts at the end and moves towards the beginning + * of this String. + * + * @param string + * the string to find + * @return the index in this String of the specified string, -1 if the + * string isn't found + * + * @throws NullPointerException + * when string is null + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int lastIndexOf(String string) { + // Use count instead of count - 1 so lastIndexOf("") answers count + return lastIndexOf(string, count); + } + + /** + * Searches in this String for the index of the specified string. The search + * for the string starts at the specified offset and moves towards the + * beginning of this String. + * + * @param subString + * the string to find + * @param start + * the starting offset + * @return the index in this String of the specified string, -1 if the + * string isn't found + * + * @throws NullPointerException + * when string is null + * + * @see #lastIndexOf(int) + * @see #lastIndexOf(int, int) + * @see #lastIndexOf(String) + * @see #lastIndexOf(String, int) + */ + public int lastIndexOf(String subString, int start) { + int subCount = subString.count; + if (subCount <= count && start >= 0) { + if (subCount > 0) { + if (start > count - subCount) + start = count - subCount; // count and subCount are both + // >= 1 + char[] target = subString.value; + int subOffset = subString.offset; + char firstChar = target[subOffset]; + int end = subOffset + subCount; + while (true) { + int i = lastIndexOf(firstChar, start); + if (i == -1) + return -1; + int o1 = offset + i, o2 = subOffset; + while (++o2 < end && value[++o1] == target[o2]) { + // Intentionally empty + } + if (o2 == end) { + return i; + } + start = i - 1; + } + } + return start < count ? start : count; + } + return -1; + } + + /** + * Answers the size of this String. + * + * @return the number of characters in this String + */ + public int length() { + return count; + } + + /** + * Compares the specified string to this String and compares the specified + * range of characters to determine if they are the same. + * + * @param thisStart + * the starting offset in this String + * @param string + * the string to compare + * @param start + * the starting offset in string + * @param length + * the number of characters to compare + * @return true if the ranges of characters is equal, false otherwise + * + * @throws NullPointerException + * when string is null + */ + public boolean regionMatches(int thisStart, String string, int start, + int length) { + if (string == null) + throw new NullPointerException(); + if (start < 0 || string.count - start < length) + return false; + if (thisStart < 0 || count - thisStart < length) + return false; + if (length <= 0) + return true; + int o1 = offset + thisStart, o2 = string.offset + start; + for (int i = 0; i < length; ++i) { + if (value[o1 + i] != string.value[o2 + i]) + return false; + } + return true; + } + + /** + * Compares the specified string to this String and compares the specified + * range of characters to determine if they are the same. When ignoreCase is + * true, the case of the characters is ignored during the comparison. + * + * @param ignoreCase + * specifies if case should be ignored + * @param thisStart + * the starting offset in this String + * @param string + * the string to compare + * @param start + * the starting offset in string + * @param length + * the number of characters to compare + * @return true if the ranges of characters is equal, false otherwise + * + * @throws NullPointerException + * when string is null + */ + public boolean regionMatches(boolean ignoreCase, int thisStart, + String string, int start, int length) { + if (!ignoreCase) + return regionMatches(thisStart, string, start, length); + + if (string != null) { + if (thisStart < 0 || length > count - thisStart) + return false; + if (start < 0 || length > string.count - start) + return false; + + thisStart += offset; + start += string.offset; + int end = thisStart + length; + char c1, c2; + char[] target = string.value; + while (thisStart < end) { + if ((c1 = value[thisStart++]) != (c2 = target[start++]) + && Character.toUpperCase(c1) != Character + .toUpperCase(c2) + // Required for unicode that we test both cases + && Character.toLowerCase(c1) != Character + .toLowerCase(c2)) { + return false; + } + } + return true; + } + throw new NullPointerException(); + } + + /** + * Copies this String replacing occurrences of the specified character with + * another character. + * + * @param oldChar + * the character to replace + * @param newChar + * the replacement character + * @return a new String with occurrences of oldChar replaced by newChar + */ + public String replace(char oldChar, char newChar) { + int index = indexOf(oldChar, 0); + if (index == -1) + return this; + + char[] buffer = new char[count]; + System.arraycopy(value, offset, buffer, 0, count); + do { + buffer[index++] = newChar; + } while ((index = indexOf(oldChar, index)) != -1); + return new String(0, count, buffer); + } + + /** + * Compares the specified string to this String to determine if the + * specified string is a prefix. + * + * @param prefix + * the string to look for + * @return true when the specified string is a prefix of this String, false + * otherwise + * + * @throws NullPointerException + * when prefix is null + */ + public boolean startsWith(String prefix) { + return startsWith(prefix, 0); + } + + /** + * Compares the specified string to this String, starting at the specified + * offset, to determine if the specified string is a prefix. + * + * @param prefix + * the string to look for + * @param start + * the starting offset + * @return true when the specified string occurs in this String at the + * specified offset, false otherwise + * + * @throws NullPointerException + * when prefix is null + */ + public boolean startsWith(String prefix, int start) { + return regionMatches(start, prefix, 0, prefix.count); + } + + /** + * Copies a range of characters into a new String. + * + * @param start + * the offset of the first character + * @return a new String containing the characters from start to the end of + * the string + * + * @throws IndexOutOfBoundsException + * when start < 0 or + * start > length() + */ + public String substring(int start) { + if (0 <= start && start <= count) + return new String(offset + start, count - start, value); + throw new StringIndexOutOfBoundsException(start); + } + + /** + * Copies a range of characters into a new String. + * + * @param start + * the offset of the first character + * @param end + * the offset one past the last character + * @return a new String containing the characters from start to end - 1 + * + * @throws IndexOutOfBoundsException + * when start < 0, start > end or + * end > length() + */ + public String substring(int start, int end) { + // NOTE last character not copied! + // Fast range check. + if (0 <= start && start <= end && end <= count) + return new String(offset + start, end - start, value); + throw new StringIndexOutOfBoundsException(); + } + + /** + * Copies the characters in this String to a character array. + * + * @return a character array containing the characters of this String + */ + public char[] toCharArray() { + char[] buffer = new char[count]; + System.arraycopy(value, offset, buffer, 0, count); + return buffer; + } + + /** + * Converts the characters in this String to lowercase, using the default + * Locale. + * + * @return a new String containing the lowercase characters equivalent to + * the characters in this String + */ + public String toLowerCase() { + return toLowerCase(Locale.getDefault()); + } + + /** + * Converts the characters in this String to lowercase, using the specified + * Locale. + * + * @param locale + * the Locale + * @return a new String containing the lowercase characters equivalent to + * the characters in this String + */ + public String toLowerCase(Locale locale) { + for (int o = offset, end = offset + count; o < end; o++) { + char ch = value[o]; + if (ch != Character.toLowerCase(ch)) { + char[] buffer = new char[count]; + int i = o - offset; + System.arraycopy(value, offset, buffer, 0, i); // not worth + // checking for + // i == 0 case + if (locale.getLanguage() != "tr") { // Turkish + while (i < count) + buffer[i++] = Character.toLowerCase(value[o++]); + } else { + while (i < count) + buffer[i++] = (ch = value[o++]) != 0x49 ? Character + .toLowerCase(ch) : (char) 0x131; + } + return new String(0, count, buffer); + } + } + return this; + } + + /** + * Answers a string containing a concise, human-readable description of the + * receiver. + * + * @return this String + */ + public String toString() { + return this; + } + + /** + * Converts the characters in this String to uppercase, using the default + * Locale. + * + * @return a new String containing the uppercase characters equivalent to + * the characters in this String + */ + public String toUpperCase() { + return toUpperCase(Locale.getDefault()); + } + + private static final char[] upperValues = "SS\u0000\u02bcN\u0000J\u030c\u0000\u0399\u0308\u0301\u03a5\u0308\u0301\u0535\u0552\u0000H\u0331\u0000T\u0308\u0000W\u030a\u0000Y\u030a\u0000A\u02be\u0000\u03a5\u0313\u0000\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5\u0313\u0342\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1fba\u0399\u0000\u0391\u0399\u0000\u0386\u0399\u0000\u0391\u0342\u0000\u0391\u0342\u0399\u0391\u0399\u0000\u1fca\u0399\u0000\u0397\u0399\u0000\u0389\u0399\u0000\u0397\u0342\u0000\u0397\u0342\u0399\u0397\u0399\u0000\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0000\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313\u0000\u03a5\u0342\u0000\u03a5\u0308\u0342\u1ffa\u0399\u0000\u03a9\u0399\u0000\u038f\u0399\u0000\u03a9\u0342\u0000\u03a9\u0342\u0399\u03a9\u0399\u0000FF\u0000FI\u0000FL\u0000FFIFFLST\u0000ST\u0000\u0544\u0546\u0000\u0544\u0535\u0000\u0544\u053b\u0000\u054e\u0546\u0000\u0544\u053d\u0000".value; + + /** + * Return the index of the specified character into the upperValues table. + * The upperValues table contains three entries at each position. These + * three characters are the upper case conversion. If only two characters + * are used, the third character in the table is \u0000. + * + * @param ch the char being converted to upper case + * + * @return the index into the upperValues table, or -1 + */ + private int upperIndex(int ch) { + int index = -1; + if (ch >= 0xdf) { + if (ch <= 0x587) { + if (ch == 0xdf) + index = 0; + else if (ch <= 0x149) { + if (ch == 0x149) + index = 1; + } else if (ch <= 0x1f0) { + if (ch == 0x1f0) + index = 2; + } else if (ch <= 0x390) { + if (ch == 0x390) + index = 3; + } else if (ch <= 0x3b0) { + if (ch == 0x3b0) + index = 4; + } else if (ch <= 0x587) { + if (ch == 0x587) + index = 5; + } + } else if (ch >= 0x1e96) { + if (ch <= 0x1e9a) + index = 6 + ch - 0x1e96; + else if (ch >= 0x1f50 && ch <= 0x1ffc) { + index = "\u000b\u0000\f\u0000\r\u0000\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>\u0000\u0000?@A\u0000BC\u0000\u0000\u0000\u0000D\u0000\u0000\u0000\u0000\u0000EFG\u0000HI\u0000\u0000\u0000\u0000J\u0000\u0000\u0000\u0000\u0000KL\u0000\u0000MN\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000OPQ\u0000RS\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000TUV\u0000WX\u0000\u0000\u0000\u0000Y".value[ch - 0x1f50]; + if (index == 0) + index = -1; + } else if (ch >= 0xfb00) { + if (ch <= 0xfb06) + index = 90 + ch - 0xfb00; + else if (ch >= 0xfb13 && ch <= 0xfb17) + index = 97 + ch - 0xfb13; + } + } + } + return index; + } + + /** + * Converts the characters in this String to uppercase, using the specified + * Locale. + * + * @param locale + * the Locale + * @return a new String containing the uppercase characters equivalent to + * the characters in this String + */ + public String toUpperCase(Locale locale) { + boolean turkish = "tr".equals(locale.getLanguage()); + char[] output = null; + int i = 0; + for (int o = offset, end = offset + count; o < end; o++) { + char ch = value[o]; + int index = upperIndex(ch); + if (index == -1) { + if (output != null && i >= output.length) { + char[] newoutput = new char[output.length + (count / 6) + 2]; + System.arraycopy(output, 0, newoutput, 0, output.length); + output = newoutput; + } + char upch = !turkish ? Character.toUpperCase(ch) + : (ch != 0x69 ? Character.toUpperCase(ch) + : (char) 0x130); + if (ch != upch) { + if (output == null) { + output = new char[count]; + i = o - offset; + System.arraycopy(value, offset, output, 0, i); + + } + output[i++] = upch; + } else if (output != null) + output[i++] = ch; + } else { + int target = index * 3; + char val3 = upperValues[target + 2]; + if (output == null) { + output = new char[count + (count / 6) + 2]; + i = o - offset; + System.arraycopy(value, offset, output, 0, i); + } else if (i + (val3 == 0 ? 1 : 2) >= output.length) { + char[] newoutput = new char[output.length + (count / 6) + 3]; + System.arraycopy(output, 0, newoutput, 0, output.length); + output = newoutput; + } + + char val = upperValues[target]; + output[i++] = val; + val = upperValues[target + 1]; + output[i++] = val; + if (val3 != 0) + output[i++] = val3; + } + } + if (output == null) + return this; + return output.length == i || output.length - i < 8 ? new String(0, i, + output) : new String(output, 0, i); + } + + /** + * Copies this String removing white space characters from the beginning and + * end of the string. + * + * @return a new String with characters <= \\u0020 removed + * from the beginning and the end + */ + public String trim() { + int start = offset, last = offset + count - 1; + int end = last; + while ((start <= end) && (value[start] <= ' ')) + start++; + while ((end >= start) && (value[end] <= ' ')) + end--; + if (start == offset && end == last) + return this; + return new String(start, end - start + 1, value); + } + + /** + * Creates a new String containing the characters in the specified character + * array. Modifying the character array after creating the String has no + * effect on the String. + * + * @param data + * the array of characters + * @return the new String + * + * @throws NullPointerException + * when data is null + */ + public static String valueOf(char[] data) { + return new String(data, 0, data.length); + } + + /** + * Creates a new String containing the specified characters in the character + * array. Modifying the character array after creating the String has no + * effect on the String. + * + * @param data + * the array of characters + * @param start + * the starting offset in the character array + * @param length + * the number of characters to use + * @return the new String + * + * @throws IndexOutOfBoundsException + * when length < 0, start < 0 or + * start + length > data.length + * @throws NullPointerException + * when data is null + */ + public static String valueOf(char[] data, int start, int length) { + return new String(data, start, length); + } + + /** + * Converts the specified character to its string representation. + * + * @param value + * the character + * @return the character converted to a string + */ + public static String valueOf(char value) { + String s; + if (value < 128) + s = new String(value, 1, ascii); + else + s = new String(0, 1, new char[] { value }); + s.hashCode = value; + return s; + } + + /** + * Converts the specified double to its string representation. + * + * @param value + * the double + * @return the double converted to a string + */ + public static String valueOf(double value) { + return Double.toString(value); + } + + /** + * Converts the specified float to its string representation. + * + * @param value + * the float + * @return the float converted to a string + */ + public static String valueOf(float value) { + return Float.toString(value); + } + + /** + * Converts the specified integer to its string representation. + * + * @param value + * the integer + * @return the integer converted to a string + */ + public static String valueOf(int value) { + return Integer.toString(value); + } + + /** + * Converts the specified long to its string representation. + * + * @param value + * the long + * @return the long converted to a string + */ + public static String valueOf(long value) { + return Long.toString(value); + } + + /** + * Converts the specified object to its string representation. If the object + * is null answer the string "null", otherwise use + * toString() to get the string representation. + * + * @param value + * the object + * @return the object converted to a string + */ + public static String valueOf(Object value) { + return value != null ? value.toString() : "null"; + } + + /** + * Converts the specified boolean to its string representation. When the + * boolean is true answer "true", otherwise answer + * "false". + * + * @param value + * the boolean + * @return the boolean converted to a string + */ + public static String valueOf(boolean value) { + return value ? "true" : "false"; + } + + /** + * Answers whether the characters in the StringBuffer strbuf are the same as + * those in this String. + * + * @param strbuf + * the StringBuffer to compare this String to + * @return true when the characters in strbuf are identical to those in this + * String. If they are not, false will be returned. + * + * @throws NullPointerException + * when strbuf is null + * + * @since 1.4 + */ + public boolean contentEquals(StringBuffer strbuf) { + synchronized (strbuf) { + int size = strbuf.length(); + if (count != size) + return false; + return regionMatches(0, new String(0, size, strbuf.getValue()), 0, + size); + } + } + + /** + * Determines whether a this String matches a given regular expression. + * + * @param expr + * the regular expression to be matched + * @return true if the expression matches, otherwise false + * + * @throws PatternSyntaxException + * if the syntax of the supplied regular expression is not valid + * @throws NullPointerException + * if expr is null + * + * @since 1.4 + */ + public boolean matches(String expr) { + return Pattern.matches(expr, this); + } + + /** + * Replace any substrings within this String that match the supplied regular + * expression expr, with the String substitute. + * + * @param expr + * the regular expression to match + * @param substitute + * the string to replace the matching substring with + * @return the new string + * + * @throws NullPointerException + * if expr is null + * + * @since 1.4 + */ + public String replaceAll(String expr, String substitute) { + return Pattern.compile(expr).matcher(this).replaceAll(substitute); + } + + /** + * Replace any substrings within this String that match the supplied regular + * expression expr, with the String substitute. + * + * @param expr + * the regular expression to match + * @param substitute + * the string to replace the matching substring with + * @return the new string + * + * @throws NullPointerException + * if expr is null + * + * @since 1.4 + */ + public String replaceFirst(String expr, String substitute) { + return Pattern.compile(expr).matcher(this).replaceFirst(substitute); + } + + /** + * Replace any substrings within this String that match the supplied regular + * expression expr, with the String substitute. + * + * @param expr + * the regular expression to match + * @return the new string + * + * @throws NullPointerException + * if expr is null + * + * @since 1.4 + */ + public String[] split(String expr) { + return Pattern.compile(expr).split(this); + } + + /** + * Splits this String using the supplied regular expression expr. max + * controls the number of times that the pattern is applied to the string. + * + * @param expr + * the regular expression used to divide the string + * @param max + * the number of times to apply the pattern + * @return an array of Strings created by separating the string along + * matches of the regular expression. + * + * @throws NullPointerException + * if expr is null + * + * @since 1.4 + */ + public String[] split(String expr, int max) { + return Pattern.compile(expr).split(this, max); + } + + /** + * Has the same result as the substring function, but is present so that + * String may implement the CharSequence interface. + * + * @param start + * the offset the first character + * @param end + * the offset of one past the last character to include + * + * @return the subsequence requested + * + * @throws IndexOutOfBoundsException + * when start or end is less than zero, start is greater than + * end, or end is greater than the length of the String. + * + * @see java.lang.CharSequence#subSequence(int, int) + * + * @since 1.4 + */ + public CharSequence subSequence(int start, int end) { + return substring(start, end); + } + + /* + * An implementation of a String.indexOf that is supposed to perform + * substantially better than the default algorithm if the the "needle" (the + * subString being searched for) is a constant string. + * + * In the jit, if we encounter a call to String.indexOf(String), where the + * needle is a constant string, we compute the values cache, md2 and + * lastChar, and change the call to the following method. This code can be + * enabled by setting TR_FastIndexOf=1. It searches for the availablility of + * the following signature before doing the optimization. + */ + private static int indexOf(String haystackString, String needleString, + int cache, int md2, char lastChar) { + char[] haystack = haystackString.value; + int haystackOffset = haystackString.offset; + int haystackLength = haystackString.count; + char[] needle = needleString.value; + int needleOffset = needleString.offset; + int needleLength = needleString.count; + int needleLengthMinus1 = needleLength - 1; + int haystackEnd = haystackOffset + haystackLength; + outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) { + if (lastChar == haystack[i]) { + for (int j = 0; j < needleLengthMinus1; ++j) { + if (needle[j + needleOffset] != haystack[i + j + - needleLengthMinus1]) { + int skip = 1; + if ((cache & (1 << haystack[i])) == 0) + skip += j; + i += Math.max(md2, skip); + continue outer_loop; + } + + } + return i - needleLengthMinus1 - haystackOffset; + } + + if ((cache & (1 << haystack[i])) == 0) + i += needleLengthMinus1; + i++; + } + + return -1; + } + + /* + * Returns the character array for this String. + */ + char[] getValue() { + return value; + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/System.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/System.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/System.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/kernel/src/java/lang/System.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,824 @@ +/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.lang; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Properties; +import java.util.PropertyPermission; + + +/** + * Class System provides a standard place for programs to find system related + * information. All System API is static. + * + */ +public final class System { + + // The standard input, output, and error streams. + // Typically, these are connected to the shell which + // ran the Java program. + /** + * Default input stream + */ + public static final InputStream in; + + /** + * Default output stream + */ + public static final PrintStream out; + + /** + * Default error output stream + */ + public static final PrintStream err; + + // Get a ref to the Runtime instance for faster lookup + private static final Runtime RUNTIME = Runtime.getRuntime(); + + // The System Properties table + private static Properties systemProperties; + + // The System default SecurityManager + private static SecurityManager security; + + // Initialize all the slots in System on first use. + static { + // Fill in the properties from the VM information. + ensureProperties(); + // Set up standard in, out, and err. + err = new String.ConsolePrintStream(new BufferedOutputStream( + new FileOutputStream(FileDescriptor.err))); + out = new String.ConsolePrintStream(new BufferedOutputStream( + new FileOutputStream(FileDescriptor.out))); + in = new BufferedInputStream(new FileInputStream(FileDescriptor.in)); + } + + /** + * Sets the value of the static slot "in" in the receiver to the passed in + * argument. + * + * @param newIn + * the new value for in. + */ + public static void setIn(InputStream newIn) { + SecurityManager secMgr = System.getSecurityManager(); + setFieldImpl("in", newIn); + } + + /** + * Sets the value of the static slot "out" in the receiver to the passed in + * argument. + * + * @param newOut + * the new value for out. + */ + public static void setOut(java.io.PrintStream newOut) { + SecurityManager secMgr = System.getSecurityManager(); + + setFieldImpl("out", newOut); + } + + /** + * Sets the value of the static slot "err" in the receiver to the passed in + * argument. + * + * @param newErr + * the new value for err. + */ + public static void setErr(java.io.PrintStream newErr) { + SecurityManager secMgr = System.getSecurityManager(); + + } + + /** + * Prevents this class from being instantiated. + */ + private System() { + } + + /** + * Copies the contents of array1 starting at offset + * start1 into array2 starting at offset + * start2 for length elements. + * + * @param array1 + * the array to copy out of + * @param start1 + * the starting index in array1 + * @param array2 + * the array to copy into + * @param start2 + * the starting index in array2 + * @param length + * the number of elements in the array to copy + */ + public static void arraycopy(Object array1, int start1, Object array2, + int start2, int length) { + // sending getClass() to both arguments will check for null + Class type1 = array1.getClass(); + Class type2 = array2.getClass(); + if (!type1.isArray() || !type2.isArray()) + throw new ArrayStoreException(); + Class componentType1 = type1.getComponentType(); + Class componentType2 = type2.getComponentType(); + if (!componentType1.isPrimitive()) { + if (componentType2.isPrimitive()) + throw new ArrayStoreException(); + arraycopy((Object[]) array1, start1, (Object[]) array2, start2, + length); + } else { + if (componentType2 != componentType1) + throw new ArrayStoreException(); + if (componentType1 == Integer.TYPE) { + arraycopy((int[]) array1, start1, (int[]) array2, start2, + length); + } else if (componentType1 == Byte.TYPE) { + arraycopy((byte[]) array1, start1, (byte[]) array2, start2, + length); + } else if (componentType1 == Long.TYPE) { + arraycopy((long[]) array1, start1, (long[]) array2, start2, + length); + } else if (componentType1 == Short.TYPE) { + arraycopy((short[]) array1, start1, (short[]) array2, start2, + length); + } else if (componentType1 == Character.TYPE) { + arraycopy((char[]) array1, start1, (char[]) array2, start2, + length); + } else if (componentType1 == Boolean.TYPE) { + arraycopy((boolean[]) array1, start1, (boolean[]) array2, + start2, length); + } else if (componentType1 == Double.TYPE) { + arraycopy((double[]) array1, start1, (double[]) array2, start2, + length); + } else if (componentType1 == Float.TYPE) { + arraycopy((float[]) array1, start1, (float[]) array2, start2, + length); + } + } + } + + /** + * Private version of the arraycopy method (used by the jit for reference arraycopies) + */ + private static void arraycopy(Object[] A1, int offset1, Object[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(int[] A1, int offset1, int[] A2, int offset2, + int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(byte[] A1, int offset1, byte[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(short[] A1, int offset1, short[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(long[] A1, int offset1, long[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(char[] A1, int offset1, char[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(boolean[] A1, int offset1, boolean[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(double[] A1, int offset1, double[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Copies the contents of A1 starting at offset offset1 + * into A2 starting at offset offset2 for + * length elements. + * + * @param A1 the array to copy out of + * @param offset1 the starting index in array1 + * @param A2 the array to copy into + * @param offset2 the starting index in array2 + * @param length the number of elements in the array to copy + */ + private static void arraycopy(float[] A1, int offset1, float[] A2, + int offset2, int length) { + if (offset1 >= 0 && offset2 >= 0 && length >= 0 + && length <= A1.length - offset1 + && length <= A2.length - offset2) { + // Check if this is a forward or backwards arraycopy + if (A1 != A2 || offset1 > offset2 || offset1 + length <= offset2) { + for (int i = 0; i < length; ++i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } else { + for (int i = length - 1; i >= 0; --i) { + A2[offset2 + i] = A1[offset1 + i]; + } + } + } else + throw new ArrayIndexOutOfBoundsException(); + } + + /** + * Answers the current time expressed as milliseconds since the time + * 00:00:00 UTC on January 1, 1970. + * + * @return the time in milliseconds. + */ + public static native long currentTimeMillis(); + + private static final int InitLocale = 0; + + private static final int PlatformEncoding = 1; + + private static final int FileEncoding = 2; + + private static final int OSEncoding = 3; + + /** + * If systemProperties is unset, then create a new one based on the values + * provided by the virtual machine. + */ + private static void ensureProperties() { + systemProperties = new Properties(); + + String platformEncoding = null; + String fileEncoding, osEncoding = null; + String definedFileEncoding = getEncoding(FileEncoding); + String definedOSEncoding = getEncoding(OSEncoding); + if (definedFileEncoding != null) { + fileEncoding = definedFileEncoding; + // if file.encoding is defined, and os.encoding is not, use the + // detected + // platform encoding for os.encoding + if (definedOSEncoding == null) { + platformEncoding = getEncoding(PlatformEncoding); + osEncoding = platformEncoding; + } else { + getEncoding(InitLocale); + } + } else { + platformEncoding = getEncoding(PlatformEncoding); + fileEncoding = platformEncoding; + } + // if os.encoding is not defined, file.encoding will be used + if (osEncoding == null) + osEncoding = definedOSEncoding; + if (osEncoding != null) + systemProperties.put("os.encoding", osEncoding); + + systemProperties.put("file.encoding", fileEncoding); + + systemProperties.put("java.version", "1.4.2 subset"); + systemProperties.put("java.specification.version", "1.4"); + + systemProperties.put("java.specification.vendor", + "Sun Microsystems Inc."); + systemProperties.put("java.specification.name", + "Java Platform API Specification"); + + systemProperties.put("com.ibm.oti.configuration", "clear"); + systemProperties.put("com.ibm.oti.configuration.dir", "jclClear"); + + String[] list = getPropertyList(); + for (int i = 0; i < list.length; i += 2) { + String key = list[i]; + if (key == null) + break; + systemProperties.put(key, list[i + 1]); + } + + String consoleEncoding = (String) systemProperties + .get("console.encoding"); + if (consoleEncoding == null) { + if (platformEncoding == null) + platformEncoding = getEncoding(PlatformEncoding); + consoleEncoding = platformEncoding; + systemProperties.put("console.encoding", consoleEncoding); + } + + systemProperties.put("com.ibm.oti.jcl.build", "plugin"); + } + + /** + * Causes the virtual machine to stop running, and the program to exit. If + * runFinalizersOnExit(true) has been invoked, then all finalizers will be + * run first. + * + * @param code + * the return code. + * + * @throws SecurityException + * if the running thread is not allowed to cause the vm to exit. + * + * @see SecurityManager#checkExit + */ + public static void exit(int code) { + RUNTIME.exit(code); + } + + /** + * Indicate to the virtual machine that it would be a good time to collect + * available memory. Note that, this is a hint only. + */ + public static void gc() { + RUNTIME.gc(); + } + + /** + * Returns an environment variable. + * + * @param var + * the name of the environment variable + * @return the value of the specified environment variable + * @deprecated Use System.getProperty() + */ + public static String getenv(String var) { + if (var == null) { + throw new NullPointerException(); + } + SecurityManager secMgr = System.getSecurityManager(); + if (secMgr != null) { + secMgr.checkPermission(new RuntimePermission("getenv." + var)); + } + throw new Error(); + } + + /** + * Answers the system properties. Note that this is not a copy, so that + * changes made to the returned Properties object will be reflected in + * subsequent calls to getProperty and getProperties. + *

+ * Security managers should restrict access to this API if possible. + * + * @return the system properties + */ + public static Properties getProperties() { + SecurityManager secMgr = System.getSecurityManager(); + if (secMgr != null) { + secMgr.checkPropertiesAccess(); + } + return systemProperties; + } + + /** + * Answers the system properties without any security checks. This is used + * for access from within java.lang. + * + * @return the system properties + */ + static Properties internalGetProperties() { + return systemProperties; + } + + /** + * Answers the value of a particular system property. Answers null if no + * such property exists, + *

+ * The properties currently provided by the virtual machine are: + * + *

+	 *       java.vendor.url
+	 *       java.class.path
+	 *       user.home
+	 *       java.class.version
+	 *       os.version
+	 *       java.vendor
+	 *       user.dir
+	 *       user.timezone
+	 *       path.separator
+	 *       os.name
+	 *       os.arch
+	 *       line.separator
+	 *       file.separator
+	 *       user.name
+	 *       java.version
+	 *       java.home
+	 * 
+ * + * @param prop + * the system property to look up + * @return the value of the specified system property, or null if the + * property doesn't exist + */ + public static String getProperty(String prop) { + return getProperty(prop, null); + } + + /** + * Answers the value of a particular system property. If no such property is + * found, answers the defaultValue. + * + * @param prop + * the system property to look up + * @param defaultValue + * return value if system property is not found + * @return the value of the specified system property, or defaultValue if + * the property doesn't exist + */ + public static String getProperty(String prop, String defaultValue) { + if (prop.length() == 0) + throw new IllegalArgumentException(); + SecurityManager secMgr = System.getSecurityManager(); + if (secMgr != null) { + secMgr.checkPropertyAccess(prop); + } + return systemProperties.getProperty(prop, defaultValue); + } + + /** + * Sets the value of a particular system property. + * + * @param prop + * the system property to change + * @param value + * the value to associate with prop + * @return the old value of the property, or null + */ + public static String setProperty(String prop, String value) { + if (prop.length() == 0) + throw new IllegalArgumentException(); + SecurityManager secMgr = System.getSecurityManager(); + if (secMgr != null) { + secMgr.checkPermission(new PropertyPermission(prop, "write")); + } + return (String) systemProperties.setProperty(prop, value); + } + + /** + * Answers an array of Strings containing key..value pairs (in consecutive + * array elements) which represent the starting values for the system + * properties as provided by the virtual machine. + * + * @return the default values for the system properties. + */ + private static native String[] getPropertyList(); + + /** + * Return the requested encoding. 0 - initialize locale 1 - detected + * platform encoding 2 - command line defined file.encoding 3 - command line + * defined os.encoding + */ + private static native String getEncoding(int type); + + /** + * Answers the active security manager. + * + * @return the system security manager object. + */ + public static SecurityManager getSecurityManager() { + return security; + } + + /** + * Answers an integer hash code for the parameter. The hash code returned is + * the same one that would be returned by java.lang.Object.hashCode(), + * whether or not the object's class has overridden hashCode(). The hash + * code for null is 0. + * + * @param anObject + * the object + * @return the hash code for the object + * + * @see java.lang.Object#hashCode + */ + public static native int identityHashCode(Object anObject); + + /** + * Loads the specified file as a dynamic library. + * + * @param pathName + * the path of the file to be loaded + */ + public static void load(String pathName) { + SecurityManager smngr = System.getSecurityManager(); + if (smngr != null) + smngr.checkLink(pathName); + ClassLoader.loadLibraryWithPath(pathName, ClassLoader + .callerClassLoader(), null); + } + + /** + * Loads and links the library specified by the argument. + * + * @param libName + * the name of the library to load + * + * @throws UnsatisfiedLinkError + * if the library could not be loaded + * @throws SecurityException + * if the library was not allowed to be loaded + */ + public static void loadLibrary(String libName) { + ClassLoader.loadLibraryWithClassLoader(libName, ClassLoader + .callerClassLoader()); + } + + /** + * Provides a hint to the virtual machine that it would be useful to attempt + * to perform any outstanding object finalizations. + */ + public static void runFinalization() { + RUNTIME.runFinalization(); + } + + /** + * Ensure that, when the virtual machine is about to exit, all objects are + * finalized. Note that all finalization which occurs when the system is + * exiting is performed after all running threads have been terminated. + * + * @param flag + * true means finalize all on exit. + * + * @deprecated This method is unsafe. + */ + public static void runFinalizersOnExit(boolean flag) { + Runtime.runFinalizersOnExit(flag); + } + + /** + * Answers the system properties. Note that the object which is passed in + * not copied, so that subsequent changes made to the object will be + * reflected in calls to getProperty and getProperties. + *

+ * Security managers should restrict access to this API if possible. + * + * @param p + * the property to set + */ + public static void setProperties(Properties p) { + SecurityManager secMgr = System.getSecurityManager(); + if (secMgr != null) { + secMgr.checkPropertiesAccess(); + } + if (p == null) { + ensureProperties(); + } else { + systemProperties = p; + } + } + + /** + * Sets the active security manager. Note that once the security manager has + * been set, it can not be changed. Attempts to do so will cause a security + * exception. + * + * @param s + * the new security manager + * + * @throws SecurityException + * if the security manager has already been set. + */ + public static void setSecurityManager(final SecurityManager s) { + final SecurityManager currentSecurity = security; + try { + // Preload classes used for checkPackageAccess(), + // otherwise we could go recursive + s.checkPackageAccess("java.lang"); + } catch (Exception e) { + } + + security = s; + } + + /** + * Answers the platform specific file name format for the shared library + * named by the argument. + * + * @param userLibName + * the name of the library to look up. + * @return the platform specific filename for the library + */ + public static native String mapLibraryName(String userLibName); + + /** + * Sets the value of the named static field in the receiver to the passed in + * argument. + * + * @param fieldName + * the name of the field to set, one of in, out, or err + * @param stream + * the new value of the field + */ + private static native void setFieldImpl(String fieldName, Object stream); + +}