aboutsummaryrefslogtreecommitdiff
path: root/lib/idn_win32.c
diff options
context:
space:
mode:
authorPierre Joye <pierre.php@gmail.com>2010-12-28 19:55:00 +0100
committerDaniel Stenberg <daniel@haxx.se>2010-12-28 20:01:03 +0100
commit420eac5542ebf41a1812ae2250a0bc09517b999d (patch)
tree9d47adc81e0ee5d78f4bbfe9477c322cacca4057 /lib/idn_win32.c
parent15aeb94f3ff9012728aff1d21b63729af7433dd1 (diff)
IDN: use win32 API if told to
The functionality is provided in a new source file: lib/idn_win32.c
Diffstat (limited to 'lib/idn_win32.c')
-rw-r--r--lib/idn_win32.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/idn_win32.c b/lib/idn_win32.c
new file mode 100644
index 000000000..41fdd5dbb
--- /dev/null
+++ b/lib/idn_win32.c
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/***************************************************************************
+ * IDN Implementation using windows native APIs
+ * Pierre Joye <pierre@php.net>
+ ***************************************************************************/
+#if defined(WIN32) && defined(USE_WIN32_IDN)
+#include "windows.h"
+#include <stdio.h>
+#include <tchar.h>
+#define IDN_MAX_LENGTH 255
+
+static wchar_t *_curl_win32_UTF8_to_wchar(const char *str_utf8)
+{
+ wchar_t *str_w = NULL;
+
+ if (str_utf8) {
+ int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ str_utf8, -1, NULL, 0);
+ if (str_w_len) {
+ str_w = (wchar_t *) malloc(str_w_len * sizeof(wchar_t));
+ if (str_w) {
+ if (MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
+ str_w_len) == 0) {
+ free(str_w);
+ str_w = NULL;
+ }
+ }
+ }
+ }
+
+ return str_w;
+}
+
+static const char *_curl_win32_wchar_to_UTF8(const wchar_t *str_w)
+{
+ char *str_utf8 = NULL;
+
+ if (str_w) {
+ size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
+ 0, NULL, NULL);
+ DWORD err = GetLastError();
+ if (str_utf8_len) {
+ str_utf8 = (char *) malloc(str_utf8_len * sizeof(wchar_t));
+ if (str_w) {
+ if (WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
+ NULL, FALSE) == 0) {
+ DWORD err = GetLastError();
+ free((void *)str_utf8);
+ str_utf8 = NULL;
+ }
+ }
+ }
+ }
+
+ return str_utf8;
+}
+
+int curl_win32_idn_to_ascii(const char *in, char **out)
+{
+ wchar_t *in_w = _curl_win32_UTF8_to_wchar(in);
+ if (in_w) {
+ wchar_t punycode[IDN_MAX_LENGTH];
+ if (IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
+ wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
+ free(in_w);
+ return 0;
+ }
+ free(in_w);
+
+ *out = (char *)_curl_win32_wchar_to_UTF8(punycode);
+ if (!(*out)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8)
+{
+ if (in) {
+ WCHAR unicode[IDN_MAX_LENGTH];
+
+ if (IdnToUnicode(0, (wchar_t *)in, -1, unicode, IDN_MAX_LENGTH) == 0) {
+ wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
+ return 0;
+ }
+ else {
+ const char *out_utf8 = _curl_win32_wchar_to_UTF8(unicode);
+ if (!out_utf8) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+#else
+typedef int dummy; /* because ISO C forbids an empty translation unit! */
+#endif
+ /* WIN32 */