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 \