#include "system/settings_store.h" #include #include #include static const char *NAMESPACE = "flipdot"; static const char *KEY = "settings"; // Increase when the Settings struct changes; old records are then ignored (defaults), // unless OLD_VERSIONS says how to read them static const uint16_t VERSION = 3; // Older versions: fields were only added at the end, so the start of an old record has // the same layout. New fields keep their defaults. struct OldVersion { uint16_t version; size_t fields; // bytes of Settings that version had }; static const OldVersion OLD_VERSIONS[] = { {1, offsetof(Settings, off_page)}, {2, offsetof(Settings, drive)}, }; struct StoredSettings { uint16_t version; uint16_t size; Settings settings; }; void loadSettings(Settings &settings) { settings = Settings(); StoredSettings stored; memset(&stored, 0, sizeof(stored)); Preferences prefs; prefs.begin(NAMESPACE, true); size_t read = prefs.getBytes(KEY, &stored, sizeof(stored)); prefs.end(); Settings loaded; if (read == sizeof(stored) && stored.version == VERSION && stored.size == sizeof(Settings)) loaded = stored.settings; else { const OldVersion *old = nullptr; for (const OldVersion &o : OLD_VERSIONS) if (o.version == stored.version) old = &o; if (!old || stored.size < old->fields || stored.size > sizeof(Settings) || read != offsetof(StoredSettings, settings) + stored.size) return; memcpy((void *)&loaded, &stored.settings, old->fields); } if (validateSettings(loaded) == nullptr) settings = loaded; } void saveSettings(const Settings &settings) { StoredSettings stored; stored.version = VERSION; stored.size = sizeof(Settings); stored.settings = settings; Preferences prefs; prefs.begin(NAMESPACE, false); prefs.putBytes(KEY, &stored, sizeof(stored)); prefs.end(); }