natString.cc (hashCode): Use cachedHashCode.
authorEric Blake <ebb9@email.byu.edu>
Sun, 30 Mar 2003 06:43:45 +0000 (06:43 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Sun, 30 Mar 2003 06:43:45 +0000 (06:43 +0000)
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

libjava/ChangeLog
libjava/java/lang/String.java
libjava/java/lang/natString.cc

index d93cdd3f5d2178566fc9ffafc6d0c9dbdb4cd298..ae9c68c0fce664e2dd1f57c9df9e24d1b8a79c48 100644 (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
index e10e7dd1814b1aeaff717425cf30d16f4c44bc91..29b9c45d44d7f08390eeebd3169d9b0096adebfa 100644 (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);
index 0d30a35af5170bf46c6f435addbbad750ba0844b..6514d816a029ca54edb896e309c35b993c20c4ac 100644 (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];
 }