Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions src/platform/linux/uhid_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <numbers>
#include <optional>
#include <set>
#include <span>
#include <sstream>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -682,24 +683,25 @@ namespace lvh::detail {
return static_cast<int>(std::lround(radians * tablet_resolution));
}

std::vector<std::uint32_t> decode_utf8(const std::string &text) {
std::vector<std::uint32_t> decode_utf8(std::string_view text) {
std::vector<std::uint32_t> codepoints;
const auto bytes = std::as_bytes(std::span {text.data(), text.size()});
for (std::size_t i = 0; i < text.size();) {
const auto first = static_cast<unsigned char>(text[i]);
const auto first = bytes[i];
std::uint32_t codepoint = 0;
std::size_t length = 0;

if (first <= 0x7F) {
codepoint = first;
if (const auto first_value = std::to_integer<std::uint32_t>(first); first_value <= 0x7FU) {
codepoint = first_value;
length = 1;
} else if ((first & 0xE0U) == 0xC0U) {
codepoint = first & 0x1FU;
} else if ((first & std::byte {0xE0}) == std::byte {0xC0}) {
codepoint = std::to_integer<std::uint32_t>(first & std::byte {0x1F});
length = 2;
} else if ((first & 0xF0U) == 0xE0U) {
codepoint = first & 0x0FU;
} else if ((first & std::byte {0xF0}) == std::byte {0xE0}) {
codepoint = std::to_integer<std::uint32_t>(first & std::byte {0x0F});
length = 3;
} else if ((first & 0xF8U) == 0xF0U) {
codepoint = first & 0x07U;
} else if ((first & std::byte {0xF8}) == std::byte {0xF0}) {
codepoint = std::to_integer<std::uint32_t>(first & std::byte {0x07});
length = 4;
} else {
++i;
Expand All @@ -712,12 +714,12 @@ namespace lvh::detail {

bool valid = true;
for (std::size_t offset = 1; offset < length; ++offset) {
const auto next = static_cast<unsigned char>(text[i + offset]);
if ((next & 0xC0U) != 0x80U) {
const auto next = bytes[i + offset];
if ((next & std::byte {0xC0}) != std::byte {0x80}) {
valid = false;
break;
}
codepoint = (codepoint << 6U) | (next & 0x3FU);
codepoint = (codepoint << 6U) | std::to_integer<std::uint32_t>(next & std::byte {0x3F});
}

if (valid) {
Expand Down
13 changes: 7 additions & 6 deletions tests/fixtures/linux_backend_test_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <numbers>
#include <optional>
#include <set>
#include <span>
#include <sstream>
#include <string>
#include <system_error>
Expand Down Expand Up @@ -600,10 +601,10 @@ namespace lvh::detail::test {
}

bool write_uhid_event(int fd, const uhid_event &event) {
auto *data = reinterpret_cast<const char *>(&event);
const auto data = std::as_bytes(std::span {&event, 1U});
std::size_t written = 0;
while (written < sizeof(event)) {
const auto result = ::write(fd, data + written, sizeof(event) - written);
while (written < data.size()) {
const auto result = ::write(fd, data.data() + written, data.size() - written);
if (result <= 0) {
return false;
}
Expand All @@ -620,10 +621,10 @@ namespace lvh::detail::test {
return false;
}

auto *data = reinterpret_cast<char *>(&event);
const auto data = std::as_writable_bytes(std::span {&event, 1U});
std::size_t read_size = 0;
while (read_size < sizeof(event)) {
const auto result = ::read(fd, data + read_size, sizeof(event) - read_size);
while (read_size < data.size()) {
const auto result = ::read(fd, data.data() + read_size, data.size() - read_size);
if (result <= 0) {
return false;
}
Expand Down