#include "file_views.h" #include #include #include #include "file_list.h" #include "track.h" namespace roro::files { std::string hexRow(uint32_t offset, const uint8_t* data, size_t len) { char head[8]; std::snprintf(head, sizeof head, "%05X", static_cast(offset)); std::string row = head, text; for (size_t i = 0; i < 8; i++) { if (i % 2 == 0) row += ' '; char hex[3] = " "; if (i < len) { std::snprintf(hex, sizeof hex, "%02x", data[i]); text += data[i] >= 0x20 && data[i] < 0x7F ? static_cast(data[i]) : '.'; } row += hex; } return row + " " + text; } namespace { // Days since 1970-01-01 (Howard Hinnant's days_from_civil): no timegm() everywhere. int64_t daysFromCivil(int y, int m, int d) { y -= m <= 2; int64_t era = (y >= 0 ? y : y - 399) / 400; int yoe = static_cast(y - era * 400); int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; return era * 146097 + doe - 719468; } bool attribute(const std::string& element, const char* name, double& out) { size_t at = element.find(name); if (at == std::string::npos) return false; const char* from = element.c_str() + at + std::strlen(name); char* end = nullptr; out = std::strtod(from, &end); return end != from; } } // namespace void GpxSummary::point(const std::string& element) { double lat, lon; if (!attribute(element, "lat=\"", lat) || !attribute(element, "lon=\"", lon)) return; if (points_ > 0) meters_ += gnss::distanceMeters(lat_, lon_, lat, lon); lat_ = lat; lon_ = lon; points_++; size_t at = element.find("