You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/08/11 12:57:06 UTC
svn commit: r430756 [2/2] -
/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java?rev=430756&r1=430755&r2=430756&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java Fri Aug 11 03:57:06 2006
@@ -1,4 +1,4 @@
-/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 1998, 2006 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.
@@ -31,6 +31,7 @@
import java.security.AccessController;
import java.util.regex.PatternSyntaxException;
+import org.apache.harmony.kernel.vm.VM;
import org.apache.harmony.luni.util.PriviAction;
/**
@@ -46,1681 +47,1760 @@
* @see Charset
* @since 1.0
*/
-public final class String implements Serializable, Comparable<String>, CharSequence {
-
- private 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 {
- private static String charset;
-
- static {
- charset = (String) AccessController.doPrivileged(new PriviAction(
- "console.encoding", "ISO8859_1")); //$NON-NLS-1$ //$NON-NLS-2$
- if (!Charset.isSupported(charset)) {
- charset = "ISO-8859-1"; //$NON-NLS-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";
-
- try {
- write(str.getBytes(charset));
- } catch (java.io.IOException e) {
- setError();
- }
- }
- }
-
- /**
- * CaseInsensitiveComparator compares Strings ignoring the case of the
- * characters.
- */
- private static final class CaseInsensitiveComparator implements Comparator<String>,
- Serializable {
- private 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(String o1, String o2) {
- return o1.compareToIgnoreCase(o2);
- }
- }
-
- /*
- * A Comparator which compares Strings ignoring the case of the characters.
- */
- public static final Comparator<String> 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;
-
- private static Charset DefaultCharset;
-
- private static Charset lastCharset;
-
- 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 <code>length < 0, start < 0</code> or
- * <code>start + length > data.length</code>
- * @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) {
- // start + length could overflow, start/length maybe MaxInt
- if (start >= 0 && 0 <= length && length <= data.length - start) {
- offset = 0;
- Charset charset = defaultCharset();
- int result;
- CharBuffer cb = charset
- .decode(ByteBuffer.wrap(data, start, length));
- if ((result = cb.length()) > 0) {
- value = cb.array();
- count = result;
- } else {
- count = 0;
- value = new char[0];
- }
- } else
- throw new StringIndexOutOfBoundsException();
- }
-
- /**
- * 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 <code>length < 0, start < 0</code> or
- * <code>start + length > data.length</code>
- * @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 <code>length < 0, start < 0</code> or
- * <code>start + length > data.length</code>
- * @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 {
- if (encoding == null)
- throw new NullPointerException();
- // start + length could overflow, start/length maybe MaxInt
- if (start >= 0 && 0 <= length && length <= data.length - start) {
- offset = 0;
- Charset charset = getCharset(encoding);
-
- int result;
- CharBuffer cb = charset
- .decode(ByteBuffer.wrap(data, start, length));
- if ((result = cb.length()) > 0) {
- value = cb.array();
- count = result;
- } else {
- count = 0;
- value = new char[0];
- }
- } else
- throw new StringIndexOutOfBoundsException();
- }
-
- /**
- * 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 <code>length < 0, start < 0</code> or
- * <code>start + length > data.length</code>
- * @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;
-
- System.arraycopy(data, start, value, 0, count);
- } 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) {
- offset = 0;
- synchronized (stringbuffer) {
- value = stringbuffer.shareValue();
- count = stringbuffer.length();
- }
- }
-
+public final class String implements Serializable, Comparable<String>,
+ CharSequence {
+
+ private 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 {
+ private static String charset;
+
+ static {
+ charset = AccessController.doPrivileged(new PriviAction<String>(
+ "console.encoding", "ISO8859_1")); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!Charset.isSupported(charset)) {
+ charset = "ISO-8859-1"; //$NON-NLS-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
+ */
+ @Override
+ public void print(String str) {
+ if (str == null) {
+ str = "null"; //$NON-NLS-1$
+ }
+
+ try {
+ write(str.getBytes(charset));
+ } catch (java.io.IOException e) {
+ setError();
+ }
+ }
+ }
+
+ /**
+ * CaseInsensitiveComparator compares Strings ignoring the case of the
+ * characters.
+ */
+ private static final class CaseInsensitiveComparator implements
+ Comparator<String>, Serializable {
+ private 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(String o1, String o2) {
+ return o1.compareToIgnoreCase(o2);
+ }
+ }
+
+ /*
+ * A Comparator which compares Strings ignoring the case of the characters.
+ */
+ public static final Comparator<String> 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;
+
+ private static Charset DefaultCharset;
+
+ private static Charset lastCharset;
+
+ 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;
+ }
+
+ @SuppressWarnings("unused")
+ 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
+ */
+ @Deprecated
+ 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 <code>length < 0, start < 0</code> or
+ * <code>start + length > data.length</code>
+ * @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) {
+ // start + length could overflow, start/length maybe MaxInt
+ if (start >= 0 && 0 <= length && length <= data.length - start) {
+ offset = 0;
+ Charset charset = defaultCharset();
+ int result;
+ CharBuffer cb = charset
+ .decode(ByteBuffer.wrap(data, start, length));
+ if ((result = cb.length()) > 0) {
+ value = cb.array();
+ count = result;
+ } else {
+ count = 0;
+ value = new char[0];
+ }
+ } else {
+ throw new StringIndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * 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 <code>length < 0, start < 0</code> or
+ * <code>start + length > data.length</code>
+ * @throws NullPointerException
+ * when data is null
+ *
+ * @deprecated Use String(byte[], int, int) instead
+ */
+ @Deprecated
+ 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 <code>length < 0, start < 0</code> or
+ * <code>start + length > data.length</code>
+ * @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 {
+ if (encoding == null) {
+ throw new NullPointerException();
+ }
+ // start + length could overflow, start/length maybe MaxInt
+ if (start >= 0 && 0 <= length && length <= data.length - start) {
+ offset = 0;
+ Charset charset = getCharset(encoding);
+
+ int result;
+ CharBuffer cb = charset
+ .decode(ByteBuffer.wrap(data, start, length));
+ if ((result = cb.length()) > 0) {
+ value = cb.array();
+ count = result;
+ } else {
+ count = 0;
+ value = new char[0];
+ }
+ } else {
+ throw new StringIndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * 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 <code>length < 0, start < 0</code> or
+ * <code>start + length > data.length</code>
+ * @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;
+ System.arraycopy(data, start, value, 0, count);
+ } 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) {
+ offset = 0;
+ synchronized (stringbuffer) {
+ value = stringbuffer.shareValue();
+ count = stringbuffer.length();
+ }
+ }
+
+ /**
+ * <p>
+ * Constructs a <code>String</code> from the sub-array of Unicode code
+ * points.
+ * </p>
+ *
+ * @param codePoints
+ * The array of Unicode code points to convert.
+ * @param offset
+ * The inclusive index into <code>codePoints</code> to begin
+ * converting from.
+ * @param count
+ * The number of element in <code>codePoints</code> to copy.
+ * @throws NullPointerException
+ * if <code>codePoints</code> is null.
+ * @throws IllegalArgumentException
+ * if any of the elements of <code>codePoints</code> are not
+ * valid Unicode code points.
+ * @throws IndexOutOfBoundsException
+ * if <code>offset</code> or <code>count</code> are not
+ * within the bounds of <code>codePoints</code>.
+ * @since 1.5
+ */
+ public String(int[] codePoints, int offset, int count) {
+ super();
+ if (codePoints == null) {
+ throw new NullPointerException();
+ }
+ if (offset < 0 || count < 0
+ || (long) offset + (long) count > codePoints.length) {
+ throw new IndexOutOfBoundsException();
+ }
+ this.offset = 0;
+ this.value = new char[count * 2];
+ int end = offset + count;
+ int c = 0;
+ for (int i = offset; i < end; i++) {
+ c += Character.toChars(codePoints[i], this.value, c);
+ }
+ this.count = c;
+ }
+
+ /**
+ * <p>
+ * Constructs a <code>String</code> from a <code>StringBuilder</code>.
+ * </p>
+ *
+ * @param sb
+ * The StringBuilder to copy from.
+ * @throws NullPointerException
+ * if <code>sb</code> is <code>null</code>.
+ * @since 1.5
+ */
+ public String(StringBuilder sb) {
+ if (sb == null) {
+ throw new NullPointerException();
+ }
+ this.offset = 0;
+ this.count = sb.length();
+ this.value = new char[this.count];
+ sb.getChars(0, this.count, this.value, 0);
+ }
+
+ /*
+ * Creates a string that is s1 + v1. May be used by JIT code.
+ */
+ @SuppressWarnings("unused")
+ private String(String s1, int v1) {
+ if (s1 == null) {
+ s1 = "null"; //$NON-NLS-1$
+ }
+ 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 <code>index < 0</code> or
+ * <code>index >= length()</code>
+ */
+ public char charAt(int index) {
+ if (0 <= index && index < count) {
+ return value[offset + index];
+ }
+ throw new StringIndexOutOfBoundsException();
+ }
+
+ /**
+ * 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 <code>length < 0, start < 0</code> or
+ * <code>start + length > data.length</code>
+ * @throws NullPointerException
+ * if data is null
+ */
+ public static String copyValueOf(char[] data, int start, int length) {
+ return new String(data, start, length);
+ }
+
+ private Charset defaultCharset() {
+ if (DefaultCharset == null) {
+ String encoding = AccessController
+ .doPrivileged(new PriviAction<String>(
+ "file.encoding", "ISO8859_1")); //$NON-NLS-1$ //$NON-NLS-2$
+ // calling System.getProperty() may cause DefaultCharset to be
+ // initialized
+ try {
+ DefaultCharset = Charset.forName(encoding);
+ } catch (IllegalCharsetNameException e) {
+ // Ignored
+ } catch (UnsupportedCharsetException e) {
+ // Ignored
+ }
+
+ if (DefaultCharset == null) {
+ DefaultCharset = Charset.forName("ISO-8859-1"); //$NON-NLS-1$
+ }
+ }
+ return DefaultCharset;
+ }
+
+ /**
+ * 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
+ */
+ @Override
+ 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 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.
+ *
+ * @return the byte array encoding of this String
+ *
+ * @see String
+ */
+ public byte[] getBytes() {
+ ByteBuffer buffer = defaultCharset().encode(
+ CharBuffer.wrap(this.value, this.offset, this.count));
+ byte[] bytes = new byte[buffer.limit()];
+ buffer.get(bytes);
+ return bytes;
+ }
+
+ /**
+ * 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
+ * <code>start < 0, end > length(), index < 0, end - start > data.length - index</code>
+ *
+ * @deprecated Use getBytes() or getBytes(String)
+ */
+ @Deprecated
+ public void getBytes(int start, int end, byte[] data, int index) {
+ 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();
+ }
+ }
+
+ /**
+ * 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 {
+ ByteBuffer buffer = getCharset(encoding).encode(
+ CharBuffer.wrap(this.value, this.offset, this.count));
+ byte[] bytes = new byte[buffer.limit()];
+ buffer.get(bytes);
+ return bytes;
+ }
+
+ private Charset getCharset(final String encoding)
+ throws UnsupportedEncodingException {
+ Charset charset = lastCharset;
+ if (charset == null || !encoding.equalsIgnoreCase(charset.name())) {
+ try {
+ charset = Charset.forName(encoding);
+ } catch (IllegalCharsetNameException e) {
+ throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
+ encoding).initCause(e));
+ } catch (UnsupportedCharsetException e) {
+ throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
+ encoding).initCause(e));
+ }
+ lastCharset = charset;
+ }
+ return charset;
+ }
+
+ /**
+ * 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 <code>start < 0, end > length(),
+ * start > end, index < 0, end - start > buffer.length - index</code>
+ * @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
+ */
+ @Override
+ 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;
+ }
+
+ /**
+ * 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 String intern() {
+ return VM.intern(this);
+ }
+
+ /**
+ * 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;
+ }
+
/**
- * <p>
- * Constructs a <code>String</code> from the sub-array of Unicode code
- * points.
- * </p>
+ * 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 codePoints The array of Unicode code points to convert.
- * @param offset The inclusive index into <code>codePoints</code> to begin
- * converting from.
- * @param count The number of element in <code>codePoints</code> to copy.
- * @throws NullPointerException if <code>codePoints</code> is null.
- * @throws IllegalArgumentException if any of the elements of
- * <code>codePoints</code> are not valid Unicode code points.
- * @throws IndexOutOfBoundsException if <code>offset</code> or
- * <code>count</code> are not within the bounds of
- * <code>codePoints</code>.
- * @since 1.5
+ * @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 String(int[] codePoints, int offset, int count) {
- super();
- if (codePoints == null)
- throw new NullPointerException();
- if (offset < 0 || count < 0 || (long)offset + (long)count > codePoints.length)
- throw new IndexOutOfBoundsException();
- this.offset = 0;
- this.value = new char[count * 2];
- int end = offset + count;
- int c = 0;
- for (int i = offset; i < end; i++) {
- c += Character.toChars(codePoints[i], this.value, c);
+ public boolean regionMatches(boolean ignoreCase, int thisStart,
+ String string, int start, int length) {
+ if (!ignoreCase) {
+ return regionMatches(thisStart, string, start, length);
}
- this.count = c;
+
+ 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();
}
-
+
/**
- * <p>
- * Constructs a <code>String</code> from a <code>StringBuilder</code>.
- * </p>
+ * Copies this String replacing occurrences of the specified character with
+ * another character.
*
- * @param sb The StringBuilder to copy from.
- * @throws NullPointerException if <code>sb</code> is <code>null</code>.
- * @since 1.5
+ * @param oldChar
+ * the character to replace
+ * @param newChar
+ * the replacement character
+ * @return a new String with occurrences of oldChar replaced by newChar
*/
- public String(StringBuilder sb) {
- if (sb == null)
- throw new NullPointerException();
- this.offset = 0;
- this.count = sb.length();
- this.value = new char[this.count];
- sb.getChars(0, this.count, this.value, 0);
+ 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);
}
- /*
- * Creates a string that is s1 + v1.
+ /**
+ * 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
*/
- 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 <code>index < 0</code> or
- * <code>index >= length()</code>
- */
- public char charAt(int index) {
- if (0 <= index && index < count)
- return value[offset + index];
- throw new StringIndexOutOfBoundsException();
- }
-
- /**
- * 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 <code>length < 0, start < 0</code> or
- * <code>start + length > data.length</code>
- * @throws NullPointerException
- * if data is null
- */
- public static String copyValueOf(char[] data, int start, int length) {
- return new String(data, start, length);
- }
-
- private Charset defaultCharset() {
- if (DefaultCharset == null) {
- String encoding = (String) AccessController
- .doPrivileged(new PriviAction("file.encoding", "ISO8859_1"));
- // calling System.getProperty() may cause DefaultCharset to be
- // initialized
- try {
- DefaultCharset = Charset.forName(encoding);
- } catch (IllegalCharsetNameException e) {
- //
- } catch (UnsupportedCharsetException e) {
- //
- }
-
- if (DefaultCharset == null) {
- DefaultCharset = Charset.forName("ISO-8859-1");
- }
- }
- return DefaultCharset;
- }
-
- /**
- * 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 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.
- *
- * @return the byte array encoding of this String
- *
- * @see String
- */
- public byte[] getBytes() {
- ByteBuffer buffer = defaultCharset().encode(
- CharBuffer.wrap(this.value, this.offset, this.count));
- byte[] bytes = new byte[buffer.limit()];
- buffer.get(bytes);
- return bytes;
- }
-
- /**
- * 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
- * <code>start < 0, end > length(), index < 0, end - start > data.length - index</code>
- *
- * @deprecated Use getBytes() or getBytes(String)
- */
- public void getBytes(int start, int end, byte[] data, int index) {
- 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();
- }
-
- /**
- * 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 {
- ByteBuffer buffer = getCharset(encoding).encode(
- CharBuffer.wrap(this.value, this.offset, this.count));
- byte[] bytes = new byte[buffer.limit()];
- buffer.get(bytes);
- return bytes;
- }
-
- private Charset getCharset(final String encoding)
- throws UnsupportedEncodingException {
- Charset charset = lastCharset;
- if (charset == null || !encoding.equalsIgnoreCase(charset.name())) {
- try {
- charset = Charset.forName(encoding);
- } catch (IllegalCharsetNameException e) {
- throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
- encoding).initCause(e));
- } catch (UnsupportedCharsetException e) {
- throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
- encoding).initCause(e));
+ 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 <code>start < 0</code> or
+ * <code>start > length()</code>
+ */
+ public String substring(int start) {
+ if (start == 0) {
+ return this;
+ }
+ 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 <code>start < 0, start > end</code> or
+ * <code>end > length()</code>
+ */
+ public String substring(int start, int end) {
+ if (start == 0 && end == count) {
+ return this;
+ }
+ // 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;
+ // Not worth checking for i == 0 case
+ System.arraycopy(value, offset, buffer, 0, i);
+ // Turkish
+ if (!"tr".equals(locale.getLanguage())) { //$NON-NLS-1$
+ 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);
}
- lastCharset = charset;
- }
- return charset;
- }
-
- /**
- * 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 <code>start < 0, end > length(),
- * start > end, index < 0, end - start > buffer.length - index</code>
- * @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;
- }
-
- /**
- * 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 String intern() {
- return org.apache.harmony.kernel.vm.VM.intern(this);
- }
-
- /**
- * 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
- */
[... 1249 lines stripped ...]