mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 09:37:34 +00:00
LibC: Implement mbsnrtowcs
This commit is contained in:
parent
552ae77f0d
commit
89afd4d063
2 changed files with 63 additions and 5 deletions
|
@ -441,6 +441,45 @@ TEST_CASE(mbsrtowcs)
|
||||||
EXPECT_EQ(src, nullptr);
|
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)
|
TEST_CASE(wcslcpy)
|
||||||
{
|
{
|
||||||
auto buf = static_cast<wchar_t*>(malloc(8 * sizeof(wchar_t)));
|
auto buf = static_cast<wchar_t*>(malloc(8 * sizeof(wchar_t)));
|
||||||
|
|
|
@ -534,7 +534,7 @@ size_t wcsnrtombs(char* dest, const wchar_t** src, size_t nwc, size_t len, mbsta
|
||||||
return written;
|
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 = {};
|
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;
|
size_t written = 0;
|
||||||
while (written < len || !dst) {
|
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.
|
// 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.
|
// Multibyte sequence is invalid.
|
||||||
if (ret == -1ul) {
|
if (ret == -1ul) {
|
||||||
|
@ -559,6 +572,7 @@ size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps)
|
||||||
}
|
}
|
||||||
|
|
||||||
*src += ret;
|
*src += ret;
|
||||||
|
nms -= ret;
|
||||||
written += 1;
|
written += 1;
|
||||||
if (dst)
|
if (dst)
|
||||||
dst += 1;
|
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);
|
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()");
|
static mbstate_t anonymous_state = {};
|
||||||
TODO();
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue