|
13 | 13 | #include "src/__support/common.h" |
14 | 14 | #include "src/__support/libc_errno.h" |
15 | 15 | #include "src/__support/macros/config.h" |
| 16 | +#include "src/__support/wchar/mbsnrtowcs.h" |
16 | 17 | #include "src/__support/wchar/mbstate.h" |
17 | | -#include "src/__support/wchar/string_converter.h" |
18 | 18 |
|
19 | 19 | namespace LIBC_NAMESPACE_DECL { |
20 | 20 |
|
21 | 21 | LLVM_LIBC_FUNCTION(size_t, mbsrtowcs, |
22 | 22 | (wchar_t *__restrict dst, const char **__restrict src, |
23 | 23 | size_t len, mbstate_t *__restrict ps)) { |
24 | 24 | static internal::mbstate internal_mbstate; |
25 | | - internal::StringConverter<char8_t> str_conv( |
26 | | - reinterpret_cast<const char8_t *>(*src), |
| 25 | + // If destination is null, ignore len |
| 26 | + len = dst == nullptr ? SIZE_MAX : len; |
| 27 | + auto ret = internal::mbsnrtowcs( |
| 28 | + dst, src, SIZE_MAX, len, |
27 | 29 | ps == nullptr ? &internal_mbstate |
28 | | - : reinterpret_cast<internal::mbstate *>(ps), |
29 | | - len); |
30 | | - |
31 | | - int dst_idx = 0; |
32 | | - ErrorOr<char32_t> converted = str_conv.popUTF32(); |
33 | | - while (converted.has_value()) { |
34 | | - dst[dst_idx] = converted.value(); |
35 | | - // null terminator should not be counted in return value |
36 | | - if (converted.value() == L'\0') { |
37 | | - src = nullptr; |
38 | | - return dst_idx; |
39 | | - } |
40 | | - dst_idx++; |
41 | | - converted = str_conv.popUTF32(); |
| 30 | + : reinterpret_cast<internal::mbstate *>(ps)); |
| 31 | + if (!ret.has_value()) { |
| 32 | + // Encoding failure |
| 33 | + libc_errno = ret.error(); |
| 34 | + return -1; |
42 | 35 | } |
43 | | - |
44 | | - *src += str_conv.getSourceIndex(); |
45 | | - if (converted.error() == -1) // if we hit conversion limit |
46 | | - return dst_idx; |
47 | | - |
48 | | - libc_errno = converted.error(); |
49 | | - return -1; |
| 36 | + return ret.value(); |
50 | 37 | } |
51 | 38 |
|
52 | 39 | } // namespace LIBC_NAMESPACE_DECL |
0 commit comments