Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libc/src/__support/wchar/character_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "hdr/types/char32_t.h"
#include "hdr/types/char8_t.h"
#include "hdr/types/size_t.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/wchar/mbstate.h"
Expand Down Expand Up @@ -39,6 +40,12 @@ class CharacterConverter {

ErrorOr<char8_t> pop_utf8();
ErrorOr<char32_t> pop_utf32();
template <typename CharType> ErrorOr<CharType> pop() {
if constexpr (cpp::is_same_v<CharType, char8_t>)
return pop_utf8();
else
return pop_utf32();
}
};

} // namespace internal
Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/wchar/mbsnrtowcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps,
len, nmc);
size_t dst_idx = 0;
ErrorOr<char32_t> converted = str_conv.popUTF32();
ErrorOr<char32_t> converted = str_conv.pop<char32_t>();
while (converted.has_value()) {
if (dst != nullptr)
dst[dst_idx] = converted.value();
Expand All @@ -47,7 +47,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
return dst_idx;
}
dst_idx++;
converted = str_conv.popUTF32();
converted = str_conv.pop<char32_t>();
}

if (converted.error() == -1) { // if we hit conversion limit
Expand Down
42 changes: 11 additions & 31 deletions libc/src/__support/wchar/string_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "hdr/types/char32_t.h"
#include "hdr/types/char8_t.h"
#include "hdr/types/size_t.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/wchar/character_converter.h"
Expand Down Expand Up @@ -53,9 +54,7 @@ template <typename T> class StringConverter {
size_t srclen = SIZE_MAX)
: cr(ps), src(s), src_len(srclen), src_idx(0), num_to_write(dstlen) {}

// TODO: following functions are almost identical
// look into templating CharacterConverter pop functions
ErrorOr<char32_t> popUTF32() {
template <typename CharType> ErrorOr<CharType> pop() {
if (num_to_write == 0)
return Error(-1);

Expand All @@ -64,42 +63,23 @@ template <typename T> class StringConverter {
if (!src_elements_read.has_value())
return Error(src_elements_read.error());

if (cr.sizeAsUTF32() > num_to_write) {
cr.clear();
return Error(-1);
}

src_idx += src_elements_read.value();
}

auto out = cr.pop_utf32();
if (out.has_value() && out.value() == L'\0')
src_len = src_idx;

num_to_write--;

return out;
}

ErrorOr<char8_t> popUTF8() {
if (num_to_write == 0)
return Error(-1);

if (cr.isEmpty() || src_idx == 0) {
auto src_elements_read = pushFullCharacter();
if (!src_elements_read.has_value())
return Error(src_elements_read.error());
size_t size;
if constexpr (cpp::is_same_v<CharType, char8_t>)
size = cr.sizeAsUTF8();
else
size = cr.sizeAsUTF32();

if (cr.sizeAsUTF8() > num_to_write) {
if (size > num_to_write) {
cr.clear();
return Error(-1);
}

src_idx += src_elements_read.value();
}

auto out = cr.pop_utf8();
if (out.has_value() && out.value() == '\0')
ErrorOr<CharType> out = cr.pop<CharType>();
// if out isn't null terminator or an error
if (out.has_value() && out.value() == 0)
src_len = src_idx;

num_to_write--;
Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/wchar/wcsnrtombs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
reinterpret_cast<const char32_t *>(*ptr_to_src), ps, dest_len,
num_src_widechars);
size_t dst_idx = 0;
ErrorOr<char8_t> converted = str_conv.popUTF8();
ErrorOr<char8_t> converted = str_conv.pop<char8_t>();
while (converted.has_value()) {
if (dest != nullptr)
dest[dst_idx] = converted.value();
Expand All @@ -51,7 +51,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
}

dst_idx++;
converted = str_conv.popUTF8();
converted = str_conv.pop<char8_t>();
}

if (dest != nullptr)
Expand Down
Loading
Loading