//===-- Implementation of wcsxfrm ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "src/wchar/wcsxfrm.h" #include "hdr/types/size_t.h" #include "hdr/types/wchar_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { // TODO: Add support for locale-aware collation keys. // For now, this implements C/POSIX-like behavior: the transformed form is the // original wide string itself, so comparing transformed strings with wcscmp // matches code-point order. LLVM_LIBC_FUNCTION(size_t, wcsxfrm, (wchar_t *__restrict dest, const wchar_t *__restrict src, size_t n)) { // Number of source characters that may be written before the trailing NUL. const size_t write_limit = n > 0 ? n - 1 : 0; size_t i = 0; // Single pass over the prefix we might need to copy. // This avoids a full wcslen(src) pass for the common case where the source // fits in the destination buffer. for (; i < write_limit; ++i) { const wchar_t ch = src[i]; if (ch == L'\0') { dest[i] = L'\0'; return i; } dest[i] = ch; } // If n > 0, always NUL-terminate. This is correct both when truncating and // when write_limit == 0 (i.e. n == 1). if (n > 0) dest[write_limit] = L'\0'; // Finish counting the remaining source length if we truncated or if n == 0. while (src[i] != L'\0') ++i; return i; } } // namespace LIBC_NAMESPACE_DECL