1 //===-- Implementation for mbrtowc function ---------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/__support/wchar/mbrtowc.h" 10 #include "hdr/errno_macros.h" 11 #include "hdr/types/mbstate_t.h" 12 #include "hdr/types/size_t.h" 13 #include "hdr/types/wchar_t.h" 14 #include "src/__support/common.h" 15 #include "src/__support/error_or.h" 16 #include "src/__support/macros/config.h" 17 #include "src/__support/wchar/character_converter.h" 18 #include "src/__support/wchar/mbstate.h" 19 20 namespace LIBC_NAMESPACE_DECL { 21 namespace internal { 22 23 ErrorOr<size_t> mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, 24 size_t n, mbstate *__restrict ps) { 25 CharacterConverter char_conv(ps); 26 if (!char_conv.isValidState()) 27 return Error(EINVAL); 28 if (s == nullptr) 29 return 0; 30 size_t i = 0; 31 // Reading in bytes until we have a complete wc or error 32 for (; i < n && !char_conv.isFull(); ++i) { 33 int err = char_conv.push(static_cast<char8_t>(s[i])); 34 // Encoding error 35 if (err == EILSEQ) 36 return Error(err); 37 } 38 auto wc = char_conv.pop_utf32(); 39 if (wc.has_value()) { 40 *pwc = wc.value(); 41 // null terminator -> return 0 42 if (wc.value() == L'\0') 43 return 0; 44 return i; 45 } 46 // Incomplete but potentially valid 47 return -2; 48 } 49 50 } // namespace internal 51 52 } // namespace LIBC_NAMESPACE_DECL 53