22#include <winpr/config.h>
23#include <winpr/assert.h>
29#include <winpr/error.h>
30#include <winpr/print.h>
149#if !defined(WITH_WINPR_DEPRECATED)
153 MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
int cbMultiByte,
154 LPWSTR lpWideCharStr,
int cchWideChar)
156 return int_MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr,
199#if !defined(WITH_WINPR_DEPRECATED)
203 WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
int cchWideChar,
204 LPSTR lpMultiByteStr,
int cbMultiByte, LPCSTR lpDefaultChar,
205 LPBOOL lpUsedDefaultChar)
207 return int_WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr,
208 cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
225#if defined(WITH_WINPR_DEPRECATED)
226int ConvertToUnicode(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
int cbMultiByte,
227 LPWSTR* lpWideCharStr,
int cchWideChar)
230 BOOL allocate = FALSE;
238 if (cbMultiByte == -1)
240 size_t len = strnlen(lpMultiByteStr, INT_MAX);
243 cbMultiByte = (int)(len + 1);
246 if (cchWideChar == 0)
248 cchWideChar = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
251 else if (!(*lpWideCharStr))
259 *lpWideCharStr = (LPWSTR)calloc(cchWideChar + 1,
sizeof(WCHAR));
261 if (!(*lpWideCharStr))
268 status = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, *lpWideCharStr,
271 if (status != cchWideChar)
275 free(*lpWideCharStr);
276 *lpWideCharStr = NULL;
297#if defined(WITH_WINPR_DEPRECATED)
298int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
int cchWideChar,
299 LPSTR* lpMultiByteStr,
int cbMultiByte, LPCSTR lpDefaultChar,
300 LPBOOL lpUsedDefaultChar)
303 BOOL allocate = FALSE;
311 if (cchWideChar == -1)
312 cchWideChar = (int)(_wcslen(lpWideCharStr) + 1);
314 if (cbMultiByte == 0)
317 WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, NULL, NULL);
320 else if (!(*lpMultiByteStr))
328 *lpMultiByteStr = (LPSTR)calloc(1, cbMultiByte + 1);
330 if (!(*lpMultiByteStr))
337 status = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, *lpMultiByteStr,
338 cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
340 if ((status != cbMultiByte) && allocate)
345 if ((status <= 0) && allocate)
347 free(*lpMultiByteStr);
348 *lpMultiByteStr = NULL;
359const WCHAR* ByteSwapUnicode(WCHAR* wstr,
size_t length)
361 WINPR_ASSERT(wstr || (length == 0));
363 for (
size_t x = 0; x < length; x++)
364 wstr[x] = _byteswap_ushort(wstr[x]);
368SSIZE_T ConvertWCharToUtf8(
const WCHAR* wstr,
char* str,
size_t len)
377 const size_t wlen = _wcslen(wstr);
378 return ConvertWCharNToUtf8(wstr, wlen + 1, str, len);
381SSIZE_T ConvertWCharNToUtf8(
const WCHAR* wstr,
size_t wlen,
char* str,
size_t len)
383 BOOL isNullTerminated = FALSE;
388 size_t iwlen = _wcsnlen(wstr, wlen);
390 if ((len > INT32_MAX) || (wlen > INT32_MAX))
392 SetLastError(ERROR_INVALID_PARAMETER);
398 isNullTerminated = TRUE;
401 const int rc = WideCharToMultiByte(CP_UTF8, 0, wstr, (
int)iwlen, str, (
int)len, NULL, NULL);
402 if ((rc <= 0) || ((len > 0) && ((
size_t)rc > len)))
404 else if (!isNullTerminated)
406 if (str && ((
size_t)rc < len))
410 else if ((
size_t)rc == len)
412 if (str && (str[rc - 1] !=
'\0'))
418SSIZE_T ConvertMszWCharNToUtf8(
const WCHAR* wstr,
size_t wlen,
char* str,
size_t len)
425 if ((len > INT32_MAX) || (wlen > INT32_MAX))
427 SetLastError(ERROR_INVALID_PARAMETER);
431 const int iwlen = (int)len;
432 const int rc = WideCharToMultiByte(CP_UTF8, 0, wstr, (
int)wlen, str, iwlen, NULL, NULL);
433 if ((rc <= 0) || ((len > 0) && (rc > iwlen)))
439SSIZE_T ConvertUtf8ToWChar(
const char* str, WCHAR* wstr,
size_t wlen)
448 const size_t len = strlen(str);
449 return ConvertUtf8NToWChar(str, len + 1, wstr, wlen);
452SSIZE_T ConvertUtf8NToWChar(
const char* str,
size_t len, WCHAR* wstr,
size_t wlen)
454 size_t ilen = strnlen(str, len);
455 BOOL isNullTerminated = FALSE;
461 if ((len > INT32_MAX) || (wlen > INT32_MAX))
463 SetLastError(ERROR_INVALID_PARAMETER);
468 isNullTerminated = TRUE;
472 const int iwlen = (int)wlen;
473 const int rc = MultiByteToWideChar(CP_UTF8, 0, str, (
int)ilen, wstr, iwlen);
474 if ((rc <= 0) || ((wlen > 0) && (rc > iwlen)))
476 if (!isNullTerminated)
478 if (wstr && (rc < iwlen))
482 else if (rc == iwlen)
484 if (wstr && (wstr[rc - 1] !=
'\0'))
490SSIZE_T ConvertMszUtf8NToWChar(
const char* str,
size_t len, WCHAR* wstr,
size_t wlen)
497 if ((len > INT32_MAX) || (wlen > INT32_MAX))
499 SetLastError(ERROR_INVALID_PARAMETER);
503 const int iwlen = (int)wlen;
504 const int rc = MultiByteToWideChar(CP_UTF8, 0, str, (
int)len, wstr, iwlen);
505 if ((rc <= 0) || ((wlen > 0) && (rc > iwlen)))
511char* ConvertWCharToUtf8Alloc(
const WCHAR* wstr,
size_t* pUtfCharLength)
514 const SSIZE_T rc = ConvertWCharToUtf8(wstr, NULL, 0);
519 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
522 const SSIZE_T rc2 = ConvertWCharToUtf8(wstr, tmp, (
size_t)rc + 1ull);
528 WINPR_ASSERT(rc == rc2);
530 *pUtfCharLength = (size_t)rc2;
534char* ConvertWCharNToUtf8Alloc(
const WCHAR* wstr,
size_t wlen,
size_t* pUtfCharLength)
537 const SSIZE_T rc = ConvertWCharNToUtf8(wstr, wlen, NULL, 0);
543 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
546 const SSIZE_T rc2 = ConvertWCharNToUtf8(wstr, wlen, tmp, (
size_t)rc + 1ull);
552 WINPR_ASSERT(rc == rc2);
554 *pUtfCharLength = (size_t)rc2;
558char* ConvertMszWCharNToUtf8Alloc(
const WCHAR* wstr,
size_t wlen,
size_t* pUtfCharLength)
561 const SSIZE_T rc = ConvertMszWCharNToUtf8(wstr, wlen, NULL, 0);
567 tmp = calloc((
size_t)rc + 1ull,
sizeof(
char));
570 const SSIZE_T rc2 = ConvertMszWCharNToUtf8(wstr, wlen, tmp, (
size_t)rc + 1ull);
576 WINPR_ASSERT(rc == rc2);
578 *pUtfCharLength = (size_t)rc2;
582WCHAR* ConvertUtf8ToWCharAlloc(
const char* str,
size_t* pSize)
585 const SSIZE_T rc = ConvertUtf8ToWChar(str, NULL, 0);
590 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
593 const SSIZE_T rc2 = ConvertUtf8ToWChar(str, tmp, (
size_t)rc + 1ull);
599 WINPR_ASSERT(rc == rc2);
601 *pSize = (size_t)rc2;
605WCHAR* ConvertUtf8NToWCharAlloc(
const char* str,
size_t len,
size_t* pSize)
608 const SSIZE_T rc = ConvertUtf8NToWChar(str, len, NULL, 0);
613 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
616 const SSIZE_T rc2 = ConvertUtf8NToWChar(str, len, tmp, (
size_t)rc + 1ull);
622 WINPR_ASSERT(rc == rc2);
624 *pSize = (size_t)rc2;
628WCHAR* ConvertMszUtf8NToWCharAlloc(
const char* str,
size_t len,
size_t* pSize)
631 const SSIZE_T rc = ConvertMszUtf8NToWChar(str, len, NULL, 0);
636 tmp = calloc((
size_t)rc + 1ull,
sizeof(WCHAR));
639 const SSIZE_T rc2 = ConvertMszUtf8NToWChar(str, len, tmp, (
size_t)rc + 1ull);
645 WINPR_ASSERT(rc == rc2);
647 *pSize = (size_t)rc2;