| /** | |
| * 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. | |
| */ | |
| #include <locale.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <wchar.h> | |
| #include "mingw-wchar.h" | |
| size_t wcsrtombs ( | |
| char *__restrict__ mbs, | |
| const wchar_t **__restrict__ wcs, | |
| size_t count, | |
| mbstate_t *__restrict__ state | |
| ) { | |
| /* Buffer to store single converted character */ | |
| char mbc[2]; | |
| /* Total number of bytes stored in `mbs` */ | |
| size_t mbcConverted = 0; | |
| /* Next wide character to convert */ | |
| const wchar_t *wc = *wcs; | |
| /* Code page used by current locale */ | |
| unsigned cp = ___lc_codepage_func (); | |
| /* Maximum character length in `cp` */ | |
| int mb_cur_max = ___mb_cur_max_func (); | |
| while (1) { | |
| const size_t length = __mingw_wcrtomb_cp (mbc, *wc, state, cp, mb_cur_max); | |
| /* Conversion failed */ | |
| if (length == (size_t) -1) { | |
| if (mbs != NULL) { | |
| *wcs = wc; | |
| } | |
| return (size_t) -1; | |
| } | |
| /* POSIX and ISO C are silent about this */ | |
| if (mbs != NULL && count == 0) { | |
| return 0; | |
| } | |
| /* Terminating '\0' has been converted, stop */ | |
| if (mbc[0] == '\0') { | |
| if (mbs != NULL) { | |
| *mbs = '\0'; | |
| *wcs = NULL; | |
| } | |
| break; | |
| } | |
| /* Storing `mbc` in `mbs` would exceed `count` */ | |
| if (mbs != NULL && mbcConverted + length > count) { | |
| *wcs = wc; | |
| break; | |
| } | |
| /* Write `mbc` to `mbs` */ | |
| if (mbs != NULL) { | |
| memcpy (mbs, mbc, length); | |
| mbs += length; | |
| } | |
| mbcConverted += length; | |
| wc += 1; | |
| /* `count` bytes have been written to `mbs`, stop */ | |
| if (mbs != NULL && mbcConverted == count) { | |
| *wcs = wc; | |
| break; | |
| } | |
| } | |
| return mbcConverted; | |
| } | |
| size_t (__cdecl *__MINGW_IMP_SYMBOL (wcsrtombs)) (char *, const wchar_t **, size_t, mbstate_t *) = wcsrtombs; |