summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java8
-rw-r--r--luni/src/main/java/java/lang/CaseMapper.java11
-rw-r--r--luni/src/test/java/libcore/java/lang/StringTest.java50
3 files changed, 49 insertions, 20 deletions
diff --git a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
index ba5b59e..cde257b 100644
--- a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
@@ -78,6 +78,14 @@ public class StringCaseMappingBenchmark extends SimpleBenchmark {
}
}
+ // toUpperCase for Greek is an extra-hard case that uses icu4c's Transliterator.
+ public void timeToUpperCase_el_GR(int reps) {
+ Locale el_GR = new Locale("el", "GR");
+ for (int i = 0; i < reps; ++i) {
+ s.value.toUpperCase(el_GR);
+ }
+ }
+
public void timeToLowerCase_US(int reps) {
for (int i = 0; i < reps; ++i) {
s.value.toUpperCase(Locale.US);
diff --git a/luni/src/main/java/java/lang/CaseMapper.java b/luni/src/main/java/java/lang/CaseMapper.java
index 5ec41f5..4e411d1 100644
--- a/luni/src/main/java/java/lang/CaseMapper.java
+++ b/luni/src/main/java/java/lang/CaseMapper.java
@@ -18,6 +18,7 @@ package java.lang;
import java.util.Locale;
import libcore.icu.ICU;
+import libcore.icu.Transliterator;
/**
* Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html.
@@ -45,6 +46,7 @@ class CaseMapper {
*/
public static String toLowerCase(Locale locale, String s, char[] value, int offset, int count) {
// Punt hard cases to ICU4C.
+ // Note that Greek isn't a particularly hard case for toLowerCase, only toUpperCase.
String languageCode = locale.getLanguage();
if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
return ICU.toLowerCase(s, locale.toString());
@@ -139,11 +141,20 @@ class CaseMapper {
return index;
}
+ private static final ThreadLocal<Transliterator> EL_UPPER = new ThreadLocal<Transliterator>() {
+ @Override protected Transliterator initialValue() {
+ return new Transliterator("el-Upper");
+ }
+ };
+
public static String toUpperCase(Locale locale, String s, char[] value, int offset, int count) {
String languageCode = locale.getLanguage();
if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
return ICU.toUpperCase(s, locale.toString());
}
+ if (languageCode.equals("el")) {
+ return EL_UPPER.get().transliterate(s);
+ }
char[] output = null;
int i = 0;
diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java
index 0c0e353..7df852e 100644
--- a/luni/src/test/java/libcore/java/lang/StringTest.java
+++ b/luni/src/test/java/libcore/java/lang/StringTest.java
@@ -174,7 +174,7 @@ public class StringTest extends TestCase {
/**
* Tests a widely assumed performance characteristic of String.substring():
- * that it reuses the original's backing array. Although behaviour should be
+ * that it reuses the original's backing array. Although behavior should be
* correct even if this test fails, many applications may suffer
* significant performance degradation.
*/
@@ -187,7 +187,7 @@ public class StringTest extends TestCase {
/**
* Tests a widely assumed performance characteristic of string's copy
* constructor: that it ensures the backing array is the same length as the
- * string. Although behaviour should be correct even if this test fails,
+ * string. Although behavior should be correct even if this test fails,
* many applications may suffer significant performance degradation.
*/
public void testStringCopiesAvoidHeapRetention() throws IllegalAccessException {
@@ -243,33 +243,43 @@ public class StringTest extends TestCase {
};
public void testCaseMapping_tr_TR() {
- Locale trTR = new Locale("tr", "TR");
- assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(trTR));
- assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(trTR));
- assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(trTR));
+ Locale tr_TR = new Locale("tr", "TR");
+ assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(tr_TR));
+ assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(tr_TR));
+ assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(tr_TR));
- assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(trTR));
- assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(trTR));
- assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_SMALL_I.toUpperCase(trTR));
+ assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(tr_TR));
+ assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(tr_TR));
+ assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_SMALL_I.toUpperCase(tr_TR));
- assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(trTR));
- assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_CAPITAL_I.toLowerCase(trTR));
+ assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(tr_TR));
+ assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_CAPITAL_I.toLowerCase(tr_TR));
}
public void testCaseMapping_en_US() {
- Locale enUs = new Locale("en", "US");
- assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_I.toUpperCase(enUs));
- assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(enUs));
- assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(enUs));
+ Locale en_US = new Locale("en", "US");
+ assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_I.toUpperCase(en_US));
+ assertEquals(LATIN_CAPITAL_I, LATIN_CAPITAL_I.toUpperCase(en_US));
+ assertEquals(LATIN_CAPITAL_I_WITH_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toUpperCase(en_US));
- assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(enUs));
- assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I.toLowerCase(enUs));
- assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(enUs));
+ assertEquals(LATIN_SMALL_I, LATIN_SMALL_I.toLowerCase(en_US));
+ assertEquals(LATIN_SMALL_I, LATIN_CAPITAL_I.toLowerCase(en_US));
+ assertEquals(LATIN_SMALL_DOTLESS_I, LATIN_SMALL_DOTLESS_I.toLowerCase(en_US));
- assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(enUs));
+ assertEquals(LATIN_CAPITAL_I, LATIN_SMALL_DOTLESS_I.toUpperCase(en_US));
// http://b/3325799: the RI fails this because it's using an obsolete version of the Unicode rules.
// Android correctly preserves canonical equivalence. (See the separate test for tr_TR.)
- assertEquals(LATIN_SMALL_I + COMBINING_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(enUs));
+ assertEquals(LATIN_SMALL_I + COMBINING_DOT_ABOVE, LATIN_CAPITAL_I_WITH_DOT_ABOVE.toLowerCase(en_US));
+ }
+
+ public void testCaseMapping_el() {
+ Locale el_GR = new Locale("el", "GR");
+ assertEquals("ΟΔΟΣ ΟΔΟΣ ΣΟ ΣΟ OΣ ΟΣ Σ ΕΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(el_GR));
+ assertEquals("ΟΔΟΣ ΟΔΟΣ ΣΟ ΣΟ OΣ ΟΣ Σ ΕΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(el_GR));
+ assertEquals("ΟΔΟΣ ΟΔΟΣ ΣΟ ΣΟ OΣ ΟΣ Σ ΕΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(el_GR));
+
+ Locale en_US = new Locale("en", "US");
+ assertEquals("ΟΔΌΣ ΟΔΌΣ ΣΟ ΣΟ OΣ ΟΣ Σ ἝΞ", "ΟΔΌΣ Οδός Σο ΣΟ oΣ ΟΣ σ ἕξ".toUpperCase(en_US));
}
public void testEqualsIgnoreCase_tr_TR() {