1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:37:34 +00:00

LibC: Implement mbsnrtowcs

This commit is contained in:
Tim Schumacher 2021-10-22 01:38:29 +02:00 committed by Brian Gianforcaro
parent 552ae77f0d
commit 89afd4d063
2 changed files with 63 additions and 5 deletions

View file

@ -441,6 +441,45 @@ TEST_CASE(mbsrtowcs)
EXPECT_EQ(src, nullptr);
}
TEST_CASE(mbsnrtowcs)
{
mbstate_t state = {};
const char good_chars[] = "\xf0\x9f\x90\x9e\xf0\x9f\x90\x9e";
const char* src;
size_t ret = 0;
// Convert nothing.
src = good_chars;
ret = mbsnrtowcs(nullptr, &src, 0, 0, &state);
EXPECT_EQ(ret, 0ul);
EXPECT_EQ(src, good_chars);
// Convert one full wide character.
src = good_chars;
ret = mbsnrtowcs(nullptr, &src, 4, 0, &state);
EXPECT_EQ(ret, 1ul);
EXPECT_EQ(src, good_chars + 4);
// Encounter a null character.
src = good_chars;
ret = mbsnrtowcs(nullptr, &src, 10, 0, &state);
EXPECT_EQ(ret, 2ul);
EXPECT_EQ(src, nullptr);
// Convert an incomplete character.
// Make sure that we point past the last processed byte.
src = good_chars;
ret = mbsnrtowcs(nullptr, &src, 6, 0, &state);
EXPECT_EQ(ret, 1ul);
EXPECT_EQ(src, good_chars + 6);
EXPECT_EQ(mbsinit(&state), 0);
// Finish converting the incomplete character.
ret = mbsnrtowcs(nullptr, &src, 2, 0, &state);
EXPECT_EQ(ret, 1ul);
EXPECT_EQ(src, good_chars + 8);
}
TEST_CASE(wcslcpy)
{
auto buf = static_cast<wchar_t*>(malloc(8 * sizeof(wchar_t)));

View file

@ -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);
}
}