summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvichang <vichang@google.com>2021-04-30 14:03:05 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-04-30 14:03:05 +0000
commit4b95112d4e6042e46e5f53c38b120b39146f91f3 (patch)
tree0a0fa59f6064413c09b3dc968d84698dc4493d8f
parent0be863c8690ce683c6de7e3fe3c45ed46a5b02d0 (diff)
parente7e36af1b0d1478c92b3dde5f7440967c1ad829a (diff)
downloadicu-4b95112d4e6042e46e5f53c38b120b39146f91f3.tar.gz
Merge "Cherry-pick: ICU-21567 Avoid using regex in ULocale.getName()"
-rw-r--r--android_icu4j/src/main/java/android/icu/util/ULocale.java35
-rw-r--r--icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java35
2 files changed, 62 insertions, 8 deletions
diff --git a/android_icu4j/src/main/java/android/icu/util/ULocale.java b/android_icu4j/src/main/java/android/icu/util/ULocale.java
index 1339cb686..466b01a8b 100644
--- a/android_icu4j/src/main/java/android/icu/util/ULocale.java
+++ b/android_icu4j/src/main/java/android/icu/util/ULocale.java
@@ -29,7 +29,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
-import java.util.regex.Pattern;
import android.icu.impl.CacheBase;
import android.icu.impl.ICUData;
@@ -106,8 +105,6 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
// using serialver from jdk1.4.2_05
private static final long serialVersionUID = 3715177670352309217L;
- private static final Pattern UND_PATTERN = Pattern.compile("^und(?=$|[_-])", Pattern.CASE_INSENSITIVE);
-
private static CacheBase<String, String, Void> nameCache = new SoftCache<String, String, Void>() {
@Override
protected String createInstance(String tmpLocaleID, Void unused) {
@@ -1064,12 +1061,42 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
} else if ("root".equalsIgnoreCase(localeID)) {
tmpLocaleID = EMPTY_STRING;
} else {
- tmpLocaleID = UND_PATTERN.matcher(localeID).replaceFirst(EMPTY_STRING);
+ tmpLocaleID = stripLeadingUnd(localeID);
}
return nameCache.getInstance(tmpLocaleID, null /* unused */);
}
/**
+ * Strips out the leading "und" language code case-insensitively.
+ *
+ * @implNote Avoids creating new local non-primitive objects to reduce GC pressure.
+ */
+ private static String stripLeadingUnd(String localeID) {
+ int length = localeID.length();
+ if (length < 3) {
+ return localeID;
+ }
+
+ // If not starts with "und", return.
+ if (!localeID.regionMatches(/*ignoreCase=*/true, 0, "und", 0, /*len=*/3)) {
+ return localeID;
+ }
+
+ // The string is equals to "und" case-insensitively.
+ if (length == 3) {
+ return EMPTY_STRING;
+ }
+
+ // localeID must have a length >= 4
+ char separator = localeID.charAt(3);
+ if (separator == '-' || separator == '_') { // "und-*" or "und_*"
+ return localeID.substring(3);
+ }
+
+ return localeID;
+ }
+
+ /**
* Returns a string representation of this object.
* @return a string representation of the object.
*/
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java b/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
index 9faa3c444..7a6586ec4 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
@@ -28,7 +28,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
-import java.util.regex.Pattern;
import com.ibm.icu.impl.CacheBase;
import com.ibm.icu.impl.ICUData;
@@ -119,8 +118,6 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
// using serialver from jdk1.4.2_05
private static final long serialVersionUID = 3715177670352309217L;
- private static final Pattern UND_PATTERN = Pattern.compile("^und(?=$|[_-])", Pattern.CASE_INSENSITIVE);
-
private static CacheBase<String, String, Void> nameCache = new SoftCache<String, String, Void>() {
@Override
protected String createInstance(String tmpLocaleID, Void unused) {
@@ -1145,12 +1142,42 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
} else if ("root".equalsIgnoreCase(localeID)) {
tmpLocaleID = EMPTY_STRING;
} else {
- tmpLocaleID = UND_PATTERN.matcher(localeID).replaceFirst(EMPTY_STRING);
+ tmpLocaleID = stripLeadingUnd(localeID);
}
return nameCache.getInstance(tmpLocaleID, null /* unused */);
}
/**
+ * Strips out the leading "und" language code case-insensitively.
+ *
+ * @implNote Avoids creating new local non-primitive objects to reduce GC pressure.
+ */
+ private static String stripLeadingUnd(String localeID) {
+ int length = localeID.length();
+ if (length < 3) {
+ return localeID;
+ }
+
+ // If not starts with "und", return.
+ if (!localeID.regionMatches(/*ignoreCase=*/true, 0, "und", 0, /*len=*/3)) {
+ return localeID;
+ }
+
+ // The string is equals to "und" case-insensitively.
+ if (length == 3) {
+ return EMPTY_STRING;
+ }
+
+ // localeID must have a length >= 4
+ char separator = localeID.charAt(3);
+ if (separator == '-' || separator == '_') { // "und-*" or "und_*"
+ return localeID.substring(3);
+ }
+
+ return localeID;
+ }
+
+ /**
* Returns a string representation of this object.
* @return a string representation of the object.
* @stable ICU 2.8