Skip to content

Commit 552ae77

Browse files
timschumibgianfo
authored andcommitted
LibC: Implement wcsnrtombs
1 parent e618602 commit 552ae77

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

Tests/LibC/TestWchar.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,32 @@ TEST_CASE(wcsrtombs)
364364
EXPECT_EQ(src, nullptr);
365365
}
366366

367+
TEST_CASE(wcsnrtombs)
368+
{
369+
mbstate_t state = {};
370+
const wchar_t good_chars[] = { L'\U0001F41E', L'\U0001F41E', L'\0' };
371+
const wchar_t* src;
372+
size_t ret = 0;
373+
374+
// Convert nothing.
375+
src = good_chars;
376+
ret = wcsnrtombs(nullptr, &src, 0, 0, &state);
377+
EXPECT_EQ(ret, 0ul);
378+
EXPECT_EQ(src, good_chars);
379+
380+
// Convert one wide char.
381+
src = good_chars;
382+
ret = wcsnrtombs(nullptr, &src, 1, 0, &state);
383+
EXPECT_EQ(ret, 4ul);
384+
EXPECT_EQ(src, good_chars + 1);
385+
386+
// Encounter a null character.
387+
src = good_chars;
388+
ret = wcsnrtombs(nullptr, &src, 4, 0, &state);
389+
EXPECT_EQ(ret, 8ul);
390+
EXPECT_EQ(src, nullptr);
391+
}
392+
367393
TEST_CASE(mbsrtowcs)
368394
{
369395
mbstate_t state = {};

Userland/Libraries/LibC/wchar.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,15 +488,16 @@ int wcwidth(wchar_t wc)
488488
return 1;
489489
}
490490

491-
size_t wcsrtombs(char* dest, const wchar_t** src, size_t len, mbstate_t* ps)
491+
size_t wcsnrtombs(char* dest, const wchar_t** src, size_t nwc, size_t len, mbstate_t* ps)
492492
{
493493
static mbstate_t _anonymous_state = {};
494494

495495
if (ps == nullptr)
496496
ps = &_anonymous_state;
497497

498498
size_t written = 0;
499-
while (true) {
499+
size_t read = 0;
500+
while (read < nwc) {
500501
size_t ret = 0;
501502
char buf[MB_LEN_MAX];
502503

@@ -526,8 +527,11 @@ size_t wcsrtombs(char* dest, const wchar_t** src, size_t len, mbstate_t* ps)
526527
}
527528

528529
*src += 1;
530+
read += 1;
529531
written += ret;
530532
}
533+
534+
return written;
531535
}
532536

533537
size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps)
@@ -573,10 +577,15 @@ int wmemcmp(const wchar_t* s1, const wchar_t* s2, size_t n)
573577
return 0;
574578
}
575579

576-
size_t wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*)
580+
size_t wcsrtombs(char* dest, const wchar_t** src, size_t len, mbstate_t* ps)
577581
{
578-
dbgln("FIXME: Implement wcsnrtombs()");
579-
TODO();
582+
static mbstate_t anonymous_state = {};
583+
584+
if (ps == nullptr)
585+
ps = &anonymous_state;
586+
587+
// SIZE_MAX is as close as we are going to get to "unlimited".
588+
return wcsnrtombs(dest, src, SIZE_MAX, len, ps);
580589
}
581590

582591
size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*)

0 commit comments

Comments
 (0)