natString.cc (hashCode): Use cachedHashCode.

2003-03-29  Eric Blake  <ebb9@email.byu.edu>
	    Tom Tromey  <tromey@redhat.com>

	* java/lang/natString.cc (hashCode): Use cachedHashCode.
	(init()): Removed.
	(charAt): Put index in exception.
	(contentEquals): New method.
	Include StringBuffer.h.
	* java/lang/String.java (cachedHashCode): New field.
	(String()): Follow classpath implementation.
	(init()): Removed.
	(contentEquals): Declare.
	(subSequence): Don't declare IndexOutIfBoundsException in throws
	clause.
	(matches, replaceFirst, replaceAll, split): New methods from
	Classpath.

Co-Authored-By: Tom Tromey <tromey@redhat.com>

From-SVN: r65037
This commit is contained in:
Eric Blake 2003-03-30 06:43:45 +00:00 committed by Tom Tromey
parent 9ba99c63ab
commit 7270451f19
3 changed files with 184 additions and 15 deletions

View File

@ -1,3 +1,20 @@
2003-03-29 Eric Blake <ebb9@email.byu.edu>
Tom Tromey <tromey@redhat.com>
* java/lang/natString.cc (hashCode): Use cachedHashCode.
(init()): Removed.
(charAt): Put index in exception.
(contentEquals): New method.
Include StringBuffer.h.
* java/lang/String.java (cachedHashCode): New field.
(String()): Follow classpath implementation.
(init()): Removed.
(contentEquals): Declare.
(subSequence): Don't declare IndexOutIfBoundsException in throws
clause.
(matches, replaceFirst, replaceAll, split): New methods from
Classpath.
2003-03-29 Tom Tromey <tromey@redhat.com>
* java/lang/String.java: Reordered to follow Classpath; merged in

View File

@ -44,6 +44,8 @@ import java.io.Serializable;
import java.lang.Comparable;
import java.util.Comparator;
import java.util.Locale;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* Strings represent an immutable set of characters. All String literals
@ -86,6 +88,12 @@ public final class String implements Serializable, Comparable, CharSequence
private int boffset; // Note this is a byte offset - don't use in Java code!
int count;
/**
* Caches the result of hashCode(). If this value is zero, the hashcode
* is considered uncached (even if 0 is the correct hash value).
*/
private int cachedHashCode;
/**
* An implementation for {@link CASE_INSENSITIVE_ORDER}.
* This must be {@link Serializable}. The class name is dictated by
@ -137,9 +145,11 @@ public final class String implements Serializable, Comparable, CharSequence
* Creates an empty String (length 0). Unless you really need a new object,
* consider using <code>""</code> instead.
*/
public String ()
public String()
{
init();
data = "".data;
boffset = 0;
count = 0;
}
/**
@ -154,6 +164,7 @@ public final class String implements Serializable, Comparable, CharSequence
data = str.data;
boffset = str.boffset;
count = str.count;
cachedHashCode = str.cachedHashCode;
}
/**
@ -510,6 +521,17 @@ public final class String implements Serializable, Comparable, CharSequence
*/
public native boolean equals (Object anObject);
/**
* Compares the given StringBuffer to this String. This is true if the
* StringBuffer has the same content as this String at this moment.
*
* @param buffer the StringBuffer to compare to
* @return true if StringBuffer has the same character sequence
* @throws NullPointerException if the given StringBuffer is null
* @since 1.4
*/
public native boolean contentEquals(StringBuffer buffer);
/**
* Compares a String to this String, ignoring case. This does not handle
* multi-character capitalization exceptions; instead the comparison is
@ -815,7 +837,6 @@ public final class String implements Serializable, Comparable, CharSequence
* @since 1.4
*/
public CharSequence subSequence(int beginIndex, int endIndex)
throws IndexOutOfBoundsException
{
return substring(beginIndex, endIndex);
}
@ -840,6 +861,124 @@ public final class String implements Serializable, Comparable, CharSequence
*/
public native String replace (char oldChar, char newChar);
/**
* Test if this String matches a regular expression. This is shorthand for
* <code>{@link Pattern}.matches(regex, this)</code>.
*
* @param regex the pattern to match
* @return true if the pattern matches
* @throws NullPointerException if regex is null
* @throws PatternSyntaxException if regex is invalid
* @see Pattern#matches(String, CharSequence)
* @since 1.4
*/
public boolean matches(String regex)
{
return Pattern.matches(regex, this);
}
/**
* Replaces the first substring match of the regular expression with a
* given replacement. This is shorthand for <code>{@link Pattern}
* .compile(regex).matcher(this).replaceFirst(replacement)</code>.
*
* @param regex the pattern to match
* @param replacement the replacement string
* @return the modified string
* @throws NullPointerException if regex or replacement is null
* @throws PatternSyntaxException if regex is invalid
* @see #replaceAll(String, String)
* @see Pattern#compile(String)
* @see Pattern#matcher(CharSequence)
* @see Matcher#replaceFirst(String)
* @since 1.4
*/
public String replaceFirst(String regex, String replacement)
{
return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
}
/**
* Replaces all matching substrings of the regular expression with a
* given replacement. This is shorthand for <code>{@link Pattern}
* .compile(regex).matcher(this).replaceAll(replacement)</code>.
*
* @param regex the pattern to match
* @param replacement the replacement string
* @return the modified string
* @throws NullPointerException if regex or replacement is null
* @throws PatternSyntaxException if regex is invalid
* @see #replaceFirst(String, String)
* @see Pattern#compile(String)
* @see Pattern#matcher(CharSequence)
* @see Matcher#replaceAll(String)
* @since 1.4
*/
public String replaceAll(String regex, String replacement)
{
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
/**
* Split this string around the matches of a regular expression. Each
* element of the returned array is the largest block of characters not
* terminated by the regular expression, in the order the matches are found.
*
* <p>The limit affects the length of the array. If it is positive, the
* array will contain at most n elements (n - 1 pattern matches). If
* negative, the array length is unlimited, but there can be trailing empty
* entries. if 0, the array length is unlimited, and trailing empty entries
* are discarded.
*
* <p>For example, splitting "boo:and:foo" yields:<br>
* <table border=0>
* <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
* <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr>
* <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr>
* <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
* <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
* <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
* <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr>
* </table>
*
* <p>This is shorthand for
* <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
*
* @param regex the pattern to match
* @param limit the limit threshold
* @return the array of split strings
* @throws NullPointerException if regex or replacement is null
* @throws PatternSyntaxException if regex is invalid
* @see Pattern#compile(String)
* @see Pattern#split(CharSequence, int)
* @since 1.4
*/
public String[] split(String regex, int limit)
{
return Pattern.compile(regex).split(this, limit);
}
/**
* Split this string around the matches of a regular expression. Each
* element of the returned array is the largest block of characters not
* terminated by the regular expression, in the order the matches are found.
* The array length is unlimited, and trailing empty entries are discarded,
* as though calling <code>split(regex, 0)</code>.
*
* @param regex the pattern to match
* @return the array of split strings
* @throws NullPointerException if regex or replacement is null
* @throws PatternSyntaxException if regex is invalid
* @see #split(String, int)
* @see Pattern#compile(String)
* @see Pattern#split(CharSequence, int)
* @since 1.4
*/
public String[] split(String regex)
{
return Pattern.compile(regex).split(this, 0);
}
/**
* Lowercases this String according to a particular locale. This uses
* Unicode's special case mappings, as applied to the given Locale, so the
@ -1088,7 +1227,6 @@ public final class String implements Serializable, Comparable, CharSequence
public native String intern ();
private native void init ();
private native void init (char[] chars, int offset, int count,
boolean dont_copy);
private native void init (byte[] chars, int hibyte, int offset, int count);

View File

@ -1,6 +1,6 @@
// natString.cc - Implementation of java.lang.String native methods.
/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
This file is part of libgcj.
@ -20,6 +20,7 @@ details. */
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/StringIndexOutOfBoundsException.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/StringBuffer.h>
#include <java/io/ByteArrayOutputStream.h>
#include <java/io/OutputStreamWriter.h>
#include <java/io/ByteArrayInputStream.h>
@ -102,7 +103,9 @@ hashChars (jchar* ptr, jint length)
jint
java::lang::String::hashCode()
{
return hashChars(JvGetStringChars(this), length());
if (cachedHashCode == 0)
cachedHashCode = hashChars(JvGetStringChars(this), length());
return cachedHashCode;
}
jstring*
@ -428,14 +431,6 @@ _Jv_NewStringLatin1(const char *bytes, jsize len)
return str;
}
void
java::lang::String::init ()
{
count = 0;
boffset = sizeof(java::lang::String);
data = this;
}
void
java::lang::String::init(jcharArray chars, jint offset, jint count,
jboolean dont_copy)
@ -552,11 +547,30 @@ java::lang::String::equals(jobject anObject)
return true;
}
jboolean
java::lang::String::contentEquals(java::lang::StringBuffer* buffer)
{
if (buffer == NULL)
throw new NullPointerException;
JvSynchronize sync(buffer);
if (count != buffer->count)
return false;
if (data == buffer->value)
return true; // Possible if shared.
jint i = count;
jchar *xptr = JvGetStringChars(this);
jchar *yptr = elements(buffer->value);
while (--i >= 0)
if (*xptr++ != *yptr++)
return false;
return true;
}
jchar
java::lang::String::charAt(jint i)
{
if (i < 0 || i >= count)
throw new java::lang::StringIndexOutOfBoundsException;
throw new java::lang::StringIndexOutOfBoundsException(i);
return JvGetStringChars(this)[i];
}