am a53c58dd: Merge "Migrate IDNA2003 implementation to ICU4J."
* commit 'a53c58dded9dd21716f2e3c66a8991aba00772f5':
Migrate IDNA2003 implementation to ICU4J.
diff --git a/benchmarks/src/benchmarks/regression/IdnBenchmark.java b/benchmarks/src/benchmarks/regression/IdnBenchmark.java
new file mode 100644
index 0000000..9de5261
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/IdnBenchmark.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.SimpleBenchmark;
+
+import java.net.IDN;
+
+public class IdnBenchmark extends SimpleBenchmark {
+
+ public void timeToUnicode(int reps) {
+ for (int i = 0; i < reps; i++) {
+ IDN.toASCII("fass.de");
+ IDN.toASCII("faß.de");
+ IDN.toASCII("fäß.de");
+ IDN.toASCII("a\u200Cb");
+ IDN.toASCII("öbb.at");
+ IDN.toASCII("abc・日本.co.jp");
+ IDN.toASCII("日本.co.jp");
+ IDN.toASCII("x\u0327\u0301.de");
+ IDN.toASCII("σόλοσ.gr");
+ }
+ }
+
+ public void timeToAscii(int reps) {
+ for (int i = 0; i < reps; i++) {
+ IDN.toUnicode("xn--fss-qla.de");
+ IDN.toUnicode("xn--n00d.com");
+ IDN.toUnicode("xn--bb-eka.at");
+ IDN.toUnicode("xn--og-09a.de");
+ IDN.toUnicode("xn--53h.de");
+ IDN.toUnicode("xn--iny-zx5a.de");
+ IDN.toUnicode("xn--abc-rs4b422ycvb.co.jp");
+ IDN.toUnicode("xn--wgv71a.co.jp");
+ IDN.toUnicode("xn--x-xbb7i.de");
+ IDN.toUnicode("xn--wxaikc6b.gr");
+ IDN.toUnicode("xn--wxaikc6b.xn--gr-gtd9a1b0g.de");
+ }
+ }
+
+}
diff --git a/luni/src/main/java/java/net/IDN.java b/luni/src/main/java/java/net/IDN.java
index 4e60209..dd256c2 100644
--- a/luni/src/main/java/java/net/IDN.java
+++ b/luni/src/main/java/java/net/IDN.java
@@ -16,7 +16,7 @@
package java.net;
-import libcore.icu.NativeIDN;
+import com.ibm.icu.text.IDNA;
/**
* Converts internationalized domain names between Unicode and the ASCII Compatible Encoding
@@ -61,7 +61,11 @@
* @throws IllegalArgumentException if {@code input} does not conform to <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>
*/
public static String toASCII(String input, int flags) {
- return NativeIDN.toASCII(input, flags);
+ try {
+ return IDNA.convertIDNToASCII(input, flags).toString();
+ } catch (com.ibm.icu.text.StringPrepParseException e) {
+ throw new IllegalArgumentException("Invalid input to toASCII: " + input, e);
+ }
}
/**
@@ -91,7 +95,28 @@
* or {@code ALLOW_UNASSIGNED | USE_STD3_ASCII_RULES}
*/
public static String toUnicode(String input, int flags) {
- return NativeIDN.toUnicode(input, flags);
+ try {
+ // ICU only translates separators to ASCII for toASCII.
+ // Java expects the translation for toUnicode too.
+ return convertFullStop(IDNA.convertIDNToUnicode(input, flags)).toString();
+ } catch (com.ibm.icu.text.StringPrepParseException e) {
+ // The RI documentation explicitly states that if the conversion was unsuccessful
+ // the original string is returned.
+ return input;
+ }
+ }
+
+ private static boolean isLabelSeperator(char c) {
+ return (c == '\u3002' || c == '\uff0e' || c == '\uff61');
+ }
+
+ private static StringBuffer convertFullStop(StringBuffer input) {
+ for (int i = 0; i < input.length(); i++) {
+ if (isLabelSeperator(input.charAt(i))) {
+ input.setCharAt(i, '.');
+ }
+ }
+ return input;
}
/**
@@ -101,6 +126,6 @@
* @return the Unicode name
*/
public static String toUnicode(String input) {
- return NativeIDN.toUnicode(input, 0);
+ return toUnicode(input, 0);
}
}
diff --git a/luni/src/main/java/libcore/icu/NativeIDN.java b/luni/src/main/java/libcore/icu/NativeIDN.java
deleted file mode 100644
index db93379..0000000
--- a/luni/src/main/java/libcore/icu/NativeIDN.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.icu;
-
-public final class NativeIDN {
- public static String toASCII(String s, int flags) {
- return convert(s, flags, true);
- }
-
- public static String toUnicode(String s, int flags) {
- try {
- return convert(s, flags, false);
- } catch (IllegalArgumentException ex) {
- // The RI documentation explicitly states that this method can't fail.
- // ICU4C disagrees, as does the RI in practice.
- // The RI just returns the input string if it can't
- return s;
- }
- }
-
- private static String convert(String s, int flags, boolean toAscii) {
- if (s == null) {
- throw new NullPointerException("s == null");
- }
- return convertImpl(s, flags, toAscii);
- }
- private static native String convertImpl(String s, int flags, boolean toAscii);
-
- private NativeIDN() {}
-}
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index dc002c2..71ac8bf 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -59,7 +59,6 @@
REGISTER(register_libcore_icu_NativeCollation);
REGISTER(register_libcore_icu_NativeConverter);
REGISTER(register_libcore_icu_NativeDecimalFormat);
- REGISTER(register_libcore_icu_NativeIDN);
REGISTER(register_libcore_icu_TimeZoneNames);
REGISTER(register_libcore_io_AsynchronousCloseMonitor);
REGISTER(register_libcore_io_Memory);
diff --git a/luni/src/main/native/libcore_icu_NativeIDN.cpp b/luni/src/main/native/libcore_icu_NativeIDN.cpp
deleted file mode 100644
index 43f3ce5..0000000
--- a/luni/src/main/native/libcore_icu_NativeIDN.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "NativeIDN"
-
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "ScopedStringChars.h"
-#include "unicode/uidna.h"
-
-static bool isLabelSeparator(const UChar ch) {
- switch (ch) {
- case 0x3002: // ideographic full stop
- case 0xff0e: // fullwidth full stop
- case 0xff61: // halfwidth ideographic full stop
- return true;
- default:
- return false;
- }
-}
-
-static jstring NativeIDN_convertImpl(JNIEnv* env, jclass, jstring javaSrc, jint flags, jboolean toAscii) {
- ScopedStringChars src(env, javaSrc);
- if (src.get() == NULL) {
- return NULL;
- }
- UChar dst[256];
- UErrorCode status = U_ZERO_ERROR;
-
- // We're stuck implementing IDNA-2003 for now since that's what we specify.
- //
- // TODO: Change our spec to IDNA-2008 + UTS-46 compatibility processing if
- // it's safe enough.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- size_t resultLength = toAscii
- ? uidna_IDNToASCII(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status)
- : uidna_IDNToUnicode(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status);
-#pragma GCC diagnostic pop
-
- if (U_FAILURE(status)) {
- jniThrowException(env, "java/lang/IllegalArgumentException", u_errorName(status));
- return NULL;
- }
- if (!toAscii) {
- // ICU only translates separators to ASCII for toASCII.
- // Java expects the translation for toUnicode too.
- // We may as well do this here, while the string is still mutable.
- for (size_t i = 0; i < resultLength; ++i) {
- if (isLabelSeparator(dst[i])) {
- dst[i] = '.';
- }
- }
- }
- return env->NewString(&dst[0], resultLength);
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(NativeIDN, convertImpl, "(Ljava/lang/String;IZ)Ljava/lang/String;"),
-};
-void register_libcore_icu_NativeIDN(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/icu/NativeIDN", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 45bafbb..df918e4 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -39,7 +39,6 @@
libcore_icu_NativeCollation.cpp \
libcore_icu_NativeConverter.cpp \
libcore_icu_NativeDecimalFormat.cpp \
- libcore_icu_NativeIDN.cpp \
libcore_icu_TimeZoneNames.cpp \
libcore_io_AsynchronousCloseMonitor.cpp \
libcore_io_Memory.cpp \