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:
parent
5dc15cc269
commit
f04d5fc3b9
@ -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
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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());
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user