diff options
Diffstat (limited to 'libjava/classpath/java/lang/String.java')
-rw-r--r-- | libjava/classpath/java/lang/String.java | 200 |
1 files changed, 159 insertions, 41 deletions
diff --git a/libjava/classpath/java/lang/String.java b/libjava/classpath/java/lang/String.java index ecb46881148..0b56accf708 100644 --- a/libjava/classpath/java/lang/String.java +++ b/libjava/classpath/java/lang/String.java @@ -1303,13 +1303,13 @@ public final class String break; if (i < 0) return this; - char[] newStr = (char[]) value.clone(); - newStr[x] = newChar; + char[] newStr = toCharArray(); + newStr[x - offset] = newChar; while (--i >= 0) if (value[++x] == oldChar) - newStr[x] = newChar; + newStr[x - offset] = newChar; // Package constructor avoids an array copy. - return new String(newStr, offset, count, true); + return new String(newStr, 0, count, true); } /** @@ -1431,27 +1431,18 @@ public final class String } /** - * Lowercases this String according to a particular locale. This uses - * Unicode's special case mappings, as applied to the given Locale, so the - * resulting string may be a different length. - * - * @param loc locale to use - * @return new lowercased String, or this if no characters were lowercased - * @throws NullPointerException if loc is null - * @see #toUpperCase(Locale) - * @since 1.1 + * Convert string to lower case for a Turkish locale that requires special + * handling of '\u0049' */ - public String toLowerCase(Locale loc) + private String toLowerCaseTurkish() { // First, see if the current string is already lower case. - boolean turkish = "tr".equals(loc.getLanguage()); int i = count; int x = offset - 1; while (--i >= 0) { char ch = value[++x]; - if ((turkish && ch == '\u0049') - || ch != Character.toLowerCase(ch)) + if ((ch == '\u0049') || ch != Character.toLowerCase(ch)) break; } if (i < 0) @@ -1459,17 +1450,75 @@ public final class String // Now we perform the conversion. Fortunately, there are no multi-character // lowercase expansions in Unicode 3.0.0. - char[] newStr = (char[]) value.clone(); + char[] newStr = new char[count]; + VMSystem.arraycopy(value, offset, newStr, 0, x - offset); do { char ch = value[x]; // Hardcoded special case. - newStr[x++] = (turkish && ch == '\u0049') ? '\u0131' - : Character.toLowerCase(ch); + if (ch != '\u0049') + { + newStr[x - offset] = Character.toLowerCase(ch); + } + else + { + newStr[x - offset] = '\u0131'; + } + x++; } while (--i >= 0); // Package constructor avoids an array copy. - return new String(newStr, offset, count, true); + return new String(newStr, 0, count, true); + } + + /** + * Lowercases this String according to a particular locale. This uses + * Unicode's special case mappings, as applied to the given Locale, so the + * resulting string may be a different length. + * + * @param loc locale to use + * @return new lowercased String, or this if no characters were lowercased + * @throws NullPointerException if loc is null + * @see #toUpperCase(Locale) + * @since 1.1 + */ + public String toLowerCase(Locale loc) + { + // First, see if the current string is already lower case. + + // Is loc turkish? String equality test is ok as Locale.language is interned + if ("tr" == loc.getLanguage()) + { + return toLowerCaseTurkish(); + } + else + { + int i = count; + int x = offset - 1; + while (--i >= 0) + { + char ch = value[++x]; + if (ch != Character.toLowerCase(ch)) + break; + } + if (i < 0) + return this; + + // Now we perform the conversion. Fortunately, there are no + // multi-character lowercase expansions in Unicode 3.0.0. + char[] newStr = new char[count]; + VMSystem.arraycopy(value, offset, newStr, 0, x - offset); + do + { + char ch = value[x]; + // Hardcoded special case. + newStr[x - offset] = Character.toLowerCase(ch); + x++; + } + while (--i >= 0); + // Package constructor avoids an array copy. + return new String(newStr, 0, count, true); + } } /** @@ -1487,21 +1536,12 @@ public final class String } /** - * Uppercases this String according to a particular locale. This uses - * Unicode's special case mappings, as applied to the given Locale, so the - * resulting string may be a different length. - * - * @param loc locale to use - * @return new uppercased String, or this if no characters were uppercased - * @throws NullPointerException if loc is null - * @see #toLowerCase(Locale) - * @since 1.1 + * Uppercase this string for a Turkish locale */ - public String toUpperCase(Locale loc) + private String toUpperCaseTurkish() { // First, see how many characters we have to grow by, as well as if the // current string is already upper case. - boolean turkish = "tr".equals(loc.getLanguage()); int expand = 0; boolean unchanged = true; int i = count; @@ -1511,7 +1551,7 @@ public final class String char ch = value[--x]; expand += upperCaseExpansion(ch); unchanged = (unchanged && expand == 0 - && ! (turkish && ch == '\u0069') + && ch != '\u0069' && ch == Character.toUpperCase(ch)); } if (unchanged) @@ -1521,16 +1561,24 @@ public final class String i = count; if (expand == 0) { - char[] newStr = (char[]) value.clone(); + char[] newStr = new char[count]; + VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset)); while (--i >= 0) { char ch = value[x]; // Hardcoded special case. - newStr[x++] = (turkish && ch == '\u0069') ? '\u0130' - : Character.toUpperCase(ch); + if (ch != '\u0069') + { + newStr[x - offset] = Character.toUpperCase(ch); + } + else + { + newStr[x - offset] = '\u0130'; + } + x++; } // Package constructor avoids an array copy. - return new String(newStr, offset, count, true); + return new String(newStr, 0, count, true); } // Expansion is necessary. @@ -1540,7 +1588,7 @@ public final class String { char ch = value[x++]; // Hardcoded special case. - if (turkish && ch == '\u0069') + if (ch == '\u0069') { newStr[j++] = '\u0130'; continue; @@ -1560,6 +1608,79 @@ public final class String } /** + * Uppercases this String according to a particular locale. This uses + * Unicode's special case mappings, as applied to the given Locale, so the + * resulting string may be a different length. + * + * @param loc locale to use + * @return new uppercased String, or this if no characters were uppercased + * @throws NullPointerException if loc is null + * @see #toLowerCase(Locale) + * @since 1.1 + */ + public String toUpperCase(Locale loc) + { + // First, see how many characters we have to grow by, as well as if the + // current string is already upper case. + + // Is loc turkish? String equality test is ok as Locale.language is interned + if ("tr" == loc.getLanguage()) + { + return toUpperCaseTurkish(); + } + else + { + int expand = 0; + boolean unchanged = true; + int i = count; + int x = i + offset; + while (--i >= 0) + { + char ch = value[--x]; + expand += upperCaseExpansion(ch); + unchanged = (unchanged && expand == 0 + && ch == Character.toUpperCase(ch)); + } + if (unchanged) + return this; + + // Now we perform the conversion. + i = count; + if (expand == 0) + { + char[] newStr = new char[count]; + VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset)); + while (--i >= 0) + { + char ch = value[x]; + newStr[x - offset] = Character.toUpperCase(ch); + x++; + } + // Package constructor avoids an array copy. + return new String(newStr, 0, count, true); + } + + // Expansion is necessary. + char[] newStr = new char[count + expand]; + int j = 0; + while (--i >= 0) + { + char ch = value[x++]; + expand = upperCaseExpansion(ch); + if (expand > 0) + { + int index = upperCaseIndex(ch); + while (expand-- >= 0) + newStr[j++] = upperExpand[index++]; + } + else + newStr[j++] = Character.toUpperCase(ch); + } + // Package constructor avoids an array copy. + return new String(newStr, 0, newStr.length, true); + } + } + /** * Uppercases this String. This uses Unicode's special case mappings, as * applied to the platform's default Locale, so the resulting string may * be a different length. @@ -1617,9 +1738,6 @@ public final class String */ public char[] toCharArray() { - if (count == value.length) - return (char[]) value.clone(); - char[] copy = new char[count]; VMSystem.arraycopy(value, offset, copy, 0, count); return copy; |