diff options
author | Tim Schumacher <timschumi@gmx.de> | 2021-10-22 01:38:29 +0200 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2021-10-21 23:57:32 -0700 |
commit | 89afd4d063b79ef2eba81d1bfc7857c388679c5e (patch) | |
tree | dd77ab520a316c376f3cd933c8f4b8b7c1eef08f /Userland/Libraries/LibC/wchar.cpp | |
parent | 552ae77f0ddc45b65d88af78f4fa080f4301a65b (diff) | |
download | serenity-89afd4d063b79ef2eba81d1bfc7857c388679c5e.zip |
LibC: Implement mbsnrtowcs
Diffstat (limited to 'Userland/Libraries/LibC/wchar.cpp')
-rw-r--r-- | Userland/Libraries/LibC/wchar.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/Userland/Libraries/LibC/wchar.cpp b/Userland/Libraries/LibC/wchar.cpp index e2cea8ea61..3188b54b5f 100644 --- a/Userland/Libraries/LibC/wchar.cpp +++ b/Userland/Libraries/LibC/wchar.cpp @@ -534,7 +534,7 @@ size_t wcsnrtombs(char* dest, const wchar_t** src, size_t nwc, size_t len, mbsta return written; } -size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) +size_t mbsnrtowcs(wchar_t* dst, const char** src, size_t nms, size_t len, mbstate_t* ps) { static mbstate_t _anonymous_state = {}; @@ -543,8 +543,21 @@ size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) size_t written = 0; while (written < len || !dst) { + // End of source buffer, no incomplete character. + // src continues to point to the next byte. + if (nms == 0) { + return written; + } + // Convert next multibyte to wchar. - size_t ret = mbrtowc(dst, *src, MB_LEN_MAX, ps); + size_t ret = mbrtowc(dst, *src, nms, ps); + + // Multibyte sequence is incomplete. + if (ret == -2ul) { + // Point just past the last processed byte. + *src += nms; + return written; + } // Multibyte sequence is invalid. if (ret == -1ul) { @@ -559,6 +572,7 @@ size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) } *src += ret; + nms -= ret; written += 1; if (dst) dst += 1; @@ -588,9 +602,14 @@ size_t wcsrtombs(char* dest, const wchar_t** src, size_t len, mbstate_t* ps) return wcsnrtombs(dest, src, SIZE_MAX, len, ps); } -size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*) +size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) { - dbgln("FIXME: Implement mbsnrtowcs()"); - TODO(); + static mbstate_t anonymous_state = {}; + + if (ps == nullptr) + ps = &anonymous_state; + + // SIZE_MAX is as close as we are going to get to "unlimited". + return mbsnrtowcs(dst, src, SIZE_MAX, len, ps); } } |