@@ -0,0 +1,86 @@
|
||||
#include <vamp_pico/http_client.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <charconv>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <system_error>
|
||||
|
||||
namespace {
|
||||
|
||||
auto copy_value(std::string_view value, std::char_t* output, std::size_t capacity) -> void {
|
||||
if (capacity == 0U) {
|
||||
return;
|
||||
}
|
||||
auto count = std::min(capacity - 1U, value.size());
|
||||
std::memcpy(output, value.data(), count);
|
||||
output[count] = '\0';
|
||||
}
|
||||
|
||||
auto parse_uint(std::string_view value, std::uint32_t& output) -> std::bool_t {
|
||||
if (value.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto parsed = std::uint64_t{};
|
||||
auto const* begin = value.data();
|
||||
auto const* end = value.data() + value.size();
|
||||
auto result = std::from_chars(begin, end, parsed, 10);
|
||||
if (result.ec != std::errc{} || result.ptr != end || parsed > std::numeric_limits<std::uint32_t>::max()) {
|
||||
return false;
|
||||
}
|
||||
output = static_cast<std::uint32_t>(parsed);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto strip_cr(std::string_view line) -> std::string_view {
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.remove_suffix(1U);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
auto vamp_pico::parse_remote_display_body(std::string_view body, vamp_pico::remote_display_state& state) -> std::bool_t {
|
||||
auto parsed = vamp_pico::remote_display_state{};
|
||||
auto saw_version = std::bool_t{};
|
||||
auto cursor = std::size_t{};
|
||||
while (cursor <= body.size()) {
|
||||
auto line_end = body.find('\n', cursor);
|
||||
auto line = line_end == std::string_view::npos ? body.substr(cursor) : body.substr(cursor, line_end - cursor);
|
||||
line = strip_cr(line);
|
||||
auto equals = line.find('=');
|
||||
if (equals != std::string_view::npos) {
|
||||
auto key = line.substr(0U, equals);
|
||||
auto value = line.substr(equals + 1U);
|
||||
if (key == "version") {
|
||||
saw_version = true;
|
||||
} else if (key == "active") {
|
||||
parsed.active = value == "1";
|
||||
} else if (key == "title") {
|
||||
copy_value(value, parsed.title, sizeof(parsed.title));
|
||||
} else if (key == "part") {
|
||||
copy_value(value, parsed.part, sizeof(parsed.part));
|
||||
} else if (key == "mode") {
|
||||
copy_value(value, parsed.mode, sizeof(parsed.mode));
|
||||
} else if (key == "page") {
|
||||
if (!parse_uint(value, parsed.page)) {
|
||||
return false;
|
||||
}
|
||||
} else if (key == "pages") {
|
||||
if (!parse_uint(value, parsed.pages)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (line_end == std::string_view::npos) {
|
||||
break;
|
||||
}
|
||||
cursor = line_end + 1U;
|
||||
}
|
||||
if (!saw_version) {
|
||||
return false;
|
||||
}
|
||||
state = parsed;
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user