Files
Gleb Mazovetskiy 4fa3732526 Add missing <cstdint> includes
Done with the following script:

```ruby
Dir["Source/**/*.{h,c,cc,cpp,hpp}"].each do |path|
  v = File.read(path)
  next if !v.include?("uint32_t") || v.include?("cstdint")

  lines = v.lines
  line_num = if lines[2].start_with?(" *")
    lines.index { |l| l.start_with?(" */") } + 3
  else
    3
  end

  lines.insert(line_num, "#include <cstdint>\n")

  File.write(path, lines.join(""))
end
```

then fixed-up manually
2023-05-10 13:50:12 +01:00

82 lines
2.1 KiB
C++

#include "utils/utf8.hpp"
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <hoehrmann_utf8.h>
#include "utils/attributes.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) {
std::size_t truncIndex = len;
while (truncIndex > 0 && IsTrailUtf8CodeUnit(str[truncIndex]))
truncIndex--;
str.remove_suffix(str.size() - truncIndex);
}
return str;
}
} // namespace
char32_t DecodeFirstUtf8CodePoint(string_view input, std::size_t *len)
{
uint32_t codepoint = 0;
uint8_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';
}
void AppendUtf8(char32_t codepoint, std::string &out)
{
if (codepoint <= 0x7F) {
out += static_cast<char>(codepoint);
return;
}
char buf[4];
if (codepoint <= 0x7FF) {
buf[0] = static_cast<char>(0xC0 | (codepoint >> 6 & 0x3F));
buf[1] = static_cast<char>(0x80 | (codepoint & 0x3F));
out.append(buf, 2);
} else if (codepoint <= 0xFFFF) {
buf[0] = static_cast<char>(0xE0 | (codepoint >> 12 & 0x3F));
buf[1] = static_cast<char>(0x80 | (codepoint >> 6 & 0x3F));
buf[2] = static_cast<char>(0x80 | (codepoint & 0x3F));
out.append(buf, 3);
} else {
buf[0] = static_cast<char>(0xF0 | (codepoint >> 18 & 0x3F));
buf[1] = static_cast<char>(0x80 | (codepoint >> 12 & 0x3F));
buf[2] = static_cast<char>(0x80 | (codepoint >> 6 & 0x3F));
buf[3] = static_cast<char>(0x80 | (codepoint & 0x3F));
out.append(buf, 4);
}
}
} // namespace devilution