win: use native APIs for UTF conversions

This commit replaces uv_utf16_to_utf8() and uv_utf8_to_utf16()
with calls to the native Windows API equivalents.

Refs: https://github.com/libuv/libuv/pull/672#discussion_r49049746
PR-URL: https://github.com/libuv/libuv/pull/762
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
cjihrig 2016-03-14 11:35:46 -04:00
parent 5dc15cc269
commit f04d5fc3b9
6 changed files with 109 additions and 68 deletions

View File

@ -634,11 +634,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct uv_req_s signal_req; \
unsigned long pending_signum;
int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
size_t utf16Size);
#ifndef F_OK
#define F_OK 0
#endif

View File

@ -31,7 +31,12 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
lib->handle = NULL;
lib->errmsg = NULL;
if (!uv_utf8_to_utf16(filename, filename_w, ARRAY_SIZE(filename_w))) {
if (!MultiByteToWideChar(CP_UTF8,
0,
filename,
-1,
filename_w,
ARRAY_SIZE(filename_w))) {
return uv__dlerror(lib, GetLastError());
}

View File

@ -159,14 +159,20 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv__handle_start(handle);
/* Convert name to UTF16. */
name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR);
name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) *
sizeof(WCHAR);
pathw = (WCHAR*)uv__malloc(name_size);
if (!pathw) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
if (!uv_utf8_to_utf16(path, pathw,
name_size / sizeof(WCHAR))) {
if (!MultiByteToWideChar(CP_UTF8,
0,
path,
-1,
pathw,
name_size / sizeof(WCHAR))) {
return uv_translate_sys_error(GetLastError());
}
@ -455,20 +461,28 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
if (filenamew) {
/* Convert the filename to utf8. */
size = uv_utf16_to_utf8(filenamew,
sizew,
NULL,
0);
size = WideCharToMultiByte(CP_UTF8,
0,
filenamew,
sizew,
NULL,
0,
NULL,
NULL);
if (size) {
filename = (char*)uv__malloc(size + 1);
if (!filename) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
size = uv_utf16_to_utf8(filenamew,
sizew,
filename,
size);
size = WideCharToMultiByte(CP_UTF8,
0,
filenamew,
sizew,
filename,
size,
NULL,
NULL);
if (size) {
filename[size] = '\0';
} else {

View File

@ -126,7 +126,14 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
addrinfo_len += addrinfo_struct_len +
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
if (addrinfow_ptr->ai_canonname != NULL) {
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
name_len = WideCharToMultiByte(CP_UTF8,
0,
addrinfow_ptr->ai_canonname,
-1,
NULL,
0,
NULL,
NULL);
if (name_len == 0) {
req->retcode = uv_translate_sys_error(GetLastError());
goto complete;
@ -170,16 +177,24 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
/* convert canonical name to UTF-8 */
if (addrinfow_ptr->ai_canonname != NULL) {
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
-1,
NULL,
0);
name_len = WideCharToMultiByte(CP_UTF8,
0,
addrinfow_ptr->ai_canonname,
-1,
NULL,
0,
NULL,
NULL);
assert(name_len > 0);
assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
-1,
cur_ptr,
name_len);
name_len = WideCharToMultiByte(CP_UTF8,
0,
addrinfow_ptr->ai_canonname,
-1,
cur_ptr,
name_len,
NULL,
NULL);
assert(name_len > 0);
addrinfo_ptr->ai_canonname = cur_ptr;
cur_ptr += ALIGNED_SIZE(name_len);
@ -261,7 +276,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* calculate required memory size for all input values */
if (node != NULL) {
nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR));
nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, node, -1, NULL, 0) *
sizeof(WCHAR));
if (nodesize == 0) {
err = GetLastError();
goto error;
@ -269,7 +285,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
}
if (service != NULL) {
servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8,
0,
service,
-1,
NULL,
0) *
sizeof(WCHAR));
if (servicesize == 0) {
err = GetLastError();
@ -294,9 +315,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* the request. */
if (node != NULL) {
req->node = (WCHAR*)alloc_ptr;
if (uv_utf8_to_utf16(node,
(WCHAR*) alloc_ptr,
nodesize / sizeof(WCHAR)) == 0) {
if (MultiByteToWideChar(CP_UTF8,
0,
node,
-1,
(WCHAR*) alloc_ptr,
nodesize / sizeof(WCHAR)) == 0) {
err = GetLastError();
goto error;
}
@ -309,9 +333,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* in the req. */
if (service != NULL) {
req->service = (WCHAR*)alloc_ptr;
if (uv_utf8_to_utf16(service,
(WCHAR*) alloc_ptr,
servicesize / sizeof(WCHAR)) == 0) {
if (MultiByteToWideChar(CP_UTF8,
0,
service,
-1,
(WCHAR*) alloc_ptr,
servicesize / sizeof(WCHAR)) == 0) {
err = GetLastError();
goto error;
}

View File

@ -513,13 +513,18 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
/* Convert name to UTF16. */
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
handle->name = (WCHAR*)uv__malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
if (!MultiByteToWideChar(CP_UTF8,
0,
name,
-1,
handle->name,
nameSize / sizeof(WCHAR))) {
err = GetLastError();
goto error;
}
@ -627,13 +632,18 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
req->cb = cb;
/* Convert name to UTF16. */
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
handle->name = (WCHAR*)uv__malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
if (!MultiByteToWideChar(CP_UTF8,
0,
name,
-1,
handle->name,
nameSize / sizeof(WCHAR))) {
err = GetLastError();
goto error;
}

View File

@ -87,30 +87,6 @@ void uv__util_init() {
}
int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size) {
return WideCharToMultiByte(CP_UTF8,
0,
utf16Buffer,
utf16Size,
utf8Buffer,
utf8Size,
NULL,
NULL);
}
int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
size_t utf16Size) {
return MultiByteToWideChar(CP_UTF8,
0,
utf8Buffer,
-1,
utf16Buffer,
utf16Size);
}
int uv_exepath(char* buffer, size_t* size_ptr) {
int utf8_len, utf16_buffer_len, utf16_len;
WCHAR* utf16_buffer;
@ -384,7 +360,7 @@ int uv_set_process_title(const char* title) {
uv__once_init();
/* Find out how big the buffer for the wide-char title must be */
length = uv_utf8_to_utf16(title, NULL, 0);
length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
if (!length) {
err = GetLastError();
goto done;
@ -396,7 +372,7 @@ int uv_set_process_title(const char* title) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
length = uv_utf8_to_utf16(title, title_w, length);
length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length);
if (!length) {
err = GetLastError();
goto done;
@ -434,7 +410,7 @@ static int uv__get_process_title() {
}
/* Find out what the size of the buffer is that we need */
length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL);
if (!length) {
return -1;
}
@ -446,7 +422,14 @@ static int uv__get_process_title() {
}
/* Do utf16 -> utf8 conversion here */
if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
if (!WideCharToMultiByte(CP_UTF8,
0,
title_w,
-1,
process_title,
length,
NULL,
NULL)) {
uv__free(process_title);
return -1;
}
@ -1214,7 +1197,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
convert_buffer:
/* Check how much space we need */
bufsize = uv_utf16_to_utf8(path, -1, NULL, 0);
bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
if (bufsize == 0) {
return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) {
@ -1223,7 +1206,14 @@ convert_buffer:
}
/* Convert to UTF-8 */
bufsize = uv_utf16_to_utf8(path, -1, buffer, *size);
bufsize = WideCharToMultiByte(CP_UTF8,
0,
path,
-1,
buffer,
*size,
NULL,
NULL);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());