Files
MarekZegare4 b8a7b5dcc0 refactor: dedup persistence header, harden action menu, tidy small items
- Persist.h: shared writeHeader()/readHeader() for the magic+version+count
  on-disk header; Waypoint and Trail snapshots now share one implementation
  (byte layout unchanged; each keeps its own count clamp/reject + extra fields).
- TrailScreen: pushAction() guards _act_map / PopupMenu capacity, so adding a
  new action can't silently overrun the fixed array.
- PopupMenu: add count()/setSelected() accessors; replace the remaining direct
  _sel/_count field pokes in NearbyScreen, TrailScreen and QuickMsgScreen.
- Trail summary: unit-suffixed time ("1h 05m" / "5m 03s") so hours can't be
  misread as minutes.
- Trail::haversineMeters delegates to geo::haversineKm — single Haversine
  implementation (also trims a little flash).

Verified: GAT562 (SSD1306) and WioTrackerL1Eink (GxEPD) solo builds compile clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 13:37:03 +02:00

41 lines
1.8 KiB
C++

#pragma once
// Shared on-disk header for the small fixed-table snapshots (waypoints, trail).
// Layout: magic(4) + version(1) + reserved(1) + count(2), little-endian, then
// table-specific payload (records, and for the trail an extra accumulated-ms
// field). Keeps the read/write boilerplate — and its short-read checks — in one
// place so both stores can't drift apart.
#include <Arduino.h>
namespace persist {
// Write magic(4) + version(1) + reserved(1) + count(2). Returns true on a full write.
template <typename F>
inline bool writeHeader(F& file, uint32_t magic, uint8_t version, uint16_t count) {
uint8_t res = 0;
return file.write((uint8_t*)&magic, sizeof(magic)) == sizeof(magic)
&& file.write(&version, 1) == 1
&& file.write(&res, 1) == 1
&& file.write((uint8_t*)&count, sizeof(count)) == sizeof(count);
}
// Read + validate the header. Returns true and sets count_out only when magic
// and version match. The caller decides how to treat count_out (clamp or
// reject against its own capacity) and reads any table-specific fields that
// follow the count.
template <typename F>
inline bool readHeader(F& file, uint32_t expect_magic, uint8_t expect_version, uint16_t& count_out) {
uint32_t magic = 0;
if (file.read((uint8_t*)&magic, sizeof(magic)) != (int)sizeof(magic)) return false;
if (magic != expect_magic) return false;
uint8_t ver = 0, res = 0;
uint16_t cnt = 0;
if (file.read(&ver, 1) != 1) return false;
if (file.read(&res, 1) != 1) return false;
if (file.read((uint8_t*)&cnt, sizeof(cnt)) != (int)sizeof(cnt)) return false;
if (ver != expect_version) return false;
count_out = cnt;
return true;
}
} // namespace persist