diff options
Diffstat (limited to 'libjava/java/lang')
-rw-r--r-- | libjava/java/lang/Character.java | 284 | ||||
-rw-r--r-- | libjava/java/lang/Double.java | 43 | ||||
-rw-r--r-- | libjava/java/lang/Float.java | 24 | ||||
-rw-r--r-- | libjava/java/lang/String.java | 130 | ||||
-rw-r--r-- | libjava/java/lang/StringBuffer.java | 261 | ||||
-rw-r--r-- | libjava/java/lang/StringBuilder.java | 67 | ||||
-rw-r--r-- | libjava/java/lang/natDouble.cc | 8 | ||||
-rw-r--r-- | libjava/java/lang/natString.cc | 15 |
8 files changed, 789 insertions, 43 deletions
diff --git a/libjava/java/lang/Character.java b/libjava/java/lang/Character.java index aa29e0bd523..f56117fdb31 100644 --- a/libjava/java/lang/Character.java +++ b/libjava/java/lang/Character.java @@ -1,5 +1,5 @@ /* java.lang.Character -- Wrapper class for char, and Unicode subsets - Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -1040,6 +1040,18 @@ public final class Character implements Serializable, Comparable public static final Class TYPE = VMClassLoader.getPrimitiveClass('C'); /** + * The number of bits needed to represent a <code>char</code>. + * @since 1.5 + */ + public static final int SIZE = 16; + + // This caches some Character values, and is used by boxing + // conversions via valueOf(). We must cache at least 0..127; + // this constant controls how much we actually cache. + private static final int MAX_CACHE = 127; + private static Character[] charCache = new Character[MAX_CACHE + 1]; + + /** * Lu = Letter, Uppercase (Informative). * * @since 1.1 @@ -1434,34 +1446,48 @@ public final class Character implements Serializable, Comparable /** - * Minimum high surrrogate code in UTF-16 encoding. + * Minimum high surrogate code in UTF-16 encoding. * * @since 1.5 */ public static final char MIN_HIGH_SURROGATE = '\ud800'; /** - * Maximum high surrrogate code in UTF-16 encoding. + * Maximum high surrogate code in UTF-16 encoding. * * @since 1.5 */ public static final char MAX_HIGH_SURROGATE = '\udbff'; /** - * Minimum low surrrogate code in UTF-16 encoding. + * Minimum low surrogate code in UTF-16 encoding. * * @since 1.5 */ public static final char MIN_LOW_SURROGATE = '\udc00'; /** - * Maximum low surrrogate code in UTF-16 encoding. + * Maximum low surrogate code in UTF-16 encoding. * * @since 1.5 */ public static final char MAX_LOW_SURROGATE = '\udfff'; /** + * Minimum surrogate code in UTF-16 encoding. + * + * @since 1.5 + */ + public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE; + + /** + * Maximum low surrogate code in UTF-16 encoding. + * + * @since 1.5 + */ + public static final char MAX_SURROGATE = MAX_LOW_SURROGATE; + + /** * Grabs an attribute offset from the Unicode attribute database. The lower * 5 bits are the character type, the next 2 bits are flags, and the top * 9 bits are the offset into the attribute tables. Note that the top 9 @@ -2213,6 +2239,37 @@ public final class Character implements Serializable, Comparable } /** + * Returns an <code>Character</code> object wrapping the value. + * In contrast to the <code>Character</code> constructor, this method + * will cache some values. It is used by boxing conversion. + * + * @param val the value to wrap + * @return the <code>Character</code> + * + * @since 1.5 + */ + public static Character valueOf(char val) + { + if (val > MAX_CACHE) + return new Character(val); + synchronized (charCache) + { + if (charCache[val - MIN_VALUE] == null) + charCache[val - MIN_VALUE] = new Character(val); + return charCache[val - MIN_VALUE]; + } + } + + /** + * Reverse the bytes in val. + * @since 1.5 + */ + public static char reverseBytes(char val) + { + return (char) (((val >> 8) & 0xff) | ((val << 8) & 0xff00)); + } + + /** * Converts a unicode code point to a UTF-16 representation of that * code point. * @@ -2263,11 +2320,11 @@ public final class Character implements Serializable, Comparable { // Write second char first to cause IndexOutOfBoundsException // immediately. - dst[dstIndex + 1] = (char) ((codePoint & 0x3ff) - + (int) MIN_LOW_SURROGATE ); - dst[dstIndex] = (char) ((codePoint >> 10) + (int) MIN_HIGH_SURROGATE); + final int cp2 = codePoint - 0x10000; + dst[dstIndex + 1] = (char) ((cp2 % 0x400) + (int) MIN_LOW_SURROGATE); + dst[dstIndex] = (char) ((cp2 / 0x400) + (int) MIN_HIGH_SURROGATE); result = 2; - } + } else { dst[dstIndex] = (char) codePoint; @@ -2280,7 +2337,7 @@ public final class Character implements Serializable, Comparable * Return number of 16-bit characters required to represent the given * code point. * - * @param codePoint a uncode code point + * @param codePoint a unicode code point * * @return 2 if codePoint >= 0x10000, 1 otherwise. * @@ -2325,4 +2382,211 @@ public final class Character implements Serializable, Comparable { return codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT; } + + /** + * Return true if the given character is a high surrogate. + * @param ch the character + * @return true if the character is a high surrogate character + * + * @since 1.5 + */ + public static boolean isHighSurrogate(char ch) + { + return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE; + } + + /** + * Return true if the given character is a low surrogate. + * @param ch the character + * @return true if the character is a low surrogate character + * + * @since 1.5 + */ + public static boolean isLowSurrogate(char ch) + { + return ch >= MIN_LOW_SURROGATE && ch <= MAX_LOW_SURROGATE; + } + + /** + * Return true if the given characters compose a surrogate pair. + * This is true if the first character is a high surrogate and the + * second character is a low surrogate. + * @param ch1 the first character + * @param ch2 the first character + * @return true if the characters compose a surrogate pair + * + * @since 1.5 + */ + public static boolean isSurrogatePair(char ch1, char ch2) + { + return isHighSurrogate(ch1) && isLowSurrogate(ch2); + } + + /** + * Given a valid surrogate pair, this returns the corresponding + * code point. + * @param high the high character of the pair + * @param low the low character of the pair + * @return the corresponding code point + * + * @since 1.5 + */ + public static int toCodePoint(char high, char low) + { + return ((high - MIN_HIGH_SURROGATE) * 0x400) + + (low - MIN_LOW_SURROGATE) + 0x10000; + } + + /** + * Get the code point at the specified index in the CharSequence. + * This is like CharSequence#charAt(int), but if the character is + * the start of a surrogate pair, and there is a following + * character, and this character completes the pair, then the + * corresponding supplementary code point is returned. Otherwise, + * the character at the index is returned. + * + * @param sequence the CharSequence + * @param index the index of the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public static int codePointAt(CharSequence sequence, int index) + { + int len = sequence.length(); + if (index < 0 || index >= len) + throw new IndexOutOfBoundsException(); + char high = sequence.charAt(index); + if (! isHighSurrogate(high) || ++index >= len) + return high; + char low = sequence.charAt(index); + if (! isLowSurrogate(low)) + return high; + return toCodePoint(high, low); + } + + /** + * Get the code point at the specified index in the CharSequence. + * If the character is the start of a surrogate pair, and there is a + * following character, and this character completes the pair, then + * the corresponding supplementary code point is returned. + * Otherwise, the character at the index is returned. + * + * @param chars the character array in which to look + * @param index the index of the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public static int codePointAt(char[] chars, int index) + { + return codePointAt(chars, index, chars.length); + } + + /** + * Get the code point at the specified index in the CharSequence. + * If the character is the start of a surrogate pair, and there is a + * following character within the specified range, and this + * character completes the pair, then the corresponding + * supplementary code point is returned. Otherwise, the character + * at the index is returned. + * + * @param chars the character array in which to look + * @param index the index of the codepoint to get, starting at 0 + * @param limit the limit past which characters should not be examined + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= + * limit, or if limit is negative or >= the length of the array + * @since 1.5 + */ + public static int codePointAt(char[] chars, int index, int limit) + { + if (index < 0 || index >= limit || limit < 0 || limit >= chars.length) + throw new IndexOutOfBoundsException(); + char high = chars[index]; + if (! isHighSurrogate(high) || ++index >= limit) + return high; + char low = chars[index]; + if (! isLowSurrogate(low)) + return high; + return toCodePoint(high, low); + } + + /** + * Get the code point before the specified index. This is like + * #codePointAt(char[], int), but checks the characters at + * <code>index-1</code> and <code>index-2</code> to see if they form + * a supplementary code point. If they do not, the character at + * <code>index-1</code> is returned. + * + * @param chars the character array + * @param index the index just past the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public static int codePointBefore(char[] chars, int index) + { + return codePointBefore(chars, index, 1); + } + + /** + * Get the code point before the specified index. This is like + * #codePointAt(char[], int), but checks the characters at + * <code>index-1</code> and <code>index-2</code> to see if they form + * a supplementary code point. If they do not, the character at + * <code>index-1</code> is returned. The start parameter is used to + * limit the range of the array which may be examined. + * + * @param chars the character array + * @param index the index just past the codepoint to get, starting at 0 + * @param start the index before which characters should not be examined + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is > start or > + * the length of the array, or if limit is negative or >= the + * length of the array + * @since 1.5 + */ + public static int codePointBefore(char[] chars, int index, int start) + { + if (index < start || index > chars.length + || start < 0 || start >= chars.length) + throw new IndexOutOfBoundsException(); + --index; + char low = chars[index]; + if (! isLowSurrogate(low) || --index < start) + return low; + char high = chars[index]; + if (! isHighSurrogate(high)) + return low; + return toCodePoint(high, low); + } + + /** + * Get the code point before the specified index. This is like + * #codePointAt(CharSequence, int), but checks the characters at + * <code>index-1</code> and <code>index-2</code> to see if they form + * a supplementary code point. If they do not, the character at + * <code>index-1</code> is returned. + * + * @param sequence the CharSequence + * @param index the index just past the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public static int codePointBefore(CharSequence sequence, int index) + { + int len = sequence.length(); + if (index < 1 || index > len) + throw new IndexOutOfBoundsException(); + --index; + char low = sequence.charAt(index); + if (! isLowSurrogate(low) || --index < 0) + return low; + char high = sequence.charAt(index); + if (! isHighSurrogate(high)) + return low; + return toCodePoint(high, low); + } } // class Character diff --git a/libjava/java/lang/Double.java b/libjava/java/lang/Double.java index f6235d5b65c..92f8a230822 100644 --- a/libjava/java/lang/Double.java +++ b/libjava/java/lang/Double.java @@ -1,5 +1,5 @@ /* Double.java -- object wrapper for double - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,7 +38,6 @@ exception statement from your version. */ package java.lang; -import gnu.classpath.Configuration; /** * Instances of class <code>Double</code> represent primitive @@ -89,6 +88,12 @@ public final class Double extends Number implements Comparable public static final double NaN = 0.0 / 0.0; /** + * The number of bits needed to represent a <code>double</code>. + * @since 1.5 + */ + public static final int SIZE = 64; + + /** * The primitive type <code>double</code> is represented by this * <code>Class</code> object. * @since 1.1 @@ -103,18 +108,6 @@ public final class Double extends Number implements Comparable private final double value; /** - * Load native routines necessary for this class. - */ - static - { - if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary("javalang"); - initIDs(); - } - } - - /** * Create a <code>Double</code> from the primitive <code>double</code> * specified. * @@ -180,6 +173,22 @@ public final class Double extends Number implements Comparable } /** + * Returns a <code>Double</code> object wrapping the value. + * In contrast to the <code>Double</code> constructor, this method + * may cache some values. It is used by boxing conversion. + * + * @param val the value to wrap + * @return the <code>Double</code> + * + * @since 1.5 + */ + public static Double valueOf(double val) + { + // We don't actually cache, but we could. + return new Double(val); + } + + /** * Create a new <code>Double</code> object using the <code>String</code>. * * @param s the <code>String</code> to convert @@ -534,10 +543,4 @@ public final class Double extends Number implements Comparable */ // Package visible for use by Float. static native String toString(double d, boolean isFloat); - - /** - * Initialize JNI cache. This method is called only by the - * static initializer when using JNI. - */ - private static native void initIDs(); } diff --git a/libjava/java/lang/Float.java b/libjava/java/lang/Float.java index b2c84c75655..7677ca4132e 100644 --- a/libjava/java/lang/Float.java +++ b/libjava/java/lang/Float.java @@ -1,5 +1,5 @@ /* Float.java -- object wrapper for float - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -94,6 +94,12 @@ public final class Float extends Number implements Comparable public static final Class TYPE = VMClassLoader.getPrimitiveClass('F'); /** + * The number of bits needed to represent a <code>float</code>. + * @since 1.5 + */ + public static final int SIZE = 32; + + /** * The immutable value of this Float. * * @serial the wrapped float @@ -192,6 +198,22 @@ public final class Float extends Number implements Comparable } /** + * Returns a <code>Float</code> object wrapping the value. + * In contrast to the <code>Float</code> constructor, this method + * may cache some values. It is used by boxing conversion. + * + * @param val the value to wrap + * @return the <code>Float</code> + * + * @since 1.5 + */ + public static Float valueOf(float val) + { + // We don't actually cache, but we could. + return new Float(val); + } + + /** * Parse the specified <code>String</code> as a <code>float</code>. The * extended BNF grammar is as follows:<br> * <pre> diff --git a/libjava/java/lang/String.java b/libjava/java/lang/String.java index 95ad1fe578c..3e0bfbee89d 100644 --- a/libjava/java/lang/String.java +++ b/libjava/java/lang/String.java @@ -1,5 +1,5 @@ /* String.java -- immutable character sequences; the object of string literals - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -455,6 +455,40 @@ public final class String implements Serializable, Comparable, CharSequence public native char charAt(int index); /** + * Get the code point at the specified index. This is like #charAt(int), + * but if the character is the start of a surrogate pair, and the + * following character completes the pair, then the corresponding + * supplementary code point is returned. + * @param index the index of the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public synchronized int codePointAt(int index) + { + // Use the CharSequence overload as we get better range checking + // this way. + return Character.codePointAt(this, index); + } + + /** + * Get the code point before the specified index. This is like + * #codePointAt(int), but checks the characters at <code>index-1</code> and + * <code>index-2</code> to see if they form a supplementary code point. + * @param index the index just past the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * (while unspecified, this is a StringIndexOutOfBoundsException) + * @since 1.5 + */ + public synchronized int codePointBefore(int index) + { + // Use the CharSequence overload as we get better range checking + // this way. + return Character.codePointBefore(this, index); + } + + /** * Copies characters from this String starting at a specified start index, * ending at a specified stop index, to a character array starting at * a specified destination begin index. @@ -566,6 +600,18 @@ public final class String implements Serializable, Comparable, CharSequence public native boolean contentEquals(StringBuffer buffer); /** + * Compares the given CharSequence to this String. This is true if + * the CharSequence has the same content as this String at this + * moment. + * + * @param seq the CharSequence to compare to + * @return true if CharSequence has the same character sequence + * @throws NullPointerException if the given CharSequence is null + * @since 1.5 + */ + public native boolean contentEquals(CharSequence seq); + + /** * Compares a String to this String, ignoring case. This does not handle * multi-character capitalization exceptions; instead the comparison is * made on a character-by-character basis, and is true if:<br><ul> @@ -1259,6 +1305,88 @@ public final class String implements Serializable, Comparable, CharSequence */ public native String intern(); + /** + * Return the number of code points between two indices in the + * <code>String</code>. An unpaired surrogate counts as a + * code point for this purpose. Characters outside the indicated + * range are not examined, even if the range ends in the middle of a + * surrogate pair. + * + * @param start the starting index + * @param end one past the ending index + * @return the number of code points + * @since 1.5 + */ + public synchronized int codePointCount(int start, int end) + { + if (start < 0 || end >= count || start > end) + throw new StringIndexOutOfBoundsException(); + + int count = 0; + while (start < end) + { + char base = charAt(start); + if (base < Character.MIN_HIGH_SURROGATE + || base > Character.MAX_HIGH_SURROGATE + || start == end + || start == count + || charAt(start + 1) < Character.MIN_LOW_SURROGATE + || charAt(start + 1) > Character.MAX_LOW_SURROGATE) + { + // Nothing. + } + else + { + // Surrogate pair. + ++start; + } + ++start; + ++count; + } + return count; + } + + /** + * Returns true iff this String contains the sequence of Characters + * described in s. + * @param s the CharSequence + * @return true iff this String contains s + * + * @since 1.5 + */ + public boolean contains (CharSequence s) + { + return this.indexOf(s.toString()) != -1; + } + + /** + * Returns a string that is this string with all instances of the sequence + * represented by <code>target</code> replaced by the sequence in + * <code>replacement</code>. + * @param target the sequence to be replaced + * @param replacement the sequence used as the replacement + * @return the string constructed as above + */ + public String replace (CharSequence target, CharSequence replacement) + { + String targetString = target.toString(); + String replaceString = replacement.toString(); + int targetLength = target.length(); + int replaceLength = replacement.length(); + + int startPos = this.indexOf(targetString); + StringBuilder result = new StringBuilder(this); + while (startPos != -1) + { + // Replace the target with the replacement + result.replace(startPos, startPos + targetLength, replaceString); + + // Search for a new occurrence of the target + startPos = result.indexOf(targetString, startPos + replaceLength); + } + return result.toString(); + } + private native void init(char[] chars, int offset, int count, boolean dont_copy); diff --git a/libjava/java/lang/StringBuffer.java b/libjava/java/lang/StringBuffer.java index d93fed5fd40..c3f112967c4 100644 --- a/libjava/java/lang/StringBuffer.java +++ b/libjava/java/lang/StringBuffer.java @@ -1,5 +1,5 @@ /* StringBuffer.java -- Growable strings - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -148,6 +148,24 @@ public final class StringBuffer implements Serializable, CharSequence } /** + * Create a new <code>StringBuffer</code> with the characters from the + * specified <code>CharSequence</code>. Initial capacity will be the + * size of the CharSequence plus 16. + * + * @param sequence the <code>String</code> to convert + * @throws NullPointerException if str is null + * + * @since 1.5 + */ + public StringBuffer(CharSequence sequence) + { + count = Math.max(0, sequence.length()); + value = new char[count + DEFAULT_CAPACITY]; + for (int i = 0; i < count; ++i) + value[i] = sequence.charAt(i); + } + + /** * Get the length of the <code>String</code> this <code>StringBuffer</code> * would create. Not to be confused with the <em>capacity</em> of the * <code>StringBuffer</code>. @@ -234,7 +252,6 @@ public final class StringBuffer implements Serializable, CharSequence * @param index the index of the character to get, starting at 0 * @return the character at the specified index * @throws IndexOutOfBoundsException if index is negative or >= length() - * (while unspecified, this is a StringIndexOutOfBoundsException) */ public synchronized char charAt(int index) { @@ -244,6 +261,39 @@ public final class StringBuffer implements Serializable, CharSequence } /** + * Get the code point at the specified index. This is like #charAt(int), + * but if the character is the start of a surrogate pair, and the + * following character completes the pair, then the corresponding + * supplementary code point is returned. + * @param index the index of the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public synchronized int codePointAt(int index) + { + return Character.codePointAt(value, index, count); + } + + /** + * Get the code point before the specified index. This is like + * #codePointAt(int), but checks the characters at <code>index-1</code> and + * <code>index-2</code> to see if they form a supplementary code point. + * @param index the index just past the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public synchronized int codePointBefore(int index) + { + // Character.codePointBefore() doesn't perform this check. We + // could use the CharSequence overload, but this is just as easy. + if (index >= count) + throw new IndexOutOfBoundsException(); + return Character.codePointBefore(value, index, 1); + } + + /** * Get the specified array of characters. <code>srcOffset - srcEnd</code> * characters will be copied into the array you pass in. * @@ -341,6 +391,46 @@ public final class StringBuffer implements Serializable, CharSequence } /** + * Append the <code>CharSequence</code> value of the argument to this + * <code>StringBuffer</code>. + * + * @param sequence the <code>CharSequence</code> to append + * @return this <code>StringBuffer</code> + * @see #append(Object) + * @since 1.5 + */ + public synchronized StringBuffer append(CharSequence sequence) + { + if (sequence == null) + sequence = "null"; + return append(sequence, 0, sequence.length()); + } + + /** + * Append the specified subsequence of the <code>CharSequence</code> + * argument to this <code>StringBuffer</code>. + * + * @param sequence the <code>CharSequence</code> to append + * @param start the starting index + * @param end one past the ending index + * @return this <code>StringBuffer</code> + * @see #append(Object) + * @since 1.5 + */ + public synchronized StringBuffer append(CharSequence sequence, + int start, int end) + { + if (sequence == null) + sequence = "null"; + if (start < 0 || end < 0 || start > end || end > sequence.length()) + throw new IndexOutOfBoundsException(); + ensureCapacity_unsynchronized(this.count + end - start); + for (int i = start; i < end; ++i) + value[count++] = sequence.charAt(i); + return this; + } + + /** * Append the <code>char</code> array to this <code>StringBuffer</code>. * This is similar (but more efficient) than * <code>append(new String(data))</code>, except in the case of null. @@ -407,6 +497,25 @@ public final class StringBuffer implements Serializable, CharSequence } /** + * Append the code point to this <code>StringBuffer</code>. + * This is like #append(char), but will append two characters + * if a supplementary code point is given. + * + * @param code the code point to append + * @return this <code>StringBuffer</code> + * @see Character#toChars(int, char[], int) + * @since 1.5 + */ + public synchronized StringBuffer appendCodePoint(int code) + { + int len = Character.charCount(code); + ensureCapacity_unsynchronized(count + len); + Character.toChars(code, value, count); + count += len; + return this; + } + + /** * Append the <code>String</code> value of the argument to this * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert * to <code>String</code>. @@ -657,6 +766,54 @@ public final class StringBuffer implements Serializable, CharSequence } /** + * Insert the <code>CharSequence</code> argument into this + * <code>StringBuffer</code>. If the sequence is null, the String + * "null" is used instead. + * + * @param offset the place to insert in this buffer + * @param sequence the <code>CharSequence</code> to insert + * @return this <code>StringBuffer</code> + * @throws IndexOutOfBoundsException if offset is out of bounds + * @since 1.5 + */ + public synchronized StringBuffer insert(int offset, CharSequence sequence) + { + if (sequence == null) + sequence = "null"; + return insert(offset, sequence, 0, sequence.length()); + } + + /** + * Insert a subsequence of the <code>CharSequence</code> argument into this + * <code>StringBuffer</code>. If the sequence is null, the String + * "null" is used instead. + * + * @param offset the place to insert in this buffer + * @param sequence the <code>CharSequence</code> to insert + * @param start the starting index of the subsequence + * @param end one past the ending index of the subsequence + * @return this <code>StringBuffer</code> + * @throws IndexOutOfBoundsException if offset, start, + * or end are out of bounds + * @since 1.5 + */ + public synchronized StringBuffer insert(int offset, CharSequence sequence, + int start, int end) + { + if (sequence == null) + sequence = "null"; + if (start < 0 || end < 0 || start > end || end > sequence.length()) + throw new IndexOutOfBoundsException(); + int len = end - start; + ensureCapacity_unsynchronized(count + len); + System.arraycopy(value, offset, value, offset + len, count - offset); + for (int i = start; i < end; ++i) + value[offset++] = sequence.charAt(i); + count += len; + return this; + } + + /** * Insert the <code>char[]</code> argument into this * <code>StringBuffer</code>. * @@ -877,6 +1034,106 @@ public final class StringBuffer implements Serializable, CharSequence } /** + * This may reduce the amount of memory used by the StringBuffer, + * by resizing the internal array to remove unused space. However, + * this method is not required to resize, so this behavior cannot + * be relied upon. + * @since 1.5 + */ + public synchronized void trimToSize() + { + int wouldSave = value.length - count; + // Some random heuristics: if we save less than 20 characters, who + // cares. + if (wouldSave < 20) + return; + // If we save more than 200 characters, shrink. + // If we save more than 1/4 of the buffer, shrink. + if (wouldSave > 200 || wouldSave * 4 > value.length) + { + char[] newValue = new char[count]; + System.arraycopy(value, 0, newValue, 0, count); + value = newValue; + } + } + + /** + * Return the number of code points between two indices in the + * <code>StringBuffer</code>. An unpaired surrogate counts as a + * code point for this purpose. Characters outside the indicated + * range are not examined, even if the range ends in the middle of a + * surrogate pair. + * + * @param start the starting index + * @param end one past the ending index + * @return the number of code points + * @since 1.5 + */ + public synchronized int codePointCount(int start, int end) + { + if (start < 0 || end >= count || start > end) + throw new StringIndexOutOfBoundsException(); + + int count = 0; + while (start < end) + { + char base = value[start]; + if (base < Character.MIN_HIGH_SURROGATE + || base > Character.MAX_HIGH_SURROGATE + || start == end + || start == count + || value[start + 1] < Character.MIN_LOW_SURROGATE + || value[start + 1] > Character.MAX_LOW_SURROGATE) + { + // Nothing. + } + else + { + // Surrogate pair. + ++start; + } + ++start; + ++count; + } + return count; + } + + /** + * Starting at the given index, this counts forward by the indicated + * number of code points, and then returns the resulting index. An + * unpaired surrogate counts as a single code point for this + * purpose. + * + * @param start the starting index + * @param codePoints the number of code points + * @return the resulting index + * @since 1.5 + */ + public synchronized int offsetByCodePoints(int start, int codePoints) + { + while (codePoints > 0) + { + char base = value[start]; + if (base < Character.MIN_HIGH_SURROGATE + || base > Character.MAX_HIGH_SURROGATE + || start == count + || value[start + 1] < Character.MIN_LOW_SURROGATE + || value[start + 1] > Character.MAX_LOW_SURROGATE) + { + // Nothing. + } + else + { + // Surrogate pair. + ++start; + } + ++start; + --codePoints; + } + return start; + } + + /** * An unsynchronized version of ensureCapacity, used internally to avoid * the cost of a second lock on the same object. This also has the side * effect of duplicating the array, if it was shared (to form copy-on-write diff --git a/libjava/java/lang/StringBuilder.java b/libjava/java/lang/StringBuilder.java index 51df8826416..5990a6d8dd5 100644 --- a/libjava/java/lang/StringBuilder.java +++ b/libjava/java/lang/StringBuilder.java @@ -1,5 +1,5 @@ /* StringBuilder.java -- Unsynchronized growable strings - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -464,6 +464,25 @@ public final class StringBuilder } /** + * Append the code point to this <code>StringBuilder</code>. + * This is like #append(char), but will append two characters + * if a supplementary code point is given. + * + * @param code the code point to append + * @return this <code>StringBuilder</code> + * @see Character#toChars(int, char[], int) + * @since 1.5 + */ + public synchronized StringBuilder appendCodePoint(int code) + { + int len = Character.charCount(code); + ensureCapacity(count + len); + Character.toChars(code, value, count); + count += len; + return this; + } + + /** * Append the <code>String</code> value of the argument to this * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert * to <code>String</code>. @@ -705,6 +724,52 @@ public final class StringBuilder } /** + * Insert the <code>CharSequence</code> argument into this + * <code>StringBuilder</code>. If the sequence is null, the String + * "null" is used instead. + * + * @param offset the place to insert in this buffer + * @param sequence the <code>CharSequence</code> to insert + * @return this <code>StringBuilder</code> + * @throws IndexOutOfBoundsException if offset is out of bounds + */ + public synchronized StringBuilder insert(int offset, CharSequence sequence) + { + if (sequence == null) + sequence = "null"; + return insert(offset, sequence, 0, sequence.length()); + } + + /** + * Insert a subsequence of the <code>CharSequence</code> argument into this + * <code>StringBuilder</code>. If the sequence is null, the String + * "null" is used instead. + * + * @param offset the place to insert in this buffer + * @param sequence the <code>CharSequence</code> to insert + * @param start the starting index of the subsequence + * @param end one past the ending index of the subsequence + * @return this <code>StringBuilder</code> + * @throws IndexOutOfBoundsException if offset, start, + * or end are out of bounds + */ + public synchronized StringBuilder insert(int offset, CharSequence sequence, + int start, int end) + { + if (sequence == null) + sequence = "null"; + if (start < 0 || end < 0 || start > end || end > sequence.length()) + throw new IndexOutOfBoundsException(); + int len = end - start; + ensureCapacity(count + len); + System.arraycopy(value, offset, value, offset + len, count - offset); + for (int i = start; i < end; ++i) + value[offset++] = sequence.charAt(i); + count += len; + return this; + } + + /** * Insert the <code>char[]</code> argument into this * <code>StringBuilder</code>. * diff --git a/libjava/java/lang/natDouble.cc b/libjava/java/lang/natDouble.cc index 72fe5fbe1c6..24dad8a6318 100644 --- a/libjava/java/lang/natDouble.cc +++ b/libjava/java/lang/natDouble.cc @@ -1,6 +1,6 @@ // natDouble.cc - Implementation of java.lang.Double native methods. -/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation This file is part of libgcj. @@ -211,9 +211,3 @@ java::lang::Double::parseDouble(jstring str) } throw new NumberFormatException(str); } - -void -java::lang::Double::initIDs() -{ - // Not used in libgcj -} diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc index c8f3129a212..3f630812d5e 100644 --- a/libjava/java/lang/natString.cc +++ b/libjava/java/lang/natString.cc @@ -1,6 +1,6 @@ // natString.cc - Implementation of java.lang.String native methods. -/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of libgcj. @@ -15,6 +15,7 @@ details. */ #include <gcj/cni.h> #include <java/lang/Character.h> +#include <java/lang/CharSequence.h> #include <java/lang/String.h> #include <java/lang/IndexOutOfBoundsException.h> #include <java/lang/ArrayIndexOutOfBoundsException.h> @@ -564,6 +565,18 @@ java::lang::String::contentEquals(java::lang::StringBuffer* buffer) return true; } +jboolean +java::lang::String::contentEquals(java::lang::CharSequence *seq) +{ + if (seq->length() != count) + return false; + jchar *value = JvGetStringChars(this); + for (int i = 0; i < count; ++i) + if (value[i] != seq->charAt(i)) + return false; + return true; +} + jchar java::lang::String::charAt(jint i) { |