#include "utils/utf8.hpp" #include #include #include namespace devilution { namespace { /** Truncates `str` to at most `len` at a code point boundary. */ string_view TruncateUtf8(string_view str, std::size_t len) { if (str.size() > len) { str.remove_suffix(str.size() - len); while (!str.empty() && !IsTrailUtf8CodeUnit(str.back())) str.remove_suffix(1); } return str; } } // namespace char32_t DecodeFirstUtf8CodePoint(string_view input, std::size_t *len) { uint32_t codepoint = 0; uint32_t state = UTF8_ACCEPT; for (std::size_t i = 0; i < input.size(); ++i) { state = utf8_decode_step(state, static_cast(input[i]), &codepoint); if (state == UTF8_ACCEPT) { *len = i + 1; return codepoint; } if (state == UTF8_REJECT) { *len = i + 1; return Utf8DecodeError; } } *len = input.size(); return Utf8DecodeError; } void CopyUtf8(char *dest, string_view source, std::size_t bytes) { source = TruncateUtf8(source, bytes - 1); std::memcpy(dest, source.data(), source.size()); dest[source.size()] = '\0'; } } // namespace devilution