brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · 6abb836 Raw
67 lines · c
1//===-- Implementation for mbsnrtowcs 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS_H10#define LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS_H11 12#include "hdr/errno_macros.h"13#include "hdr/types/size_t.h"14#include "hdr/types/wchar_t.h"15#include "src/__support/common.h"16#include "src/__support/error_or.h"17#include "src/__support/macros/config.h"18#include "src/__support/macros/null_check.h"19#include "src/__support/wchar/character_converter.h"20#include "src/__support/wchar/mbstate.h"21#include "src/__support/wchar/string_converter.h"22 23namespace LIBC_NAMESPACE_DECL {24namespace internal {25 26LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,27                                              const char **__restrict src,28                                              size_t nmc, size_t len,29                                              mbstate *__restrict ps) {30  LIBC_CRASH_ON_NULLPTR(src);31  // Checking if mbstate is valid32  CharacterConverter char_conv(ps);33  if (!char_conv.isValidState())34    return Error(EINVAL);35 36  StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps,37                                    len, nmc);38  size_t dst_idx = 0;39  ErrorOr<char32_t> converted = str_conv.pop<char32_t>();40  while (converted.has_value()) {41    if (dst != nullptr)42      dst[dst_idx] = converted.value();43    // null terminator should not be counted in return value44    if (converted.value() == L'\0') {45      if (dst != nullptr)46        *src = nullptr;47      return dst_idx;48    }49    dst_idx++;50    converted = str_conv.pop<char32_t>();51  }52 53  if (converted.error() == -1) { // if we hit conversion limit54    if (dst != nullptr)55      *src += str_conv.getSourceIndex();56    return dst_idx;57  }58 59  return Error(converted.error());60}61 62} // namespace internal63 64} // namespace LIBC_NAMESPACE_DECL65 66#endif // LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS_H67