aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mbyte.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/mbyte.c')
-rw-r--r--src/nvim/mbyte.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index fae7635d34..e40beed0dd 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1356,45 +1356,41 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
# define CP_UTF8 65001 /* magic number from winnls.h */
#endif
-/// Reassigns `strw` to a new, allocated pointer to a UTF16 string.
-int utf8_to_utf16(const char *str, wchar_t **strw)
+/// Converts string from UTF-8 to UTF-16.
+///
+/// @param utf8 UTF-8 string.
+/// @param utf8len Length of `utf8`. May be -1 if `utf8` is NUL-terminated.
+/// @param utf16[out,allocated] NUL-terminated UTF-16 string, or NULL on error
+/// @return 0 on success, or libuv error code
+int utf8_to_utf16(const char *utf8, int utf8len, wchar_t **utf16)
FUNC_ATTR_NONNULL_ALL
{
- ssize_t wchar_len = 0;
-
- // Compute the length needed to store the converted widechar string.
- wchar_len = MultiByteToWideChar(CP_UTF8,
- 0, // dwFlags: must be 0 for utf8
- str, // lpMultiByteStr: string to convert
- -1, // -1 => process up to NUL
- NULL, // lpWideCharStr: converted string
- 0); // 0 => return length, don't convert
- if (wchar_len == 0) {
- return GetLastError();
- }
-
- ssize_t buf_sz = wchar_len * sizeof(wchar_t);
-
- if (buf_sz == 0) {
- *strw = NULL;
- return 0;
+ // Compute the length needed for the converted UTF-16 string.
+ int bufsize = MultiByteToWideChar(CP_UTF8,
+ 0, // dwFlags: must be 0 for UTF-8
+ utf8, // -1: process up to NUL
+ utf8len,
+ NULL,
+ 0); // 0: get length, don't convert
+ if (bufsize == 0) {
+ *utf16 = NULL;
+ return uv_translate_sys_error(GetLastError());
}
- char *buf = xmalloc(buf_sz);
- char *pos = buf;
+ // Allocate the destination buffer adding an extra byte for the terminating
+ // NULL. If `utf8len` is not -1 MultiByteToWideChar will not add it, so
+ // we do it ourselves always, just in case.
+ *utf16 = xmalloc(sizeof(wchar_t) * (bufsize + 1));
- int r = MultiByteToWideChar(CP_UTF8,
- 0,
- str,
- -1,
- (wchar_t *)pos,
- wchar_len);
- assert(r == wchar_len);
- if (r != wchar_len) {
- EMSG2("MultiByteToWideChar failed: %d", r);
+ // Convert to UTF-16.
+ bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
+ if (bufsize == 0) {
+ xfree(*utf16);
+ *utf16 = NULL;
+ return uv_translate_sys_error(GetLastError());
}
- *strw = (wchar_t *)pos;
+ (*utf16)[bufsize] = L'\0';
return 0;
}