/** * This file has no copyright assigned and is placed in the Public Domain. * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include "mb_wc_common.h" #include #include #include #include #include __attribute__((noinline)) static int __MINGW_ATTRIB_NONNULL(1) __wcrtomb_cp (char *dst, wchar_t wc, const unsigned int cp, const unsigned int mb_max) { if (cp == 0) { if (wc > 255) { errno = EILSEQ; return -1; } *dst = (char) wc; return 1; } else { int invalid_char = 0; int size = WideCharToMultiByte (cp, 0 /* Is this correct flag? */, &wc, 1, dst, mb_max, NULL, &invalid_char); if (size == 0 || invalid_char) { errno = EILSEQ; return -1; } return size; } } size_t wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps)) { char byte_bucket [MB_LEN_MAX]; char* tmp_dst = dst ? dst : &byte_bucket[0]; return (size_t)__wcrtomb_cp (tmp_dst, wc, ___lc_codepage_func(), MB_CUR_MAX); } size_t wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t * __UNUSED_PARAM (ps)) { int ret = 0; size_t n = 0; const unsigned int cp = ___lc_codepage_func(); const unsigned int mb_max = MB_CUR_MAX; const wchar_t *pwc = *src; if (src == NULL || *src == NULL) /* undefined behavior */ return 0; if (dst != NULL) { while (n < len) { if ((ret = __wcrtomb_cp (dst, *pwc, cp, mb_max)) <= 0) return (size_t) -1; n += ret; dst += ret; if (*(dst - 1) == '\0') { *src = (wchar_t *) NULL; return (n - 1); } pwc++; } *src = pwc; } else { char byte_bucket [MB_LEN_MAX]; while (1) { if ((ret = __wcrtomb_cp (&byte_bucket[0], *pwc, cp, mb_max)) <= 0) return (size_t) -1; n += ret; if (byte_bucket [ret - 1] == '\0') return (n - 1); pwc++; } } return n; }