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; \ struct uv_req_s signal_req; \
unsigned long pending_signum; 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 #ifndef F_OK
#define F_OK 0 #define F_OK 0
#endif #endif

View File

@ -31,7 +31,12 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
lib->handle = NULL; lib->handle = NULL;
lib->errmsg = 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()); 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); uv__handle_start(handle);
/* Convert name to UTF16. */ /* 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); pathw = (WCHAR*)uv__malloc(name_size);
if (!pathw) { if (!pathw) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
} }
if (!uv_utf8_to_utf16(path, pathw, if (!MultiByteToWideChar(CP_UTF8,
name_size / sizeof(WCHAR))) { 0,
path,
-1,
pathw,
name_size / sizeof(WCHAR))) {
return uv_translate_sys_error(GetLastError()); 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) { if (filenamew) {
/* Convert the filename to utf8. */ /* Convert the filename to utf8. */
size = uv_utf16_to_utf8(filenamew, size = WideCharToMultiByte(CP_UTF8,
sizew, 0,
NULL, filenamew,
0); sizew,
NULL,
0,
NULL,
NULL);
if (size) { if (size) {
filename = (char*)uv__malloc(size + 1); filename = (char*)uv__malloc(size + 1);
if (!filename) { if (!filename) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
} }
size = uv_utf16_to_utf8(filenamew, size = WideCharToMultiByte(CP_UTF8,
sizew, 0,
filename, filenamew,
size); sizew,
filename,
size,
NULL,
NULL);
if (size) { if (size) {
filename[size] = '\0'; filename[size] = '\0';
} else { } else {

View File

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

View File

@ -513,13 +513,18 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
} }
/* Convert name to UTF16. */ /* 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); handle->name = (WCHAR*)uv__malloc(nameSize);
if (!handle->name) { if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); 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(); err = GetLastError();
goto error; goto error;
} }
@ -627,13 +632,18 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
req->cb = cb; req->cb = cb;
/* Convert name to UTF16. */ /* 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); handle->name = (WCHAR*)uv__malloc(nameSize);
if (!handle->name) { if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); 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(); err = GetLastError();
goto error; 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 uv_exepath(char* buffer, size_t* size_ptr) {
int utf8_len, utf16_buffer_len, utf16_len; int utf8_len, utf16_buffer_len, utf16_len;
WCHAR* utf16_buffer; WCHAR* utf16_buffer;
@ -384,7 +360,7 @@ int uv_set_process_title(const char* title) {
uv__once_init(); uv__once_init();
/* Find out how big the buffer for the wide-char title must be */ /* 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) { if (!length) {
err = GetLastError(); err = GetLastError();
goto done; goto done;
@ -396,7 +372,7 @@ int uv_set_process_title(const char* title) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); 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) { if (!length) {
err = GetLastError(); err = GetLastError();
goto done; goto done;
@ -434,7 +410,7 @@ static int uv__get_process_title() {
} }
/* Find out what the size of the buffer is that we need */ /* 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) { if (!length) {
return -1; return -1;
} }
@ -446,7 +422,14 @@ static int uv__get_process_title() {
} }
/* Do utf16 -> utf8 conversion here */ /* 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); uv__free(process_title);
return -1; return -1;
} }
@ -1214,7 +1197,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
convert_buffer: convert_buffer:
/* Check how much space we need */ /* 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) { if (bufsize == 0) {
return uv_translate_sys_error(GetLastError()); return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) { } else if (bufsize > *size) {
@ -1223,7 +1206,14 @@ convert_buffer:
} }
/* Convert to UTF-8 */ /* 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) if (bufsize == 0)
return uv_translate_sys_error(GetLastError()); return uv_translate_sys_error(GetLastError());