You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.1 KiB
51 lines
1.1 KiB
#include "utils/utf8.hpp" |
|
|
|
#include <cstddef> |
|
#include <cstring> |
|
|
|
#include <hoehrmann_utf8.h> |
|
|
|
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<uint8_t>(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
|
|
|